classical_control_demo/
classical_control_demo.rs

1//! Example demonstrating classical control flow in quantum circuits
2
3use quantrs2_circuit::prelude::*;
4use quantrs2_core::gate::single::{Hadamard, PauliX, PauliZ};
5use quantrs2_core::qubit::QubitId;
6
7fn main() -> Result<(), Box<dyn std::error::Error>> {
8    println!("Classical Control Flow Demo");
9    println!("===========================\n");
10
11    // Example 1: Simple measurement and conditional operation
12    simple_conditional()?;
13
14    // Example 2: Quantum teleportation with classical communication
15    quantum_teleportation()?;
16
17    // Example 3: Adaptive phase estimation
18    adaptive_phase_estimation()?;
19
20    Ok(())
21}
22
23/// Simple conditional operation based on measurement
24fn simple_conditional() -> Result<(), Box<dyn std::error::Error>> {
25    println!("Example 1: Simple Conditional Operation");
26    println!("--------------------------------------");
27
28    // Create a circuit with classical control
29    let circuit = ClassicalCircuitBuilder::<2>::new()
30        .classical_register("c", 2)?
31        .gate(Hadamard { target: QubitId(0) })?
32        .measure(QubitId(0), "c", 0)?
33        .conditional(
34            ClassicalCondition::register_equals("c", 1),
35            PauliX { target: QubitId(1) },
36        )?
37        .build();
38
39    println!(
40        "Created circuit with {} operations",
41        circuit.num_operations()
42    );
43    println!("Circuit applies X to qubit 1 if qubit 0 measures to |1⟩\n");
44
45    Ok(())
46}
47
48/// Quantum teleportation with classical communication
49fn quantum_teleportation() -> Result<(), Box<dyn std::error::Error>> {
50    println!("Example 2: Quantum Teleportation");
51    println!("--------------------------------");
52
53    // Create Bell pair between qubits 1 and 2
54    let mut circuit = Circuit::<3>::new();
55    circuit.h(1)?;
56    circuit.cnot(1, 2)?;
57
58    // Convert to classical circuit for measurements
59    let mut classical_circuit = circuit.with_classical_control();
60    classical_circuit.add_classical_register("alice", 2)?;
61
62    // Alice's operations
63    classical_circuit.add_gate(quantrs2_core::gate::multi::CNOT {
64        control: QubitId(0),
65        target: QubitId(1),
66    })?;
67    classical_circuit.add_gate(Hadamard { target: QubitId(0) })?;
68
69    // Alice measures her qubits
70    classical_circuit.measure(QubitId(0), "alice", 0)?;
71    classical_circuit.measure(QubitId(1), "alice", 1)?;
72
73    // Bob applies corrections based on Alice's measurements
74    classical_circuit.add_conditional(
75        ClassicalCondition {
76            lhs: ClassicalValue::Register("alice".to_string()),
77            op: ComparisonOp::Equal,
78            rhs: ClassicalValue::Integer(0b01),
79        },
80        PauliX { target: QubitId(2) },
81    )?;
82
83    classical_circuit.add_conditional(
84        ClassicalCondition {
85            lhs: ClassicalValue::Register("alice".to_string()),
86            op: ComparisonOp::Equal,
87            rhs: ClassicalValue::Integer(0b10),
88        },
89        PauliZ { target: QubitId(2) },
90    )?;
91
92    classical_circuit.add_conditional(
93        ClassicalCondition {
94            lhs: ClassicalValue::Register("alice".to_string()),
95            op: ComparisonOp::Equal,
96            rhs: ClassicalValue::Integer(0b11),
97        },
98        PauliX { target: QubitId(2) }, // In reality, this would be X then Z
99    )?;
100
101    println!(
102        "Created teleportation circuit with {} operations",
103        classical_circuit.num_operations()
104    );
105    println!("Bob's qubit 2 receives the state that was on Alice's qubit 0\n");
106
107    Ok(())
108}
109
110/// Adaptive phase estimation using conditional rotations
111fn adaptive_phase_estimation() -> Result<(), Box<dyn std::error::Error>> {
112    println!("Example 3: Adaptive Phase Estimation");
113    println!("-----------------------------------");
114
115    let circuit = ClassicalCircuitBuilder::<4>::new()
116        .classical_register("phase_bits", 3)?
117        // First estimation round
118        .gate(Hadamard { target: QubitId(0) })?
119        .gate(quantrs2_core::gate::multi::CRZ {
120            control: QubitId(0),
121            target: QubitId(3),
122            theta: std::f64::consts::PI,
123        })?
124        .gate(Hadamard { target: QubitId(0) })?
125        .measure(QubitId(0), "phase_bits", 0)?
126        // Second round (adaptive based on first measurement)
127        .gate(Hadamard { target: QubitId(1) })?
128        .conditional(
129            ClassicalCondition::register_equals("phase_bits", 1),
130            quantrs2_core::gate::single::Phase { target: QubitId(1) }
131        )?
132        .gate(quantrs2_core::gate::multi::CRZ {
133            control: QubitId(1),
134            target: QubitId(3),
135            theta: std::f64::consts::PI / 2.0,
136        })?
137        .gate(Hadamard { target: QubitId(1) })?
138        .measure(QubitId(1), "phase_bits", 1)?
139        // Third round (adaptive based on previous measurements)
140        .gate(Hadamard { target: QubitId(2) })?
141        // Apply phase corrections based on previous measurements
142        .conditional(
143            ClassicalCondition {
144                lhs: ClassicalValue::Register("phase_bits".to_string()),
145                op: ComparisonOp::GreaterEqual,
146                rhs: ClassicalValue::Integer(1),
147            },
148            quantrs2_core::gate::single::RotationZ {
149                target: QubitId(2),
150                theta: -std::f64::consts::PI / 4.0,
151            }
152        )?
153        .gate(quantrs2_core::gate::multi::CRZ {
154            control: QubitId(2),
155            target: QubitId(3),
156            theta: std::f64::consts::PI / 4.0,
157        })?
158        .gate(Hadamard { target: QubitId(2) })?
159        .measure(QubitId(2), "phase_bits", 2)?
160        .build();
161
162    println!(
163        "Created adaptive phase estimation circuit with {} operations",
164        circuit.num_operations()
165    );
166    println!("The circuit adaptively estimates the phase using 3 rounds of measurement\n");
167
168    // Demonstrate builder pattern
169    println!("Alternative: Using standard circuit with conversion");
170    let mut standard_circuit = Circuit::<4>::new();
171    standard_circuit.h(0)?;
172    standard_circuit.h(1)?;
173    standard_circuit.h(2)?;
174
175    let classical = standard_circuit.with_classical_control();
176    println!("Converted standard circuit to classical control\n");
177
178    Ok(())
179}