About this map
Sections
What this is
Quantum algorithms are not written from scratch. They are assembled from a small number of reusable steps, and almost every published method is a different route through the same handful of them.
This is a map of those routes. Circles are the things an algorithm can be holding. Lines are the steps that carry you from one to the next. A method is a path across.
Nothing here is generated. Every line was read out of a paper and checked against it.
How to read it
- Something you can hold — a state, a matrix, a circuit, an answer.
- The same, in the middle of a step you have opened.
- A step. Someone has published a way through it.
- A step whose way through has not been pinned to one method.
- A step nothing published fills yet.
- A step you have opened. What is drawn inside it is how it was done.
- There is a record in the repository for this one.
How to move around
- Two fingers move the map. Pinch to zoom, or hold ctrl and scroll.
- Click a step to open it in place — everything else stays where it is.
- Click a name to read the full record without leaving the map.
- Arrow keys move, plus and minus zoom, zero puts it back.
What a line is claiming
A solid line means a paper puts those two steps together and we have the citation. A long-dashed line means the route is recorded but no single method has been named for that step. A short-dashed line means nothing published fills it — the step is real, the way through is not written yet.
A count after a step's name — ×T/h, ×O(κ) — means the route walks that step that many times rather than once. It is the source's own symbol, and the card says what it stands for and what one turn costs. A step with no count is a step no source we read said is repeated, which is not the same as one taken once.
A line drawn nested under another, on the soft shaded band behind it, is a narrower version of the line above it: the same construction, re-analysed or re-tuned, filling the same step. It is why two lines can draw the identical interior and still be two entries. Lines outside the band are alternatives to their neighbours, not versions of them.
The map does not hide the gaps. An empty step is drawn as an empty step.
What is not here yet
The map covers the algorithm literature. The repository covers circuits and primitives. They overlap less than you would expect, and where a method has no record we say so on its page rather than leaving the space blank.
Where something named here does have a record, its name links straight to it.
Method
Truncated-Taylor LCU simulation
Truncate the Taylor series of over short segments and implement the truncated sum as a linear combination of unitaries — PREPARE loads the coefficients, SELECT applies the terms, PREPARE unprepares — with the all-zeros ancilla flag amplified.
Open the full recordFills the slot: Simulate Hamiltonian evolutionExpand it here — a map of just this
Requires as a linear combination of efficiently implementable unitaries with a cheap PREPARE over the coefficients. The projection onto the wanted block succeeds only on the all-zeros flag, so amplification is part of the method rather than an afterthought, and the cost scales with the 1-norm of the coefficient vector rather than with — a decomposition with many comparable terms is expensive even for a benign .
An access model for — a sum of efficiently exponentiable terms, sparse-access oracles, or a block-encoding — plus an evolution time and a target error .
Hamiltonian you can query → Block-encodingBlock-encode a matrix
With into unitary , what this method needs from the slot is access not to but to the truncated Taylor terms. Indexing , the target unitaries are , each of the form , and the access operator is abstracted as . Concretely maps to , and is built from controlled- operations, each mapping to ; the th acts on the th qubit of , which is encoded in unary, and on the register holding , applying to only when . approximation: each is applied exactly, by the mechanism the paper assumes for it, so the only approximation entering at this layer is the cut at order — the index register carries and nothing beyond it.
approximation
Block-encoding → Circuit for e^{-iHt}sum the truncated series, then amplify
The evolution is cut into segments and each segment's is replaced by its Taylor series truncated at order , which expands into a sum of unitaries . Berry, Childs, Cleve, Kothari and Somma implement that sum by preparing with and sandwiching the selection: , whose all-zeros ancilla branch carries . Segment length is then chosen to make the amplitude exactly right rather than merely large: with and one has , and oblivious amplitude amplification turns the branch into certainty as with . approximation: Truncating at makes close to unitary but not unitary, which is exactly what ordinary oblivious amplitude amplification needs, so the paper proves a robust version instead. Taking keeps and the per-segment error , so the whole evolution lands within . This is why the cost is paid in the -norm of the decomposition rather than in : is a sum of coefficient magnitudes, and is built from .
approximation
A circuit approximating to within , with a stated query or gate count, an ancilla count, and the norm parameter — sparsity times , or the LCU 1-norm — that the cost is measured against.
- Prepare an input state
Map to a state whose amplitudes are proportional to a specified vector , to within . The cost is set by which description of you hold, not by the algorithm that consumes it.
What this method asks of the slot is one fixed state, not an arbitrary vector: with , over the register indexing , whose amplitudes are the LCU coefficients . Those factorize register by register, so is a tensor product over the registers: the order register goes from to a normalized superposition of the unary strings in gates, by a cascade of singly-controlled rotations; each of the index registers goes from to the normalized at a gate cost of . The inverse is wanted as often as the preparation: the paper prices one amplification step at two instances of , one of , and three each of and — so a single segment of evolution runs this slot three times forward and three times back.
- Amplify a success branch
Take a routine whose output lands in the wanted subspace only with probability , and raise that probability to near 1 using quadratically fewer repetitions than restarting the routine would need.
What this method hands the slot is , whose all-zeros ancilla branch reads with and the order- truncation of one segment's evolution — and nothing at all about . Hence the realization has to be the oblivious one: the ancilla reflection that interleaves with and is the identity on the system register, so one fixed circuit serves every input, where ordinary amplitude amplification would reflect about and so need it known and re-preparable. What returns is an operator identity rather than a raised probability: for exactly unitary , , unmeasured, once per segment and times over the evolution — once, because leaves nothing for a second round. assumption: the robust form actually invoked returns , and needs two closeness conditions at once, and , before follows; a normalization near without near buys nothing here.
assumption
given H = sum_j c_j V_j with each V_j efficiently implementable and a cheap
PREPARE over the coefficients; evolution time t split into short
segments
for each segment:
truncate the Taylor series of exp(-iH t_seg) and collect its terms as a
linear combination of unitaries
PREPARE # load the coefficients into the ancilla register
SELECT # apply the terms, controlled on that register
PREPARE^-1 # unprepare
amplify the all-zeros ancilla flag
# the projection onto the wanted block succeeds only on that flag,
# so this is part of the method rather than an afterthought
# the cost scales with the 1-norm of the coefficient vector rather than with
# ||H||: a decomposition with many comparable terms is expensive even for a
# benign HBerry, Childs, Cleve, Kothari and Somma: the cost of the algorithm depends logarithmically on the inverse of the desired precision, which the authors state is optimal. Berry, Childs and Kothari, using a linear combination of quantum walk steps with coefficients given by Bessel functions, report a complexity in queries and 2-qubit gates that is "logarithmic in the inverse error, and nearly linear in the product of the evolution time, the sparsity, and the magnitude of the largest entry of the Hamiltonian".
None found yet.
None found yet.
QuDiffEq.jl's `taylorcircuit`/`taylorsolve` construction
- Simulating Hamiltonian dynamics with a truncated Taylor series
Dominic W. Berry, Andrew M. Childs, Richard Cleve, Robin Kothari, Rolando D. Somma · 2014
About
QuDiffEq.jl is a Julia package built on the Yao.jl circuit framework; its README describes it as "Quantum algorithms for solving differential equations" and states "This project is part of Julia's Season of Contribution 2019". Its documentation page for this feature names this record's own source paper directly: "Taylor truncation based Hamiltonian simulation (https://arxiv.org/abs/1412.4687) has many clear advantages. It has better complexity dependence on the precision and allows a greater range of Hamiltonians to be simulated." That page states the package "provides circuits for five kinds of problems": "Unitary Taylor simulation", "Non-unitary Taylor simulation", "Unitary QuLDE Problem", "Non-unitary QuLDEProblem", and "Solution by linearising a non-linear differential equation" — the first two are the plain e^{Mt} construction this record's hops describe; the other three add a differential-equation source term the record does not cover and this entry does not draw on. The docs describe both branches in the record's own PREPARE/SELECT/PREPARE-dagger terms without using those names: for the case where the generator itself is unitary, "the VS1 block acts on the ancilla register to generate an appropriate superpostion ... Multiplication of M^j block is controlled by |j> in the ancilla register. VS1', the adjoint of VS1, un-computes the ancilla registers. The desired result is obtained when the resulting state is projected onto |0> ancilla state."; for the non-unitary case, "M is expressed as a linear combination of four (at most) unitary i.e. M = sum_i (1/2) F_i", selected by a second per-order register, and again "un-computed and measured in the zero ancilla state".
Methods
The package implements the PREPARE-SELECT-PREPARE-dagger sandwich for a single time window, not the record's full construction: there is no loop splitting the evolution into r segments, and no oblivious-amplitude-amplification stage — `taylorsolve` postselects the ancilla on the all-zeros outcome once and returns the sub-normalized branch together with a classical rescaling factor, rather than boosting the branch to certainty. `TaylorParam`'s constructor branches on `u = isunitary(H/opn)` (opn = opnorm(H)); for `u = false` it sets `c = 2; rs = k; l = 2`, and this is the branch that matches the record's block-encode-matrix hop closely: `calc_vs1` writes the PREPARE amplitudes into rows `VS1[(2^k - 2^(k-j) + 1),1]` for `j` in `0:k` (a k-qubit unary encoding of the order, since `2^k - 2^(k-j)` is the bit pattern `1^j 0^(k-j)`), each set to `sqrt(C(j, x, opn, t, 2))/C_tilda` with `C(m,x,opn,t,c) = norm(x)*(opn*t*c)^m/factorial(m)`, then extends this partial first column to a full unitary via `VS1 = -1*qr(VS1).Q` — applying VS1 to the all-zeros ancilla yields its first column, i.e. exactly the amplitudes just written. `unitary_decompose(H)` supplies the terms SELECT chooses among: it splits `Mu = H/opnorm(H)` into Hermitian and anti-Hermitian parts `B1, B2` and returns four unitaries `F[1] = B1 + i*sqrt(I - B1*B1)`, `F[2] = B1 - i*sqrt(I - B1*B1)`, `F[3] = i*B2 - sqrt(I - B2*B2)`, `F[4] = i*B2 + sqrt(I - B2*B2)` — a fixed decomposition into at most 4 unitaries that the package derives automatically from H, not an arbitrary L-term decomposition supplied by the caller as the record's hop assumes. `circuit_intermediate` (the `u = false` method) then loops `for i in 1:k, for j in 0:2^l-1` and appends a Yao `control` gate applying `F[j+1]` to the target register, controlled on order-register qubit `i` together with a 2-qubit sub-register holding `j` — the per-slot select this record's block-encode-matrix hop describes, with L fixed at (up to) 4 rather than general. PREPARE for this branch is not `VS1` alone: `taylorsolve`'s `rs == k` path also builds `VT = calc_vt(CPType)`, a fixed 4-by-4 unitary whose first column is uniform (`VT[:,1] = 0.5*ones(4)`, then extended to a full unitary by the same `-1*qr(...).Q` construction as `VS1`) — an unconditional preparation of the equal superposition over the (at most) 4 `F_i` terms, applied once per order-index qubit. It then calls the four-argument `taylorcircuit(n, blk, VS1, VT)`, which chains `circuit_ends(n, blk, VS1, VT)` (PREPARE: `VS1` on the order register composed with, for each `i` in `1:k`, an unconditional `lc(...)` placing `VT` on that index's own 2-qubit term-selection sub-register), `circuit_intermediate` (SELECT), and `circuit_ends(n, blk, VS1', VT')` (PREPARE-dagger) in that order — matching the package's own description, "the second register is superposed by `VT`, where each new state corresponds to a `F_i`". The three-argument `taylorcircuit(n, blk, VS1)`, which chains the VT-free `circuit_ends(n, blk, VS1)` alone with `circuit_intermediate` and `circuit_ends(n, blk, VS1')`, is dispatched only for `TaylorParam{CPType, true}` — the `u = true` (unitary-H) branch — and is not what runs for the `u = false` branch this paragraph describes. `taylorsolve`'s docstring reads "Simulates a Hamiltonian using the Taylor truncation method. Returns the state register and inverse probability of finding it."; its body runs `r = apply!(inreg,cir) |> focus!(1:n - nbit...,) |> select!(0)` and returns `r, blk.N` — postselecting the ancilla on 0 once, with no amplification, and handing back `N = blk.N` (the classically-summed Taylor-magnitude normalization) for the caller to rescale by afterward. The `u = true` branch (H itself already proportional to a unitary) uses a different, binary order-register encoding, `rs = log2i(k+1)`, and repeatedly multiplies the same H rather than selecting among several terms; it is a special case the record's general L-term construction does not describe and this entry does not claim matches it structurally.
Data
No molecule or physical model: `test/TaylorTrunc_tests.jl` builds one random 1-qubit unitary `Au = rand_unitary(2)` and one random 1-qubit non-unitary matrix `An = rand(ComplexF64, 2, 2)`, plus normalized random vectors `b, x`, with `Random.seed!(2)`, Taylor order `k = 3`, and evolution time `tspan = (0.0, 0.1)`. Each is wrapped in a `QuLDEProblem(A, b, x, tspan)` and then passed to the plain Hamiltonian-simulation entry point `taylorsolve(qprob.A, qprob.u0, k, tspan[2])`, not to a QuLDE-specific solver.
Code
`src/TaylorTrunc.jl` in https://github.com/QuantumBFS/QuDiffEq.jl — Julia, MIT License (`LICENSE`: "Copyright (c) 2019 Divyanshu Gupta"), 334 lines on `master` as read on 2026-08-26 at commit 83dd4b4a, which is also `master`'s current HEAD and the last commit to touch this file (2024-08-24). `Project.toml` names the package `QuDiffEq`, version `0.2.0`, depending on `Yao = "0.9"`. The relevant exports from this file are `TaylorParam`, `taylorcircuit`, `taylorsolve`, `circuit_ends`, `circuit_intermediate`; `calc_vs1`, `calc_vs2`, `calc_vt` and `unitary_decompose` are unexported helpers in the same file. Documentation source is `docs/src/man/taylor.md`. Tests are `test/TaylorTrunc_tests.jl`.
Results
The only check is a numerical comparison against exact matrix exponentiation, run for both branches. `test/TaylorTrunc_tests.jl` computes `out = N*vec(state(r))` from `r, N = taylorsolve(qprob.A, qprob.u0, k, tspan[2])` and compares it to `r_out = exp(qprob.A*tspan[2])*qprob.u0`, asserting `isapprox.(r_out, out, atol = 1e-3) |> all` — once for the unitary instance `Au` and once for the non-unitary instance `An`, both at `k = 3`, `t = 0.1`, on a single qubit. No gate count, T-count, circuit depth or hardware/simulator backend is reported anywhere in the package for this construction; the only named computational engine is Yao.jl's own state-vector simulation via `apply!`.
- Simulating Hamiltonian dynamics with a truncated Taylor series
Linear combination of unitaries · Qiskit
From the repository — run, not written up from a paper · native
About
A block-encoding primitive that turns a weighted sum of unitary operations into one larger unitary circuit.
Methods
None found yet.
Data
None found yet.
Code
Qiskit
Results
Two-term PREPARE–SELECT–unprepare circuit checked on a one-qubit target · success branch and coefficient normalization recorded
- Linear combination of unitaries
A block-encoding primitive that turns a weighted sum of unitary operations into one larger unitary circuit.
References
- Simulating Hamiltonian dynamics with a truncated Taylor series
Dominic W. Berry, Andrew M. Childs, Richard Cleve, Robin Kothari, Rolando D. Somma · 2014
- Hamiltonian simulation with nearly optimal dependence on all parameters
Dominic W. Berry, Andrew M. Childs, Robin Kothari · 2015
- Hamiltonian Simulation Using Linear Combinations of Unitary Operations
Andrew M. Childs, Nathan Wiebe · 2012
Where the routes meet
11 problems nothing else needs — the places a reader arrives. Open a line to see what is recorded inside it, or click its name to go there.
19 lines have something recorded inside that you have not opened.
Of the routes that have been taken apart, 15 are built entirely from named slots, 15 hand off part of the work and finish the rest themselves, and 20 are one undivided act. None of the three is a defect; they are different things to reuse.
Every line on this figure, in words
The lines on this figure
Solve a nonlinear ODE dy/dt = F(y)
- Embed a nonlinear system into a linear one — opens into 6 · a way across — click it to open it here
- Solve a linear ODE du/dt = A(t)u + b(t) — open · opened: what was inside is drawn in its place
- Linear multistep method, all-at-once encoding — opens into 2 · a way across — click it to open it here
- Taylor propagator, all-at-once encoding — opens into 2 · a way across — click it to open it here
- Chebyshev spectral method, global collocation — opens into 2 · a way across — click it to open it here
- Dyson propagator, all-at-once encoding — opens into 2 · a way across — click it to open it here
- Time-marching with uniform singular value amplification — opens into 2 · a way across — click it to open it here
- LCHS — linear combination of Hamiltonian simulation — opens into 3 · a way across — click it to open it here
- Schrödingerisation (linear PDEs as Schrödinger equations) — opens into 3 · a way across — click it to open it here
- Choose a time discretization or propagator approximation → Quantum linear solve — open
- Choose a time discretization or propagator approximation — opens into 6 · a way across — click it to open it here
- Quantum linear solve — opens into 5 · a way across — click it to open it here
- Simulate Hamiltonian evolution → Estimate an observable — open
- Simulate Hamiltonian evolution — opens into 3 · a way across — click it to open it here
- Estimate an observable — opens into 4 · a way across — click it to open it here
Estimate an excited-state energy
- Variational quantum deflation — opens into 3 · a way across — click it to open it here
- Subspace-search variational eigensolver — opens into 3 · a way across — click it to open it here
- Quantum subspace expansion
- Quantum equation of motion
- Folded-spectrum variational eigensolver — opens into 3 · a way across — click it to open it here
- Penalty-constrained variational eigensolver — opens into 3 · a way across — click it to open it here
- Multistate contracted variational eigensolver — opens into 3 · a way across — click it to open it here
Every step you can open
1 of these have an object recorded in the middle; the rest open into the methods that fill them.
- Solve a nonlinear ODE dy/dt = F(y)
- Replace a spatial domain with a finite grid
- Discretize a PDE into one linear system
- Embed a nonlinear system into a linear one
- Solve a linear ODE du/dt = A(t)u + b(t)
- Recast a non-Hermitian generator as Hamiltonian evolution
- Choose a time discretization or propagator approximation
- Quantum linear solve
- Matrix function
- QSP phase factors
- Polynomial approximation
- Block-encode a matrix
- Prepare an input state
- Amplify a success branch
- Simulate Hamiltonian evolution
- Estimate an observable
- Compile a circuit to a specific device
- Satisfy the hardware connectivity constraint
- Approximate a continuous rotation in a discrete gate set
- Recover a noiseless expectation value by post-processing
- Build logical qubits at a target logical error rate
- Estimate a Hamiltonian's ground-state energy
- Choose a parameterised trial state
- Minimise the objective over the parameters
- Estimate an excited-state energy
- Measure what the machine can actually do
- Recover the period of a periodic function
- Estimate the eigenphase of a unitary
- Find the item a check accepts
- Walk a graph to the vertex you want
- Search a cost Hamiltonian for the assignment it minimises
What is on this map, counted
What is here, counted
147 nodes — 31 slots and 116 methods.
76 of the 147 link to a record in the Atlas, between them naming 89 records. The rest name papers and nothing else: this graph describes work the catalogue has not got yet, and the nodes with no record are the list of what a corpus pass has to go and read.
0 slots have no method recorded, and 32 methods have not been taken apart. Both are shown as what they are rather than left blank.
Every claim here rests on a source. This graph cites 140 papers; they and the 172 the Atlas cites alone are registered in one place, with what each reports and everywhere it is cited from. Papers