Quojo-Rust provides a set of quantum gates for building quantum circuits.
Gates are represented by the Gate
enum in the quojo_rust::qcore::gates
module:
pub enum Gate {
X, // Pauli-X (NOT) gate
Y, // Pauli-Y gate
Z, // Pauli-Z gate
H, // Hadamard gate
P(f64), // Phase rotation gate
CNOT { control: usize, target: usize }, // Controlled-NOT
CZ { control: usize, target: usize }, // Controlled-Z
SWAP { qubit1: usize, qubit2: usize }, // SWAP
Toffoli { control1: usize, control2: usize, target: usize }, // Toffoli (CCX)
Fredkin { control: usize, target1: usize, target2: usize }, // Fredkin (CSWAP)
}
The Pauli X gate flips the state of a qubit, similar to a classical NOT gate.
circuit.Apply(Gate::X, Targets(&[0])); // Apply X to qubit 0
Matrix representation:
X = [0 1]
[1 0]
The Pauli Y gate.
circuit.Apply(Gate::Y, Targets(&[0])); // Apply Y to qubit 0
Matrix representation:
Y = [0 -i]
[i 0]
The Pauli Z gate changes the phase of the |1⟩ state.
circuit.Apply(Gate::Z, Targets(&[0])); // Apply Z to qubit 0
Matrix representation:
Z = [1 0]
[0 -1]
The Hadamard gate creates a superposition of states.
circuit.Apply(Gate::H, Targets(&[0])); // Apply H to qubit 0
Matrix representation:
H = 1/√2 * [1 1]
[1 -1]
The phase gate applies a rotation around the Z-axis.
// Apply π/4 phase rotation to qubit 0 (T gate)
circuit.Apply(Gate::P(std::f64::consts::PI/4.0), Targets(&[0]));
Matrix representation for phase φ:
P(φ) = [1 0]
[0 e^(iφ)]
The Controlled-NOT gate flips the target qubit if the control qubit is |1⟩.
// CNOT with control on qubit 0 and target on qubit 1
circuit.ApplyControlled(Gate::X, 0, 1);
The Controlled-Z gate applies a Z gate to the target if the control is |1⟩.
// CZ with control on qubit 1 and target on qubit 2
circuit.ApplyControlled(Gate::Z, 1, 2);
The SWAP gate exchanges the states of two qubits.
// Swap qubits 2 and 3
circuit.ApplySwap(2, 3);
The Toffoli gate applies an X to the target if both controls are |1⟩.
// Toffoli with control1=0, control2=1, target=2
let toffoli = Gate::Toffoli { control1: 0, control2: 1, target: 2 };
circuit.Apply(toffoli, Targets(&[0, 1, 2]));
The Fredkin gate swaps two target qubits if the control is |1⟩.
// Fredkin with control=0, target1=1, target2=2
let fredkin = Gate::Fredkin { control: 0, target1: 1, target2: 2 };
circuit.Apply(fredkin, Targets(&[0, 1, 2]));
All gates can be decomposed into primitive gates, which is useful for simulation and ZX-calculus.
use quojo_rust::qcore::gates::GateDecomposition;
let gate = Gate::CNOT { control: 0, target: 1 };
let primitives = gate.decompose();
for primitive in primitives {
println!("{:?} on qubits {:?}", primitive.gate, primitive.qubits);
}
The primitive gates used in decompositions are:
PrimitiveGate::X
: Pauli X gatePrimitiveGate::Z
: Pauli Z gatePrimitiveGate::H
: Hadamard gatePrimitiveGate::P(f64)
: Phase gatePrimitiveGate::Connect
: Multi-qubit connection indicator
// Create a Bell state |Φ⁺⟩ = (|00⟩ + |11⟩)/√2
circuit.Apply(Gate::H, Targets(&[0]));
circuit.ApplyControlled(Gate::X, 0, 1);
// 2-qubit QFT
circuit.Apply(Gate::H, Targets(&[0]));
circuit.ApplyControlled(Gate::P(std::f64::consts::PI/2.0), 1, 0);
circuit.Apply(Gate::H, Targets(&[1]));
circuit.ApplySwap(0, 1);