Execution Core¶
MicroQuantum’s execution model turns a QuantumCircuit
into real, sampled measurement results through the native contract:
QuantumCircuit -> Backend.run(circuit, shots, seed) -> ExecutionResult
(state) (state evolution + measurement) (counts/algebra)
The canonical entry point is a backend run with an optional shot count and deterministic seed:
from microquantum import QuantumCircuit, StatevectorBackend
qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
qc.measure_all()
backend = StatevectorBackend()
result = backend.run(qc, shots=1000, seed=42)
print(result.counts) # {'00': 503, '11': 497} (seed=42)
The result is a BackendResult exposing sampled
measurement information (counts, samples), state information
(state / statevector) and execution metadata (shots, seed,
backend_name, target_name, metadata).
Measurement¶
Measurements are recorded explicitly on the circuit as data; they never silently alter the gate sequence or execute anything:
qc = QuantumCircuit(2).h(0).cx(0, 1)
qc.measure(0) # measure qubit 0 only
qc.measure_all() # measure every qubit
measure()marks a single qubit.measure_all()marks all qubits.qc.measurementslists the measured qubits in order; measured classical output follows that same order (left-to-right, big-endian), so the ordering is deterministic and documented.Measurement annotations survive serialization: JSON (
to_json/from_json), OpenQASM 2.0 (qasm/from_qasm), IR andbind_parameters/__add__all preserve them.
When a circuit marks a subset of its qubits for measurement, the backend’s
counts report only those qubits (e.g. measuring qubit 0 of a two-qubit
circuit yields single-bit keys like '0' / '1'). When nothing is
measured, the backend samples the full register for backward compatibility.
Shots¶
shots is the number of times the output distribution is sampled. The
backend evolves the state once and samples shots outcomes by Born’s rule;
the totals always add up exactly to the requested shots:
result = backend.run(qc, shots=1000, seed=42)
assert sum(result.counts.values()) == 1000
shotsmust be an integer>= 1; invalid values raiseValueError.Each shot is an independent random outcome; the raw per-shot outcome indices are available as
result.samples(big-endian).
Counts¶
result.counts is a dict mapping bitstrings to shot counts. Bitstrings
are big-endian: the leftmost character corresponds to the first measured
qubit. result.get_counts() is an equivalent method accessor.
result.probabilities normalizes the counts, and
result.most_frequent() returns the top bitstring.
Seeds and reproducibility¶
Supplying the same seed reproduces the same sampled counts on the same
backend:
r1 = backend.run(qc, shots=1000, seed=42)
r2 = backend.run(qc, shots=1000, seed=42)
assert r1.counts == r2.counts
Reproducibility is guaranteed only for the same backend and execution configuration; different backends are not guaranteed bit-for-bit matches.
Backends¶
Simulation backends implement the execution model today:
StatevectorBackend— exact state-vector simulation with shot sampling.LocalSimulatorBackend— the reference local simulator.DensityMatrixBackend— density-matrix simulation (including noise).MPSBackend/TreeTensorNetworkBackend— tensor-network simulators.
Backends that cannot perform the requested operation report a clear
capability limitation through validate() /
supports() rather than returning fabricated
results. See Backends for the full backend contract.
Execution does not imply hardware: only simulator backends are available, and no claim of real-device execution is made anywhere.