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 theta1 … theta12, 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.)