Appendix A: Qiskit Quick Reference

Targets Qiskit 2.5.x. Where an API changed, the change is noted — Chapter 31 opened with qiskit.pulse being removed in 2.0, and that will not be the last removal.


Building circuits

from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister

qc = QuantumCircuit(3)                      # 3 qubits, no classical bits
qc = QuantumCircuit(3, 3)                   # 3 qubits, 3 classical bits
qr, cr = QuantumRegister(2, "q"), ClassicalRegister(2, "c")
qc = QuantumCircuit(qr, cr)                 # named registers

qc.h(0)                                     # Hadamard
qc.cx(0, 1)                                 # CNOT: control 0, target 1
qc.rz(theta, 0)                             # parameterized rotation
qc.measure([0, 1], [0, 1])
qc.measure_all()                            # adds its own classical register
qc.barrier()                                # transpiler directive, not physical
Task Call
Depth / size qc.depth(), qc.size()
Gate counts qc.count_ops()
Inverse qc.inverse()
Repeat qc.repeat(n)
Compose qc.compose(other, qubits=[0,1])
To gate qc.to_gate() / qc.to_instruction()
Draw qc.draw("mpl") or print(qc)

Parameters

from qiskit.circuit import Parameter, ParameterVector

theta = Parameter("θ")
params = ParameterVector("p", 8)
qc.ry(theta, 0)
bound = qc.assign_parameters({theta: 0.5})       # returns a NEW circuit

⚠️ assign_parameters returns a new circuit unless inplace=True. Chapter 8 measured how often that is missed.

Simulation

from qiskit_aer import AerSimulator
from qiskit.quantum_info import Statevector, Operator, DensityMatrix

sim = AerSimulator()
result = sim.run(transpiled, shots=4096).result()
counts = result.get_counts()

Statevector.from_instruction(qc)          # exact state, no measurements
Operator.from_circuit(transpiled)         # applies layout AND routing (Ch. 26)
DensityMatrix.from_instruction(qc)        # mixed states

Simulation methods: AerSimulator(method="statevector" | "density_matrix" | "matrix_product_state" | "stabilizer" | "extended_stabilizer").

Transpilation

from qiskit import transpile
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager

tqc = transpile(qc, backend, optimization_level=3, seed_transpiler=42)

pm = generate_preset_pass_manager(optimization_level=2, backend=backend)
tqc = pm.run(qc)
Level Intent
0 No optimization — use this when you need id gates preserved (Ch. 25)
1 Light; the default
2 Medium
3 Heavy; differs from level 2 in 14 of 40 circuit-seed pairs (Ch. 28)
tqc.layout.final_index_layout()     # virtual -> physical mapping

Primitives

from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2, EstimatorV2
from qiskit_ibm_runtime import Batch, Session

service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)

sampler = SamplerV2(mode=backend)
job = sampler.run([(tqc,)], shots=4096)
counts = job.result()[0].data.meas.get_counts()

estimator = EstimatorV2(mode=backend)
job = estimator.run([(tqc, observable)])
value = job.result()[0].data.evs

Execution modes — the single biggest lever on wall clock (Ch. 39):

with Batch(backend=backend):    ...    # many circuits, ONE queue wait
with Session(backend=backend):  ...    # dependent jobs, e.g. a variational loop

Observables

from qiskit.quantum_info import SparsePauliOp

H = SparsePauliOp.from_list([("ZZ", 1.0), ("XI", 0.5)])
H = H.apply_layout(tqc.layout)      # REQUIRED before an Estimator on a transpiled circuit

⚠️ Forgetting apply_layout silently measures the wrong physical qubits.

Backends and calibration

target = backend.target
target.dt                                        # time resolution
target["cz"][(0, 1)].error                       # two-qubit error on a link
target["cz"][(0, 1)].duration                    # seconds
target.qubit_properties[0].t1                    # seconds
backend.coupling_map.neighbors(3)                # DIRECTED — see Ch. 29

Noise models

from qiskit_aer.noise import NoiseModel, depolarizing_error, thermal_relaxation_error

nm = NoiseModel.from_backend(backend)
sim = AerSimulator(noise_model=nm)

Error mitigation

estimator.options.resilience_level = 1      # readout mitigation
estimator.options.twirling.enable_gates = True

Levels differ by version. Check the default before quoting a mitigated result — it is not "none."

Version notes

Change Version
qiskit.pulse removed, with add_calibration, .calibrations, backend.defaults, instruction_schedule_map, drive_channel 2.0
QuantumCircuit.duration deprecated — use ALAPScheduleAnalysis 1.3
QFT class deprecated — use synth_qft_full / QFTGate 2.1
EfficientSU2 class deprecated — use efficient_su2() 2.1
BackendV1 removed; backend.target is the interface 1.x–2.0

See also: Appendix B (gates), Appendix E (framework translation), Appendix G (hardware).