QuantumCore

Lesson 41 · 80 min · advanced

The Inversion (Compute–Uncompute) Test

Loading progress…

The inversion test estimates a fidelity kernel with no extra qubits: prepare ∣ϕ(x)⟩=U(x)∣0n⟩\lvert\phi(x)\rangle=U(x)\lvert0^n\rangle, run the inverse circuit U(x′)†U(x')^\dagger, and measure; the probability of the all-zeros outcome is K(x,x′)=∣⟨ϕ(x′)∣ϕ(x)⟩∣2K(x,x')=\lvert\langle\phi(x')\vert\phi(x)\rangle\rvert^2. This lesson proves that identity, proves that the inverse of a circuit is the reversed sequence of inverted gates and tabulates the inverses of the standard gates, inverts the ZZ feature map gate by gate, shows that product RXR_X encodings collapse to ⨂jRX(xj−xj′)\bigotimes_jR_X(x_j-x'_j) with P(0n)=∏jcos⁡2xj−xj′2P(0^n)=\prod_j\cos^2\frac{x_j-x'_j}{2}, counts qubits, gates, CNOTs and depth against the SWAP test, proves that the inversion-test estimator has the smaller variance, K(1−K)≤1−K2K(1-K)\le1-K^2, and explains why hardware noise biases the measured all-zeros probability.

Prerequisites: Quantum Kernels & Fidelity Kernels

Objectives and key results
  • Prove that the all-zeros probability of U(x′)†U(x)∣0n⟩U(x')^\dagger U(x)\lvert0^n\rangle equals the fidelity kernel K(x,x′)K(x,x') and interpret the other outcomes.

  • Prove (AB)†=B†A†(AB)^\dagger=B^\dagger A^\dagger and, by induction, that the inverse of a gate sequence is the reversed sequence of inverted gates; invert HH, Pauli, SS, TT, rotation, phase, CNOT, CZ, SWAP and controlled-rotation gates.

  • Write down the inverse of the two-qubit ZZ feature map gate by gate and simplify the resulting inversion-test circuit.

  • Show that for product RXR_X encodings the inversion test collapses to ⨂jRX(xj−xj′)\bigotimes_jR_X(x_j-x'_j) and compute the complete outcome distribution.

  • Compare the inversion test and the SWAP test in qubits, gates, CNOTs and depth, and state when the SWAP test is unavoidable.

  • Prove that the inversion-test estimator needs fewer shots than the SWAP-test estimator, by the factor (1+K)/K(1+K)/K, and explain the bias that noise introduces into the measured all-zeros probability.

identity · Inversion test
P(0n)=∣⟨0n∣U(x′)†U(x)∣0n⟩∣2=∣⟨ϕ(x′)∣ϕ(x)⟩∣2=K(x,x′)P(0^n)=\big\lvert\langle0^n\vert U(x')^\dagger U(x)\vert0^n\rangle\big\rvert^2=\lvert\langle\phi(x')\vert\phi(x)\rangle\rvert^2=K(x,x')
theorem · Adjoint of a circuit
U=GL⋯G2G1 ⇒ U−1=U†=G1†G2†⋯GL†,RP(θ)†=RP(−θ)U=G_L\cdots G_2G_1\ \Rightarrow\ U^{-1}=U^\dagger=G_1^\dagger G_2^\dagger\cdots G_L^\dagger,\qquad R_P(\theta)^\dagger=R_P(-\theta)
formula · Collapse of product R_X encodings
U(x′)†U(x)=⨂j=0n−1RX(xj−xj′),P(0n)=∏j=0n−1cos⁡2xj−xj′2U(x')^\dagger U(x)=\bigotimes_{j=0}^{n-1}R_X(x_j-x'_j),\qquad P(0^n)=\prod_{j=0}^{n-1}\cos^2\frac{x_j-x'_j}{2}
formula · Resources
inversion: n qubits, 2g gates, depth≤2d;SWAP: 2n+1 qubits, 2g+n+2 gates, depth≤d+n+1, 2c+8n CNOTs\text{inversion: }n\text{ qubits},\ 2g\text{ gates},\ \text{depth}\le2d;\qquad\text{SWAP: }2n+1\text{ qubits},\ 2g+n+2\text{ gates},\ \text{depth}\le d+n+1,\ 2c+8n\text{ CNOTs}
theorem · Shot variances
Var[K^inv]=K(1−K)N≤1−K2N=Var[K^SWAP],NSWAPNinv=1+KK\mathrm{Var}[\hat K_{\mathrm{inv}}]=\frac{K(1-K)}N\le\frac{1-K^2}N=\mathrm{Var}[\hat K_{\mathrm{SWAP}}],\qquad\frac{N_{\mathrm{SWAP}}}{N_{\mathrm{inv}}}=\frac{1+K}{K}

The all-zeros probability is the kernel#

The previous lessons gave two ways of reading a fidelity kernel K(x,x′)=∣⟨ϕ(x)∣ϕ(x′)⟩∣2K(x,x')=\lvert\langle\phi(x)\vert\phi(x')\rangle\rvert^2 off a quantum computer. The SWAP test places both feature states side by side on 2n2n qubits and lets an ancilla interfere them; it never needs to know how the states were made. When the states come from known circuits, as they always do in a quantum kernel method, there is a cheaper route: prepare ∣ϕ(x)⟩\lvert\phi(x)\rangle, then run the preparation of ∣ϕ(x′)⟩\lvert\phi(x')\rangle backwards. If the two states coincide, the backwards circuit returns the register exactly to ∣0n⟩\lvert0^n\rangle; if they differ, it returns it only partially, and the probability of finding all qubits in 00 measures how close the two states are. The construction is called the inversion test or the compute–uncompute test, and it is the kernel estimator used in the quantum-kernel experiments of Havlíček et al. (2019). This lesson proves why it works, how to build the inverse of a circuit, what it costs compared with the SWAP test, how many shots it needs, and what noise does to it.

Definition

Inversion (compute–uncompute) test

Let x↦U(x)x\mapsto U(x) be a quantum feature map on nn qubits with feature states ∣ϕ(x)⟩=U(x)∣0n⟩\lvert\phi(x)\rangle=U(x)\lvert0^n\rangle. For two inputs x,x′x,x' the inversion-test circuit is V(x,x′)=U(x′)† U(x),V(x,x')=U(x')^\dagger\,U(x), i.e. first the encoding circuit of xx (compute), then the inverse of the encoding circuit of x′x' (uncompute). The test runs V(x,x′)V(x,x') on ∣0n⟩\lvert0^n\rangle, measures all nn qubits in the computational basis, and records whether the outcome is the all-zeros string 0n=0⋯00^n=0\cdots0. After NN shots with N0nN_{0^n} all-zeros outcomes, the estimate of the kernel is K^inv=N0n/N\hat K_{\mathrm{inv}}=N_{0^n}/N.

Theorem

The inversion test measures the fidelity kernel

For every unitary feature map and all inputs x,x′x,x', P(0n)=∣⟨0n∣U(x′)†U(x)∣0n⟩∣2=∣⟨ϕ(x′)∣ϕ(x)⟩∣2=K(x,x′).P(0^n)=\big\lvert\langle0^n\vert U(x')^\dagger U(x)\vert0^n\rangle\big\rvert^2=\lvert\langle\phi(x')\vert\phi(x)\rangle\rvert^2=K(x,x'). More generally, the outcome b∈{0,1}nb\in\{0,1\}^n has probability P(b)=∣⟨ϕb(x′)∣ϕ(x)⟩∣2P(b)=\lvert\langle\phi_b(x')\vert\phi(x)\rangle\rvert^2 with ∣ϕb(x′)⟩=U(x′)∣b⟩\lvert\phi_b(x')\rangle=U(x')\lvert b\rangle; the 2n2^n states ∣ϕb(x′)⟩\lvert\phi_b(x')\rangle form an orthonormal basis, so the outcomes b≠0nb\ne0^n together have probability 1−K(x,x′)1-K(x,x'). Exchanging the roles of xx and x′x' does not change P(0n)P(0^n).

Proof (7 steps)
  1. Step 1:
    P(b)=∣⟨b∣V∣0n⟩∣2,V=U(x′)†U(x)P(b)=\big\lvert\langle b\vert V\vert0^n\rangle\big\rvert^2,\qquad V=U(x')^\dagger U(x)
    Born rule: measuring every qubit of the pure state V∣0n⟩V\lvert0^n\rangle in the computational basis returns the string bb with the squared modulus of the amplitude ⟨b∣V∣0n⟩\langle b\vert V\vert0^n\rangle.
  2. Step 2:
    ⟨b∣U(x′)†=(U(x′)∣b⟩)†=⟨ϕb(x′)∣,⟨0n∣U(x′)†=⟨ϕ(x′)∣\langle b\vert U(x')^\dagger=\big(U(x')\lvert b\rangle\big)^\dagger=\langle\phi_b(x')\rvert,\qquad\langle0^n\vert U(x')^\dagger=\langle\phi(x')\rvert
    The adjoint of a product is the reversed product of adjoints, (AB)†=B†A†(AB)^\dagger=B^\dagger A^\dagger (proved in the next section), applied to the matrix A=U(x′)A=U(x') and the column vector B=∣b⟩B=\lvert b\rangle; for b=0nb=0^n this is the bra of the feature state of x′x'.
  3. Step 3:
    ⟨b∣U(x′)†U(x)∣0n⟩=⟨ϕb(x′)∣(U(x)∣0n⟩)=⟨ϕb(x′)∣ϕ(x)⟩\langle b\vert U(x')^\dagger U(x)\vert0^n\rangle=\langle\phi_b(x')\vert\big(U(x)\lvert0^n\rangle\big)=\langle\phi_b(x')\vert\phi(x)\rangle
    Associativity of the matrix product: the row vector ⟨ϕb(x′)∣\langle\phi_b(x')\rvert multiplies the column vector U(x)∣0n⟩=∣ϕ(x)⟩U(x)\lvert0^n\rangle=\lvert\phi(x)\rangle.
  4. Step 4:
    P(0n)=∣⟨ϕ(x′)∣ϕ(x)⟩∣2=∣⟨ϕ(x)∣ϕ(x′)⟩‾∣2=K(x,x′)P(0^n)=\lvert\langle\phi(x')\vert\phi(x)\rangle\rvert^2=\Big\lvert\overline{\langle\phi(x)\vert\phi(x')\rangle}\Big\rvert^2=K(x,x')
    Set b=0nb=0^n. Conjugate symmetry ⟨ψ∣χ⟩=⟨χ∣ψ⟩‾\langle\psi\vert\chi\rangle=\overline{\langle\chi\vert\psi\rangle} and ∣zˉ∣=∣z∣\lvert\bar z\rvert=\lvert z\rvert show that the order of the two states inside the modulus is irrelevant.
  5. Step 5:
    ⟨ϕb(x′)∣ϕb′(x′)⟩=⟨b∣U(x′)†U(x′)∣b′⟩=⟨b∣b′⟩=δbb′\langle\phi_b(x')\vert\phi_{b'}(x')\rangle=\langle b\vert U(x')^\dagger U(x')\vert b'\rangle=\langle b\vert b'\rangle=\delta_{bb'}
    A unitary maps the orthonormal computational basis to an orthonormal basis {∣ϕb(x′)⟩}b\{\lvert\phi_b(x')\rangle\}_b of C2n\mathbb C^{2^n}.
  6. Step 6:
    ∑bP(b)=∑b∣⟨ϕb(x′)∣ϕ(x)⟩∣2=∥ϕ(x)∥2=1 ⇒ ∑b≠0nP(b)=1−K(x,x′)\sum_{b}P(b)=\sum_b\lvert\langle\phi_b(x')\vert\phi(x)\rangle\rvert^2=\lVert\phi(x)\rVert^2=1\ \Rightarrow\ \sum_{b\ne0^n}P(b)=1-K(x,x')
    Parseval's identity in the basis {∣ϕb(x′)⟩}\{\lvert\phi_b(x')\rangle\}: the other outcomes record the components of ∣ϕ(x)⟩\lvert\phi(x)\rangle orthogonal to ∣ϕ(x′)⟩\lvert\phi(x')\rangle.
  7. Step 7:
    ∣⟨0n∣U(x)†U(x′)∣0n⟩∣2=∣⟨ϕ(x)∣ϕ(x′)⟩∣2=K(x′,x)=K(x,x′)\big\lvert\langle0^n\vert U(x)^\dagger U(x')\vert0^n\rangle\big\rvert^2=\lvert\langle\phi(x)\vert\phi(x')\rangle\rvert^2=K(x',x)=K(x,x')
    The same computation with xx and x′x' exchanged; the kernel is symmetric. Either circuit order estimates the same number.

∎

Circuit · 2 qubits

Quantum circuit on 2 qubitsRX(0.30) on q0; RX(1.20) on q1; RX(-1.00) on q0; RX(-0.40) on q1q0q1RX(0.30)RX(1.20)RX(-1.00)RX(-0.40)

The lab's inversion test for the RXR_X product encoding: U(x)=RX(0.3)⊗RX(1.2)U(x)=R_X(0.3)\otimes R_X(1.2) (compute), then U(x′)†=RX(−1.0)⊗RX(−0.4)U(x')^\dagger=R_X(-1.0)\otimes R_X(-0.4) (uncompute), for x=(0.3,1.2)x=(0.3,1.2) and x′=(1.0,0.4)x'=(1.0,0.4). The histogram shows P(00)=K(x,x′)≈0.7486P(00)=K(x,x')\approx0.7486; the outcomes 0101, 1010, 1111 carry the remaining 1−K≈0.25141-K\approx0.2514.

  • |00⟩0.7486
  • |01⟩0.1338
  • |10⟩0.0997
  • |11⟩0.0178

Quick check

An inversion test on n=3n=3 qubits returns 000000 in N000=620N_{000}=620 of N=1000N=1000 shots. What do the other 380380 shots tell you?

Select one answer

Inverting a circuit#

To run the inversion test one must build U(x′)†U(x')^\dagger as a circuit. A unitary satisfies U†U=IU^\dagger U=I, so U†=U−1U^\dagger=U^{-1} undoes UU; the question is how to obtain it from the gate list of UU without ever forming a 2n×2n2^n\times2^n matrix. The answer rests on one identity for adjoints of products, followed by an induction over the number of gates, and on a short table of inverses of the individual gates.

Lemma

The adjoint of a product is the reversed product of the adjoints

For complex matrices A∈Cp×qA\in\mathbb C^{p\times q} and B∈Cq×rB\in\mathbb C^{q\times r}, (AB)†=B†A†,(AB)^\dagger=B^\dagger A^\dagger, where M†=M‾TM^\dagger=\overline{M}^{\mathsf T} is the conjugate transpose, (M†)ik=Mki‾(M^\dagger)_{ik}=\overline{M_{ki}}. In particular, if AA and BB are unitary, so is ABAB, and (AB)−1=B−1A−1(AB)^{-1}=B^{-1}A^{-1}.

Proof (4 steps)
  1. Step 1:
    ((AB)†)ik=(AB)ki‾=∑j=1qAkjBji‾\big((AB)^\dagger\big)_{ik}=\overline{(AB)_{ki}}=\overline{\sum_{j=1}^qA_{kj}B_{ji}}
    Definition of the conjugate transpose and of the matrix product, for 1≤i≤r1\le i\le r and 1≤k≤p1\le k\le p.
  2. Step 2:
    =∑j=1qBji‾  Akj‾=∑j=1q(B†)ij(A†)jk=\sum_{j=1}^q\overline{B_{ji}}\;\overline{A_{kj}}=\sum_{j=1}^q(B^\dagger)_{ij}(A^\dagger)_{jk}
    Complex conjugation is additive and multiplicative, z+w‾=zˉ+wˉ\overline{z+w}=\bar z+\bar w and zw‾=zˉwˉ\overline{zw}=\bar z\bar w, and complex numbers commute, so each product can be written with the BB factor first.
  3. Step 3:
    =(B†A†)ikfor all i,k ⇒ (AB)†=B†A†=(B^\dagger A^\dagger)_{ik}\quad\text{for all }i,k\ \Rightarrow\ (AB)^\dagger=B^\dagger A^\dagger
    The last sum is entry (i,k)(i,k) of the product B†A†B^\dagger A^\dagger of an r×qr\times q and a q×pq\times p matrix.
  4. Step 4:
    (AB)†(AB)=B†(A†A)B=B†B=I ⇒ (AB)−1=(AB)†=B†A†=B−1A−1(AB)^\dagger(AB)=B^\dagger(A^\dagger A)B=B^\dagger B=I\ \Rightarrow\ (AB)^{-1}=(AB)^\dagger=B^\dagger A^\dagger=B^{-1}A^{-1}
    For unitary square A,BA,B use the identity just proved, associativity, and A†A=B†B=IA^\dagger A=B^\dagger B=I; a square matrix with a left inverse is invertible, with the same two-sided inverse.

∎

Proposition

The inverse of a circuit is the reversed sequence of inverted gates

Let a circuit apply the gates G1,G2,…,GLG_1,G_2,\dots,G_L in this time order, each GkG_k a unitary acting on a subset SkS_k of the qubits (as Gk⊗IG_k\otimes I on the full register). Then U=GL⋯G2G1U=G_L\cdots G_2G_1 and U−1=U†=G1†G2†⋯GL†,U^{-1}=U^\dagger=G_1^\dagger G_2^\dagger\cdots G_L^\dagger, i.e. the inverse circuit applies GL†,GL−1†,…,G1†G_L^\dagger,G_{L-1}^\dagger,\dots,G_1^\dagger in this time order, each on the same qubits SkS_k as the original gate. The inverse circuit has the same number of gates and the same depth as UU.

Proof (6 steps)
  1. Step 1:
    L=1:U=G1,U†=G1†L=1:\quad U=G_1,\qquad U^\dagger=G_1^\dagger
    Base case: a one-gate circuit is inverted by the inverse of its gate.
  2. Step 2:
    UL+1=GL+1UL ⇒ UL+1†=UL† GL+1†U_{L+1}=G_{L+1}U_L\ \Rightarrow\ U_{L+1}^\dagger=U_L^\dagger\,G_{L+1}^\dagger
    Induction step: adding a gate at the end of the circuit multiplies the unitary from the left; apply the lemma with A=GL+1A=G_{L+1}, B=ULB=U_L.
  3. Step 3:
    UL+1†=(G1†⋯GL†)GL+1†=G1†G2†⋯GL+1†U_{L+1}^\dagger=\big(G_1^\dagger\cdots G_L^\dagger\big)G_{L+1}^\dagger=G_1^\dagger G_2^\dagger\cdots G_{L+1}^\dagger
    Insert the induction hypothesis UL†=G1†⋯GL†U_L^\dagger=G_1^\dagger\cdots G_L^\dagger. As a time-ordered circuit the product is read from the right: GL+1†G_{L+1}^\dagger is applied first and G1†G_1^\dagger last.
  4. Step 4:
    U†U=G1†⋯GL−1†(GL†GL)GL−1⋯G1=G1†⋯GL−1†GL−1⋯G1=⋯=IU^\dagger U=G_1^\dagger\cdots G_{L-1}^\dagger\big(G_L^\dagger G_L\big)G_{L-1}\cdots G_1=G_1^\dagger\cdots G_{L-1}^\dagger G_{L-1}\cdots G_1=\cdots=I
    Direct check that the reversed circuit undoes the original one: the product telescopes from the middle outwards, each Gk†Gk=IG_k^\dagger G_k=I.
  5. Step 5:
    (G⊗ISˉ)†=G†⊗ISˉ(G\otimes I_{\bar S})^\dagger=G^\dagger\otimes I_{\bar S}
    A gate on the qubits SS is the tensor product of its small matrix with the identity on the remaining qubits Sˉ\bar S, and (A⊗B)†=A†⊗B†(A\otimes B)^\dagger=A^\dagger\otimes B^\dagger entrywise; so each inverted gate acts on the same qubits as the original one.
  6. Step 6:
    moments M1,…,Md of U ⇒ moments Md†,…,M1† of U†\text{moments }M_1,\dots,M_d\text{ of }U\ \Rightarrow\ \text{moments }M_d^\dagger,\dots,M_1^\dagger\text{ of }U^\dagger
    Gates in one moment act on disjoint qubits, so their inverses do too; reversing the list of moments gives a valid layering of U†U^\dagger with the same depth dd, and the gate count LL is unchanged.

∎

Inverses of the standard gates. The proposition reduces the problem to inverting single gates. The table lists every gate of the circuit builder; the proposition after it proves each line.

gatematrix or definitioninverse
HH, XX, YY, ZZHermitian and unitaryitself
CNOT\mathrm{CNOT}, CZ\mathrm{CZ}, SWAP\mathrm{SWAP}real symmetric permutation or diagonal ±1\pm1 matricesitself
CCX\mathrm{CCX}, CSWAP\mathrm{CSWAP}real symmetric permutation matricesitself
S=diag(1,i)S=\mathrm{diag}(1,i)phase gate P(π/2)P(\pi/2)S†=diag(1,−i)=P(−π/2)S^\dagger=\mathrm{diag}(1,-i)=P(-\pi/2)
T=diag(1,eiπ/4)T=\mathrm{diag}(1,e^{i\pi/4})phase gate P(π/4)P(\pi/4)T†=diag(1,e−iπ/4)=P(−π/4)T^\dagger=\mathrm{diag}(1,e^{-i\pi/4})=P(-\pi/4)
RP(θ)R_P(\theta), P∈{X,Y,Z}P\in\{X,Y,Z\}e−iθP/2e^{-i\theta P/2}RP(−θ)=e+iθP/2R_P(-\theta)=e^{+i\theta P/2}
P(φ)P(\varphi)diag(1,eiφ)\mathrm{diag}(1,e^{i\varphi})P(−φ)P(-\varphi)
CRZ(θ)\mathrm{CRZ}(\theta)∣0⟩⟨0∣⊗I+∣1⟩⟨1∣⊗RZ(θ)\lvert0\rangle\langle0\rvert\otimes I+\lvert1\rangle\langle1\rvert\otimes R_Z(\theta)CRZ(−θ)\mathrm{CRZ}(-\theta)

Self-inverse gates are copied unchanged into the inverse circuit, SS and TT become S†S^\dagger and T†T^\dagger, and every parameterised gate keeps its qubits and gets its angle negated. Together with the reversal of the order this is the whole recipe: reverse the order and negate the angles.

Proposition

Inverses of the standard gates

H,X,Y,Z,CNOT,CZ,SWAP,CCX,CSWAPH,X,Y,Z,\mathrm{CNOT},\mathrm{CZ},\mathrm{SWAP},\mathrm{CCX},\mathrm{CSWAP} are their own inverses; S−1=S†S^{-1}=S^\dagger and T−1=T†T^{-1}=T^\dagger as in the table; for P∈{X,Y,Z}P\in\{X,Y,Z\} and all real θ,φ\theta,\varphi, RP(θ)†=RP(−θ),P(φ)†=P(−φ),CRZ(θ)†=CRZ(−θ).R_P(\theta)^\dagger=R_P(-\theta),\qquad P(\varphi)^\dagger=P(-\varphi),\qquad\mathrm{CRZ}(\theta)^\dagger=\mathrm{CRZ}(-\theta).

Proof (7 steps)
  1. Step 1:
    G=G†, G†G=I ⇒ G2=I ⇒ G−1=GG=G^\dagger,\ G^\dagger G=I\ \Rightarrow\ G^2=I\ \Rightarrow\ G^{-1}=G
    A matrix that is both Hermitian and unitary squares to the identity. X,Y,ZX,Y,Z are Hermitian by inspection and H=12(X+Z)H=\frac1{\sqrt2}(X+Z) is a real combination of Hermitian matrices.
  2. Step 2:
    CNOT=∣0⟩⟨0∣⊗I+∣1⟩⟨1∣⊗X,CZ=diag(1,1,1,−1)\mathrm{CNOT}=\lvert0\rangle\langle0\rvert\otimes I+\lvert1\rangle\langle1\rvert\otimes X,\qquad\mathrm{CZ}=\mathrm{diag}(1,1,1,-1)
    Both are Hermitian (sums of tensor products of Hermitian factors, resp. real diagonal) and unitary, hence self-inverse. SWAP\mathrm{SWAP}, CCX\mathrm{CCX} and CSWAP\mathrm{CSWAP} are permutation matrices of involutions of the basis states (swapping two bits, flipping a bit under a condition that the flip does not change, exchanging two bits under a control), so applying them twice restores every basis state.
  3. Step 3:
    (eA)†=(∑k≥0Akk!)†=∑k≥0(A†)kk!=eA†\big(e^{A}\big)^\dagger=\Big(\sum_{k\ge0}\frac{A^k}{k!}\Big)^\dagger=\sum_{k\ge0}\frac{(A^\dagger)^k}{k!}=e^{A^\dagger}
    The exponential series converges absolutely, the adjoint is linear and continuous, and (Ak)†=(A†)k(A^k)^\dagger=(A^\dagger)^k by the lemma applied k−1k-1 times.
  4. Step 4:
    RP(θ)†=(e−iθP/2)†=e iθP†/2=e−i(−θ)P/2=RP(−θ)R_P(\theta)^\dagger=\big(e^{-i\theta P/2}\big)^\dagger=e^{\,i\theta P^\dagger/2}=e^{-i(-\theta)P/2}=R_P(-\theta)
    Use the previous line with A=−iθP/2A=-i\theta P/2, −i‾=i\overline{-i}=i, and P†=PP^\dagger=P for the Pauli matrices.
  5. Step 5:
    RP(−θ)RP(θ)=(cos⁡θ2I+isin⁡θ2P)(cos⁡θ2I−isin⁡θ2P)=(cos⁡2θ2+sin⁡2θ2)I=IR_P(-\theta)R_P(\theta)=\Big(\cos\tfrac\theta2I+i\sin\tfrac\theta2P\Big)\Big(\cos\tfrac\theta2I-i\sin\tfrac\theta2P\Big)=\Big(\cos^2\tfrac\theta2+\sin^2\tfrac\theta2\Big)I=I
    An explicit check with RP(θ)=cos⁡θ2I−isin⁡θ2PR_P(\theta)=\cos\frac\theta2I-i\sin\frac\theta2P (exponential series with P2=IP^2=I): the cross terms cancel and (isin⁡θ2P)(−isin⁡θ2P)=sin⁡2θ2P2(i\sin\frac\theta2P)(-i\sin\frac\theta2P)=\sin^2\frac\theta2P^2.
  6. Step 6:
    P(φ)†=diag(1,eiφ)†=diag(1,e−iφ)=P(−φ),S†=P(−π2),T†=P(−π4)P(\varphi)^\dagger=\mathrm{diag}\big(1,e^{i\varphi}\big)^\dagger=\mathrm{diag}\big(1,e^{-i\varphi}\big)=P(-\varphi),\qquad S^\dagger=P(-\tfrac\pi2),\quad T^\dagger=P(-\tfrac\pi4)
    The adjoint of a diagonal matrix conjugates its diagonal, and eiφ‾=e−iφ\overline{e^{i\varphi}}=e^{-i\varphi}. Since S=P(π/2)S=P(\pi/2) and T=P(π/4)T=P(\pi/4), their inverses are phase gates with negated angles, which are not equal to SS and TT.
  7. Step 7:
    CRZ(θ)†=∣0⟩⟨0∣†⊗I+∣1⟩⟨1∣†⊗RZ(θ)†=∣0⟩⟨0∣⊗I+∣1⟩⟨1∣⊗RZ(−θ)=CRZ(−θ)\mathrm{CRZ}(\theta)^\dagger=\lvert0\rangle\langle0\rvert^\dagger\otimes I+\lvert1\rangle\langle1\rvert^\dagger\otimes R_Z(\theta)^\dagger=\lvert0\rangle\langle0\rvert\otimes I+\lvert1\rangle\langle1\rvert\otimes R_Z(-\theta)=\mathrm{CRZ}(-\theta)
    (A⊗B)†=A†⊗B†(A\otimes B)^\dagger=A^\dagger\otimes B^\dagger, projectors are Hermitian, and the rotation line above. The same argument inverts every controlled-UU gate to controlled-U†U^\dagger, e.g. CP(φ)†=CP(−φ)\mathrm{CP}(\varphi)^\dagger=\mathrm{CP}(-\varphi) and CRX(θ)†=CRX(−θ)\mathrm{CRX}(\theta)^\dagger=\mathrm{CRX}(-\theta).

∎

Derivation

Worked inverse: the two-qubit ZZ feature map with one repetition

  1. Step 1:
    H(0), H(1), RZ(0)(2x0), RZ(1)(2x1), CNOT0→1, RZ(1)(2ϕ(x)), CNOT0→1,ϕ(x)=(π−x0)(π−x1)H^{(0)},\ H^{(1)},\ R_Z^{(0)}(2x_0),\ R_Z^{(1)}(2x_1),\ \mathrm{CNOT}_{0\to1},\ R_Z^{(1)}(2\phi(x)),\ \mathrm{CNOT}_{0\to1},\qquad\phi(x)=(\pi-x_0)(\pi-x_1)
    The ZZ feature map of Havlíček et al. (2019) with one repetition, in time order (seven gates, depth 55). The last three gates implement e−iϕ(x)Z⊗Ze^{-i\phi(x)Z\otimes Z}, because conjugating I⊗ZI\otimes Z by a CNOT gives Z⊗ZZ\otimes Z.
  2. Step 2:
    U(x)=CNOT RZ(1)(2ϕ) CNOT  RZ(1)(2x1) RZ(0)(2x0)  H(1)H(0)=D(x) (H⊗H)U(x)=\mathrm{CNOT}\,R_Z^{(1)}(2\phi)\,\mathrm{CNOT}\;R_Z^{(1)}(2x_1)\,R_Z^{(0)}(2x_0)\;H^{(1)}H^{(0)}=D(x)\,(H\otimes H)
    The unitary is the product in reverse time order. All gates between the Hadamards are diagonal, and D(x)=exp⁡(−i[x0Z0+x1Z1+ϕ(x)Z0Z1])D(x)=\exp\big(-i[x_0Z_0+x_1Z_1+\phi(x)Z_0Z_1]\big) because RZ(2a)=e−iaZR_Z(2a)=e^{-iaZ} and commuting exponents add.
  3. Step 3:
    U(x′)†=H(0)H(1) RZ(0)(−2x0′) RZ(1)(−2x1′) CNOT RZ(1)(−2ϕ(x′)) CNOTU(x')^\dagger=H^{(0)}H^{(1)}\,R_Z^{(0)}(-2x'_0)\,R_Z^{(1)}(-2x'_1)\,\mathrm{CNOT}\,R_Z^{(1)}(-2\phi(x'))\,\mathrm{CNOT}
    The proposition: reverse the factors and invert each one. The CNOTs and Hadamards are self-inverse and every RZR_Z angle is negated.
  4. Step 4:
    CNOT0→1, RZ(1)(−2ϕ(x′)), CNOT0→1, RZ(1)(−2x1′), RZ(0)(−2x0′), H(1), H(0)\mathrm{CNOT}_{0\to1},\ R_Z^{(1)}(-2\phi(x')),\ \mathrm{CNOT}_{0\to1},\ R_Z^{(1)}(-2x'_1),\ R_Z^{(0)}(-2x'_0),\ H^{(1)},\ H^{(0)}
    The same inverse read as a circuit in time order, gate by gate: the last gate of U(x′)U(x') comes first. This is exactly the gate list that the engine function adjointCircuit returns in the code cell below.
  5. Step 5:
    x′=(1.0,0.4):ϕ(x′)=(π−1.0)(π−0.4)=5.871375,angles −11.742749, −0.8, −2x'=(1.0,0.4):\quad\phi(x')=(\pi-1.0)(\pi-0.4)=5.871375,\qquad\text{angles }{-11.742749},\ {-0.8},\ {-2}
    The numerical angles of the uncompute half for the lab point x′x'; the compute half uses 2x0=0.62x_0=0.6, 2x1=2.42x_1=2.4 and 2ϕ(x)=2(π−0.3)(π−1.2)=11.0344312\phi(x)=2(\pi-0.3)(\pi-1.2)=11.034431.
  6. Step 6:
    V=U(x′)†U(x)=(H⊗H) D(x′)†D(x) (H⊗H)V=U(x')^\dagger U(x)=(H\otimes H)\,D(x')^\dagger D(x)\,(H\otimes H)
    Concatenate both halves: 1414 gates and depth 1010 as written. In the middle, CNOT⋅CNOT=I\mathrm{CNOT}\cdot\mathrm{CNOT}=I cancels, and since all diagonal factors commute the circuit compiles to H⊗2H^{\otimes2}, RZ(0)(2(x0−x0′))R_Z^{(0)}(2(x_0-x'_0)), RZ(1)(2(x1−x1′))R_Z^{(1)}(2(x_1-x'_1)), CNOT\mathrm{CNOT}, RZ(1)(2(ϕ(x)−ϕ(x′)))R_Z^{(1)}(2(\phi(x)-\phi(x'))), CNOT\mathrm{CNOT}, H⊗2H^{\otimes2}: 99 gates, depth 66.
  7. Step 7:
    D(x′)†D(x)=exp⁡(−i[Δ0Z0+Δ1Z1+ΔϕZ0Z1]),Δj=xj−xj′,  Δϕ=ϕ(x)−ϕ(x′)D(x')^\dagger D(x)=\exp\big(-i[\Delta_0Z_0+\Delta_1Z_1+\Delta_\phi Z_0Z_1]\big),\qquad\Delta_j=x_j-x'_j,\ \ \Delta_\phi=\phi(x)-\phi(x')
    Diagonal exponents commute, so their exponents subtract.
  8. Step 8:
    K(x,x′)=∣⟨++∣D(x′)†D(x)∣++⟩∣2=∣14∑z0,z1=±1e−i(Δ0z0+Δ1z1+Δϕz0z1)∣2K(x,x')=\big\lvert\langle{+}{+}\vert D(x')^\dagger D(x)\vert{+}{+}\rangle\big\rvert^2=\Big\lvert\frac14\sum_{z_0,z_1=\pm1}e^{-i(\Delta_0z_0+\Delta_1z_1+\Delta_\phi z_0z_1)}\Big\rvert^2
    H⊗H∣00⟩=∣++⟩=12∑z∣z⟩H\otimes H\lvert00\rangle=\lvert{+}{+}\rangle=\frac12\sum_{z}\lvert z\rangle, and the diagonal unitary multiplies the basis state with Z0=z0Z_0=z_0, Z1=z1Z_1=z_1 by e−i(⋯ )e^{-i(\cdots)}. For the lab points Δ=(−0.7,0.8)\Delta=(-0.7,0.8), Δϕ=−0.354159\Delta_\phi=-0.354159, and the formula gives K=0.275486K=0.275486, the value printed by the code cells.

Result

UZZ(x′)†=H⊗2 RZ(0)(−2x0′)RZ(1)(−2x1′) CNOT RZ(1)(−2ϕ(x′)) CNOT,KZZ((0.3,1.2),(1.0,0.4))=0.2754859933…\boxed{U_{ZZ}(x')^\dagger=H^{\otimes2}\,R_Z^{(0)}(-2x'_0)R_Z^{(1)}(-2x'_1)\,\mathrm{CNOT}\,R_Z^{(1)}(-2\phi(x'))\,\mathrm{CNOT},\qquad K_{ZZ}\big((0.3,1.2),(1.0,0.4)\big)=0.2754859933\ldots}

Quick check

A two-qubit encoding applies, in time order, RY(a)R_Y(a) on qubit 00, then CNOT0→1\mathrm{CNOT}_{0\to1}, then TT on qubit 11. Which time-ordered gate list implements its inverse?

Select one answer

Product R_X encodings collapse#

For the product (angle) encodings of the lesson Angle & Phase Encoding the inversion test simplifies dramatically: the compute and uncompute rotations on each qubit merge into a single rotation by the difference of the features. This explains the closed form K=∏jcos⁡2xj−xj′2K=\prod_j\cos^2\frac{x_j-x'_j}{2} of the previous lesson from the circuit side and gives the complete outcome distribution that the lab checks.

Theorem

The inversion test of a product R_X encoding is a product of R_X rotations

Let U(x)=⨂j=0n−1RX(xj)U(x)=\bigotimes_{j=0}^{n-1}R_X(x_j), with feature xjx_j on qubit jj. Then U(x′)†U(x)=⨂j=0n−1RX(xj−xj′),U(x')^\dagger U(x)=\bigotimes_{j=0}^{n-1}R_X(x_j-x'_j), and the outcome b=b0⋯bn−1b=b_0\cdots b_{n-1} of the inversion test has probability P(b)=∏j=0n−1(cos⁡2xj−xj′2)1−bj(sin⁡2xj−xj′2)bj,P(0n)=∏j=0n−1cos⁡2xj−xj′2=K(x,x′).P(b)=\prod_{j=0}^{n-1}\Big(\cos^2\frac{x_j-x'_j}{2}\Big)^{1-b_j}\Big(\sin^2\frac{x_j-x'_j}{2}\Big)^{b_j},\qquad P(0^n)=\prod_{j=0}^{n-1}\cos^2\frac{x_j-x'_j}{2}=K(x,x'). The same holds for RYR_Y in place of RXR_X.

Proof (7 steps)
  1. Step 1:
    U(x′)†=(⨂jRX(xj′))†=⨂jRX(xj′)†=⨂jRX(−xj′)U(x')^\dagger=\Big(\bigotimes_jR_X(x'_j)\Big)^\dagger=\bigotimes_jR_X(x'_j)^\dagger=\bigotimes_jR_X(-x'_j)
    (A⊗B)†=A†⊗B†(A\otimes B)^\dagger=A^\dagger\otimes B^\dagger and RX(θ)†=RX(−θ)R_X(\theta)^\dagger=R_X(-\theta). Gates on different qubits commute, (A⊗I)(I⊗B)=A⊗B=(I⊗B)(A⊗I)(A\otimes I)(I\otimes B)=A\otimes B=(I\otimes B)(A\otimes I), so the reversed order of the circuit proposition is immaterial here.
  2. Step 2:
    U(x′)†U(x)=⨂jRX(−xj′)⋅⨂jRX(xj)=⨂jRX(−xj′)RX(xj)U(x')^\dagger U(x)=\bigotimes_jR_X(-x'_j)\cdot\bigotimes_jR_X(x_j)=\bigotimes_jR_X(-x'_j)R_X(x_j)
    The mixed-product rule (⨂jAj)(⨂jBj)=⨂jAjBj(\bigotimes_jA_j)(\bigotimes_jB_j)=\bigotimes_jA_jB_j: each qubit sees only its own two rotations.
  3. Step 3:
    RX(α)RX(β)=(cαI−isαX)(cβI−isβX)=(cαcβ−sαsβ)I−i(sαcβ+cαsβ)XR_X(\alpha)R_X(\beta)=\Big(c_\alpha I-is_\alpha X\Big)\Big(c_\beta I-is_\beta X\Big)=\big(c_\alpha c_\beta-s_\alpha s_\beta\big)I-i\big(s_\alpha c_\beta+c_\alpha s_\beta\big)X
    Abbreviate cα=cos⁡α2c_\alpha=\cos\frac\alpha2, sα=sin⁡α2s_\alpha=\sin\frac\alpha2 and use RX(α)=cαI−isαXR_X(\alpha)=c_\alpha I-is_\alpha X and X2=IX^2=I; the term (−isαX)(−isβX)=−sαsβI(-is_\alpha X)(-is_\beta X)=-s_\alpha s_\beta I.
  4. Step 4:
    =cos⁡α+β2 I−isin⁡α+β2 X=RX(α+β)=\cos\frac{\alpha+\beta}2\,I-i\sin\frac{\alpha+\beta}2\,X=R_X(\alpha+\beta)
    The addition theorems for cosine and sine. Equivalently, e−iαX/2e−iβX/2=e−i(α+β)X/2e^{-i\alpha X/2}e^{-i\beta X/2}=e^{-i(\alpha+\beta)X/2} because the two exponents are multiples of the same matrix and therefore commute.
  5. Step 5:
    RX(−xj′)RX(xj)=RX(xj−xj′) ⇒ U(x′)†U(x)=⨂jRX(xj−xj′)R_X(-x'_j)R_X(x_j)=R_X(x_j-x'_j)\ \Rightarrow\ U(x')^\dagger U(x)=\bigotimes_jR_X(x_j-x'_j)
    Set α=−xj′\alpha=-x'_j, β=xj\beta=x_j. Compute and uncompute merge into one rotation by the feature difference Δj=xj−xj′\Delta_j=x_j-x'_j.
  6. Step 6:
    RX(Δj)∣0⟩=cos⁡Δj2∣0⟩−isin⁡Δj2∣1⟩,V∣0n⟩=⨂j(cos⁡Δj2∣0⟩−isin⁡Δj2∣1⟩)R_X(\Delta_j)\lvert0\rangle=\cos\frac{\Delta_j}2\lvert0\rangle-i\sin\frac{\Delta_j}2\lvert1\rangle,\qquad V\lvert0^n\rangle=\bigotimes_j\Big(\cos\frac{\Delta_j}2\lvert0\rangle-i\sin\frac{\Delta_j}2\lvert1\rangle\Big)
    First column of RX(Δj)R_X(\Delta_j); the output is a product state.
  7. Step 7:
    P(b)=∏j∣⟨bj∣RX(Δj)∣0⟩∣2=∏j(cos⁡2Δj2)1−bj(sin⁡2Δj2)bjP(b)=\prod_j\Big\lvert\langle b_j\vert R_X(\Delta_j)\vert0\rangle\Big\rvert^2=\prod_j\Big(\cos^2\frac{\Delta_j}2\Big)^{1-b_j}\Big(\sin^2\frac{\Delta_j}2\Big)^{b_j}
    The amplitude of ∣b⟩=⨂j∣bj⟩\lvert b\rangle=\bigotimes_j\lvert b_j\rangle in a product state is the product of the one-qubit amplitudes; ∣−i∣=1\lvert-i\rvert=1. For b=0nb=0^n this is the product-kernel formula of the previous lesson. For RYR_Y the same steps apply with YY in place of XX (also Y2=IY^2=I), and RY(Δ)∣0⟩=cos⁡Δ2∣0⟩+sin⁡Δ2∣1⟩R_Y(\Delta)\lvert0\rangle=\cos\frac\Delta2\lvert0\rangle+\sin\frac\Delta2\lvert1\rangle.

∎

Derivation

Worked example: x = (0.3, 1.2), x′ = (1.0, 0.4)

  1. Step 1:
    V=RX(0.3−1.0)⊗RX(1.2−0.4)=RX(−0.7)⊗RX(0.8),12Δ=(−0.35, 0.4)V=R_X(0.3-1.0)\otimes R_X(1.2-0.4)=R_X(-0.7)\otimes R_X(0.8),\qquad\tfrac12\Delta=(-0.35,\ 0.4)
    The collapse theorem with the lab points; qubit 00 is rotated by −0.7-0.7, qubit 11 by 0.80.8.
  2. Step 2:
    cos⁡2(0.35)=0.882421,sin⁡2(0.35)=0.117579,cos⁡2(0.4)=0.848353,sin⁡2(0.4)=0.151647\cos^2(0.35)=0.882421,\quad\sin^2(0.35)=0.117579,\quad\cos^2(0.4)=0.848353,\quad\sin^2(0.4)=0.151647
    The one-qubit outcome probabilities; cosine is even, so the sign of −0.35-0.35 does not matter.
  3. Step 3:
    P(00)=cos⁡2(0.35)cos⁡2(0.4)=0.882421×0.848353=0.748605=K(x,x′)P(00)=\cos^2(0.35)\cos^2(0.4)=0.882421\times0.848353=0.748605=K(x,x')
    Both qubits return 00: the kernel value of the previous lesson's lab.
  4. Step 4:
    P(01)=cos⁡2(0.35)sin⁡2(0.4)=0.133816,P(10)=sin⁡2(0.35)cos⁡2(0.4)=0.099748P(01)=\cos^2(0.35)\sin^2(0.4)=0.133816,\qquad P(10)=\sin^2(0.35)\cos^2(0.4)=0.099748
    Exactly one qubit flips. The outcome string lists qubit 00 first, so 0101 means qubit 11 returned 11.
  5. Step 5:
    P(11)=sin⁡2(0.35)sin⁡2(0.4)=0.017830,P(00)+P(01)+P(10)+P(11)=1P(11)=\sin^2(0.35)\sin^2(0.4)=0.017830,\qquad P(00)+P(01)+P(10)+P(11)=1
    Both flip. The four numbers factorise as (0.882421+0.117579)(0.848353+0.151647)=1(0.882421+0.117579)(0.848353+0.151647)=1.
  6. Step 6:
    U(x′)U(x)=RX(1.3)⊗RX(1.6):P(00)=cos⁡2(0.65)cos⁡2(0.8)=0.633749×0.485400=0.307622U(x')U(x)=R_X(1.3)\otimes R_X(1.6):\quad P(00)=\cos^2(0.65)\cos^2(0.8)=0.633749\times0.485400=0.307622
    The lab's first diagnostic: appending U(x′)U(x') instead of U(x′)†U(x')^\dagger adds the features instead of subtracting them.
  7. Step 7:
    RX(0.3−0.4)⊗RX(1.2−1.0):P(00)=cos⁡2(0.05)cos⁡2(0.1)=0.997502×0.990033=0.987560R_X(0.3-0.4)\otimes R_X(1.2-1.0):\quad P(00)=\cos^2(0.05)\cos^2(0.1)=0.997502\times0.990033=0.987560
    The second diagnostic: the inverse rotations of x1′x'_1 and x0′x'_0 placed on the wrong qubits compare xx with the swapped point (0.4,1.0)(0.4,1.0).

Result

(P(00),P(01),P(10),P(11))=(0.7486048950, 0.1338161986, 0.0997484596, 0.0178304467)\boxed{\big(P(00),P(01),P(10),P(11)\big)=(0.7486048950,\ 0.1338161986,\ 0.0997484596,\ 0.0178304467)}
V=RX(−0.7)⊗RX(0.8)=(c0c1−ic0s1−is0c1−s0s1−ic0s1c0c1−s0s1−is0c1−is0c1−s0s1c0c1−ic0s1−s0s1−is0c1−ic0s1c0c1),c0=cos⁡0.35, s0=−sin⁡0.35, c1=cos⁡0.4, s1=sin⁡0.4V=R_X(-0.7)\otimes R_X(0.8)=\begin{pmatrix}c_0c_1&-ic_0s_1&-is_0c_1&-s_0s_1\\-ic_0s_1&c_0c_1&-s_0s_1&-is_0c_1\\-is_0c_1&-s_0s_1&c_0c_1&-ic_0s_1\\-s_0s_1&-is_0c_1&-ic_0s_1&c_0c_1\end{pmatrix},\quad c_0=\cos0.35,\ s_0=-\sin0.35,\ c_1=\cos0.4,\ s_1=\sin0.4
V = U(x′)† U(x) = R_X(−0.7) ⊗ R_X(0.8)4×4

Unitary verified: U†U=IU^\dagger U = I (max deviation 1.1e-16)

The comparer shows the two kernel circuits for the lab points side by side: on the left the SWAP test on 2n+1=52n+1=5 qubits, which returns ancilla outcome 00 with probability P(0)=12(1+K)=0.874302P(0)=\frac12(1+K)=0.874302; on the right the inversion test on 22 qubits, which returns 0000 with probability K=0.748605K=0.748605. Both read off the same kernel. The first column of the matrix above is the output state V∣00⟩V\lvert00\rangle, whose squared moduli are the four probabilities of the worked example.

Why the two-gate circuit also passes the lab. The collapse theorem says that the four-gate circuit RX(0.3)R_X(0.3), RX(1.2)R_X(1.2), RX(−1.0)R_X(-1.0), RX(−0.4)R_X(-0.4) and the two-gate circuit RX(−0.7)R_X(-0.7), RX(0.8)R_X(0.8) are the same unitary, so they produce the same state and the same distribution, and the grader, which simulates the circuit, cannot and should not tell them apart. A compiler does exactly this merge, and on hardware the compiled inversion test of a product encoding has depth 11. The collapse is special to encodings whose compute and uncompute gates commute qubit by qubit; for entangling maps such as the ZZ map only part of the circuit merges, as the worked inverse above showed. For the same reason the reversed circuit U(x)†U(x′)=⨂jRX(xj′−xj)U(x)^\dagger U(x')=\bigotimes_jR_X(x'_j-x_j) passes: cosine and sine squared are even, so its distribution is identical.

Quick check

Two features are encoded with RXR_X rotations. The inversion test is run for x=(0.5, 2.0)x=(0.5,\,2.0) and x′=(0.5, 0.0)x'=(0.5,\,0.0). What is P(00)P(00)? Give four decimals.

tolerance ±0.0001

Resources: inversion test versus SWAP test#

Both tests estimate the same kernel, but they spend different resources. Write gg for the number of gates, cc for the number of CNOTs and dd for the depth of one encoding circuit U(x)U(x) on nn qubits; the encoding of x′x' has the same structure with different angles. Depth is counted in moments: gates on disjoint qubits share a moment, and each gate is placed in the earliest moment after the last gate on any of its qubits (greedy left-packing).

Proposition

Qubits, gates, CNOTs and depth of the two kernel circuits

The inversion test uses nn qubits, 2g2g gates, 2c2c CNOTs and depth at most 2d2d. The SWAP test uses 2n+12n+1 qubits, 2g+n+22g+n+2 gates (counting each controlled-SWAP as one gate) and depth at most d+n+1d+n+1 and at least n+2n+2. With CSWAP=CNOT⋅CCX⋅CNOT\mathrm{CSWAP}=\mathrm{CNOT}\cdot\mathrm{CCX}\cdot\mathrm{CNOT} and the standard 66-CNOT Toffoli, the SWAP test needs 2c+8n2c+8n CNOTs, and its depth stays d+O(n)d+O(n).

Proof (8 steps)
  1. Step 1:
    V=U(x′)†U(x) acts on the n encoding qubits onlyV=U(x')^\dagger U(x)\ \text{acts on the }n\text{ encoding qubits only}
    Inversion test, qubits: compute and uncompute act on the same register and no ancilla is needed.
  2. Step 2:
    #gates(V)=g+g=2g,#CNOT(V)=c+c=2c\#\text{gates}(V)=g+g=2g,\qquad\#\mathrm{CNOT}(V)=c+c=2c
    U(x′)†U(x')^\dagger has one inverted gate for each gate of U(x′)U(x') (circuit proposition), and the inverse of a CNOT is a CNOT.
  3. Step 3:
    depth(V)≤depth U(x)+depth U(x′)†=d+d=2d\mathrm{depth}(V)\le\mathrm{depth}\,U(x)+\mathrm{depth}\,U(x')^\dagger=d+d=2d
    The dd moments of U(x)U(x) followed by the dd moments of U(x′)†U(x')^\dagger form a valid layering; left-packing can only shorten it when a gate at the junction finds an idle qubit.
  4. Step 4:
    ∣0⟩anc⊗∣ϕ(x)⟩1..n⊗∣ϕ(x′)⟩n+1..2n:1+n+n=2n+1 qubits\lvert0\rangle_{\mathrm{anc}}\otimes\lvert\phi(x)\rangle_{1..n}\otimes\lvert\phi(x')\rangle_{n+1..2n}:\quad1+n+n=2n+1\ \text{qubits}
    SWAP test, qubits: one ancilla and one register per feature state.
  5. Step 5:
    #gates=g+g⏟U(x), U(x′)+2⏟H, H+n⏟CSWAP0; 1+i, 1+n+i=2g+n+2\#\text{gates}=\underbrace{g+g}_{U(x),\,U(x')}+\underbrace{2}_{H,\,H}+\underbrace{n}_{\mathrm{CSWAP}_{0;\,1+i,\,1+n+i}}=2g+n+2
    The two preparations, the two Hadamards on the ancilla, and one controlled-SWAP per qubit pair (1+i, 1+n+i)(1+i,\,1+n+i), i=0,…,n−1i=0,\dots,n-1.
  6. Step 6:
    depth≤d⏟parallel preparations+n⏟CSWAPs+1⏟final H,depth≥1+n+1\mathrm{depth}\le\underbrace{d}_{\text{parallel preparations}}+\underbrace{n}_{\text{CSWAPs}}+\underbrace{1}_{\text{final }H},\qquad\mathrm{depth}\ge1+n+1
    The two preparations act on disjoint registers and run in parallel, and the first Hadamard acts on the idle ancilla during the first moment. Every controlled-SWAP involves the ancilla, so no two of them share a moment: they occupy nn distinct moments after the first Hadamard, and the last Hadamard comes after all of them, which gives the lower bound.
  7. Step 7:
    SWAPab=CNOTb→aCNOTa→bCNOTb→a ⇒ CSWAPc; a,b=CNOTb→a CCXc,a→b CNOTb→a\mathrm{SWAP}_{ab}=\mathrm{CNOT}_{b\to a}\mathrm{CNOT}_{a\to b}\mathrm{CNOT}_{b\to a}\ \Rightarrow\ \mathrm{CSWAP}_{c;\,a,b}=\mathrm{CNOT}_{b\to a}\,\mathrm{CCX}_{c,a\to b}\,\mathrm{CNOT}_{b\to a}
    Three CNOTs swap two qubits (∣a,b⟩↦∣a⊕b,b⟩↦∣a⊕b,a⟩↦∣b,a⟩\lvert a,b\rangle\mapsto\lvert a\oplus b,b\rangle\mapsto\lvert a\oplus b,a\rangle\mapsto\lvert b,a\rangle). To control the swap it suffices to control the middle CNOT: if the control is 00 the two outer CNOTs cancel each other.
  8. Step 8:
    #CNOT(CCX)=6 ⇒ #CNOT(CSWAP)=2+6=8,#CNOT(SWAP test)=2c+8n\#\mathrm{CNOT}(\mathrm{CCX})=6\ \Rightarrow\ \#\mathrm{CNOT}(\mathrm{CSWAP})=2+6=8,\qquad\#\mathrm{CNOT}(\text{SWAP test})=2c+8n
    The standard Toffoli circuit (Nielsen and Chuang, Fig. 4.9) uses 66 CNOTs, 22 Hadamards and single-qubit phase gates, seven of them TT or T†T^\dagger, and 66 CNOTs are necessary for a Toffoli (Shende and Markov 2009). Each decomposed controlled-SWAP is a block of constant depth that still touches the ancilla, so the depth becomes d+O(n)d+O(n).

∎

The two circuits side by side. The general counts of the proposition, and the counts for three concrete feature maps with the lab points (and x=(0.3,1.2,2.0)x=(0.3,1.2,2.0), x′=(1.0,0.4,0.5)x'=(1.0,0.4,0.5) for three features), counted with native HH, RXR_X, RZR_Z, CNOT and CSWAP gates and greedy left-packed moments:

inversion testSWAP test
qubitsnn2n+12n+1
gates2g2g2g+n+22g+n+2
CNOTs (CSWAP == CNOT, CCX, CNOT; 66-CNOT Toffoli)2c2c2c+8n2c+8n
depthat most 2d2dat most d+n+1d+n+1; d+O(n)d+O(n) after decomposition
needs the inverse circuit U(x′)†U(x')^\daggeryesno
estimator of KKN0n/NN_{0^n}/N2N0/N−12N_0/N-1
RXR_X product, n=2n=2 (g=2g=2, c=0c=0, d=1d=1)22 qubits, 44 gates, 00 CNOTs, depth 2255 qubits, 88 gates, 1616 CNOTs, depth 44
ZZ map, reps 11, n=2n=2 (g=7g=7, c=2c=2, d=5d=5)22 qubits, 1414 gates, 44 CNOTs, depth 101055 qubits, 1818 gates, 2020 CNOTs, depth 88
ZZ map, reps 22, n=3n=3 (g=24g=24, c=8c=8, d=16d=16)33 qubits, 4848 gates, 1616 CNOTs, depth 323277 qubits, 5353 gates, 4040 CNOTs, depth 1919

The trade-off is visible in the last rows. The inversion test always wins on width and on entangling gates: it never needs the 8n8n CNOTs of the controlled-SWAPs, which on hardware dominate the error budget. The SWAP test can win on depth in the native gate count, because it runs the two preparations in parallel instead of in series; for the deep ZZ map (d=16d=16) the inversion test is 3232 moments deep against 1919. Once the controlled-SWAPs are compiled into CNOTs and single-qubit gates, each of them costs a block of roughly a dozen moments, and the SWAP test loses that advantage unless dd is large compared with nn.

The second comparer uses the entangling ZZ feature map with three features and two repetitions. The kernel value is small, K(x,x′)=0.020471K(x,x')=0.020471, so the SWAP test returns ancilla outcome 00 with probability 12(1+K)=0.510235\frac12(1+K)=0.510235, barely distinguishable from a fair coin, while the inversion test returns 000000 with probability 0.0204710.020471, a rare event whose frequency directly is the kernel. The next section turns this observation into a statement about shots.

Quick check

In which situation can the inversion test not be used to estimate ∣⟨ψ∣ϕ⟩∣2\lvert\langle\psi\vert\phi\rangle\rvert^2?

Select one answer

Shot statistics#

Theorem

The inversion test needs fewer shots than the SWAP test

Let K=K(x,x′)∈[0,1]K=K(x,x')\in[0,1]. With NN shots, the inversion-test estimator K^inv=N0n/N\hat K_{\mathrm{inv}}=N_{0^n}/N and the SWAP-test estimator K^SWAP=2N0/N−1\hat K_{\mathrm{SWAP}}=2N_0/N-1 are unbiased, with Var[K^inv]=K(1−K)N,Var[K^SWAP]=1−K2N,K(1−K)≤1−K2,\mathrm{Var}[\hat K_{\mathrm{inv}}]=\frac{K(1-K)}{N},\qquad\mathrm{Var}[\hat K_{\mathrm{SWAP}}]=\frac{1-K^2}{N},\qquad K(1-K)\le1-K^2, with equality only at K=1K=1. For 0<K<10<K<1, reaching the same standard deviation requires NSWAPNinv=1+KK=1+1K ≥ 2\frac{N_{\mathrm{SWAP}}}{N_{\mathrm{inv}}}=\frac{1+K}{K}=1+\frac1K\ \ge\ 2 times as many SWAP-test shots, a ratio that grows like 1/K1/K as K→0K\to0.

Proof (7 steps)
  1. Step 1:
    N0n∼Bin(N,K) ⇒ E[K^inv]=K,Var[K^inv]=NK(1−K)N2=K(1−K)NN_{0^n}\sim\mathrm{Bin}(N,K)\ \Rightarrow\ \mathbb E[\hat K_{\mathrm{inv}}]=K,\qquad\mathrm{Var}[\hat K_{\mathrm{inv}}]=\frac{NK(1-K)}{N^2}=\frac{K(1-K)}N
    Each shot independently returns 0n0^n with probability P(0n)=KP(0^n)=K (first theorem), so the count is binomial with mean NKNK and variance NK(1−K)NK(1-K).
  2. Step 2:
    N0∼Bin(N,1+K2) ⇒ E[K^SWAP]=2⋅1+K2−1=KN_0\sim\mathrm{Bin}\Big(N,\frac{1+K}2\Big)\ \Rightarrow\ \mathbb E[\hat K_{\mathrm{SWAP}}]=2\cdot\frac{1+K}2-1=K
    The SWAP test returns ancilla outcome 00 with probability 1+K2\frac{1+K}2 (previous lesson); the affine estimator 2P^0−12\hat P_0-1 is unbiased by linearity.
  3. Step 3:
    Var[K^SWAP]=4 Var[P^0]=4N⋅1+K2⋅1−K2=1−K2N\mathrm{Var}[\hat K_{\mathrm{SWAP}}]=4\,\mathrm{Var}[\hat P_0]=\frac4N\cdot\frac{1+K}2\cdot\frac{1-K}2=\frac{1-K^2}N
    Var[aY+b]=a2Var[Y]\mathrm{Var}[aY+b]=a^2\mathrm{Var}[Y] with a=2a=2, and the Bernoulli variance p(1−p)p(1-p) with p=1+K2p=\frac{1+K}2, 1−p=1−K21-p=\frac{1-K}2.
  4. Step 4:
    (1−K2)−K(1−K)=1−K2−K+K2=1−K ≥ 0(1-K^2)-K(1-K)=1-K^2-K+K^2=1-K\ \ge\ 0
    The difference of the two single-shot variances is 1−K1-K, nonnegative on [0,1][0,1] and zero only at K=1K=1. Hence the inversion test is never worse.
  5. Step 5:
    σ2N≤ε  ⟺  N≥σ2ε2 ⇒ NSWAPNinv=1−K2K(1−K)=(1+K)(1−K)K(1−K)=1+KK\sqrt{\frac{\sigma^2}N}\le\varepsilon\iff N\ge\frac{\sigma^2}{\varepsilon^2}\ \Rightarrow\ \frac{N_{\mathrm{SWAP}}}{N_{\mathrm{inv}}}=\frac{1-K^2}{K(1-K)}=\frac{(1+K)(1-K)}{K(1-K)}=\frac{1+K}K
    Equal standard deviation ε\varepsilon needs shots proportional to the single-shot variance σ2\sigma^2; for 0<K<10<K<1 cancel the common factor 1−K1-K.
  6. Step 6:
    1+KK=1+1K≥2  (0<K≤1),1+KK∼1K  (K→0),K=2−n: 1+KK=2n+1\frac{1+K}K=1+\frac1K\ge2\ \ (0<K\le1),\qquad\frac{1+K}K\sim\frac1K\ \ (K\to0),\qquad K=2^{-n}:\ \frac{1+K}K=2^n+1
    As K→1K\to1 the ratio tends to its minimum 22, and for small kernels the gap explodes: the inversion test's variance K(1−K)≈KK(1-K)\approx K vanishes with KK, whereas the SWAP test's variance 1−K2≈11-K^2\approx1 stays at its maximum. For a concentrated kernel of size 2−n2^{-n} the SWAP test needs about 2n2^n times as many shots.
  7. Step 7:
    K=0.748605, ε=0.01:Ninv=⌈0.18819610−4⌉=1882,NSWAP=⌈0.43959110−4⌉=4396K=0.748605,\ \varepsilon=0.01:\quad N_{\mathrm{inv}}=\Big\lceil\frac{0.188196}{10^{-4}}\Big\rceil=1882,\qquad N_{\mathrm{SWAP}}=\Big\lceil\frac{0.439591}{10^{-4}}\Big\rceil=4396
    The lab value: K(1−K)=0.188196K(1-K)=0.188196 and 1−K2=0.4395911-K^2=0.439591; the ratio is 1+KK=2.3358\frac{1+K}K=2.3358.

∎

Quick check

For a kernel value K=0.25K=0.25, how many times as many shots does the SWAP test need as the inversion test to reach the same standard deviation?

tolerance ±0.000001

Depth doubling and noise bias#

Everything so far assumed a perfect device. On hardware every gate is followed by some decoherence, and the inversion test runs two encoding circuits in series, so a qubit experiences twice as many noisy operations as in a single encoding. The measured all-zeros frequency then estimates a noisy probability P~(0n)≠K(x,x′)\tilde P(0^n)\ne K(x,x'), and more shots do not remove the difference: the estimator becomes biased. Two exactly solvable noise models show the direction of the bias.

Derivation

Local depolarizing noise on a product R_X inversion test

  1. Step 1:
    Ep(ρ)=(1−p)ρ+p3(XρX+YρY+ZρZ)=(1−4p3)ρ+4p3 I2 Tr ρ\mathcal E_p(\rho)=(1-p)\rho+\frac p3\big(X\rho X+Y\rho Y+Z\rho Z\big)=\Big(1-\frac{4p}3\Big)\rho+\frac{4p}3\,\frac I2\,\mathrm{Tr}\,\rho
    Model: after every gate, the depolarizing channel with error probability pp acts on each qubit the gate touched. The second form follows from ∑P∈{I,X,Y,Z}PρP=2 Tr(ρ) I\sum_{P\in\{I,X,Y,Z\}}P\rho P=2\,\mathrm{Tr}(\rho)\,I for a qubit.
  2. Step 2:
    Ep(12(I+r⃗⋅σ⃗))=12(I+η1 r⃗⋅σ⃗),η1=1−4p3\mathcal E_p\Big(\tfrac12(I+\vec r\cdot\vec\sigma)\Big)=\tfrac12\Big(I+\eta_1\,\vec r\cdot\vec\sigma\Big),\qquad\eta_1=1-\frac{4p}3
    In Bloch coordinates the channel shrinks the Bloch vector by the factor η1\eta_1 and keeps its direction.
  3. Step 3:
    Ep(WρW†)=W Ep(ρ) W†for every one-qubit unitary W\mathcal E_p\big(W\rho W^\dagger\big)=W\,\mathcal E_p(\rho)\,W^\dagger\quad\text{for every one-qubit unitary }W
    The channel is covariant: WρW†W\rho W^\dagger gets the factor 1−4p31-\frac{4p}3 like ρ\rho, and WIW†=IWIW^\dagger=I. So all noise steps on a qubit can be moved past its rotations to the end of the circuit.
  4. Step 4:
    ρ~j=RX(Δj) Ep gj(∣0⟩⟨0∣) RX(Δj)†,r⃗j=η (0, −sin⁡Δj, cos⁡Δj),η=η1 gj\tilde\rho_j=R_X(\Delta_j)\,\mathcal E_p^{\,g_j}\big(\lvert0\rangle\langle0\rvert\big)\,R_X(\Delta_j)^\dagger,\qquad\vec r_j=\eta\,(0,\,-\sin\Delta_j,\,\cos\Delta_j),\quad\eta=\eta_1^{\,g_j}
    All gates are one-qubit gates, so the state stays a product state. Qubit jj undergoes gj=2g_j=2 noisy gates in the inversion test (one per encoding), its two rotations merge into RX(Δj)R_X(\Delta_j), and RX(Δ)R_X(\Delta) maps the Bloch vector (0,0,1)(0,0,1) of ∣0⟩\lvert0\rangle to (0,−sin⁡Δ,cos⁡Δ)(0,-\sin\Delta,\cos\Delta).
  5. Step 5:
    P~(0n)=∏j=0n−11+ηcos⁡Δj2versusK=∏j=0n−11+cos⁡Δj2\tilde P(0^n)=\prod_{j=0}^{n-1}\frac{1+\eta\cos\Delta_j}2\qquad\text{versus}\qquad K=\prod_{j=0}^{n-1}\frac{1+\cos\Delta_j}2
    The probability of outcome 00 on a qubit with Bloch vector r⃗\vec r is 12(1+rz)\frac12(1+r_z), and the qubits are independent.
  6. Step 6:
    1+ηcos⁡Δj2−12=η(1+cos⁡Δj2−12),P~(x,x)=(1+η2)n<1\frac{1+\eta\cos\Delta_j}2-\frac12=\eta\Big(\frac{1+\cos\Delta_j}2-\frac12\Big),\qquad\tilde P(x,x)=\Big(\frac{1+\eta}2\Big)^n<1
    Each factor is pulled towards 12\frac12 by the factor η\eta, so P~(0n)\tilde P(0^n) is pulled towards 2−n2^{-n}; even identical inputs no longer give 11. Because every qubit sees twice the gates of one encoding, the contraction is η12\eta_1^2 instead of η1\eta_1: doubling the depth squares the damage.
  7. Step 7:
    p=0.01:η=(1−0.043)2=0.973511,P~(00)=0.731962,K=0.748605,P~(x,x)=0.973687p=0.01:\quad\eta=\Big(1-\frac{0.04}3\Big)^2=0.973511,\quad\tilde P(00)=0.731962,\quad K=0.748605,\quad\tilde P(x,x)=0.973687
    The lab circuit under 1%1\% depolarizing noise per gate: the estimate is biased by −0.016643-0.016643, larger than the statistical error K(1−K)/N=0.0043\sqrt{K(1-K)/N}=0.0043 of 10410^4 shots, so more shots alone cannot fix it.

Result

P~(0n)=∏j=0n−11+ηcos⁡(xj−xj′)2,η=(1−4p3)2\boxed{\tilde P(0^n)=\prod_{j=0}^{n-1}\frac{1+\eta\cos(x_j-x'_j)}{2},\qquad\eta=\Big(1-\frac{4p}{3}\Big)^{2}}
Derivation

Global depolarizing noise and its correction from the diagonal

  1. Step 1:
    ρ~=λ V∣0n⟩⟨0n∣V†+(1−λ) I2n,0<λ≤1\tilde\rho=\lambda\,V\lvert0^n\rangle\langle0^n\rvert V^\dagger+(1-\lambda)\,\frac{I}{2^n},\qquad0<\lambda\le1
    Model: the whole circuit is followed by a global depolarizing channel that keeps the ideal state with probability λ\lambda and replaces it by the maximally mixed state otherwise; λ\lambda decreases with the depth of VV.
  2. Step 2:
    P~(0n)=⟨0n∣ρ~∣0n⟩=λK(x,x′)+(1−λ) 2−n\tilde P(0^n)=\langle0^n\vert\tilde\rho\vert0^n\rangle=\lambda K(x,x')+(1-\lambda)\,2^{-n}
    Linearity: the ideal part contributes λK\lambda K and the maximally mixed part assigns probability 2−n2^{-n} to every outcome.
  3. Step 3:
    P~(0n)−K=(1−λ)(2−n−K)\tilde P(0^n)-K=(1-\lambda)\big(2^{-n}-K\big)
    The bias is negative whenever K>2−nK>2^{-n} and positive below: noise pulls every kernel value towards the uninformative constant 2−n2^{-n}, the noise-induced concentration of Thanasilp et al. (2024).
  4. Step 4:
    P~diag=λ+(1−λ)2−n ⇒ λ=P~diag−2−n1−2−n\tilde P_{\mathrm{diag}}=\lambda+(1-\lambda)2^{-n}\ \Rightarrow\ \lambda=\frac{\tilde P_{\mathrm{diag}}-2^{-n}}{1-2^{-n}}
    Running the inversion test with x′=xx'=x (ideally K=1K=1) measures λ\lambda, provided the noise does not depend on the data.
  5. Step 5:
    K(x,x′)=P~(0n)−(1−λ)2−nλK(x,x')=\frac{\tilde P(0^n)-(1-\lambda)2^{-n}}{\lambda}
    Invert the affine relation; this is the device-noise correction of Hubregtsen et al. (2022). Dividing by λ\lambda multiplies the statistical error by 1/λ1/\lambda, so the corrected estimate needs about 1/λ21/\lambda^2 times as many shots.

Result

P~(0n)=λK(x,x′)+(1−λ)2−n,K(x,x′)=P~(0n)−(1−λ)2−nλ\boxed{\tilde P(0^n)=\lambda K(x,x')+(1-\lambda)2^{-n},\qquad K(x,x')=\frac{\tilde P(0^n)-(1-\lambda)2^{-n}}{\lambda}}

Verification in code#

The TypeScript cell builds the lab circuit with the engine function inversionTestCircuit, prints its gate list (note the reversed order of the uncompute half), its outcome distribution and the collapse to RX(−0.7)⊗RX(0.8)R_X(-0.7)\otimes R_X(0.8); prints the inverse of the ZZ feature map produced by adjointCircuit; checks on 100100 random pairs that P(0n)P(0^n) equals the exact kernel for an RXR_X encoding and for the ZZ map with two repetitions; reproduces the SWAP-test value P(0)=12(1+K)P(0)=\frac12(1+K); and recounts the resources of the second comparer.

TypeScriptrunnable
import { circuitUnitary, mulberry32, runStatevector, matrix } from '@/lib/quantum-simulator';
import { adjointCircuit, angleEncoding, fidelityKernel, inversionTestCircuit, inversionTestProbability, swapTestCircuit, swapTestProbability, zzFeatureMap } from '@/lib/qml';

type Op = { kind: string; gate?: string; targets?: number[]; controls?: number[]; params?: unknown[] };
const fmt = (v: number) => v.toFixed(10);
const show = (op: Op) =>
  op.kind !== 'gate' ? op.kind : op.gate + '(' + op.targets!.join(',') + (op.params ? ', ' + Number(op.params[0]).toFixed(4) : '') + ')';
const depth = (ops: Op[]) => {
  const last = new Map<number, number>();
  let d = 0;
  for (const op of ops) {
    if (op.kind !== 'gate') continue;
    const qs = [...(op.controls ?? []), ...op.targets!];
    const level = 1 + Math.max(...qs.map((q) => last.get(q) ?? 0));
    qs.forEach((q) => last.set(q, level));
    d = Math.max(d, level);
  }
  return d;
};
const stats = (ops: Op[]) => {
  const gates = ops.filter((op) => op.kind === 'gate');
  const cnots = gates.filter((op) => op.gate === 'CNOT').length;
  const cswaps = gates.filter((op) => op.gate === 'CSWAP').length;
  return 'gates ' + gates.length + ', CNOTs after decomposition ' + (cnots + 8 * cswaps) + ', depth ' + depth(gates);
};

const x = [0.3, 1.2];
const xp = [1.0, 0.4];

// (1) The lab circuit: R_X product encoding, V = U(x')^dagger U(x).
const rx = angleEncoding(2, { rotation: 'RX' });
const V = inversionTestCircuit(rx, x, xp);
console.log('V = ' + V.ops.map(show).join('; '));
console.log('P(00), P(01), P(10), P(11) = ' + Array.from(runStatevector(V).probabilities()).map(fmt).join(', '));
console.log("P(00) = " + fmt(inversionTestProbability(rx, x, xp)) + "   K(x, x') = " + fmt(fidelityKernel(rx, x, xp)));
const collapsed = circuitUnitary({ version: 1, numQubits: 2, numClbits: 0, ops: [
  { kind: 'gate', gate: 'RX', targets: [0], params: [-0.7] },
  { kind: 'gate', gate: 'RX', targets: [1], params: [0.8] },
] });
console.log('V equals R_X(-0.7) (x) R_X(0.8): ' + (matrix.maxAbsDiff(circuitUnitary(V), collapsed) < 1e-12));

// (2) The ZZ feature map (reps 1): the adjoint is the reversed list with negated angles.
const zz = zzFeatureMap(2, { reps: 1 });
console.log("U(x')^dagger = " + adjointCircuit(zz(xp)).ops.map(show).join('; '));
console.log("ZZ: P(00) = " + fmt(inversionTestProbability(zz, x, xp)) + "   K(x, x') = " + fmt(fidelityKernel(zz, x, xp)));

// (3) Agreement on random data for both encodings (3 qubits, ZZ with 2 repetitions).
const rng = mulberry32(41);
for (const [name, map] of [['angle (R_X)', angleEncoding(3, { rotation: 'RX' })], ['ZZ, reps 2', zzFeatureMap(3, { reps: 2 })]] as const) {
  let worst = 0;
  for (let t = 0; t < 100; t++) {
    const a = [0, 1, 2].map(() => 2 * Math.PI * rng());
    const b = [0, 1, 2].map(() => 2 * Math.PI * rng());
    worst = Math.max(worst, Math.abs(inversionTestProbability(map, a, b) - fidelityKernel(map, a, b)));
  }
  console.log(name + ': 100 random pairs, max |P(000) - K| < 1e-12: ' + (worst < 1e-12));
}

// (4) The SWAP test on 2n + 1 = 5 qubits estimates the same kernel through P(0) = (1 + K) / 2.
const p0 = swapTestProbability(runStatevector(rx(x)), runStatevector(rx(xp)));
console.log('SWAP test: P(0) = ' + fmt(p0) + '   2 P(0) - 1 = ' + fmt(2 * p0 - 1));

// (5) Resources for the ZZ map with 3 features and 2 repetitions.
const zz3 = zzFeatureMap(3, { reps: 2 });
const a3 = [0.3, 1.2, 2.0];
const b3 = [1.0, 0.4, 0.5];
console.log('ZZ, 3 features, reps 2: K = ' + fmt(fidelityKernel(zz3, a3, b3)));
console.log('  inversion test (3 qubits): ' + stats(inversionTestCircuit(zz3, a3, b3).ops));
console.log('  SWAP test (7 qubits):      ' + stats(swapTestCircuit(3)(zz3(a3), zz3(b3)).ops));

Expected output

V = RX(0, 0.3000); RX(1, 1.2000); RX(1, -0.4000); RX(0, -1.0000)
P(00), P(01), P(10), P(11) = 0.7486048950, 0.1338161986, 0.0997484596, 0.0178304467
P(00) = 0.7486048950   K(x, x') = 0.7486048950
V equals R_X(-0.7) (x) R_X(0.8): true
U(x')^dagger = CNOT(0,1); RZ(1, -11.7427); CNOT(0,1); RZ(1, -0.8000); RZ(0, -2.0000); H(1); H(0)
ZZ: P(00) = 0.2754859933   K(x, x') = 0.2754859933
angle (R_X): 100 random pairs, max |P(000) - K| < 1e-12: true
ZZ, reps 2: 100 random pairs, max |P(000) - K| < 1e-12: true
SWAP test: P(0) = 0.8743024475   2 P(0) - 1 = 0.7486048950
ZZ, 3 features, reps 2: K = 0.0204708258
  inversion test (3 qubits): gates 48, CNOTs after decomposition 16, depth 32
  SWAP test (7 qubits):      gates 53, CNOTs after decomposition 40, depth 19

The NumPy cell rebuilds everything from 2×22\times2 and 4×44\times4 matrices: a circuit is a time-ordered list of gates, its unitary the product in reverse order, and its inverse the reversed list of conjugate transposes. It prints the lab distribution against the closed form, the two diagnostic values, the ZZ kernel three ways (inversion test, overlap, and the diagonal formula of the worked inverse), a five-qubit SWAP test, the variance comparison with the ratio 1+KK\frac{1+K}{K}, and a density-matrix simulation of the lab circuit under 1%1\% local depolarizing noise against the closed form ∏j1+ηcos⁡Δj2\prod_j\frac{1+\eta\cos\Delta_j}2.

Pythonrunnable
import numpy as np

I2 = np.eye(2, dtype=complex)
H = np.array([[1, 1], [1, -1]], dtype=complex) / np.sqrt(2)
CNOT = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]], dtype=complex)

def rx(t):
    c, s = np.cos(t / 2), np.sin(t / 2)
    return np.array([[c, -1j * s], [-1j * s, c]])

def rz(t):
    return np.diag([np.exp(-0.5j * t), np.exp(0.5j * t)])

def on(gate, q):
    # a one-qubit gate on qubit q of two (qubit 0 is the left Kronecker factor)
    return np.kron(gate, I2) if q == 0 else np.kron(I2, gate)

def run(gates):
    # time-ordered gate list G_1, ..., G_L  ->  U = G_L ... G_1
    U = np.eye(4, dtype=complex)
    for G in gates:
        U = G @ U
    return U

def adjoint(gates):
    # reverse the order and replace every gate by its conjugate transpose
    return [G.conj().T for G in reversed(gates)]

def rx_map(x):
    return [on(rx(x[0]), 0), on(rx(x[1]), 1)]

def zz_map(x):
    phi = (np.pi - x[0]) * (np.pi - x[1])
    return [on(H, 0), on(H, 1), on(rz(2 * x[0]), 0), on(rz(2 * x[1]), 1), CNOT, on(rz(2 * phi), 1), CNOT]

zero = np.array([1, 0, 0, 0], dtype=complex)
x, xp = np.array([0.3, 1.2]), np.array([1.0, 0.4])

# (1) The lab circuit V = U(x')^dagger U(x) and its four outcome probabilities.
V = run(rx_map(x) + adjoint(rx_map(xp)))
p = np.abs(V @ zero) ** 2
c2, s2 = np.cos((x - xp) / 2) ** 2, np.sin((x - xp) / 2) ** 2
closed = np.array([c2[0] * c2[1], c2[0] * s2[1], s2[0] * c2[1], s2[0] * s2[1]])
print("P(00), P(01), P(10), P(11):", " ".join(f"{v:.10f}" for v in p))
print("product of cos^2 / sin^2:  ", " ".join(f"{v:.10f}" for v in closed))
print("V == R_X(-0.7) (x) R_X(0.8):", bool(np.allclose(V, np.kron(rx(-0.7), rx(0.8)), atol=1e-12)))

# (2) The two wrong circuits of the lab diagnostics.
no_dagger = run(rx_map(x) + rx_map(xp))
crossed = run(rx_map(x) + adjoint(rx_map(xp[::-1])))
print(f"forgot the dagger: P(00) = {abs(no_dagger[0, 0]) ** 2:.10f}   crossed features: P(00) = {abs(crossed[0, 0]) ** 2:.10f}")

# (3) ZZ feature map (reps 1): inversion test, overlap, and the diagonal middle block.
ux, uxp = run(zz_map(x)), run(zz_map(xp))
Vzz = run(zz_map(x) + adjoint(zz_map(xp)))
overlap = abs(np.vdot(uxp @ zero, ux @ zero)) ** 2
dphi = (np.pi - x[0]) * (np.pi - x[1]) - (np.pi - xp[0]) * (np.pi - xp[1])
z = np.array([1, -1])
theta = (x[0] - xp[0]) * z[:, None] + (x[1] - xp[1]) * z[None, :] + dphi * np.outer(z, z)
diag_form = abs(np.exp(-1j * theta).mean()) ** 2
print(f"ZZ: P(00) = {abs(Vzz[0, 0]) ** 2:.10f}   |<phi(x')|phi(x)>|^2 = {overlap:.10f}   |mean exp(-i theta)|^2 = {diag_form:.10f}")
print("ZZ: V^dagger V == I:", bool(np.allclose(Vzz.conj().T @ Vzz, np.eye(4), atol=1e-12)), "  U(x')^dagger from the reversed list:", bool(np.allclose(run(adjoint(zz_map(xp))), uxp.conj().T, atol=1e-12)))

# (4) SWAP test on 5 qubits for the R_X states: P(ancilla = 0) = (1 + K) / 2.
a, b = run(rx_map(x)) @ zero, run(rx_map(xp)) @ zero
psi = np.kron(np.array([1, 0], dtype=complex), np.kron(a, b)).reshape(2, 4, 4)
psi = np.tensordot(H, psi, axes=(1, 0))
psi[1] = psi[1].T.copy()
psi = np.tensordot(H, psi, axes=(1, 0))
p0 = float(np.sum(np.abs(psi[0]) ** 2))
print(f"SWAP test: P(0) = {p0:.10f}   2 P(0) - 1 = {2 * p0 - 1:.10f}")

# (5) Single-shot variances K(1 - K) and 1 - K^2, and the shot ratio (1 + K) / K.
for K in [0.9, p[0], 0.5, 0.25, 0.1, 2.0 ** -10]:
    print(f"K = {K:.6f}   inversion {K * (1 - K):.6f}   SWAP {1 - K * K:.6f}   ratio {(1 + K) / K:9.4f}")

# (6) Local depolarizing noise (p = 0.01) after every gate of the lab circuit, density-matrix simulation.
X = np.array([[0, 1], [1, 0]], dtype=complex)
Y = np.array([[0, -1j], [1j, 0]])
Zm = np.diag([1.0 + 0j, -1.0])
def depolarize(rho, q, pr):
    kraus = [np.sqrt(1 - pr) * I2, np.sqrt(pr / 3) * X, np.sqrt(pr / 3) * Y, np.sqrt(pr / 3) * Zm]
    return sum(on(k, q) @ rho @ on(k, q).conj().T for k in kraus)
def noisy_p00(gates_with_qubits, pr):
    rho = np.outer(zero, zero.conj())
    for G, q in gates_with_qubits:
        rho = depolarize(G @ rho @ G.conj().T, q, pr)
    return rho[0, 0].real
lab = [(on(rx(0.3), 0), 0), (on(rx(1.2), 1), 1), (on(rx(-1.0), 0), 0), (on(rx(-0.4), 1), 1)]
diagonal = [(on(rx(0.3), 0), 0), (on(rx(1.2), 1), 1), (on(rx(-0.3), 0), 0), (on(rx(-1.2), 1), 1)]
eta = (1 - 4 * 0.01 / 3) ** 2
print(f"noisy P(00) = {noisy_p00(lab, 0.01):.10f}   prod (1 + eta cos d) / 2 = {np.prod((1 + eta * np.cos(x - xp)) / 2):.10f}   noiseless K = {p[0]:.10f}")
print(f"noisy K(x, x) = {noisy_p00(diagonal, 0.01):.10f}   ((1 + eta) / 2)^2 = {((1 + eta) / 2) ** 2:.10f}")

Expected output

P(00), P(01), P(10), P(11): 0.7486048950 0.1338161986 0.0997484596 0.0178304467
product of cos^2 / sin^2:   0.7486048950 0.1338161986 0.0997484596 0.0178304467
V == R_X(-0.7) (x) R_X(0.8): True
forgot the dagger: P(00) = 0.3076221171   crossed features: P(00) = 0.9875602676
ZZ: P(00) = 0.2754859933   |<phi(x')|phi(x)>|^2 = 0.2754859933   |mean exp(-i theta)|^2 = 0.2754859933
ZZ: V^dagger V == I: True   U(x')^dagger from the reversed list: True
SWAP test: P(0) = 0.8743024475   2 P(0) - 1 = 0.7486048950
K = 0.900000   inversion 0.090000   SWAP 0.190000   ratio    2.1111
K = 0.748605   inversion 0.188196   SWAP 0.439591   ratio    2.3358
K = 0.500000   inversion 0.250000   SWAP 0.750000   ratio    3.0000
K = 0.250000   inversion 0.187500   SWAP 0.937500   ratio    5.0000
K = 0.100000   inversion 0.090000   SWAP 0.990000   ratio   11.0000
K = 0.000977   inversion 0.000976   SWAP 0.999999   ratio 1025.0000
noisy P(00) = 0.7319620910   prod (1 + eta cos d) / 2 = 0.7319620910   noiseless K = 0.7486048950
noisy K(x, x) = 0.9736865264   ((1 + eta) / 2)^2 = 0.9736865264

References

  1. V. Havlíček, A. D. Córcoles, K. Temme, A. W. Harrow, A. Kandala, J. M. Chow and J. M. Gambetta, Supervised learning with quantum-enhanced feature spaces, Nature 567, 209–212 (2019).doi:10.1038/s41586-019-0980-2
  2. H. Buhrman, R. Cleve, J. Watrous and R. de Wolf, Quantum fingerprinting, Physical Review Letters 87, 167902 (2001).doi:10.1103/PhysRevLett.87.167902
  3. M. A. Nielsen and I. L. Chuang, Quantum Computation and Quantum Information, 10th anniversary edition, Cambridge University Press (2010), Section 4.3 and Figure 4.9.doi:10.1017/CBO9780511976667
  4. V. V. Shende and I. L. Markov, On the CNOT-cost of TOFFOLI gates, Quantum Information and Computation 9, 461–486 (2009).arxiv.org
  5. S. Thanasilp, S. Wang, M. Cerezo and Z. Holmes, Exponential concentration in quantum kernel methods, Nature Communications 15, 5200 (2024).doi:10.1038/s41467-024-49287-w
  6. T. Hubregtsen, D. Wierichs, E. Gil-Fuster, P.-J. H. S. Derks, P. K. Faehrmann and J. J. Meyer, Training quantum embedding kernels on near-term quantum computers, Physical Review A 106, 042431 (2022).doi:10.1103/PhysRevA.106.042431
  7. V. Heyraud, Z. Li, Z. Denis, A. Le Boité and C. Ciuti, Noisy quantum kernel machines, Physical Review A 106, 052421 (2022).doi:10.1103/PhysRevA.106.052421
  8. S. Wang, E. Fontana, M. Cerezo, K. Sharma, A. Sone, L. Cincio and P. J. Coles, Noise-induced barren plateaus in variational quantum algorithms, Nature Communications 12, 6961 (2021).doi:10.1038/s41467-021-27045-6

Hands-on labs

  • Build the inversion test of an angle-encoding kernel

    1 step · auto-graded

    Build the compute–uncompute circuit U(x′)†U(x)U(x')^\dagger U(x) of the two-qubit RXR_X product encoding for x=(0.3,1.2)x=(0.3,1.2) and x′=(1.0,0.4)x'=(1.0,0.4) with RXR_X gates only, and read the kernel value K(x,x′)=cos⁡2(0.35)cos⁡2(0.4)≈0.7486K(x,x')=\cos^2(0.35)\cos^2(0.4)\approx0.7486 off the probability of the outcome 0000.

    Open lab