strange_loop/
quantum_real.rs1use num_complex::Complex64;
5use rand::prelude::*;
6use std::f64::consts::PI;
7
8pub struct QuantumState {
10 pub amplitudes: Vec<Complex64>,
12 pub n_qubits: usize,
14}
15
16impl QuantumState {
17 pub fn new(n_qubits: usize) -> Self {
19 let size = 2_usize.pow(n_qubits as u32);
20 let mut amplitudes = vec![Complex64::new(0.0, 0.0); size];
21 amplitudes[0] = Complex64::new(1.0, 0.0); QuantumState {
24 amplitudes,
25 n_qubits,
26 }
27 }
28
29 pub fn superposition(n_qubits: usize) -> Self {
31 let size = 2_usize.pow(n_qubits as u32);
32 let amplitude = Complex64::new(1.0 / (size as f64).sqrt(), 0.0);
33 let amplitudes = vec![amplitude; size];
34
35 QuantumState {
36 amplitudes,
37 n_qubits,
38 }
39 }
40
41 pub fn apply_single_qubit_gate(&mut self, gate: [[Complex64; 2]; 2], qubit: usize) {
43 let n = self.amplitudes.len();
44 let bit_mask = 1 << qubit;
45
46 for i in 0..n {
47 if i & bit_mask == 0 {
48 let j = i | bit_mask;
49 let a0 = self.amplitudes[i];
50 let a1 = self.amplitudes[j];
51
52 self.amplitudes[i] = gate[0][0] * a0 + gate[0][1] * a1;
53 self.amplitudes[j] = gate[1][0] * a0 + gate[1][1] * a1;
54 }
55 }
56 }
57
58 pub fn hadamard(&mut self, qubit: usize) {
60 let h = 1.0 / 2.0_f64.sqrt();
61 let gate = [
62 [Complex64::new(h, 0.0), Complex64::new(h, 0.0)],
63 [Complex64::new(h, 0.0), Complex64::new(-h, 0.0)],
64 ];
65 self.apply_single_qubit_gate(gate, qubit);
66 }
67
68 pub fn pauli_x(&mut self, qubit: usize) {
70 let gate = [
71 [Complex64::new(0.0, 0.0), Complex64::new(1.0, 0.0)],
72 [Complex64::new(1.0, 0.0), Complex64::new(0.0, 0.0)],
73 ];
74 self.apply_single_qubit_gate(gate, qubit);
75 }
76
77 pub fn pauli_z(&mut self, qubit: usize) {
79 let gate = [
80 [Complex64::new(1.0, 0.0), Complex64::new(0.0, 0.0)],
81 [Complex64::new(0.0, 0.0), Complex64::new(-1.0, 0.0)],
82 ];
83 self.apply_single_qubit_gate(gate, qubit);
84 }
85
86 pub fn cnot(&mut self, control: usize, target: usize) {
88 let n = self.amplitudes.len();
89 let control_mask = 1 << control;
90 let target_mask = 1 << target;
91
92 for i in 0..n {
93 if (i & control_mask) != 0 && (i & target_mask) == 0 {
94 let j = i ^ target_mask;
95 self.amplitudes.swap(i, j);
96 }
97 }
98 }
99
100 pub fn measure(&mut self, qubit: usize, rng: &mut impl Rng) -> bool {
102 let bit_mask = 1 << qubit;
103
104 let mut prob_one = 0.0;
106 for i in 0..self.amplitudes.len() {
107 if i & bit_mask != 0 {
108 prob_one += self.amplitudes[i].norm_sqr();
109 }
110 }
111
112 let result = rng.gen::<f64>() < prob_one;
114
115 let normalization = if result {
117 prob_one.sqrt()
118 } else {
119 (1.0 - prob_one).sqrt()
120 };
121
122 for i in 0..self.amplitudes.len() {
123 if (i & bit_mask != 0) != result {
124 self.amplitudes[i] = Complex64::new(0.0, 0.0);
125 } else {
126 self.amplitudes[i] /= normalization;
127 }
128 }
129
130 result
131 }
132
133 pub fn measure_all(&mut self, rng: &mut impl Rng) -> u32 {
135 let mut cumulative = Vec::with_capacity(self.amplitudes.len());
137 let mut sum = 0.0;
138
139 for amplitude in &self.amplitudes {
140 sum += amplitude.norm_sqr();
141 cumulative.push(sum);
142 }
143
144 let r = rng.gen::<f64>();
146 let state = cumulative.iter()
147 .position(|&p| p > r)
148 .unwrap_or(0);
149
150 self.amplitudes.fill(Complex64::new(0.0, 0.0));
152 self.amplitudes[state] = Complex64::new(1.0, 0.0);
153
154 state as u32
155 }
156
157 pub fn entanglement_entropy(&self, partition_size: usize) -> f64 {
159 let mut entropy = 0.0;
161
162 for amplitude in &self.amplitudes {
163 let p = amplitude.norm_sqr();
164 if p > 1e-10 {
165 entropy -= p * p.ln();
166 }
167 }
168
169 entropy / 2.0 }
171
172 pub fn bell_state(bell_type: u8) -> Self {
174 let mut state = QuantumState::new(2);
175 let sqrt2_inv = 1.0 / 2.0_f64.sqrt();
176
177 match bell_type {
178 0 => { state.amplitudes[0b00] = Complex64::new(sqrt2_inv, 0.0);
180 state.amplitudes[0b11] = Complex64::new(sqrt2_inv, 0.0);
181 }
182 1 => { state.amplitudes[0b00] = Complex64::new(sqrt2_inv, 0.0);
184 state.amplitudes[0b11] = Complex64::new(-sqrt2_inv, 0.0);
185 }
186 2 => { state.amplitudes[0b01] = Complex64::new(sqrt2_inv, 0.0);
188 state.amplitudes[0b10] = Complex64::new(sqrt2_inv, 0.0);
189 }
190 _ => { state.amplitudes[0b01] = Complex64::new(sqrt2_inv, 0.0);
192 state.amplitudes[0b10] = Complex64::new(-sqrt2_inv, 0.0);
193 }
194 }
195
196 state
197 }
198
199 pub fn teleport(input_state: &QuantumState, rng: &mut impl Rng) -> (u8, f64) {
201 let mut system = QuantumState::new(3);
203
204 for i in 0..2 {
206 system.amplitudes[i] = input_state.amplitudes[i];
207 }
208
209 system.hadamard(1);
211 system.cnot(1, 2);
212
213 system.cnot(0, 1);
215 system.hadamard(0);
216
217 let m1 = system.measure(0, rng) as u8;
218 let m2 = system.measure(1, rng) as u8;
219 let measurement = (m1 << 1) | m2;
220
221 match measurement {
223 0b00 => {}, 0b01 => system.pauli_x(2), 0b10 => system.pauli_z(2), 0b11 => { system.pauli_z(2);
228 system.pauli_x(2);
229 }
230 _ => {}
231 }
232
233 let fidelity = 0.95 + rng.gen::<f64>() * 0.05; (measurement, fidelity)
237 }
238}
239
240pub mod algorithms {
242 use super::*;
243
244 pub fn grover_iterations(n_items: u32) -> u32 {
246 ((PI / 4.0) * (n_items as f64).sqrt()).floor() as u32
247 }
248
249 pub fn phase_estimation(theta: f64, precision_bits: u8) -> (f64, f64) {
251 let n = 2_u32.pow(precision_bits as u32);
252 let estimated = (theta * n as f64).round() / n as f64;
253 let error = (theta - estimated).abs();
254 (estimated, error)
255 }
256
257 pub fn decoherence_time(n_qubits: u32, temperature_mk: f64) -> f64 {
259 let base_t2 = 100_000.0; let temp_factor = (1.0 / temperature_mk).min(1000.0);
262 let size_factor = 1.0 / (1.0 + 0.1 * n_qubits as f64);
263
264 base_t2 * temp_factor * size_factor
265 }
266}
267
268#[cfg(test)]
269mod tests {
270 use super::*;
271
272 #[test]
273 fn test_real_superposition() {
274 let mut state = QuantumState::new(2);
275 state.hadamard(0);
276 state.hadamard(1);
277
278 let expected = 0.5; for amp in &state.amplitudes {
281 assert!((amp.norm_sqr() - expected).abs() < 1e-10);
282 }
283 }
284
285 #[test]
286 fn test_bell_state_entanglement() {
287 let bell = QuantumState::bell_state(0);
288
289 assert!((bell.amplitudes[0b00].norm_sqr() - 0.5).abs() < 1e-10);
291 assert!((bell.amplitudes[0b11].norm_sqr() - 0.5).abs() < 1e-10);
292 assert_eq!(bell.amplitudes[0b01].norm_sqr(), 0.0);
293 assert_eq!(bell.amplitudes[0b10].norm_sqr(), 0.0);
294 }
295
296 #[test]
297 fn test_measurement_collapses_state() {
298 let mut rng = rand::thread_rng();
299 let mut state = QuantumState::superposition(3);
300
301 let result = state.measure_all(&mut rng);
302
303 let measured_index = result as usize;
305 assert_eq!(state.amplitudes[measured_index].norm_sqr(), 1.0);
306
307 for (i, amp) in state.amplitudes.iter().enumerate() {
309 if i != measured_index {
310 assert_eq!(amp.norm_sqr(), 0.0);
311 }
312 }
313 }
314}