u3 from two pulses
Part G, lesson G3. You need lessons G1 and G2.
Every one-qubit gate of a circuit (h, s, t, x, a rotation) is a u3, and the compiler replaces every u3 by two native instructions: one physical pulse and one frame update. This lesson proves that replacement right on the π/4 grid, and checks it against the pulses the compiler really wrote for a Hadamard.
*Lessons G1 and G2 are restated, unseen, above this line: the numbers, cis n = e^(inπ/4) and cosE, sinE on the grid (an angle is a whole number of eighths of a turn), matrices with *, • and dagger, the Paulis PX, PY, PZ, and the pulses R θ φ, VZ λ and RZ λ. R is written by its explicit entries, QCCDC.Pulse.Native's R_eq, which lesson G2 checked against the definition for every beam angle the compiler's Clifford+T output uses.*
1. The general one-qubit gate
OpenQASM writes a one-qubit gate as u3(θ, φ, λ). QCCDC.Pulse.Native:
noncomputable def u3 (θ φ lam : ℝ) : Matrix (Fin 2) (Fin 2) ℂ :=
!![(Real.cos (θ / 2) : ℂ),
-Complex.exp ((lam : ℂ) * Complex.I) * (Real.sin (θ / 2) : ℂ);
Complex.exp ((φ : ℂ) * Complex.I) * (Real.sin (θ / 2) : ℂ),
Complex.exp (((φ : ℂ) + (lam : ℂ)) * Complex.I) * (Real.cos (θ / 2) : ℂ)]
Ours, entry for entry; θ enters halved again, so it is an even number of eighths.
The compiler keeps a table, u3_of_gate, beside its lowering, that gives every gate it supports as a u3. Its Clifford+T rows:
| "id", _ -> Some (0.0, 0.0, 0.0)
| "x", _ -> Some (pi, 0.0, pi)
| "y", _ -> Some (pi, pi /. 2.0, pi /. 2.0)
| "z", _ -> Some (0.0, 0.0, pi)
| "h", _ -> Some (pi /. 2.0, 0.0, pi)
| "s", _ -> Some (0.0, 0.0, pi /. 2.0)
| "sdg", _ -> Some (0.0, 0.0, -.pi /. 2.0)
| "t", _ -> Some (0.0, 0.0, pi /. 4.0)
| "tdg", _ -> Some (0.0, 0.0, -.pi /. 4.0)
| "sx", _ -> Some (pi /. 2.0, -.pi /. 2.0, pi /. 2.0)
| "sxdg", _ -> Some (pi /. 2.0, pi /. 2.0, -.pi /. 2.0)
The same rows, in eighths of a turn. Every θ is 0, π/2 or π: this is why lesson G2 could keep θ even.
Exercise 1 ★ table_gates open
Prove the table right for six of its gates: its u3 is exactly X, Y, Z, H, S and T.
Not every row is exact. The square root of X, as qiskit defines sx, is ½·[[1+i, 1−i], [1−i, 1+i]]; the table's u3 for sx is that times a phase. Two matrices that differ by a number of size one make the same gate on their own, and lesson G4 is about when that is enough.
Exercise 2 ★ sx_phase open
Prove SX = ω • u3(π/2, −π/2, π/2).
2. One pulse and one frame
The module QCCDC.Pulse.Decompose proves, for all real angles:
theorem u3_decomp (θ φ lam : ℝ) :
u3 θ φ lam = VZ (φ + lam) * R θ (Real.pi / 2 - lam)
"exactly, with no global phase". Its header says why it matters for cost: the general one-qubit gate is one virtual frame update and "exactly one physical pulse — not the three a naive Euler (Z-X-Z) decomposition would emit". The compiler's lowering, decompose_u3, is the theorem's computational content:
let decompose_u3 ~(qubit : int) (theta, phi, lam) : decomposed =
{
pulses =
[
Beam { theta; phi = (pi /. 2.0) -. lam; qubit };
Frame { lam = phi +. lam; qubit };
];
phase = 0.0;
}
The pulses are listed in time order, the beam first; a matrix product applies its rightmost factor first, so the beam is on the right of VZ (φ + λ) * R θ (π/2 − λ). In eighths of a turn, π/2 − λ is 2 - l.
Exercise 3 ★ decomp_table open
Prove u3_decomp for every row of the table. (The whole grid, θ = 0, π/2 or π with all 64 pairs of phases, is 192 identities. They hold too, but take the kernel a few seconds, so this page checks the table's rows here and every phase at θ = π/2 in Exercise 4.)
Exercise 4 ★★★ decomp_quarter_turn open
Prove u3_decomp at θ = π/2 for every φ and λ on the grid: all whole numbers, the method of lessons G1 and G2. Both sides depend on φ and λ only through their remainders a and b mod 8; lhs a b and rhs a b below are the two sides with the table lookups in place. Show each side equals its table form (unfold, then omega for the indices), and finish with a 64-case key.
3. The Hadamard the compiler wrote
The Compilation page compiles h q[0]; on its own, onto chain4. Its certificate, h.qcert.json, has one witness: op 0 at cycle 2 in trap C1 on ion q0, with the pulses the compiler emitted for it, in time order:
"pulses":["R(1.5708,-1.5708)@q0","VZ(3.14159)@q0"]
That is R(π/2, −π/2) then VZ(π): the table's row for h is (π/2, 0, π), so the beam has phase π/2 − π and the frame turns by 0 + π. Here is the certificate as the proved checker reads it (h.qcheck.json), played in the studio. The checker sees the witness, the trap and the ion; it never sees the two pulses. Which gate they make is this lesson's question.
hCert; it appears when Lean has checked the lesson.Exercise 5 ★ h_witness open
Prove the two pulses of the witness make the Hadamard, exactly: the frame after the beam.
The semantic check, check_cert, checks the same two pulses, read from the programme, with a stabilizer tableau (lesson G5). The page's other one-qubit examples (x, z, s and t on the Compilation page) carry these in their certificates:
| gate | pulses | in eighths |
|---|---|---|
x | R(3.14159,-1.5708), VZ(3.14159) | R(4, −2), VZ(4) |
z | R(0,-1.5708), VZ(3.14159) | R(0, −2), VZ(4) |
s | R(0,0), VZ(1.5708) | R(0, 0), VZ(2) |
t | R(0,0.785398), VZ(0.785398) | R(0, 1), VZ(1) |
Reading 3.14159 as π and 0.785398 as π/4 is a step this lesson takes on trust; lesson G7 says exactly what it is.
Exercise 6 ★ witnesses open
Prove all four make their gate exactly.
Exercise 7 ★★ h_pulses_twice open
H·H = 1, so the witness's pulses, played twice, do nothing. Prove it by rewriting with h_witness and computing what is left.
4. A beam that turns by nothing
For z, s and t the table's θ is 0, and the compiler still writes the beam, of angle 0. That beam is the identity whatever its phase, so these three gates are their frame update alone.
Exercise 8 ★★ zero_beam open
Prove R(0, φ) = 1 for every φ. This is not a finite check: φ is any whole number. The cosine and sine of 0 are computations; the two other entries are something times sinE (0 / 2), which is 0, and mul_zero_right from lesson G1 (restated above) does the rest.
5. Euler's three
The "naive Euler (Z-X-Z) decomposition" the cost comment warns about writes a one-qubit gate as a Z rotation, an X rotation and a Z rotation. For the Hadamard it is H = i·Rz(π/2)·Rx(π/2)·Rz(π/2), with QCCDC.Pulse.Native's symmetric RZ, and its Rx θ, which it defines as R θ 0.
Exercise 9 ★ euler_zxz_h open
Prove it. Three rotations and a phase, against u3_decomp's one pulse and one free frame.
6. What this lesson proved
The compiler's one-qubit rule, u3 = VZ(φ+λ)·R(θ, π/2−λ), holds exactly for every Clifford+T row of its table, and for every phase on the grid at θ = π/2; the Hadamard's two pulses in a real certificate make the Hadamard, with no phase left over. The two-qubit rule is not like that: lesson G4 finds the CNOT in five pulses and one Mølmer-Sørensen gate, and a phase that does not go away.