Sign outOpen workspaceSign in

MethodLayer 2

Fixed-point amplification

Replace the ±1±1 reflections of textbook amplification with tuned phase shifts, so the iteration converges on the target instead of rotating past it — which is what happens when the initial success amplitude is known only as a lower bound.

Takes

The preparation unitary AA and its inverse, a reflection about 0\lvert 0\rangle, and a reflection marking the good subspace — the Grover operator Q=AS0A1SχQ = -A S_0 A^{-1} S_\chi must be applicable at arbitrary powers. Individual variants additionally require a lower bound on aa, or a per-branch stopping flag.

Returns

A routine that produces the wanted branch with a stated failure probability, together with the query count and the maximum sequential depth consumed.

Same contract as the slot it fills.

This one, drawn

Drag to pan. Pinch, or hold ctrl and scroll, to zoom. Arrow keys pan, plus and minus zoom, zero resets the view.

From Routine with a good branch to Reliable routine

A circle is an object you are holding. This method is drawn heavier, opened into its own steps; the other lines between the same two ends are the alternatives recorded for the same slot. Circles are named on hover, and each one is a link.

Nothing drawn here has a recorded way through it that this figure leaves shut. See it on the map

What it fills

  • Amplify a success branch

    Take a routine whose output lands in the wanted subspace only with probability aa, and raise that probability to near 1 using quadratically fewer repetitions than restarting the routine would need.

When it applies

Needs a reliable lower bound on the fraction λ\lambda of the initial state made up of target states, rather than λ\lambda itself. Grover's earlier π/3\pi/3 construction achieves fixed-point convergence but, as Yoder, Low and Chuang put it, such algorithms "lose the very quadratic advantage that makes Grover's algorithm so appealing". Their own construction is described by them as "the first version of amplitude amplification that achieves fixed-point behavior without sacrificing the quantum speedup", and it carries an adjustable bound on the failure probability.

Requires

These do not move the route along. The method needs each of them alongside its own work, and the cost of getting them is part of what the method costs.

  • Prepare an input state

    Map 00|0\ldots0⟩ to a state whose amplitudes are proportional to a specified vector bb, to within ε\varepsilon. The cost is set by which description of bb you hold, not by the algorithm that consumes it.

    This method asks the slot for "the state preparation AA and oracle UU", and runs "a quantum circuit SL\mathcal{S}_{L} consisting of A,A,UA, A^{\dagger}, U, and efficiently implementable nn-qubit gates". AA enters only through the reflection about the prepared state, Ss(α)=I(1eiα)ssS_s(\alpha) = I - (1-e^{-i\alpha})|s\rangle\langle s|, whose circuit (Fig. 2) conjugates a multiply-controlled phase on one reusable ancilla with AA^{\dagger} then AA: forward once, inverse once, per iterate G(αj,βj)=Ss(αj)St(βj)G(\alpha_j,\beta_j) = -S_s(\alpha_j)S_t(\beta_j). The target-side reflection St(β)=I(1eiβ)ttS_t(\beta) = I - (1-e^{i\beta})|t\rangle\langle t| needs no AA — it is two calls to UU alone. So a length-LL sequence SL=j=1lG(αj,βj)\mathcal{S}_{L} = \prod_{j=1}^{l}G(\alpha_j,\beta_j) of l=(L1)/2l = (L-1)/2 iterates, which the paper prices at L1=2lL-1 = 2l queries to UU, spends ll forward and ll inverse calls to AA. assumption: AA must be supplied as a circuit that can be run in reverse; a source that only emits s|s\rangle cannot build Ss(α)S_s(\alpha).

    assumption

Example

given  the preparation unitary A and its inverse, a reflection S_0 about |0>,
       and a reflection S_chi marking the good subspace, so that
       Q = - A S_0 A^{-1} S_chi can be applied at arbitrary powers;
       and a reliable lower bound on the fraction lambda of the initial
       state made up of target states

# a lower bound, not lambda itself -- that is all this variant of the layer
# asks for. A is the state-preparation step below this method.

choose the bound on the failure probability -- it is adjustable

replace the +/-1 reflections of textbook amplification with tuned phase
    shifts, and run the resulting iteration for the number of oracle
    queries fixed by the lower bound on lambda and the failure tolerance

# so the iteration converges on the target instead of rotating past it;
# rotating past it is what happens when the success amplitude is known only
# as a lower bound

return the wanted branch with the chosen failure probability, together with
    the query count and the maximum sequential depth consumed

# neither the tuned phase shifts nor the query count as a function of
# lambda's lower bound and the failure tolerance is quoted on this record:
# the query count is in the paper's full text, and the record stops at the
# abstract on purpose

# the optimality in their title has exactly this shape: for a given number
# of oracle queries, the adjustable failure bound is guaranteed over "the
# broadest possible range" of lambda

# do not build this: Grover's earlier pi/3 construction also achieves
# fixed-point convergence, but such algorithms "lose the very quadratic
# advantage that makes Grover's algorithm so appealing" -- the construction
# above is described by its authors as the first to reach fixed-point
# behavior without sacrificing the quantum speedup

Cost, as the source states it

The abstract states no query-count formula; its cost claims are comparative. The construction keeps the quadratic quantum speedup that fixed-point predecessors gave up, and the optimality named in the title is of exactly this shape: for a given number of oracle queries, the adjustable failure-probability bound is guaranteed, as Yoder, Low and Chuang put it, over "the broadest possible range" of the target fraction λ\lambda. The explicit query count as a function of λ\lambda's lower bound and the failure tolerance is in the paper's full text and is not quoted here.

Implementations

  • PennyLane's `qml.AmplitudeAmplification` template, `fixed_point=True`

    PennyLane's single `AmplitudeAmplification` operation implements textbook amplitude amplification by default, and its class docstring states "the implementation of the algorithm is based on" Brassard, Hoyer, Mosca and Tapp, then adds that "the template also unlocks advanced techniques such as fixed-point quantum search [arXiv:1409.3305] ... by reflecting on a subset of wires" -- the same Yoder-Low-Chuang paper this method's own citations name. The fixed-point branch is a mode of the one class rather than a separate one: the constructor takes a boolean `fixed_point` (default `False`) and a `work_wire` the docstring calls required "if fixed_point == True", which the code enforces by raising `WireError("work_wire must be specified if fixed_point == True.")` when it is missing.

    `_get_fixed_point_angles(iters, p_min)` sets `delta = np.sqrt(1 - p_min)` and `gamma = np.cos(np.arccos(1 / delta, dtype=np.complex128) / iters, dtype=np.complex128) ** -1`, a complex-valued route to the same fractional-Chebyshev quantity this record's own hop calls γ1=T1/L(1/δ)\gamma^{-1} = T_{1/L}(1/\delta): because cos(ix)=cosh(x)\cos(ix) = \cosh(x), taking `arccos` of the complex `1/delta` and dividing by `iters` computes what `arccosh(1/delta)/iters` would compute directly. It returns `alphas = [np.real(2 * np.arctan(1 / (np.tan(2 * np.pi * j / iters) * np.sqrt(1 - gamma**2)))) for j in range(1, iters // 2 + 1)]` and `betas = [-alphas[-j] for j in range(1, iters // 2 + 1)]` -- the palindromic pairing this record states as αj=βlj+1\alpha_j = -\beta_{l-j+1}. `compute_decomposition` then builds, for each of `iters // 2` generalized iterates, a Hadamard-controlled(`O`)-Hadamard-`PhaseShift(betas[it])`-Hadamard-controlled(`O`)-Hadamard sandwich on the caller-supplied `work_wire` -- an ancilla construction of the target-side reflection from calls to the oracle `O` alone -- followed by `Reflection(U, -alphas[it], reflection_wires=reflection_wires)` for the state-side reflection built from the preparation operator `U`. The `fixed_point=False` branch it falls back to instead applies `O` directly and `Reflection(U, np.pi, ...)`, the textbook ±π\pm\pi reflections this record's `conditions` contrasts the construction against.

    `pennylane/templates/subroutines/amplitude_amplification.py` in https://github.com/PennyLaneAI/pennylane -- Python, Apache License 2.0, header "Copyright 2018-2024 Xanadu Quantum Technologies Inc.", 294 lines on `main` at commit `45622b173b686ee0ea37915f4cc7bf4291af2e6f`, read 2026-08-27. The class is `AmplitudeAmplification(Operation)`, exported from `pennylane/templates/subroutines/__init__.py` as `from .amplitude_amplification import AmplitudeAmplification`. Constructor: `__init__(self, U, O, iters=1, fixed_point=False, work_wire=None, p_min=0.9, reflection_wires=None)`. Neither `__init__` nor `_get_fixed_point_angles` checks that `iters` is odd, though this record's own hop states the paper constructs the sequence "for any odd integer L1L \ge 1 ... so an even LL has no construction at all" -- an even `iters` is accepted and silently halved by `iters // 2` rather than rejected.

    The class docstring's own worked example amplifies 2|2\rangle on 3 qubits, with `U` a Hadamard-built uniform superposition and `O = qp.FlipSign(2, wires=range(3))`, run as `qp.AmplitudeAmplification(U, O, iters=5, fixed_point=True, work_wire=3)` inside a `qp.qnode` on `qp.device("default.qubit")`, PennyLane's state-vector simulator. The printed output, `print(np.round(circuit(),3))`, is `[0.013 0.013 0.91 0.013 0.013 0.013 0.013 0.013]` -- probability 0.91 on the marked index 2.

  • `ampamp`'s `FixedPointEngine`

    `ampamp` is a Python "research library for building quantum amplification circuits, inspecting their mathematical behavior, profiling compilation cost, and validating ideal/noisy backend behavior from one compact API" (its README), maintained by the GitHub org `QuantumAmplification` under the MIT licence and distributed on PyPI. It is organised one engine per amplification variant rather than one generic amplifier: the README's own capability table lists "Fixed-point AA" against `FixedPointEngine` in a row separate from "Variable-time AA" against `VTAAEngine`, and its section headers likewise separate "### Fixed-point amplification" from a later "### Variable-time branch analysis" -- this record's artefact is the former module only. A companion survey article by the same three authors, "Amplitude Amplification Algorithms" (Zenodo, 2026), states in its abstract that it follows "the progression through oblivious, fixed-point, and distributed amplification schemes" and lists "Fixed-Point Amplification" among its own keywords.

    `FixedPointEngine.__init__(self, L, delta)` requires `L` odd -- it raises `ValueError("L must be an odd integer for FPAA.")` when `L % 2 == 0` -- and sets `self.num_grover_iterates = (L - 1) // 2`, this record's own l=(L1)/2l = (L-1)/2. `_compute_gamma` returns `1.0 / np.cosh(np.arccosh(1.0 / self.delta) / self.L)`, documented as computing "gamma through gamma^{-1} = T_{1/L}(1 / delta)". `_generate_phase_pairs` then sets, for `j` from 1 to `num_grover_iterates`, `alphas[j-1] = 2.0 * np.arctan2(1.0, np.tan(2.0 * np.pi * j / self.L) * sq_term)` with `sq_term = sqrt(1 - gamma**2)`, and `betas = -alphas[::-1]` -- this record's αj=βlj+1\alpha_j = -\beta_{l-j+1}. `success_probability(lambda_val)` evaluates `1 - delta**2 * T_L((1/gamma) * sqrt(1-lambda_val))**2` through its own `_chebyshev_polynomial`, this record's closed form PL=1δ2TL()2P_L = 1-\delta^2 T_L(\cdot)^2. `build_fixed_point_circuit(num_qubits, marked_indices)` synthesizes the circuit directly in Qiskit: it Hadamards every qubit, then for each `(a_j, b_j)` pair applies a `DiagonalGate` placing phase eiβje^{i\beta_j} on the marked computational-basis indices (the target-side reflection, built from the oracle alone), Hadamards, a `DiagonalGate` placing phase eiαje^{-i\alpha_j} on index 0 (the reflection about the Hadamard-prepared source state), and Hadamards again to close the sandwich.

    `src/ampamp/fixed_point.py` in https://github.com/QuantumAmplification/ampamp -- Python, MIT licence, 176 lines on `main` at commit `a482ee2eea80a53db02ff33d6bbace7f529fcee2`, read 2026-08-27. Distributed on PyPI as `ampamp`; `pyproject.toml` at that commit records `version = "0.1.4"`. The README's own usage example imports it at top level, `from ampamp import FixedPointEngine`, and the class depends on `from qiskit import QuantumCircuit` plus, inside `build_fixed_point_circuit`, `from qiskit.circuit.library import DiagonalGate as Diagonal` with a fallback `from qiskit.circuit.library import Diagonal` for older Qiskit releases.

    The library's own test suite checks the synthesized circuit against the closed form on a state-vector simulator. `tests/test_core_engines.py`'s `test_fixed_point_engine_generates_phases_and_circuit` builds `FixedPointEngine(L=5, delta=0.1)` -- 2 generalized iterates -- and asserts `engine.success_probability(engine.lambda_min) == pytest.approx(1.0 - engine.delta**2)`, and, for a synthesized one-qubit circuit with `marked_indices=[1]`, that `Statevector.from_instruction(one_qubit_circuit).probabilities()[1] == pytest.approx(engine.success_probability(0.5))` -- Qiskit's `Statevector` state-vector simulator, not hardware. A separate parametrized test, `test_fixed_point_engine_rejects_invalid_parameters`, checks that invalid `(L, delta)` pairs raise `ValueError` rather than silently building a circuit.

  • pyqsp's `FPSearch` phase generator (`fpsearch`)

    pyqsp is a quantum-signal-processing phase-finding package maintained on GitHub under the username `ichuang`; its own `CITATION` file's primary reference, "Grand Unification of Quantum Algorithms", is coauthored by Isaac L. Chuang, the third author of the fixed-point paper this method records. `pyqsp/phases.py`'s module docstring describes the file as "Known QSP phases for specific responses", a library of precomputed sequences rather than a general numerical solver, and one entry in it, the `FPSearch` class, is documented as returning "phases for fixed point quantum search, following https://arxiv.org/abs/1409.3305" -- this method's own citation.

    `FPSearch.generate(self, d, delta=None, gamma=None, return_alpha=False)` sets `L = 2 * d + 1`, this record's odd length with `d` its ll, and, when `gamma` is not supplied, computes it from `delta` (default 0.1) as `gamma = 1 / np.cosh((1 / L) * np.arccosh(1 / delta))` -- the same γ1=T1/L(1/δ)\gamma^{-1}=T_{1/L}(1/\delta) quantity this record names. With `sg = np.sqrt(1 - gamma**2)`, it sets `avec = 2 * np.arctan2(1, (np.tan(2 * np.pi * kvec / L) * sg))` for `kvec = np.arange(1, d + 1)` -- this record's αj=2cot1(tan(2πj/L)1γ2)\alpha_j = 2\cot^{-1}(\tan(2\pi j/L)\sqrt{1-\gamma^2}), since `arctan2(1, x)` equals cot1(x)\cot^{-1}(x) for x>0x>0 -- and `bvec = - avec[::-1]`, the same palindromic pairing. Unless `return_alpha=True` is passed, `generate` does not return `avec`/`bvec` directly: it repacks them into a length-`2*d` array `phivec`, via `phivec[2*k] = -avec[d-k-1] / 2` and `phivec[2*k+1] = bvec[d-k-1] / 2`, because pyqsp's own output convention is a single QSP phase sequence in what its README calls the "WxW_x convention" rather than the two per-iterate reflection angles this record lists separately.

    `pyqsp/phases.py` in https://github.com/ichuang/pyqsp -- Python, 109 lines at commit `4436bb63d4aea0f636015ace26bb5453c77b999c`, read 2026-08-27; distributed on PyPI as `pyqsp`, version 0.2.0. `FPSearch(PhaseGenerator)` is registered under the string key `'fpsearch'` in the module-level dict `phase_generators`. `pyqsp/main.py` reaches it from the command line: its `elif args.cmd == "fpsearch":` branch instantiates `pg = pyqsp.phases.FPSearch()` and calls `pg.generate(*args.seqargs)`, and the tool's own help text gives a worked invocation, `pyqsp --plot-npts=4000 --plot-positive-only --plot-magnitude --plot --seqargs=1000,1.0e-20 --seqname fpsearch angles` -- d=1000d=1000, δ=1020\delta=10^{-20}.

    The package's own continuous-integration test suite exercises this path end to end rather than only unit-testing the class: `pyqsp/test/test_main.py` includes `"--plot-positive-only --plot-magnitude --plot-npts=400 --seqargs=10,0.01 fpsearch"` in its list of `test_cmds`, run through `pyqsp.main` -- d=10d=10, δ=0.01\delta=0.01 -- and plotted as a magnitude response. The test asserts only that the command completes; it makes no numeric assertion on the phases `generate` returns.

What it needs

Every step this method names is listed under Requires above. It walks its own span in one hop and calls out to the rest — that is a fact about the recorded route, not a claim that the span is simple.

Other ways to fill the same slot

Different approaches

  • Variable-time amplification

    When the branches of the amplified routine stop at different times, amplify in nested stages so branches that finish early are not charged at the worst-case depth.

In the Atlas

No record in the Atlas covers this yet. The catalogue is circuits and primitives; this part of the literature is not in it.

Sources