Circuit
This module provides a representation of quantum circuits and operations for quantum computing simulations. It implements the fundamental building blocks for creating, manipulating, and measuring quantum circuits.
Circuit Module Documentation
Overview
The Circuit module provides the core functionality for building and executing quantum circuits in LogosQ. It allows you to construct quantum circuits by adding gates sequentially, execute them on quantum states, and perform various circuit manipulations.
Core Components
Circuit Structure
pub struct Circuit {
pub operations: Vec<Operation>,
pub num_qubits: usize,
pub name: Option<String>,
pub noise_models: Vec<Rc<dyn NoiseModel>>,
}
Operation Structure
pub struct Operation {
pub gate: Rc<dyn Gate>,
pub qubits: Vec<usize>,
pub name: String,
}
Basic Usage
Creating a Circuit
use logosq::circuits::Circuit;
use logosq::states::State;
// Create a 3-qubit circuit
let mut circuit = Circuit::new(3);
// Create a named circuit
let mut named_circuit = Circuit::new(2).with_name("Bell State Circuit");
Adding Gates
Single-Qubit Gates
// Add Pauli gates
circuit.x(0); // Pauli-X on qubit 0
circuit.y(1); // Pauli-Y on qubit 1
circuit.z(2); // Pauli-Z on qubit 2
// Add Hadamard gate
circuit.h(0); // Hadamard on qubit 0
// Add phase gates
circuit.s(1); // S gate on qubit 1
circuit.t(2); // T gate on qubit 2
// Add rotation gates
circuit.rx(0, std::f64::consts::PI / 4.0); // RX rotation
circuit.ry(1, std::f64::consts::PI / 2.0); // RY rotation
circuit.rz(2, std::f64::consts::PI / 3.0); // RZ rotation
Two-Qubit Gates
// CNOT gate
circuit.cnot(0, 1); // Control: qubit 0, Target: qubit 1
// Controlled-Z gate
circuit.cz(0, 2); // Control: qubit 0, Target: qubit 2
// SWAP gate
circuit.swap(1, 2); // Swap qubits 1 and 2
Three-Qubit Gates
// Toffoli (CCX) gate
circuit.toffoli(0, 1, 2); // Controls: qubits 0,1, Target: qubit 2
Method Chaining
The circuit methods support method chaining for convenient circuit construction:
let mut circuit = Circuit::new(3)
.with_name("Example Circuit");
circuit.h(0)
.cnot(0, 1)
.x(2)
.cz(1, 2)
.ry(0, std::f64::consts::PI / 4.0);
Circuit Execution
Execute on a State
// Create initial state
let mut state = State::zero_state(3);
// Execute circuit
circuit.execute(&mut state);
// The state is now modified according to the circuit operations
Execute and Measure
// Execute circuit and measure all qubits
let measurement_results = circuit.execute_and_measure();
println!("Measurement results: {:?}", measurement_results);
Execute with Noise
// Add noise model to circuit
circuit.add_noise(some_noise_model);
// Execute with noise applied
let noisy_results = circuit.execute_and_measure_with_noise();
Advanced Operations
Circuit Composition
Combine multiple circuits together:
let mut circuit1 = Circuit::new(2);
circuit1.h(0).cnot(0, 1);
let mut circuit2 = Circuit::new(2);
circuit2.x(0).z(1);
// Compose circuits
circuit1.compose(&circuit2);
// circuit1 now contains operations from both circuits
Circuit Reversal
Create a reversed version of a circuit:
let original = Circuit::new(2);
original.h(0).cnot(0, 1).x(1);
let reversed = original.reversed();
// Operations are applied in reverse order
Expectation Values
Calculate expectation values of observables:
use logosq::gates::z_gate;
let observable = z_gate();
let expectation = circuit.expectation(&observable);
println!("Expectation value: {}", expectation);
Custom Gates
Adding Matrix Gates
You can add custom gates by providing their matrix representation:
use ndarray::Array2;
use num_complex::Complex64;
// Define a custom 2x2 matrix
let custom_matrix = Array2::from_shape_vec(
(2, 2),
vec![
Complex64::new(1.0, 0.0), Complex64::new(0.0, 0.0),
Complex64::new(0.0, 0.0), Complex64::new(-1.0, 0.0),
],
).unwrap();
// Add to circuit
circuit.add_matrix_gate(custom_matrix, vec![0], "CustomGate");
Single-Qubit Custom Gates
circuit.add_single_qubit_gate(custom_matrix, 0, "MyGate");
Two-Qubit Custom Gates
// 4x4 matrix for two-qubit gate
let two_qubit_matrix = Array2::zeros((4, 4));
circuit.add_two_qubit_gate(two_qubit_matrix, 0, 1, "CustomTwoQubit");
Common Quantum Circuit Patterns
Bell State Preparation
let mut bell_circuit = Circuit::new(2).with_name("Bell State");
bell_circuit.h(0)
.cnot(0, 1);
let mut state = State::zero_state(2);
bell_circuit.execute(&mut state);
// Now |state⟩ = (|00⟩ + |11⟩)/√2
GHZ State Preparation
let mut ghz_circuit = Circuit::new(3).with_name("GHZ State");
ghz_circuit.h(0)
.cnot(0, 1)
.cnot(0, 2);
let mut state = State::zero_state(3);
ghz_circuit.execute(&mut state);
// Now |state⟩ = (|000⟩ + |111⟩)/√2
Quantum Fourier Transform
use logosq::algorithms::qft;
let qft_circuit = qft::create_circuit(4); // 4-qubit QFT
let mut state = State::plus_state(4);
qft_circuit.execute(&mut state);
Error Handling
The circuit module includes several assertion checks:
// These will panic if conditions aren't met:
circuit.x(5); // Panics if circuit has < 6 qubits
circuit.cnot(0, 0); // Panics: control and target must be different
// Always check qubit indices are valid
assert!(qubit_index < circuit.num_qubits);
Debugging and Visualization
Debug Output
println!("{:?}", circuit);
// Output:
// Circuit: Bell State (2 qubits)
// 0: H(qubits: [0])
// 1: CNOT(qubits: [0, 1])
Circuit Information
println!("Circuit has {} qubits", circuit.num_qubits);
println!("Circuit has {} operations", circuit.operations.len());
if let Some(name) = &circuit.name {
println!("Circuit name: {}", name);
}
Performance Considerations
- Gate Order: The order of operations matters for quantum circuits
- Memory Usage: Large circuits with many qubits consume exponential memory
- Noise Models: Adding noise models increases execution time
- Matrix Operations: Custom matrix gates may be slower than built-in gates
Integration with Other Modules
States Module
use logosq::states::State;
let mut state = State::zero_state(circuit.num_qubits);
circuit.execute(&mut state);
Gates Module
use logosq::gates::{x_gate, h_gate};
// Built-in gates are automatically available through circuit methods
Algorithms Module
use logosq::algorithms::qft;
let algorithm_circuit = qft::create_circuit(4);
circuit.compose(&algorithm_circuit);
Example: Complete Quantum Algorithm
use logosq::prelude::*;
fn quantum_teleportation_circuit() -> Circuit {
let mut circuit = Circuit::new(3).with_name("Quantum Teleportation");
// Prepare Bell pair between qubits 1 and 2
circuit.h(1)
.cnot(1, 2);
// Alice's operations (teleporting qubit 0)
circuit.cnot(0, 1)
.h(0);
// Measurements would go here (not shown in circuit)
// Bob's corrections (conditional on measurements)
// circuit.cnot(1, 2); // If Alice measured 1 on qubit 1
// circuit.z(2); // If Alice measured 1 on qubit 0
circuit
}
fn main() {
let circuit = quantum_teleportation_circuit();
let results = circuit.execute_and_measure();
println!("Teleportation results: {:?}", results);
}
This documentation provides comprehensive coverage of the Circuit module's functionality, from basic usage to advanced features, with practical examples throughout.