ClassicalCondition

Struct ClassicalCondition 

Source
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

Source

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}
Source

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
Hide additional 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

Source§

fn clone(&self) -> ClassicalCondition

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ClassicalCondition

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

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 more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

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

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> Ungil for T
where T: Send,