Sweep a parameter
examples/parameter_sweep.py
The problem
Section titled “The problem”Evaluate one circuit at many parameter values, as one job. A variational algorithm evaluates the same circuit at many points, and submitting one job per point queues, schedules and accounts each separately. A PUB carries the whole sweep — one circuit, many rows of parameter values — and the platform runs it as one job with one result.
The walkthrough
Section titled “The walkthrough”The parametric circuit
Section titled “The parametric circuit”# `input float[64] theta;` is the whole binding mechanism. `include "stdgates.inc";` is# required for `ry` to be defined — OpenQASM 3 declares no gates of its own.ROTATION = """OPENQASM 3.0;include "stdgates.inc";input float[64] theta;qubit[1] q;ry(theta) q[0];"""The binding is expressed in the circuit itself. An OpenQASM 3 input declaration names
a value the program leaves free, and the importer turns it into a bound parameter.
Everything about the sweep lives in the circuit text and the parameter rows, which is
why a sweep needs no vendor-specific side channel.
The observable and the angles
Section titled “The observable and the angles”Z = Observable(num_qubits=1, terms=(PauliTerm(pauli="Z", qubits=(0,), coefficient=1.0),))
# One row per run, one value per `input`. A published cap bounds how many rows a PUB may# carry, and a sweep past it is rejected at submit rather than discovered mid-run.ANGLES = [0.0, math.pi / 2, math.pi]Rotating by theta about the Y axis walks the state from |0> to |1>. Read with
Z, that traces a cosine: +1 at 0, 0 at π/2, −1 at π — a curve you can check by eye.
One submit for the whole sweep
Section titled “One submit for the whole sweep” job = client.jobs.submit( backend_id=backend_id, circuit=ROTATION, observables=[Z], parameter_values=[[angle] for angle in ANGLES], shots=SHOTS, name="ry sweep", )parameter_values supplies one row per run, each row holding one value per input in
declaration order. This circuit has one input, so each row is a single-element list.
Read one value per row
Section titled “Read one value per row” # One expectation value per parameter row, in the order the rows were submitted. values = client.jobs.result(job.id).values or () if len(values) != len(ANGLES): print(f"expected {len(ANGLES)} values, got {len(values)}", file=sys.stderr) return 1
print() for angle, value in zip(ANGLES, values, strict=True): bar = round(20 * (value + 1)) print( f" theta={angle:5.3f} <Z>={value:+.4f} (cos={math.cos(angle):+.1f}) {'█' * bar}" ) return 0The result carries one expectation value per parameter row, in submission order, so the loop pairs each angle with its value directly.
Running it
Section titled “Running it”QUBITRA_API_KEY=qpk_... python examples/parameter_sweep.pyOutput from a live run, trimmed to the values:
theta=0.000 <Z>=+1.0000 (cos=+1.0) ████████████████████████████████████████ theta=1.571 <Z>=+0.0000 (cos=+0.0) ████████████████████ theta=3.142 <Z>=-1.0000 (cos=-1.0)The three values trace the cosine — approximately [1.0, 0.0, -1.0] at angles
[0, π/2, π] — and the whole sweep travelled as one PUB in one job.
Where to go next
Section titled “Where to go next”- Primitives and PUBs — sweeps, the row cap, and multi-PUB jobs.
- Sessions — correlating a whole optimisation run of sweep jobs.