# Schrödingerization
**English** · 简体中文
> Category C2 · Module [`oracq.algorithms.qode.schrodingerization`](../../api/algorithms/qode/schrodingerization.rst) · Stage V2
## Overview
For $u'=Gu$ write $G=H_1+iH_2$ ($H_1,H_2$ both Hermitian). Introduce the auxiliary variable $p$; inside the valid recovery region use $v(t,p)=e^{-p}u(t)$, extending the initial value to both sides as $v(0,p)=e^{-|p|}u_0$. The lifted equation is then
$$
\partial_t v=-H_1\,\partial_p v+iH_2 v ,
$$
and after Fourier transformation it becomes evolution under the Hermitian Hamiltonian $K=P\otimes H_1-I\otimes H_2$ (following [§3.1 of the Schrödingerization technical paper](https://arxiv.org/html/2212.14703v1); see also [the differential equations chapter §5](../differential-equations.md)). This implementation keeps the auxiliary coordinate as a quantum register and finally selects one $p$ channel to read out the physical solution.
## Interface and input model
```python
schrodinger_qode(generator, initial, time, *, plan=None,
hamiltonian_function=taylor_hamiltonian)
SchrodingerPlan(auxiliary_width=2, period=8.0, selected_index=1)
fourier_momentum(width, period)
```
API entries: {obj}`schrodinger_qode `, {obj}`SchrodingerPlan `, {obj}`fourier_momentum `
- `generator`: a {obj}`BlockEncoding ` of $G$ (the input model is a BE); $H_1=(G+G^\dagger)/2$ and $H_2=(G-G^\dagger)/(2i)$ are generated by `HermitianParts.from_operator`.
- `initial`: a {obj}`StatePreparation ` (SP) acting on the physical register.
- {obj}`SchrodingerPlan `: the auxiliary register width `auxiliary_width` (1..63), the period `period`, and the selected channel `selected_index` ($0..2^p-1$).
- `hamiltonian_function`: `(K, t) -> BlockEncoding`, by default {obj}`taylor_hamiltonian `.
- {obj}`fourier_momentum(width, period) `: a standalone construction entry for the frequency-diagonal operator $P$.
Returns a {obj}`StateOracle ` (`target`/`signal`) with module attributes:
| Attribute | Meaning |
|---|---|
| `algorithm` | `"schrodingerization_qode"` |
| `auxiliary_grid` | a JSON table of the auxiliary grid coordinates |
| `selected_p` / `recovery_scale` | the $p_j$ of the selected channel and $e^{p_j}$ |
| `recovery_assumption` | `"selected p in valid warped region; periodic truncation pending"` |
## Implementation notes
$P$ is constructed bitwise with `fourier_momentum`: one projection BE per bit (alpha 1) with coefficient $(2^b)\cdot 2\pi/\text{period}$, the most significant bit negated to realize two's-complement negative frequencies, then summed with an LCU, avoiding dense matrices. The register layout is `target = physical n bits (low) + auxiliary p bits (high)`, and `work` carries the work bits of the initial-state preparation.
Generation flow: the initial state acts on `target[:n]`; the auxiliary bits prepare the normalized $e^{-|p_j|}$ ({obj}`gate_state_prep `) and then a QFT is applied; `hamiltonian_function` is called on $K=P\otimes H_1-I\otimes H_2$; after the inverse QFT, {obj}`select_subspace ` selects the channel whose auxiliary register equals `selected_index`, with the selection condition folded into the signal. The auxiliary grid, in encoding order, is $p_j=(j$ if $j<2^{p-1}$ else $j-2^p)\cdot\text{period}/2^p$; the default configuration $p=2$, period 8, index 1 corresponds to the grid $[0,2,-4,-2]$ with $p=2$ selected.
Applicability boundary: the implementation does not automatically verify that the selected channel lies in the recovery region, nor that the periodic window is large enough (the window and channel must be chosen from the propagation speed of $H_1$, the time, and the periodic boundary; $p>0$ alone is not a sufficient condition). `recovery_scale` records only one factor of the warp; under the ideal recovery relation the success block is approximately $e^{-p_j}|u(t)\rangle/(rZ\alpha_E)$ ($r$ the initial-value norm, $Z$ the discrete warp norm, $\alpha_E$ the evolution BE normalization). A complete norm-recovery interface is not yet provided; these quantities must be kept by the host itself. At the entry, the capability check of {obj}`operator_state_contract("schrodingerization") ` runs first.
## Validation approach
Category C2 (approximately continuous semantics; the acceptance criteria are in `../development/validation-plan.md` §2). Three layers of evidence:
- Structure: the schrodingerization subtest of `tests/core/test_differential.py:DifferentialStructureTests.test_four_methods_keep_input_oracles` — with abstract BE/SP inputs the open slots (`input_A`/`input_b`) are kept, the `algorithm` attribute is correct, and the RIR round-trips through serialization.
- Numerical: `tests/core/test_differential.py` is positioned as a structure test; the overall numerical validation of the Fourier sign convention, the finite grid, and the recovery region is still pending (see known gaps).
- Binding: same-type registration and contract checks — the entry contract is enforced through `operator_state_contract`, and the protocol-level assumptions (auxiliary window, Fourier convention, and recovery region requiring application-layer validation) are recorded by `QODEProtocol.contract` (see [QODE problem and protocol](qode-problem.md)).
## Known gaps and planned stages
A unified "analytically solvable ODE family" convergence benchmark is missing; it is assigned to the stage V2 convergence-sweep framework, consistent with the schrodingerization.py row of `validation-coverage.md`. Per the protocol assumptions, numerical validation of the auxiliary window and the recovery region is an application-layer responsibility and is not currently automated.
## Numerical validation
Paper-grade numerical experiments are in `tests/verification/verify_ode.py` (the ode group; this file covers the parts of `schrodingerization.py`). All classical references are independent: a full-stack numpy simulation (warp → positive-sign DFT → truncated-Taylor or exact `expm` evolution → inverse DFT → channel selection) and analytic solutions ($e^{-t}$ decay, an analytic rotation matrix); the quantum programs run on the real backends reference and OriginIR-ext (the $8^{\text{degree}}$ branch scaling of nested LCUs pushes the pysparq-family paths over budget, as noted in the cases).
**Experiment design**: (a) momentum block — the zero-signal block of `fourier_momentum(2, 8.0)` against the two's-complement signed-frequency diagonal matrix (unitary `to_matrix` + reference cross-check); (b) scalar decay $G=-I$ with plan(auxiliary_width=2, period=1.2, selected_index=1) ($\Delta p=t$ makes the grid shift pointwise exact), Taylor degree 4, $t=0.3$: assembly fidelity, recovery amplitude, and error decomposition; (c) independent re-assembly — inside the verification script, an isomorphic real quantum program is assembled from public combinators for $K'=-P\otimes H_1-I\otimes H_2$ (the fixed in-library convention), serving as a regression pin for the sign convention; (d) the rotation generator $G=J$ ($H_1=0$, pure $H_2$) recovering the analytic rotation.
**Key metrics**:
| Case | Scale | Paths | Metric | Value |
|---|---|---|---|---|
| fourier-momentum-block | 4 qubits | originir+to_matrix, reference | maximum deviation of the momentum block | 2.2e-16 |
| schrodingerization-scalar-decay-grid | 21 qubits | reference, originir | assembly fidelity (vs full-stack simulation of $K'$) | 2.0e-18 |
| ditto | | | grid error of the recovery amplitude against exactly evolved $e^{-t}u_0$ (forward flow) | 1.3e-16 |
| ditto | | | mismatch against $e^{+t}u_0$ (time reversal), directional evidence | 0.43 |
| ditto | | | end-to-end recovery error (Taylor remainder of the Nyquist mode) | 3.3e-2 |
| schrodingerization-sign-flipped-degree2/4 | ditto | reference | independent re-assembly implementation error / grid error | 8.8e-18 / 1.3e-16 |
| ditto | | | quantum recovery error (Taylor remainder of the Nyquist mode, decreasing with degree) | 9.1e-2 → 3.3e-2 |
| schrodingerization-rotation-recovery | ditto | reference | implementation error / recovery error | 9.3e-19 / 1.5e-5 |
**Sign-convention finding and fix**: a historical version assembled $K=P\otimes H_1-I\otimes H_2$, which together with the positive-sign DFT convention gives a warp transport direction opposite to the recovery relation — the recovery amplitude fit the time-reversed solution exactly (fit 4.8e-16 against $e^{+t}u_0$, mismatch 0.43 against $e^{-t}u_0$, mutually decisive evidence). Based on this, the validation round fixed the momentum-term sign of the in-library generator to $K'=-P\otimes H_1-I\otimes H_2$: the recovery error of exact evolution on the same grid dropped to 1.3e-16, proving the sign was the only structural mismatch; the library now takes $K'$ as its convention and pins it with the regression case "independent re-assembly agrees with the library program amplitude by amplitude" (to prevent regressions). The pure $H_2$ generator (rotation case) is unaffected by this sign, with an end-to-end recovery error of 1.5e-5. The end-to-end residual error is the Taylor truncation of the Nyquist momentum mode (phase $\pi$), decreasing with degree (degree 2→4: 9.1e-2→3.3e-2), and belongs to the method error of the replaceable `hamiltonian_function` protocol.
**Reproduction**:
```bash
PYTHONPATH=src /home/agony/projects/qcfd-dev/quantum-cfd-software/.venv/bin/python tests/verification/verify_ode.py
```
Artifacts: `out/verification/ode.json` (6 cases in total: `schrodingerization-*` and `fourier-momentum-block`).
## Related links
- Source: `src/oracq/algorithms/qode/schrodingerization.py`
- Tutorial: [Swapping QODE methods for the same linear problem](../../tutorials/differential-equations.md)
- API reference: [Schrödingerization](../../api/algorithms/qode/schrodingerization.rst)
- Related pages: [QODE problem and protocol](qode-problem.md) · [LCHS](lchs.md) (the other linear route) · [Carleman linearization](carleman.md) (lifting, then this method)
- Validation matrix: [Validation coverage matrix](../../development/validation-coverage.md)