One circuit, three simulation methods¶
Run the same GHZ circuit on a statevector, an MPS and a stabilizer simulator, from 20 to 1,000 qubits.
import time
import maestro
from maestro.circuits import QuantumCircuit
def ghz(num_qubits):
qc = QuantumCircuit()
qc.h(0)
for q in range(num_qubits - 1):
qc.cx(q, q + 1)
qc.measure_all()
return qc
runs = [
(20, maestro.SimulatorConfig(simulation_type=maestro.SimulationType.Statevector)),
(100, maestro.SimulatorConfig(
simulation_type=maestro.SimulationType.MatrixProductState,
max_bond_dimension=4,
)),
(1000, maestro.SimulatorConfig(simulation_type=maestro.SimulationType.Stabilizer)),
]
for num_qubits, config in runs:
start = time.perf_counter()
counts = ghz(num_qubits).execute(shots=1000, config=config)["counts"]
elapsed = time.perf_counter() - start
outcomes = {"all zeros" if set(k) == {"0"} else "all ones": v for k, v in counts.items()}
print(f"{num_qubits:>5} qubits {config.simulation_type.name:<20} {outcomes} {elapsed * 1000:.1f} ms")
20 qubits Statevector {'all zeros': 494, 'all ones': 506} 18.5 ms
100 qubits MatrixProductState {'all ones': 493, 'all zeros': 507} 12.5 ms
1000 qubits Stabilizer {'all ones': 513, 'all zeros': 487} 6.5 ms
A GHZ state puts every qubit into (|00…0⟩ + |11…1⟩)/√2, so sampling it only ever returns all zeros or all ones, in roughly equal numbers. Each method above runs at a size the others can’t reach:
A statevector stores all 2ⁿ amplitudes, so 20 qubits is easy but 100 is out of reach.
An MPS needs only bond dimension 2 for a GHZ state, however many qubits it has.
A stabilizer simulator handles Clifford circuits like this one in polynomial time.
Choosing a simulation method covers how to pick a method for your own circuits.