pub struct ClassicalCondition {
pub lhs: ClassicalValue,
pub op: ComparisonOp,
pub rhs: ClassicalValue,
}
Expand description
A condition that gates execution based on classical values
Fields§
§lhs: ClassicalValue
Left-hand side of the comparison
op: ComparisonOp
Comparison operator
rhs: ClassicalValue
Right-hand side of the comparison
Implementations§
Source§impl ClassicalCondition
impl ClassicalCondition
Sourcepub fn equals(lhs: ClassicalValue, rhs: ClassicalValue) -> Self
pub fn equals(lhs: ClassicalValue, rhs: ClassicalValue) -> Self
Create a new equality condition
Examples found in repository?
examples/advanced_features_demo.rs (lines 127-130)
18fn main() -> Result<(), Box<dyn std::error::Error>> {
19 println!("=== QuantRS2 Circuit Advanced Features Demo ===\n");
20
21 // 1. Basic circuit creation
22 println!("1. Creating a basic quantum circuit:");
23 let mut circuit = Circuit::<3>::new();
24 circuit.add_gate(Hadamard { target: QubitId(0) })?;
25 circuit.add_gate(CNOT {
26 control: QubitId(0),
27 target: QubitId(1),
28 })?;
29 circuit.add_gate(CNOT {
30 control: QubitId(1),
31 target: QubitId(2),
32 })?;
33 println!(" Circuit with {} gates created", circuit.gates().len());
34
35 // 2. ZX-calculus optimization
36 println!("\n2. ZX-calculus optimization:");
37 let zx_optimizer = ZXOptimizer::new();
38 let zx_diagram = zx_optimizer.circuit_to_zx(&circuit)?;
39 println!(
40 " ZX diagram with {} nodes created",
41 zx_diagram.nodes.len()
42 );
43
44 // 3. SciRS2 graph analysis
45 println!("\n3. SciRS2 graph analysis:");
46 let mut analyzer = SciRS2CircuitAnalyzer::new();
47 let analysis = analyzer.analyze_circuit(&circuit)?;
48 println!(
49 " Graph metrics: {} nodes, {} edges",
50 analysis.metrics.num_nodes, analysis.metrics.num_edges
51 );
52 println!(" Communities detected: {}", analysis.communities.len());
53
54 // 4. ML-based optimization
55 println!("\n4. ML-based circuit optimization:");
56 let ml_strategy = MLStrategy::NeuralNetwork {
57 architecture: vec![32, 16, 8],
58 learning_rate: 0.001,
59 epochs: 10,
60 batch_size: 16,
61 };
62 let mut ml_optimizer = MLCircuitOptimizer::new(ml_strategy);
63 let ml_result = ml_optimizer.optimize(&circuit)?;
64 println!(
65 " ML optimization completed in {:?}",
66 ml_result.optimization_time
67 );
68
69 // 5. Fault-tolerant compilation
70 println!("\n5. Fault-tolerant compilation:");
71 let code = QECCode::SteaneCode;
72 let ft_compiler = FaultTolerantCompiler::new(code);
73 let ft_circuit = ft_compiler.compile(&circuit)?;
74 println!(
75 " Fault-tolerant circuit: {} physical qubits, {} magic states",
76 ft_circuit.physical_qubit_count, ft_circuit.magic_state_requirements
77 );
78
79 // 6. Photonic circuit conversion
80 println!("\n6. Photonic quantum computation:");
81 let photonic_circuit = PhotonicConverter::quantum_to_photonic(&circuit)?;
82 println!(
83 " Photonic circuit: {} modes, {} gates",
84 photonic_circuit.num_modes,
85 photonic_circuit.gates.len()
86 );
87
88 // 7. Topological quantum computation
89 println!("\n7. Topological quantum computation:");
90 let anyon_model = AnyonModel::fibonacci();
91 let topo_compiler = TopologicalCompiler::new(anyon_model);
92 let topo_circuit = topo_compiler.compile_quantum_circuit(&circuit)?;
93 println!(
94 " Topological circuit: {} anyons, {} braiding operations",
95 topo_circuit.anyon_count(),
96 topo_circuit.total_braiding_operations()
97 );
98
99 // 8. Circuit-to-simulator interface
100 println!("\n8. Circuit compilation for simulators:");
101 let mut compiler = CircuitCompiler::new();
102 compiler.add_target(CompilationTarget {
103 backend: SimulatorBackend::StateVector {
104 max_qubits: 20,
105 use_gpu: false,
106 memory_optimization: MemoryOptimization::Basic,
107 },
108 optimization_level: SimulatorOptimizationLevel::Basic,
109 instruction_set: InstructionSet::Universal,
110 parallel_execution: true,
111 batch_size: Some(10),
112 });
113
114 let compiled = compiler.compile(&circuit)?;
115 println!(
116 " Compiled circuit: {} instructions, estimated memory: {} bytes",
117 compiled.instructions.len(),
118 compiled.resources.memory_bytes
119 );
120
121 // 9. Mid-circuit measurements and feed-forward
122 println!("\n9. Mid-circuit measurements and feed-forward:");
123 let mut measurement_circuit = MeasurementCircuit::<2>::new();
124 measurement_circuit.add_gate(Box::new(Hadamard { target: QubitId(0) }))?;
125 let bit = measurement_circuit.measure(QubitId(0))?;
126
127 let condition = ClassicalCondition::equals(
128 ClassicalValue::Integer(bit as u64),
129 ClassicalValue::Integer(1),
130 );
131 measurement_circuit.add_conditional(condition, Box::new(PauliX { target: QubitId(1) }))?;
132 println!(
133 " Measurement circuit with {} operations created",
134 measurement_circuit.num_operations()
135 );
136
137 // 10. Cross-talk aware scheduling
138 println!("\n10. Cross-talk aware scheduling:");
139 let crosstalk_model = CrosstalkModel::uniform(3, 0.05);
140 let scheduler = CrosstalkScheduler::new(crosstalk_model);
141 let schedule = scheduler.schedule(&circuit)?;
142 println!(
143 " Scheduled into {} time slices, total crosstalk: {:.3}",
144 schedule.time_slices.len(),
145 schedule.total_crosstalk
146 );
147
148 println!("\n=== Demo completed successfully! ===");
149 Ok(())
150}
Sourcepub fn register_equals(register: &str, value: u64) -> Self
pub fn register_equals(register: &str, value: u64) -> Self
Check if a register equals a specific value
Examples found in repository?
examples/classical_control_demo.rs (line 34)
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}
More examples
examples/measurement_demo.rs (line 35)
22fn demo_basic_measurement() -> quantrs2_core::error::QuantRS2Result<()> {
23 println!("--- Basic Mid-Circuit Measurement ---");
24
25 let mut circuit = MeasurementCircuit::<3>::new();
26
27 // Create superposition
28 circuit.add_gate(Box::new(Hadamard { target: QubitId(0) }))?;
29
30 // Measure qubit 0
31 let bit0 = circuit.measure(QubitId(0))?;
32 println!("Measured qubit 0 -> classical bit {}", bit0);
33
34 // Apply X gate to qubit 1 conditioned on measurement
35 let condition = ClassicalCondition::register_equals("default", 1);
36 circuit.add_conditional(condition, Box::new(PauliX { target: QubitId(1) }))?;
37
38 println!("Circuit has {} operations", circuit.num_operations());
39 println!("Circuit has {} measurements\n", circuit.num_measurements());
40
41 Ok(())
42}
43
44fn demo_feed_forward() -> quantrs2_core::error::QuantRS2Result<()> {
45 println!("--- Feed-Forward Control ---");
46
47 let (builder, bit) = MeasurementCircuitBuilder::<4>::new()
48 // Prepare Bell state
49 .gate(Box::new(Hadamard { target: QubitId(0) }))?
50 .gate(Box::new(CNOT { control: QubitId(0), target: QubitId(1) }))?
51 // Measure first qubit
52 .measure(QubitId(0))?;
53
54 let circuit = builder
55 // Apply correction based on measurement
56 .when(
57 ClassicalCondition::register_equals("default", 1),
58 Box::new(PauliX { target: QubitId(1) })
59 )?
60 // Add barrier for synchronization
61 .barrier(vec![QubitId(1), QubitId(2)])?
62 // Continue with more operations
63 .gate(Box::new(Hadamard { target: QubitId(2) }))?
64 .build();
65
66 // Analyze dependencies
67 let deps = circuit.analyze_dependencies();
68 println!("Found {} measurements", deps.num_measurements());
69 println!("Has feed-forward: {}", deps.has_feed_forward());
70
71 for (meas_idx, ff_idx) in &deps.feed_forward_deps {
72 println!("Operation {} depends on measurement {}", ff_idx, meas_idx);
73 }
74
75 println!();
76 Ok(())
77}
78
79fn demo_quantum_teleportation() -> quantrs2_core::error::QuantRS2Result<()> {
80 println!("--- Quantum Teleportation Protocol ---");
81
82 let mut circuit = MeasurementCircuit::<3>::new();
83
84 // Prepare state to teleport on qubit 0 (|ψ⟩ = α|0⟩ + β|1⟩)
85 // For demo, use |+⟩ state
86 circuit.add_gate(Box::new(Hadamard { target: QubitId(0) }))?;
87
88 // Create Bell pair between qubits 1 and 2
89 circuit.add_gate(Box::new(Hadamard { target: QubitId(1) }))?;
90 circuit.add_gate(Box::new(CNOT {
91 control: QubitId(1),
92 target: QubitId(2),
93 }))?;
94
95 println!("Prepared Bell pair and state to teleport");
96
97 // Bell measurement on qubits 0 and 1
98 circuit.add_gate(Box::new(CNOT {
99 control: QubitId(0),
100 target: QubitId(1),
101 }))?;
102 circuit.add_gate(Box::new(Hadamard { target: QubitId(0) }))?;
103
104 // Measure qubits 0 and 1
105 let bit0 = circuit.measure(QubitId(0))?;
106 let bit1 = circuit.measure(QubitId(1))?;
107
108 println!("Performed Bell measurement");
109
110 // Apply corrections to qubit 2 based on measurements
111 circuit.add_conditional(
112 ClassicalCondition::register_equals("default", 1),
113 Box::new(PauliX { target: QubitId(2) }),
114 )?;
115
116 circuit.add_conditional(
117 ClassicalCondition::register_equals("default", 1),
118 Box::new(PauliZ { target: QubitId(2) }),
119 )?;
120
121 println!("Applied classical corrections");
122 println!(
123 "Teleportation circuit has {} operations",
124 circuit.num_operations()
125 );
126
127 println!();
128 Ok(())
129}
130
131fn demo_error_correction() -> quantrs2_core::error::QuantRS2Result<()> {
132 println!("--- Simple Error Correction ---");
133
134 let mut circuit = MeasurementCircuit::<5>::new();
135
136 // Encode logical qubit using repetition code
137 // |0⟩ -> |000⟩, |1⟩ -> |111⟩
138
139 // Prepare initial state (for demo, use |1⟩)
140 circuit.add_gate(Box::new(PauliX { target: QubitId(0) }))?;
141
142 // Encode
143 circuit.add_gate(Box::new(CNOT {
144 control: QubitId(0),
145 target: QubitId(1),
146 }))?;
147 circuit.add_gate(Box::new(CNOT {
148 control: QubitId(0),
149 target: QubitId(2),
150 }))?;
151
152 println!("Encoded logical qubit");
153
154 // Simulate error (bit flip on qubit 1)
155 circuit.add_gate(Box::new(PauliX { target: QubitId(1) }))?;
156 println!("Introduced error on qubit 1");
157
158 // Syndrome measurement using ancillas
159 circuit.add_gate(Box::new(CNOT {
160 control: QubitId(0),
161 target: QubitId(3),
162 }))?;
163 circuit.add_gate(Box::new(CNOT {
164 control: QubitId(1),
165 target: QubitId(3),
166 }))?;
167
168 circuit.add_gate(Box::new(CNOT {
169 control: QubitId(1),
170 target: QubitId(4),
171 }))?;
172 circuit.add_gate(Box::new(CNOT {
173 control: QubitId(2),
174 target: QubitId(4),
175 }))?;
176
177 // Measure syndrome
178 let syndrome1 = circuit.measure(QubitId(3))?;
179 let syndrome2 = circuit.measure(QubitId(4))?;
180
181 println!("Measured error syndrome");
182
183 // Decode syndrome and apply correction
184 // Note: In a full implementation, we would need compound conditions
185 // For now, apply simple conditional corrections based on syndrome bits
186
187 // Apply correction based on first syndrome bit
188 circuit.add_conditional(
189 ClassicalCondition::register_equals("default", 1),
190 Box::new(PauliX { target: QubitId(1) }),
191 )?;
192
193 println!("Applied error correction");
194 println!("Total operations: {}", circuit.num_operations());
195
196 // Reset ancillas for reuse
197 circuit.reset(QubitId(3))?;
198 circuit.reset(QubitId(4))?;
199
200 println!();
201 Ok(())
202}
Trait Implementations§
Source§impl Clone for ClassicalCondition
impl Clone for ClassicalCondition
Source§fn clone(&self) -> ClassicalCondition
fn clone(&self) -> ClassicalCondition
Returns a duplicate of the value. Read more
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source
. Read moreAuto Trait Implementations§
impl Freeze for ClassicalCondition
impl RefUnwindSafe for ClassicalCondition
impl Send for ClassicalCondition
impl Sync for ClassicalCondition
impl Unpin for ClassicalCondition
impl UnwindSafe for ClassicalCondition
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
Converts
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
Converts
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
The inverse inclusion map: attempts to construct
self
from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
Checks if
self
is actually part of its subset T
(and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
Use with care! Same as
self.to_subset
but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
The inclusion map: converts
self
to the equivalent element of its superset.