MethodLayer 2
FABLE approximate circuit construction
Build the block-encoding directly from uniformly controlled Ry (magnitude) and Rz (phase) rotations between Hadamards and a SWAP, with no oracle assumption at all, then threshold the rotation angles and cancel the resulting CNOT chains to compress the circuit.
An access model for — sparse-access oracles, a Pauli or LCU decomposition, a purification, or an explicit arithmetic description — plus a target precision .
A unitary on qubits, its subnormalization , and its ancilla/flag count . Because , Gilyén, Su, Low and Wiebe's Definition 43 forces .
Same contract as the slot it fills.
This one, drawn
From Matrix you can query to Block-encoding
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
- Block-encode a matrix
Wrap an operator inside a larger unitary so that sits in 's top-left block, giving every routine above it one uniform way to touch the matrix. The subnormalization and the ancilla count are outputs of this layer, not free parameters.
When it applies
Requires |a_ij| ≤ 1. The authors state the gate complexity is "bounded by O(N^2) gates with a modest prefactor of 2 for real-valued matrices (4 for complex-valued matrices), and a limited polylogarithmic overhead", and that "this gate complexity scales exponentially in the number of qubits for generic dense matrices". So this is a compression technique for structured matrices — Heisenberg, Hubbard, Laplacian — and not a way to load dense unstructured data cheaply. The paper states only that the circuit parameters can be easily generated for problems up to fifteen qubits.
Requires
Every step this method names moves its route along, so there is nothing it needs alongside them.
Example
given A with |a_ij| <= 1, and no oracle assumption at all
build the block-encoding circuit directly from:
uniformly controlled Ry rotations # magnitude
uniformly controlled Rz rotations # phase
Hadamards and a SWAP, the rotations sitting between them
# Camps and Van Beeumen Theorem 1: that circuit is a (1/2^n, n+1)-block-
# encoding of A when |a_ij| <= 1
threshold the rotation angles at a cutoff compression threshold delta_c
cancel the CNOT chains the thresholding leaves behind
return the compressed circuit
# Camps and Van Beeumen Theorem 2: the cutoff delta_c gives a
# (1/2^n, n+1, N^3*delta_c)-block-encoding of A, up to third order in delta_c
# the 1/2^n above is transcribed as the paper states it, and contested on this
# record: it is inconsistent with the paper's own Definition 1, which sets
# A = alpha * A-tilde and therefore ||A||_2 <= alpha, the same orientation as
# Gilyen et al.'s Definition 43 and not its reciprocal, while the Theorem 1
# proof derives a block equal to a_ij/2^n. Under either paper's definition the
# subnormalization is alpha = 2^n = N. This applies to the arXiv text as
# served; a journal version may differ
# gate complexity, in the authors' words: bounded by O(N^2) gates with a
# modest prefactor of 2 for real-valued matrices (4 for complex-valued
# matrices), and a limited polylogarithmic overhead -- and this gate complexity
# scales exponentially in the number of qubits for generic dense matrices
# so this is a compression technique for structured matrices -- Heisenberg,
# Hubbard, Laplacian -- and not a way to load dense unstructured data cheaply
# the paper states only that the circuit parameters can be easily generated
# for problems up to fifteen qubitsCost, as the source states it
Camps and Van Beeumen's Theorem 1 states the circuit is an "-block-encoding" of when , and Theorem 2 that a cutoff compression threshold gives an -block-encoding of up to third order in .
Implementations
FABLE reference implementation (Qiskit and QCLAB)
Camps and Van Beeumen built FABLE at Lawrence Berkeley National Laboratory — Camps at the National Energy Research Scientific Computing Center, Van Beeumen in the Applied Mathematics and Computational Research Division. The problem they state is that "Many of these algorithms achieve optimal complexity in terms of black box matrix oracle queries, but so far the problem of computing quantum circuit implementations for block-encodings of matrices has been under-appreciated" — "these algorithms" being the ones derived from the quantum singular value transformation, and "many", not all, of them. The artefact is the tool that closes that gap: a routine that takes a matrix and returns an explicit circuit of one- and two-qubit gates, plus the compression pass that shrinks it.
The release is two routines, and they differ in ways a caller meets on the first call, so each step below is attributed. Both rescale only when the infinity norm of the vectorised matrix exceeds 1: the Python routine sets and divides by it — the term is what makes the rescaled entries strictly less than 1, and so defined is the number the function hands back — while the MATLAB routine uses exactly; otherwise both set and leave alone. On shape they diverge outright: the Python routine zero-pads a non-square or non-power-of-two input out to the next power of two, the MATLAB routine asserts `N == 2^n` and `N == size(A,2)` and fails on anything else. For real data both form the angle vector . For complex data both build a magnitude and a phase vector and compose two uniformly controlled rotations, for the magnitude and for the phase, but not from the same quantities: Python takes the magnitude angles as and the phase angles as throughout, while MATLAB keeps the signed real part as the magnitude and sets the phase to zero for any entry whose imaginary part falls below . Each then solves the uniformly-controlled-rotation angle system with a scaled fast Walsh–Hadamard transform followed by the Gray-code permutation — the paper states this is "efficiently solved by a classical algorithm in using a fast Walsh–Hadamard transform [20] which is implemented in the reference implementation of FABLE". Compression is where the two part again. Both carry the cutoff criterion, and both implement it as a test on magnitude — coefficients with at or below the cutoff are set to zero, where the paper's step (i) is written "Remove all rotation gates for angles " — and in Python that step runs only when a truthy `epsilon` is passed, so the default call compresses nothing. MATLAB carries a second criterion the Python routine does not have, `'percentage'`: sort the coefficients by magnitude and zero the smallest of them. The surviving gates are emitted by the compressed-uniform-rotation builder, which applies the second half of the paper's rule: parity-check each run of consecutive CNOTs and keep one CNOT per control qubit that occurs an odd number of times. The assembled circuit is Hadamards on the row register, the oracle, a SWAP pairing the two -qubit registers, and Hadamards again; the Python routine then closes with `circ.reverse_bits()`, the little-endian convention that puts the leading block in the order its own test asserts.
The benchmark inputs are stated in the paper. The accuracy sweep of Fig. 4 uses "randomly generated matrices with entries drawn from the standard normal distribution, the matrices are 2 to 7 qubit operators such that the FABLE circuits require 5 to 15 qubits". The Hamiltonian benchmarks are a Heisenberg XXX chain with and on 2 to 7 qubits; Fermi–Hubbard Hamiltonians "generated through OpenFermion [22] for the case , , i.e., non-interacting fermions on a 1D and 2D lattices with two spin orbitals per site and non-periodic boundary conditions", then "mapped to qubits using the Bravyi–Kitaev transformation"; and finite-difference discretised Laplacians — 1D on 2 to 7 qubits with periodic and non-periodic Dirichlet boundary conditions, and 2D five-point-stencil Kronecker sums on rectangular grids "requiring at most 7 qubits".
Both implementations are released together at https://github.com/QuantumComputingLab/fable; the paper's introduction states that "Implementations of the FABLE algorithm built on top of QCLAB [12, 13] and Qiskit [14] are made publicly available" there, and the README describes them as "two reference implementations of the FABLE algorithm". The Python version is `py/fable`, depends on `qiskit>=0.19.1` and `numpy>=1.20.3`, and is distributed on PyPI as `fable-circuits` (version 1.0.2, uploaded 2025-01-03); its entry point is `fable(a, epsilon=None)`, returning a Qiskit `QuantumCircuit` and the subnormalization factor `alpha`. The MATLAB version is the single file `fable-qclab/fable.m`, built on QCLAB (cited as version 0.1.3) and called as `[circuit, OA, alpha, info] = fable( A, 'cutoff', 1e-4, logging )`; it also accepts `'percentage', 80`, and the README notes that "The `'percentage'` and `logging` options are only available in the MATLAB version of FABLE." The licence is a three-clause BSD notice with LBNL's standard enhancements clause: "FABLE Copyright (c) 2022, The Regents of the University of California, through Lawrence Berkeley National Laboratory". The whole repository tree is nine files — the two synthesis routines and the Python helper module, a two-case Python test file, `pyproject.toml`, `setup.cfg`, the README and the licence — so the drivers that produced Figs. 4–6 and Table I are not in it.
Everything reported in the arXiv version read here (v2, dated 29 July 2022) is classical simulation and gate counting; the paper reports no run on quantum hardware. Fig. 4 shows "the result of noise-free QCLAB [12] simulations for compressed FABLE circuits" — the one benchmark the paper attributes to a named implementation, and it attributes it to the MATLAB/QCLAB half — for randomly generated real-valued 2-qubit () to 7-qubit () matrices at three compression cutoffs : "the bound from Theorem 2 always holds but is overly pessimistic", and "Not shown in Fig. 4 are the majority of random realizations with an error close to the machine precision." The remaining benchmarks name no implementation. For the Heisenberg XXX chain on 2 to 7 qubits with the compression threshold set to machine precision, "FABLE can give an accurate encoding of a Heisenberg XXX model with just 50% of the CNOT gates and 25% of the Ry rotations". Table I gives the Hubbard counts against the maximum : 1D, 2 sites, 4 qubits — 130 CNOT (50.8%) and 65 Ry (25.4%); 1D, 6 sites, 12 qubits — 180,234 CNOT (1.1%) and 81,921 Ry (0.5%); 2D, 2×3 sites, 12 qubits — 252,626 CNOT (1.5%) and 90,113 Ry (0.5%). Turning the interaction on removes the gain: "We ran the same experiment for interacting Hubbard Hamiltonians () but for this case, the matrices do not compress well and the maximum number of gates is required to encode the Hamiltonians." For the Laplacians, "the 2D Laplacians can be compressed better than 1D Laplacians and require in some cases fewer than 5% of the maximum number of gates". The acknowledgment states the work "used resources of the National Energy Research Scientific Computing Center (NERSC)". Separately, the shipped Python tests record what the released code recovers: `test_fable_real` and `test_fable_complex` build a random real and a random complex matrix respectively, run the circuit on Qiskit Aer's `AerSimulator(method="unitary")`, and assert that `a/alpha/2**n` equals the leading block of the returned unitary — its real part, in the real-valued test. The README's usage block states the same relation the other way round, `np.linalg.norm(alpha * N * unitary.data[0:N, 0:N] - A)/np.linalg.norm(A)`. So in the released code the target matrix is recovered from that block by multiplying it by , with the rescaling factor the routine returns.
PennyLane qml.FABLE template
Xanadu's PennyLane shipped FABLE as a built-in template. Its v0.36.0 release note says the algorithm "as outlined in arXiv:2205.00081 is now accessible via the `qml.FABLE` template", and places it against PennyLane's existing exact block-encoder: "The usage of `qml.FABLE` is similar to `qml.BlockEncode` but provides a more efficient circuit construction at the cost of a user-defined approximation level, `tol`."
The template takes a matrix and wires, where is the size after padding: like the LBNL Python routine it zero-pads an arbitrary input, warning each time it does so, and its docstring says as much — "FABLE can be implemented for matrices of arbitrary shape and size. When given a matrix, the matrix is padded with zeroes until it is of dimension, where is equal to , and is an integer." It reuses the Möttönen state-preparation machinery already in PennyLane — `compute_theta` and `gray_code` from `pennylane/templates/state_preparations/mottonen.py` — to turn into the uniformly-controlled-rotation angles, emits an `RY(2*theta)` only when `abs(2 * theta) > tol`, and cancels CNOTs by the same parity rule as the paper: a control wire already pending in the accumulator is deleted rather than emitted twice. The circuit ends with SWAPs pairing the two index registers and a second layer of Hadamards. Where it departs from the LBNL reference implementation is on the input, and only for concrete — non-traced — input: it is real-only, a complex input raising `ValueError("Support for imaginary values has not been implemented.")`, and it does not rescale, raising instead when , with the docstring telling the caller "It is also assumed that the values of the input matrix are within . Apply a subnormalization factor if needed." Neither check runs under JIT tracing: both sit inside `if not qml.math.is_abstract(input_matrix):`, the constructor refusing `tol != 0` in that branch instead, and the `tol` threshold is likewise skipped for abstract angles, which are emitted as `RY` unconditionally.
`pennylane/templates/subroutines/fable.py` in https://github.com/PennyLaneAI/pennylane — Python, Apache License 2.0, "Copyright 2018-2024 Xanadu Quantum Technologies Inc." The documented signature, at the v0.36.0 tag and on the current stable API page alike, is `FABLE(input_matrix, wires, tol=0, id=None)`. It was added by pull request 5107 ("Implement FABLE as a Template (issue 4848)"), merged on 2024-04-11, and first shipped in PennyLane v0.36.0.
The v0.36.0 release note's worked example block-encodes on three wires of the `default.qubit` state-vector simulator with `tol = 0.001`, and recovers it from the circuit matrix as `2 * mat[0:2, 0:2]`, printing `array([[0.1+0.j, 0.2+0.j], [0.3+0.j, 0.4+0.j]])`. The current API documentation runs the same check on `default.qubit` for with `tol=0`, recovering the matrix as `2**s * qp.matrix(example_circuit)().real[0 : 2**s, 0 : 2**s]`.
Where the claim is contested
The stated parameter is inconsistent with the paper's own Definition 1, which sets A = α·Ã and therefore — the same orientation as Gilyén et al.'s Definition 43, not its reciprocal — while the Theorem 1 proof derives a block equal to . Under either paper's definition the subnormalization is . This applies to the arXiv text as served; a journal version may differ.
What it needs
Nothing below this — it bottoms out here.
Other ways to fill the same slot
Different approaches
- Sparse-access oracle construction
Given row and column index oracles , and an entry oracle , prepare uniform superpositions over the sparsity pattern, rotate an ancilla by arcsin of each entry, and swap registers to leave in the flagged block. This is the standard construction behind the sparse-Hamiltonian line, formalized as a block-encoding by Gilyén, Su, Low and Wiebe.
- Block-encoding from a Pauli decomposition
Write over Pauli strings; PREPARE loads amplitudes proportional to into an ancilla register, SELECT applies the controlled Pauli strings, and PREPARE unprepares, leaving in the block flagged by the all-zeros ancilla. This is the input model chemistry and lattice Hamiltonians supply for free.
- Tensor hypercontraction block encoding
Factorize the chemistry Hamiltonian's two-electron integrals into a product of much smaller matrices first, then build the block-encoding of the factorized form. The saving is not in the encoding technique but in what is being encoded — a tensor with far fewer independent entries than the one the basis handed you.
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.