Exercises: PennyLane
All of these run locally — pip install pennylane. Solutions to starred exercises are in
Answers to Selected Exercises.
Warm-up
16.1 ★ Build a QNode returning $\langle Z\rangle$ after RY(theta). Evaluate it at
$\theta = 0, \pi/4, \pi/2, \pi$ and confirm it matches $\cos\theta$.
16.2 Write four QNodes on the same Bell circuit returning qml.probs, qml.state, qml.expval,
and qml.sample respectively. Which require a shot count? Which can be differentiated?
16.3 ★ Differentiate the QNode from 16.1 at five values of $\theta$ and compare each to $-\sin\theta$. Report the maximum error.
16.4 Use qml.draw to print a 3-qubit circuit with StronglyEntanglingLayers. Then use
qml.draw_mpl if you have matplotlib. What does the drawn form tell you about the template's
structure?
The parameter-shift rule
16.5 ★ Implement the parameter-shift rule by hand for a single RY gate and verify it matches
qml.grad to machine precision.
16.6 ★ Reproduce §16.3's finite-difference table for $h$ from $10^{-1}$ to $10^{-9}$. Identify the sweet spot and explain both failure modes.
16.7 ★★ Prove that $f(\theta) = A\cos\theta + B\sin\theta$ for a single Pauli-generated rotation, by fitting $A$ and $B$ from evaluations and reporting the residual. How many evaluation points do you need to determine the fit?
16.8 ★★ Simulate hardware conditions: add shot noise by using qml.device("default.qubit",
wires=1, shots=1000). Compare the parameter-shift gradient to a finite-difference gradient at
$h = 10^{-3}$ under shot noise. Which degrades more, and by how much?
16.9 ★★★ Find a gate in PennyLane whose generator has more than two distinct eigenvalues, so the two-term shift rule does not apply. What does PennyLane do instead? Verify the gradient is still exact.
Gradient cost
16.10 ★ Use qml.Tracker to count circuit executions for one gradient at 1, 2, 4, 8, 16, and 32
parameters. Confirm the $2n+1$ rule.
16.11 ★ Compute the total shot cost for: 20 parameters, 200 iterations, 4096 shots. Then for 100 parameters. How much of your budget does the gradient consume versus the forward passes?
16.12 ★★ Build a circuit where half the parameters act on wires that the observable does not touch. Confirm PennyLane's execution count reflects only the connected parameters, and that the disconnected gradients are exactly zero.
16.13 ★★ Compare diff_method="parameter-shift", "backprop", and "finite-diff" on the same
circuit: gradient accuracy, execution count, and wall-clock time. Which would you use on a simulator?
On hardware? Why is backprop unavailable on hardware?
16.14 ★★★ The parameter-shift cost is $2n+1$ per gradient. Design and test a scheme that estimates the gradient with fewer executions by sampling a random subset of parameters each iteration (stochastic coordinate descent). Does it converge? How does total shot count to convergence compare?
Optimization
16.15 ★ Reproduce §16.5's stall: 4 parameters, GradientDescentOptimizer(0.25), 40 steps. Report
the final energy and whether the trace is still descending.
16.16 ★ Take the same setup and run 400 steps. Report the energy. Then run Adam(0.1) for 400
steps. Which converges faster in iterations? In wall-clock time?
16.17 ★★ Reproduce §16.5's optimizer table including GradientDescent(0.05). Explain why the
smaller step size is worse, with reference to the trace.
16.18 ★★ Write has_converged(trace, tolerance) returning (bool, reason). Test it against a
truncated run, a converged run, and an oscillating run. What tolerance is appropriate, and what does
it depend on?
16.19 ★★ Build the same Hamiltonian and find the exact ground state by diagonalization. Then optimize from 20 random initializations and report the distribution of final energies. How often does the optimizer find a local minimum rather than the global one?
16.20 ★★★ Add shot noise (shots=1000) to the optimization from 16.16. Does it still converge?
What happens to the convergence criterion from 16.18 when the cost function is stochastic?
Barren plateaus
16.21 ★★ Reproduce §16.6's measurement for 2 through 8 qubits. Report the fitted decay per qubit and confirm it is near 0.5.
16.22 ★★ Sample only parameter index 0 (as Case Study 1 did) and reproduce the artifact. Confirm the gradients are near $10^{-17}$ and explain why.
16.23 ★★ Implement the three-way discriminator from §16.7. Test it on: (a) the structurally-zero
first RZ, (b) a parameter acting on an unmeasured wire, (c) a genuine middle-layer parameter at 10
qubits.
16.24 ★★ Compare gradient variance for a global observable ($Z$ on every qubit) against the local one used in §16.6 ($Z_0 Z_1$). Does the locality of the observable change the decay rate? Relate your answer to the literature claim about local cost functions.
16.25 ★★★ Test one proposed mitigation: initialize parameters near zero (small random values) rather than uniformly in $[0, 2\pi]$. Measure the gradient variance at 4, 6, 8, and 10 qubits under both initializations. Does it help? Does it help asymptotically, or only by a constant?
16.26 ★★★ Extrapolate your §16.6 fit to 30, 40, and 50 qubits and compute the shots required to resolve a gradient at each. Then find the largest qubit count at which a 24-hour run at 10,000 shots/second could resolve gradients for a 100-parameter ansatz.
Project
16.27 ★★ (Project Checkpoint) Build vqelab/variational.py with gradient_cost(),
measure_gradient_cost(), classify_zero_gradient(), measure_gradient_variance() (reporting
exclusions), and optimize() returning a VariationalResult with a converged flag. Write tests
asserting:
gradient_cost(16)gives 33 executions per gradient.- Measured execution count equals $2n+1$ for $n = 1, 4, 8$.
- The first
StronglyEntanglingLayersparameter classifies as"structural". - The largest-gradient parameter classifies as
"nonzero". - Gradient variance decreases monotonically with width and drops >20× from 2 to 8 qubits.
- The decay per qubit is between 0.3 and 0.85.
- Structurally-zero parameters are counted and reported, not silently dropped.
- A 400-step Adam run reaches the reference within $10^{-5}$ and reports
converged=True. - A 40-step gradient-descent run reports
converged=Falseandstill_descending=True.
Test 9 is the one that would have prevented Case Study 2's misdiagnosis.
16.28 ★★★ Extend variational.py with suggest_diagnosis(result), which takes a
VariationalResult and returns an ordered list of things to try: "increase iterations," "change
optimizer," "check for structural zeros," "the ansatz may genuinely be too small." Order them by the
cost of testing, cheapest first. Validate it against both of this chapter's case studies.
Going further
16.29 ★★★ Use pennylane-qiskit to run a QNode on FakeSherbrooke. Measure the gradient with and
without Chapter 13's readout mitigation. Does mitigation improve the gradient as much as it improves
the expectation value?
16.30 ★★★ Chapter 13 measured that ZNE improves a readout-mitigated expectation value by 42%. Apply the same reasoning to gradients: since a parameter-shift gradient is a difference of two expectation values, does a systematic bias cancel? Design an experiment and report.