\(\psi\): a quantum computational toolkit
\(\psi\) is a powerful quantum computing toolkit designed for simulating quantum circuits and wavefunction dynamics on classical hardware.
features
quantum gates
clifford gates: - single-qubit: h, x, y, z, s - two-qubit: cnot, cz, swap - three-qubit: ccnot (toffoli), cswap (fredkin)
non-clifford gates: - fixed: t, \(S^\dagger\), \(T^\dagger\), \(\sqrt{X}\), \(\sqrt{X}^\dagger\) - parametric rotations: \(R_x(\theta)\), \(R_y(\theta)\), \(R_z(\theta)\), \(P(\theta)\) - general unitaries: \(U_1(\lambda)\), \(U_2(\phi, \lambda)\), \(U_3(\theta, \phi, \lambda)\) - controlled parametric: \(CR_x(\theta)\), \(CR_y(\theta)\), \(CR_z(\theta)\), \(CP(\theta)\)
custom gates: - define gates from unitary matrices - build composite gates from sequences of operations
composable runtime system
build custom execution pipelines by combining optimisation features:
| feature | description |
|---|---|
.batched() |
kernel batching with gate fusion |
.simd() |
simd acceleration (avx-512/avx2/neon) |
.structure_aware() |
commutation analysis and advanced fusion |
.parallel() |
multi-threaded execution |
.with_threshold(n) |
set parallel threshold (default: 8 qubits) |
predefined runtimes:
- Runtime::BasicRT / BasicRTMT — direct state vector simulation
- Runtime::BatchedRT / BatchedRTMT — batched kernel execution
- Runtime::SimdRT / SimdRTMT — batched + simd
- Runtime::StructureAwareRT / StructureAwareMT — structure-aware + simd
- Runtime::optimal() — structure-aware + simd + parallel
simd acceleration
automatic detection and use of platform-specific simd instructions:
- avx-512: modern intel/amd processors
- avx2+fma: older x86_64 processors
- neon: arm processors (apple silicon, etc.)
- scalar fallback: universal compatibility
kernel optimisations
batching: - groups consecutive single-qubit gates on the same qubit - fuses gate matrices to reduce operations - typically achieves 30–50% kernel reduction
structure-aware: - gate type detection (diagonal, non-diagonal, controlled) - commutation analysis for reordering - multi-pass fusion until convergence - execution layer grouping for parallelism
noise channels (density matrix)
realistic quantum noise simulation using kraus operators:
| channel | description |
|---|---|
depolarising(p) |
random pauli error with probability \(p\) |
amplitude_damping(γ) |
energy decay (\(T_1\) relaxation) |
phase_damping(γ) |
phase decoherence (\(T_2\) dephasing) |
bit_flip(p) |
\(X\) error with probability \(p\) |
phase_flip(p) |
\(Z\) error with probability \(p\) |
bit_phase_flip(p) |
\(Y\) error with probability \(p\) |
use psi::{DensityMatrix, NoiseChannel};
// Create density matrix from circuit state
let dm = DensityMatrix::from_state_vector(&state_vec);
// Apply noise
let noise = NoiseChannel::depolarising(0.05);
dm.apply_noise_channel(&noise, 0); // Apply to qubit 0
// Check properties
println!("Purity: {}", dm.purity()); // 1.0 = pure, <1.0 = mixed
println!("Fidelity: {}", dm.fidelity_with_pure_state(&ideal_state));
project structure
psi is a single crate. the library lives under src/:
core: quantum gates, circuits, registers, and runtimesmaths: complex numbers, vectors, matrices, simd operationsvisualizer: circuit visualisation (ascii horizontal/vertical)
the comprehensive test suite and benchmarks live in examples/tester.
quick start
use psi::{QuantumCircuit, Runtime};
fn main() {
let mut circuit = QuantumCircuit::new(3);
// Build a GHZ state
circuit.h(0).cnot(0, 1).cnot(0, 2);
// Execute with optimal settings
circuit.compute_with_config(Runtime::optimal());
println!("{}", circuit.state());
}
composable runtimes
use psi::{QuantumCircuit, RuntimeConfig};
let mut circuit = QuantumCircuit::new(8);
// ... add gates ...
// Combine features as needed
let config = RuntimeConfig::new()
.structure_aware()
.simd()
.parallel();
circuit.compute_with_config(config);
parametric gates
use std::f64::consts::PI;
circuit
.rx(0, PI / 4.0) // Rotation around X
.ry(0, PI / 3.0) // Rotation around Y
.rz(1, PI / 2.0) // Rotation around Z
.crz(0, 1, PI / 4.0); // Controlled-Rz
custom gates
use psi::{CustomGateBuilder, CustomGate, complex, matrix};
// From operations
let bell_gate = CustomGateBuilder::new("BELL", 2)
.h(0)
.cnot(0, 1)
.build();
// From a unitary matrix
let sqrt_x_matrix = matrix!(
[complex!(0.5, 0.5), complex!(0.5, -0.5)];
[complex!(0.5, -0.5), complex!(0.5, 0.5)]
);
let sqrt_x = CustomGate::from_matrix("√X", sqrt_x_matrix);
running tests
cargo run --release --example tester # All tests
cargo run --release --example tester -- clifford
cargo run --release --example tester -- non-clifford
cargo run --release --example tester -- kernels
cargo run --release --example tester -- simd
cargo run --release --example tester -- bench
cargo run --release --example tester -- help
disclaimer
this project is under active development. features and apis may change.
license
this project is made available under the apache license, version 2.0, allowing free use, modification, and distribution with proper attribution. community contributions, improvements, and research collaborations are encouraged. full licensing terms can be found in license.
