Exercises: Building Complex Circuits

The ordering hazard in Part B is the one to do even if you skip everything else.

Difficulty: ⭐ warm-up · ⭐⭐ standard · ⭐⭐⭐ deeper. Solutions: worked answers to the daggered (†) and odd-numbered problems are in appendices/answers-to-selected.md; runnable code in code/exercise-solutions.py.


Part A — Warm-ups ⭐

8.1 † What does a Parameter do to a circuit, and what can you still do with the circuit before binding it?

8.2 In what order does qc.parameters return parameters? Why does that matter for assign_parameters([...])?

8.3 † State the difference between compose and append in one sentence each. Which one lets you later control the block?

8.4 Name three things that come free once a subcircuit is converted with .to_gate().

8.5 † Why were the circuit-library classes (EfficientSU2, TwoLocal, QFT) deprecated, and what replaced them?


Part B — Parameters ⭐⭐

8.6 † Build a two-qubit circuit in which one Parameter drives three gates with different coefficients. Print the stored expressions, then bind and print the resulting angles. How many free parameters does the optimizer see?

8.7 † The ordering hazard. Create twelve parameters named theta1theta12, apply them to twelve gates in order, and bind [1, 2, …, 12] by sequence. Report which gate received which value and count how many are wrong. Then repeat with a ParameterVector, and again with dictionary binding. Explain the sort order that causes it.

8.8 † Build a subcircuit and add it to a parent both ways. Compare count_ops, depth, and the drawn diagram, and confirm the unitaries agree. Then stack ten appended blocks and report qc.depth(), qc.decompose().depth(), and the transpiled depth. Which one is the depth?


Part C — The Library and Barriers ⭐⭐

8.9 Build efficient_su2(4), real_amplitudes(4), and n_local(4, "ry", "cz", reps=2). Tabulate parameters, decomposed depth, and gate counts. Why does efficient_su2 have twice the parameters of real_amplitudes?

8.10 † Demonstrate that barriers block optimization on the trivial x; x case. Then build a 4-qubit depth-3 ansatz with a barrier between each layer, strip the barriers with RemoveBarriers, transpile both at optimization level 3, and report ISA depth, two-qubit count, and real pulses for each. What did the barriers cost?

8.11 Tabulate CNOT counts for full, linear, circular, pairwise, and reverse_linear entanglement at $n = 4, 6, 8$, plus the depth at $n = 8$. Which pattern is quadratic? Which has the same count as linear but lower depth, and why?


Part D — Deeper ⭐⭐⭐

8.12 † Build the same 4-qubit depth-2 ansatz with ry rotations and with ry+rz rotations. Transpile both and compare parameters, ISA depth, two-qubit count, and real pulses. Doubling the parameters costs how much in circuit terms? Explain the result using Chapter 3's Case Study 2, and state what the ry-versus-ryrz decision is actually about.

8.13 Measure the logical-to-ISA depth ratio for efficient_su2 at $(n, \text{reps})$ of $(2,1), (4,2), (6,2), (8,3), (10,3)$. Is the ratio stable? What is most of the added depth made of, and does it cost anything?

8.14 † Write ansatz_cost(n, depth, entanglement, backend) returning a dictionary with parameters, logical depth, ISA depth, two-qubit gates, real pulses, and free rz count. Use it to find the largest $n$ for which a depth-3 linear ansatz stays under 200 two-qubit gates. What does that tell you about which molecules Chapter 36 can reach?

8.15 Custom gates carry a global_phase. Construct a subcircuit whose transpilation introduces one, confirm it, then control the gate and show that the phase becomes observable. Write the check you would run before controlling any transpiled subcircuit.

8.16 † The n_local function lets you specify arbitrary rotation and entangling blocks. Build an ansatz using rz rotations and cz entanglers, and one using ry and cx. Transpile both for FakeSherbrooke and compare real pulse counts. Which basis choice is cheaper on this hardware, and why? (Chapter 3 §3.8.)

8.17 Barriers have a legitimate use in benchmarking: forcing a sequence that cancels algebraically to actually execute. Construct a circuit that applies x 2$k$ times, with and without barriers, and show that only the barriered version survives transpilation. Why would a benchmarking experiment want this?


Part E — Project ⭐⭐

8.18 † Implement the Chapter 8 🧱 Project Checkpoint: replace Chapter 4's two-qubit ansatz with hardware_efficient_ansatz(n, depth, entanglement, rotation) using a ParameterVector, plus ansatz_report() and format_report().

8.19 Verify that your ansatz's sequence binding is safe: bind [1, 2, …, k] and confirm every gate received the intended value. Why is this test worth writing even though it will never fail?

8.20 ⭐⭐⭐ Use ansatz_report to choose an ansatz for a hypothetical 8-qubit problem, given a budget of 100 two-qubit gates and a requirement that the ansatz reach entangled states across every bipartition. Report your choice of depth and entanglement pattern, the numbers that justify it, and one thing your report does not tell you that you would want to know before committing. (Hint: Chapter 4's reachable_entanglement, and Chapter 35.)