Quickstart (Rust)

This walkthrough takes you from an empty project to a simulated quantum circuit with measurement statistics.

1. Create a project

cargo new hello-quantum
cd hello-quantum
cargo add simq

2. Build and simulate a circuit

The fluent QuantumCircuit builder is the fastest way to get going. Replace src/main.rs with:

use simq::QuantumCircuit;

fn main() {
    // Create a 3-qubit GHZ circuit
    let mut qc = QuantumCircuit::new(3);
    qc.h(0)          // Hadamard on qubit 0
        .cnot(0, 1)  // CNOT: control=0, target=1
        .cnot(1, 2); // CNOT: control=1, target=2

    // Simulate with 1024 measurement shots
    let result = qc.simulate_with_shots(1024).unwrap();
    let counts = result.measurements.unwrap();
    println!("Results: {:?}", counts.sorted());
    // e.g. [("000", 517), ("111", 507)]
}

Run it:

cargo run

Only 000 and 111 appear — the three qubits are entangled in a GHZ state.

Error handling without panics

Gate methods chain fluently and never panic: the first invalid operation (for example, an out-of-range qubit index) is recorded and returned as an error from build() or simulate():

use simq::QuantumCircuit;

let mut qc = QuantumCircuit::new(2);
qc.h(0).cnot(0, 5); // qubit 5 doesn't exist
assert!(qc.build().is_err());

The standard gate set

All common gates are available as chainable methods:

Category

Methods

Single-qubit

h, x, y, z, id, s, sdg, t, tdg, sx, sxdg

Rotations

rx(θ, q), ry(θ, q), rz(θ, q), p(θ, q), u1, u2, u3

Two-qubit

cnot/cx, cy, cz, cp, swap, iswap, ecr, rxx, ryy, rzz

Three-qubit

toffoli/ccx, cswap

Escape hatch

gate(Arc<dyn Gate>, &[qubits]) for custom gates

3. Exact quantities, not just shots

You don’t need sampling to inspect a state — probabilities and expectation values are exact:

use simq::{PauliObservable, PauliString, QuantumCircuit};

let mut qc = QuantumCircuit::new(1);
qc.ry(0.8, 0);

// Exact basis-state probabilities
let probs = qc.probabilities().unwrap();

// Exact ⟨Z⟩ expectation value: cos(0.8)
let z = PauliObservable::from_pauli_string(
    PauliString::from_str("Z").unwrap(), 1.0);
let energy = qc.expectation_value(&z).unwrap();
assert!((energy - 0.8f64.cos()).abs() < 1e-10);

Where to next?