Simulation¶
vqubit ships three local simulators. They all run offline, with no dependencies.
State vector¶
Simulator evolves the state vector and is the one you will reach for on any
noise-free circuit.
import vqubit as vq
q0, q1 = vq.LineQubit.range(2)
circuit = vq.Circuit(vq.H(q0), vq.CNOT(q0, q1))
# Get the final state
result = vq.Simulator().simulate(circuit)
print(result.dirac_notation()) # 0.707|00⟩ + 0.707|11⟩
# Sample measurements
result = vq.Simulator(seed=0).run(
vq.Circuit(vq.H(q0), vq.CNOT(q0, q1), vq.measure(q0, q1, key="m")),
repetitions=1000,
)
print(result.histogram(key="m")) # Counter({0: ..., 3: ...})
simulate returns a SimulationResult with final_state and state_vector();
run returns a Result with measurements and histogram.
Density matrix¶
DensityMatrixSimulator evolves a density matrix, so it can simulate noisy
circuits.
import vqubit as vq
q0, q1 = vq.LineQubit.range(2)
circuit = vq.Circuit(vq.H(q0), vq.depolarize(0.1)(q0), vq.CNOT(q0, q1))
result = vq.DensityMatrixSimulator().simulate(circuit)
rho = result.density_matrix()
print(rho[0][3]) # the coherence, reduced by the noise
Clifford (stabilizers)¶
For Clifford circuits (H, S, CNOT, CZ, SWAP and Paulis), CliffordSimulator
tracks a stabilizer tableau instead of the state vector, so it scales far
better.
import vqubit as vq
q0, q1, q2 = vq.LineQubit.range(3)
circuit = vq.Circuit(vq.H(q0), vq.CNOT(q0, q1), vq.CNOT(q1, q2))
state = vq.CliffordSimulator().simulate(circuit).final_state
print([str(s) for s in state.stabilizers()])
# ['X(0)*X(1)*X(2)', 'Z(0)*Z(1)', 'Z(1)*Z(2)']
Next steps¶
- Add noise to your circuits.
- Optimize your circuits in the optimization chapter.