pub struct ClassicalCircuit<const N: usize> {
pub classical_registers: HashMap<String, ClassicalRegister>,
pub operations: Vec<CircuitOp>,
}
Expand description
A circuit with classical control flow support
Fields§
§classical_registers: HashMap<String, ClassicalRegister>
Classical registers
operations: Vec<CircuitOp>
Operations (both quantum and classical)
Implementations§
Source§impl<const N: usize> ClassicalCircuit<N>
impl<const N: usize> ClassicalCircuit<N>
Sourcepub fn add_classical_register(
&mut self,
name: &str,
size: usize,
) -> QuantRS2Result<()>
pub fn add_classical_register( &mut self, name: &str, size: usize, ) -> QuantRS2Result<()>
Add a classical register
Examples found in repository?
examples/classical_control_demo.rs (line 60)
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}
Sourcepub fn add_gate<G: GateOp + 'static>(&mut self, gate: G) -> QuantRS2Result<()>
pub fn add_gate<G: GateOp + 'static>(&mut self, gate: G) -> QuantRS2Result<()>
Add a quantum gate
Examples found in repository?
examples/classical_control_demo.rs (lines 63-66)
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}
Sourcepub fn measure(
&mut self,
qubit: QubitId,
register: &str,
bit: usize,
) -> QuantRS2Result<()>
pub fn measure( &mut self, qubit: QubitId, register: &str, bit: usize, ) -> QuantRS2Result<()>
Add a measurement
Examples found in repository?
examples/classical_control_demo.rs (line 70)
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}
Sourcepub fn add_conditional<G: GateOp + 'static>(
&mut self,
condition: ClassicalCondition,
gate: G,
) -> QuantRS2Result<()>
pub fn add_conditional<G: GateOp + 'static>( &mut self, condition: ClassicalCondition, gate: G, ) -> QuantRS2Result<()>
Add a conditional gate
Examples found in repository?
examples/classical_control_demo.rs (lines 74-81)
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}
Sourcepub fn reset_classical(&mut self, register: &str) -> QuantRS2Result<()>
pub fn reset_classical(&mut self, register: &str) -> QuantRS2Result<()>
Reset a classical register to zero
Sourcepub fn num_operations(&self) -> usize
pub fn num_operations(&self) -> usize
Get the number of operations
Examples found in repository?
examples/classical_control_demo.rs (line 41)
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}
Auto Trait Implementations§
impl<const N: usize> Freeze for ClassicalCircuit<N>
impl<const N: usize> !RefUnwindSafe for ClassicalCircuit<N>
impl<const N: usize> Send for ClassicalCircuit<N>
impl<const N: usize> Sync for ClassicalCircuit<N>
impl<const N: usize> Unpin for ClassicalCircuit<N>
impl<const N: usize> !UnwindSafe for ClassicalCircuit<N>
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> 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.