agentic-flow 1.5.13 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/CHANGELOG.md +199 -0
  2. package/README.md +42 -23
  3. package/dist/cli-proxy.js +195 -1
  4. package/dist/config/quic.js +6 -0
  5. package/dist/transport/quic.js +43 -0
  6. package/dist/utils/cli.js +5 -0
  7. package/docs/.claude-flow/metrics/performance.json +80 -2
  8. package/docs/.claude-flow/metrics/task-metrics.json +3 -3
  9. package/docs/INDEX.md +55 -9
  10. package/docs/INTEGRATION-COMPLETE.md +291 -0
  11. package/docs/QUIC_FINAL_STATUS.md +399 -0
  12. package/docs/README_QUIC_PHASE1.md +117 -0
  13. package/docs/integration-docs/CLAUDE-FLOW-INTEGRATION-ANALYSIS.md +653 -0
  14. package/docs/integration-docs/INTEGRATION-QUICK-SUMMARY.md +249 -0
  15. package/docs/integration-docs/INTEGRATION-STATUS-CORRECTED.md +488 -0
  16. package/docs/integration-docs/README.md +61 -0
  17. package/docs/quantum-goap/DEPENDENCY_GRAPH.mermaid +133 -0
  18. package/docs/quantum-goap/EXECUTION_SUMMARY.md +199 -0
  19. package/docs/quantum-goap/GOAP_IMPLEMENTATION_PLAN.md +2406 -0
  20. package/docs/quantum-goap/QUICK_START.md +301 -0
  21. package/docs/quantum-research/QUANTUM_RESEARCH_LITERATURE_REVIEW.md +2071 -0
  22. package/docs/quantum-research/README.md +94 -0
  23. package/docs/reasoningbank/MEMORY_VALIDATION_REPORT.md +417 -0
  24. package/docs/reasoningbank/README.md +43 -0
  25. package/docs/reasoningbank/REASONINGBANK_ARCHITECTURE.md +663 -0
  26. package/docs/releases/v1.5.14-QUIC-TRANSPORT.md +201 -0
  27. package/docs/validation-reports/BENCHMARK_AND_OPTIMIZATION_REPORT.md +470 -0
  28. package/docs/validation-reports/NPM-PACKAGE-ANALYSIS-FINAL.md +543 -0
  29. package/docs/validation-reports/README.md +43 -0
  30. package/docs/validation-reports/V2.7.0-ALPHA.10_FINAL_VALIDATION.md +817 -0
  31. package/docs/validation-reports/V2.7.0-ALPHA.9_VALIDATION.md +546 -0
  32. package/docs/validation-reports/v1.6.0-QUIC-CLI-VALIDATION.md +558 -0
  33. package/docs/version-releases/README.md +82 -0
  34. package/package.json +4 -2
  35. package/validation/docker-quic-test.sh +42 -0
  36. package/validation/docker-quic-validation.sh +60 -0
  37. package/validation/quic-deep-validation.ts +304 -0
  38. package/validation/test-quic-wasm.ts +94 -0
  39. package/wasm/quic/README.md +75 -0
  40. package/wasm/quic/agentic_flow_quic.d.ts +37 -0
  41. package/wasm/quic/agentic_flow_quic.js +779 -0
  42. package/wasm/quic/agentic_flow_quic_bg.wasm +0 -0
  43. package/wasm/quic/agentic_flow_quic_bg.wasm.d.ts +19 -0
  44. package/wasm/quic/package.json +20 -0
  45. package/wasm/reasoningbank/reasoningbank_wasm_bg.js +2 -2
  46. package/wasm/reasoningbank/reasoningbank_wasm_bg.wasm +0 -0
  47. /package/docs/{PACKAGE_STRUCTURE.md → architecture/PACKAGE_STRUCTURE.md} +0 -0
  48. /package/docs/{MODEL-ID-MAPPING.md → guides/MODEL-ID-MAPPING.md} +0 -0
  49. /package/docs/{ONNX-PROXY-IMPLEMENTATION.md → guides/ONNX-PROXY-IMPLEMENTATION.md} +0 -0
  50. /package/docs/{STANDALONE_PROXY_GUIDE.md → guides/STANDALONE_PROXY_GUIDE.md} +0 -0
  51. /package/docs/{AGENT-BOOSTER-INTEGRATION.md → integration-docs/AGENT-BOOSTER-INTEGRATION.md} +0 -0
  52. /package/docs/{CLI-INTEGRATION-COMPLETE.md → integration-docs/CLI-INTEGRATION-COMPLETE.md} +0 -0
  53. /package/docs/{IMPLEMENTATION_SUMMARY.md → integration-docs/IMPLEMENTATION_SUMMARY.md} +0 -0
  54. /package/docs/{INTEGRATION_COMPLETE_SUMMARY.md → integration-docs/INTEGRATION_COMPLETE_SUMMARY.md} +0 -0
  55. /package/docs/{WASM_ESM_FIX.md → integration-docs/WASM_ESM_FIX.md} +0 -0
  56. /package/docs/{WASM_INTEGRATION_COMPLETE.md → integration-docs/WASM_INTEGRATION_COMPLETE.md} +0 -0
  57. /package/docs/{REASONING-AGENTS.md → reasoningbank/REASONING-AGENTS.md} +0 -0
  58. /package/docs/{REASONINGBANK-BENCHMARK-RESULTS.md → reasoningbank/REASONINGBANK-BENCHMARK-RESULTS.md} +0 -0
  59. /package/docs/{REASONINGBANK-BENCHMARK.md → reasoningbank/REASONINGBANK-BENCHMARK.md} +0 -0
  60. /package/docs/{REASONINGBANK-CLI-INTEGRATION.md → reasoningbank/REASONINGBANK-CLI-INTEGRATION.md} +0 -0
  61. /package/docs/{REASONINGBANK-DEMO.md → reasoningbank/REASONINGBANK-DEMO.md} +0 -0
  62. /package/docs/{REASONINGBANK-VALIDATION.md → reasoningbank/REASONINGBANK-VALIDATION.md} +0 -0
  63. /package/docs/{REASONINGBANK_BACKENDS.md → reasoningbank/REASONINGBANK_BACKENDS.md} +0 -0
  64. /package/docs/{REASONINGBANK_FIXES.md → reasoningbank/REASONINGBANK_FIXES.md} +0 -0
  65. /package/docs/{REASONINGBANK_IMPLEMENTATION_STATUS.md → reasoningbank/REASONINGBANK_IMPLEMENTATION_STATUS.md} +0 -0
  66. /package/docs/{REASONINGBANK_INTEGRATION_PLAN.md → reasoningbank/REASONINGBANK_INTEGRATION_PLAN.md} +0 -0
  67. /package/docs/{REASONINGBANK_INVESTIGATION.md → reasoningbank/REASONINGBANK_INVESTIGATION.md} +0 -0
  68. /package/docs/{DOCKER_VALIDATION_RESULTS.md → validation-reports/DOCKER_VALIDATION_RESULTS.md} +0 -0
  69. /package/docs/{NO_REGRESSIONS_CONFIRMED.md → validation-reports/NO_REGRESSIONS_CONFIRMED.md} +0 -0
  70. /package/docs/{PUBLICATION_REPORT_v1.5.11.md → version-releases/PUBLICATION_REPORT_v1.5.11.md} +0 -0
  71. /package/docs/{v1.5.9-DOCKER-VERIFICATION.md → version-releases/v1.5.9-DOCKER-VERIFICATION.md} +0 -0
  72. /package/docs/{v1.5.9-RELEASE-SUMMARY.md → version-releases/v1.5.9-RELEASE-SUMMARY.md} +0 -0
@@ -0,0 +1,2071 @@
1
+ # Observer-Agnostic Quantum Measurement: Comprehensive Literature Review
2
+
3
+ **Research Date:** 2025-10-14
4
+ **Researcher:** Research Agent
5
+ **Context:** Implementation requirements for Observer-Agnostic Measurement and No-Retrocausal Marginals Theorem
6
+ **Purpose:** Deep research to support falsifiable quantum mechanics experiment testing consciousness effects on quantum measurement outcomes
7
+
8
+ ---
9
+
10
+ ## Executive Summary
11
+
12
+ This comprehensive literature review examines five critical areas for implementing the Observer-Agnostic Measurement experiment in Rust:
13
+
14
+ 1. **Quantum Measurement Theory** - POVM formalism, Born rule, delayed-choice quantum eraser experiments
15
+ 2. **Rust Quantum Computing Libraries** - nalgebra, num-complex, quantum simulation frameworks, SIMD optimization
16
+ 3. **Experimental Design** - Photonic quantum eraser setups, entangled photon generation, interferometry
17
+ 4. **Best Practices** - Pre-registration protocols, reproducibility standards, falsification criteria
18
+ 5. **Implementation Considerations** - Scientific Rust project structure, testing strategies, visualization
19
+
20
+ **Key Finding:** The existing research document provides an excellent theoretical foundation. This review adds critical implementation details, library recommendations, and best practices from 2024's quantum computing ecosystem.
21
+
22
+ ---
23
+
24
+ ## 1. Quantum Measurement Theory
25
+
26
+ ### 1.1 POVM (Positive Operator-Valued Measure) Formalism
27
+
28
+ **Theoretical Foundation:**
29
+ - POVMs represent the most general class of quantum measurements
30
+ - An n-outcome POVM is a set of n positive semi-definite Hermitian operators {E_k} that sum to identity: Σ E_k = I
31
+ - Given a d-dimensional quantum state ρ, the probability of observing outcome k is given by Born's rule: p(k) = Tr(E_k ρ)
32
+ - POVMs extend standard projective measurements (PVMs) and are essential for describing realistic, imperfect measurements
33
+
34
+ **Recent Developments (2024):**
35
+ - The POVM theorem has been systematically presented in Bohmian mechanics context, grounding measurement formalism in quantum equilibrium hypothesis
36
+ - POVM formalism is extensively used in quantum information, quantum field theory, and quantum computing
37
+ - Qiskit now includes POVM Toolbox for practical implementations
38
+
39
+ **Computational Representation:**
40
+ ```rust
41
+ use nalgebra::{DMatrix, Complex};
42
+ use num_complex::Complex64 as C64;
43
+
44
+ /// POVM element (positive semi-definite operator)
45
+ pub struct POVMElement {
46
+ operator: DMatrix<C64>,
47
+ }
48
+
49
+ impl POVMElement {
50
+ /// Create from projector |ψ⟩⟨ψ|
51
+ pub fn from_projector(psi: &DVector<C64>) -> Self {
52
+ let n = psi.len();
53
+ let mut op = DMatrix::zeros(n, n);
54
+ for i in 0..n {
55
+ for j in 0..n {
56
+ op[(i, j)] = psi[i] * psi[j].conj();
57
+ }
58
+ }
59
+ Self { operator: op }
60
+ }
61
+
62
+ /// Verify positive semi-definiteness
63
+ pub fn is_valid(&self) -> bool {
64
+ // Check eigenvalues are non-negative
65
+ let eigs = self.operator.complex_eigenvalues();
66
+ eigs.iter().all(|e| e.re >= -1e-10)
67
+ }
68
+ }
69
+
70
+ /// Complete POVM measurement set
71
+ pub struct POVM {
72
+ elements: Vec<POVMElement>,
73
+ }
74
+
75
+ impl POVM {
76
+ /// Verify POVM completeness: Σ E_k = I
77
+ pub fn verify_completeness(&self) -> bool {
78
+ let sum = self.elements.iter()
79
+ .fold(DMatrix::zeros(2, 2), |acc, e| acc + e.operator.clone());
80
+
81
+ let identity = DMatrix::identity(2, 2);
82
+ (sum - identity).norm() < 1e-10
83
+ }
84
+
85
+ /// Calculate Born rule probability
86
+ pub fn probability(&self, outcome: usize, rho: &DMatrix<C64>) -> f64 {
87
+ let result = &self.elements[outcome].operator * rho;
88
+ result.trace().re
89
+ }
90
+ }
91
+ ```
92
+
93
+ ### 1.2 Born Rule and Measurement Probabilities
94
+
95
+ **Theoretical Foundation:**
96
+ - Born rule: p(outcome) = Tr(M_outcome ρ) where M is measurement operator and ρ is density matrix
97
+ - For pure states |ψ⟩: p(outcome) = |⟨ψ|M|ψ⟩|²
98
+ - The rule is linear in ρ, meaning measurement statistics depend only on quantum state and measurement setup, NOT on observer identity
99
+
100
+ **Computational Implementation:**
101
+ ```rust
102
+ /// Calculate measurement probability using Born rule
103
+ pub fn born_probability(
104
+ state: &DMatrix<C64>, // Density matrix ρ
105
+ measurement: &DMatrix<C64>, // Measurement operator M
106
+ ) -> f64 {
107
+ let result = measurement * state;
108
+ result.trace().re.max(0.0).min(1.0) // Clamp to [0,1] for numerical stability
109
+ }
110
+
111
+ /// For pure states: p = |⟨ψ|M|ψ⟩|²
112
+ pub fn born_pure_state(
113
+ psi: &DVector<C64>,
114
+ measurement: &DMatrix<C64>,
115
+ ) -> f64 {
116
+ let m_psi = measurement * psi;
117
+ let amplitude = psi.dotc(&m_psi);
118
+ (amplitude * amplitude.conj()).re
119
+ }
120
+ ```
121
+
122
+ ### 1.3 Delayed-Choice Quantum Eraser Experiments
123
+
124
+ **Experimental Context:**
125
+ - Elaboration on Wheeler's delayed-choice experiment incorporating quantum eraser concepts
126
+ - Tests wave-particle duality and complementarity principle
127
+ - Heart of the experiment: mutually exclusive quantum features that appear to violate cause-effect relations
128
+
129
+ **Key Components:**
130
+ 1. **Entangled Photon Pairs:** Generated via spontaneous parametric down-conversion (SPDC)
131
+ 2. **Signal Path:** Signal photon passes through double-slit interferometer
132
+ 3. **Idler Path:** Idler photon measured in different bases (which-path vs eraser)
133
+ 4. **Delayed Choice:** Decision about idler measurement can be made after signal detection
134
+
135
+ **2024 Experimental Demonstrations:**
136
+ - Recent experiments using coherent photons from attenuated CW lasers
137
+ - Proposal for electron-light entanglement via cathodoluminescence in transmission electron microscope
138
+ - Scientific Reports (2023-2024): Observations with frequency-entangled photon pairs
139
+
140
+ **Critical Predictions:**
141
+ - Singles on signal photon are ALWAYS flat (50-50 distribution) regardless of idler measurement choice
142
+ - Conditional statistics (coincidence counts) show interference fringes only when conditioning on eraser basis outcomes
143
+ - NO retrocausal signaling: later measurement choice cannot alter already-registered singles
144
+
145
+ **Computational Model:**
146
+ ```rust
147
+ /// Delayed-choice quantum eraser simulation
148
+ pub struct QuantumEraser {
149
+ phi: f64, // Phase parameter
150
+ }
151
+
152
+ impl QuantumEraser {
153
+ /// Create Bell state with phase: (|00⟩ + e^(iφ)|11⟩)/√2
154
+ pub fn bell_state_with_phase(&self) -> DVector<C64> {
155
+ let s = 1.0 / 2.0_f64.sqrt();
156
+ DVector::from_vec(vec![
157
+ C64::new(s, 0.0),
158
+ C64::new(0.0, 0.0),
159
+ C64::new(0.0, 0.0),
160
+ C64::from_polar(s, self.phi),
161
+ ])
162
+ }
163
+
164
+ /// Singles probability (MUST be 0.5, 0.5 regardless of idler measurement)
165
+ pub fn singles_probability(&self) -> [f64; 2] {
166
+ let psi = self.bell_state_with_phase();
167
+ let rho = density_matrix(&psi);
168
+ let rho_signal = partial_trace_second(&rho);
169
+
170
+ let p0 = born_probability(&rho_signal, &projector(&ket0()));
171
+ let p1 = born_probability(&rho_signal, &projector(&ket1()));
172
+
173
+ [p0, p1]
174
+ }
175
+
176
+ /// Conditional probability p(signal|idler, basis)
177
+ pub fn conditional_probability(
178
+ &self,
179
+ idler_basis: IdlerBasis,
180
+ ) -> [[f64; 2]; 2] {
181
+ // Implementation shows phase-dependent fringes for eraser basis
182
+ // but NOT in singles statistics
183
+ todo!("See existing research.md for full implementation")
184
+ }
185
+ }
186
+ ```
187
+
188
+ ### 1.4 Wave-Particle Duality and Complementarity
189
+
190
+ **Englert's Duality Relation:**
191
+ - For any quantum interferometer: V² + D² ≤ 1
192
+ - V = visibility (wave-like behavior), D = distinguishability (particle-like behavior)
193
+ - Perfect implementation: V² + D² = 1 for pure states
194
+ - Partial which-path information: 0 < V² + D² < 1
195
+
196
+ **Computational Verification:**
197
+ ```rust
198
+ pub fn verify_duality_bound(
199
+ visibility: f64,
200
+ distinguishability: f64,
201
+ ) -> bool {
202
+ let sum = visibility.powi(2) + distinguishability.powi(2);
203
+ sum <= 1.0 + 1e-10 // Allow small numerical error
204
+ }
205
+
206
+ /// Calculate visibility from off-diagonal density matrix elements
207
+ pub fn calculate_visibility(rho_signal: &DMatrix<C64>) -> f64 {
208
+ 2.0 * rho_signal[(0, 1)].norm()
209
+ }
210
+
211
+ /// Calculate distinguishability from diagonal elements
212
+ pub fn calculate_distinguishability(rho_signal: &DMatrix<C64>) -> f64 {
213
+ (rho_signal[(0, 0)].re - rho_signal[(1, 1)].re).abs()
214
+ }
215
+ ```
216
+
217
+ ---
218
+
219
+ ## 2. Rust Quantum Computing Libraries
220
+
221
+ ### 2.1 Core Mathematical Libraries
222
+
223
+ #### **nalgebra** (v0.32+)
224
+ **Purpose:** Linear algebra operations, matrix manipulations, quantum state representations
225
+
226
+ **Justification:**
227
+ - Most mature linear algebra library in Rust ecosystem
228
+ - Excellent performance with compile-time optimizations
229
+ - Supports complex numbers via num-complex integration
230
+ - Used extensively in scientific computing projects
231
+ - Strong type safety with dimension checking
232
+
233
+ **Key Features for Quantum Simulation:**
234
+ - `DMatrix<Complex64>`: Dynamic matrices for density matrices and operators
235
+ - `DVector<Complex64>`: State vectors |ψ⟩
236
+ - Matrix operations: multiplication, trace, eigenvalues
237
+ - Kronecker products for tensor products of quantum systems
238
+
239
+ **Example Usage:**
240
+ ```rust
241
+ [dependencies]
242
+ nalgebra = "0.32"
243
+ num-complex = "0.4"
244
+
245
+ use nalgebra::{DMatrix, DVector};
246
+ use num_complex::Complex64 as C64;
247
+
248
+ // Quantum state
249
+ let psi = DVector::from_vec(vec![
250
+ C64::new(1.0/f64::sqrt(2.0), 0.0),
251
+ C64::new(0.0, 1.0/f64::sqrt(2.0)),
252
+ ]);
253
+
254
+ // Operator
255
+ let sigma_x = DMatrix::from_row_slice(2, 2, &[
256
+ C64::new(0.0, 0.0), C64::new(1.0, 0.0),
257
+ C64::new(1.0, 0.0), C64::new(0.0, 0.0),
258
+ ]);
259
+ ```
260
+
261
+ #### **num-complex** (v0.4+)
262
+ **Purpose:** Complex number arithmetic
263
+
264
+ **Justification:**
265
+ - Standard complex number implementation in Rust
266
+ - Integrates seamlessly with nalgebra
267
+ - Efficient operations with SIMD potential
268
+ - Supports polar form for phase representation
269
+
270
+ **Key Features:**
271
+ ```rust
272
+ use num_complex::Complex64;
273
+
274
+ // Rectangular form
275
+ let z1 = Complex64::new(1.0, 2.0);
276
+
277
+ // Polar form (for phase factors e^(iφ))
278
+ let z2 = Complex64::from_polar(1.0, std::f64::consts::PI / 4.0);
279
+
280
+ // Operations
281
+ let sum = z1 + z2;
282
+ let conj = z1.conj();
283
+ let norm = z1.norm();
284
+ ```
285
+
286
+ ### 2.2 Quantum Simulation Frameworks
287
+
288
+ #### **RustQIP** ⭐ RECOMMENDED
289
+ **GitHub:** https://github.com/Renmusxd/RustQIP
290
+
291
+ **Justification:**
292
+ - Most feature-complete quantum simulation library
293
+ - Leverages Rust's borrow checker to enforce no-cloning theorem
294
+ - Graph-based circuit building for optimization
295
+ - Active maintenance and community
296
+
297
+ **Key Features:**
298
+ - Quantum circuit builder with type-safe gate operations
299
+ - State vector simulation with efficient memory management
300
+ - Support for measurements and conditional operations
301
+ - Noise models for realistic simulations
302
+
303
+ **Example:**
304
+ ```rust
305
+ use qip::prelude::*;
306
+
307
+ let n_qubits = 2;
308
+ let mut b = OpBuilder::new();
309
+ let q = b.qubit(); // |0⟩
310
+
311
+ // Build quantum circuit
312
+ let q = b.hadamard(q);
313
+ let q = b.phase(q, std::f64::consts::PI / 4.0);
314
+
315
+ // Measure
316
+ let (_, measured) = b.measure(q);
317
+ ```
318
+
319
+ #### **q1tsim** (Alternative)
320
+ **Crates.io:** https://crates.io/crates/q1tsim
321
+
322
+ **Justification:**
323
+ - Simpler API, easier learning curve
324
+ - Efficient for small-scale simulations
325
+ - Good for educational purposes and prototyping
326
+
327
+ **Trade-offs:**
328
+ - Less feature-rich than RustQIP
329
+ - Smaller community
330
+ - Better for straightforward simulations
331
+
332
+ #### **Spinoza** (High Performance)
333
+ **GitHub:** https://github.com/QuState/spinoza
334
+
335
+ **Justification:**
336
+ - Pure Rust implementation with Python bindings
337
+ - Designed for performance
338
+ - Flexible and fast for classical simulation
339
+
340
+ **Use Cases:**
341
+ - Large-scale state vector simulations
342
+ - Performance-critical applications
343
+ - Hybrid quantum-classical algorithms
344
+
345
+ ### 2.3 SIMD Optimization Strategies
346
+
347
+ **Context:** Quantum state vectors scale as 2^n for n qubits. SIMD can provide 2-8× speedup for vector operations.
348
+
349
+ #### **rayon** (v1.8+) - Data Parallelism
350
+ ```rust
351
+ [dependencies]
352
+ rayon = "1.8"
353
+
354
+ use rayon::prelude::*;
355
+
356
+ // Parallel state vector operations
357
+ fn apply_gate_parallel(
358
+ state: &mut Vec<Complex64>,
359
+ gate: &Gate,
360
+ ) {
361
+ state.par_chunks_mut(2)
362
+ .for_each(|chunk| {
363
+ gate.apply_to_pair(chunk);
364
+ });
365
+ }
366
+ ```
367
+
368
+ #### **packed_simd2** - Explicit SIMD
369
+ ```rust
370
+ [dependencies]
371
+ packed_simd_2 = "0.3"
372
+
373
+ use packed_simd_2::*;
374
+
375
+ // SIMD complex multiplication
376
+ #[inline]
377
+ fn complex_mul_simd(a: f64x4, b: f64x4) -> f64x4 {
378
+ // a = [a.re, a.im, c.re, c.im]
379
+ // b = [b.re, b.im, d.re, d.im]
380
+ // Implements 2 complex multiplications in parallel
381
+ todo!("SIMD implementation")
382
+ }
383
+ ```
384
+
385
+ #### **SimSIMD** - Mixed Precision SIMD
386
+ **Library:** https://lib.rs/crates/simsimd
387
+
388
+ **Features:**
389
+ - 350+ SIMD-optimized kernels
390
+ - Dot products for complex vectors
391
+ - Ideal for quantum computing workloads
392
+ - Used in AI, search, and DBMS
393
+
394
+ **Application to Quantum:**
395
+ ```rust
396
+ // Inner products for quantum state overlap
397
+ // ⟨ψ|φ⟩ = Σ ψ_i* φ_i
398
+ fn quantum_inner_product(
399
+ psi: &[Complex64],
400
+ phi: &[Complex64],
401
+ ) -> Complex64 {
402
+ // Use SimSIMD for 4-8× speedup
403
+ todo!("SimSIMD integration")
404
+ }
405
+ ```
406
+
407
+ ### 2.4 Performance Comparison (2024 Data)
408
+
409
+ Based on available benchmarks and community reports:
410
+
411
+ | Library | State Vector Size | Performance | Memory | Use Case |
412
+ |---------|------------------|-------------|---------|----------|
413
+ | RustQIP | Up to 20 qubits | ⭐⭐⭐⭐ | Efficient | General purpose |
414
+ | q1tsim | Up to 15 qubits | ⭐⭐⭐ | Good | Education |
415
+ | Spinoza | Up to 25 qubits | ⭐⭐⭐⭐⭐ | Optimized | HPC |
416
+ | Raw nalgebra | Unlimited | ⭐⭐⭐ | Manual | Custom algorithms |
417
+
418
+ **Recommendation for Observer-Agnostic Experiment:**
419
+ - **Primary:** Raw nalgebra + num-complex (full control, matches research.md)
420
+ - **Validation:** RustQIP (cross-check against established library)
421
+ - **Optimization:** rayon for parallelism, consider SimSIMD for production
422
+
423
+ ---
424
+
425
+ ## 3. Experimental Design: Photonic Quantum Eraser
426
+
427
+ ### 3.1 Entangled Photon Generation via SPDC
428
+
429
+ **Spontaneous Parametric Down-Conversion (SPDC):**
430
+
431
+ **Process:**
432
+ - High-power UV pump laser (typically 405 nm) focused on nonlinear crystal
433
+ - Crystal material: Beta-Barium Borate (BBO) or Lithium Niobate (LN)
434
+ - Single pump photon → two lower-energy photons (signal + idler)
435
+ - Energy conservation: ω_pump = ω_signal + ω_idler
436
+ - Momentum conservation: k_pump = k_signal + k_idler
437
+
438
+ **Types of SPDC:**
439
+
440
+ 1. **Type-I SPDC:**
441
+ - Signal and idler have same polarization
442
+ - Perpendicular to pump polarization
443
+ - Simpler to implement
444
+ - Good for basic quantum eraser experiments
445
+
446
+ 2. **Type-II SPDC:**
447
+ - Signal and idler have orthogonal polarizations
448
+ - More complex setup
449
+ - Natural polarization entanglement
450
+ - Preferred for Observer-Agnostic experiment
451
+
452
+ **Laboratory Setup (2024 Standards):**
453
+
454
+ ```
455
+ Pump Laser (405 nm, 50-100 mW)
456
+
457
+ Focusing Optics (f = 50-100 mm)
458
+
459
+ BBO Crystal (Type-II, 1-2 mm thick)
460
+
461
+ Collimating Optics
462
+
463
+ Dichroic Mirror (separate pump from down-converted photons)
464
+
465
+ Signal (810 nm) ← HOM Beam Splitter → Idler (810 nm)
466
+ ```
467
+
468
+ **BBO Crystal Specifications:**
469
+ - Material: β-BaB₂O₄
470
+ - Type: Type-II phase matching
471
+ - Thickness: 1-2 mm (optimal for 405 nm → 810 nm)
472
+ - Cutting angle: Optimized for collinear or non-collinear emission
473
+ - AR coating: 405 nm and 810 nm
474
+
475
+ **Commercial Sources (2024):**
476
+ - Thorlabs: SPDC crystals and complete kits
477
+ - qutools: Integrated SPDC sources with alignment fixtures
478
+ - Typical cost: $5,000-$15,000 for complete SPDC source
479
+
480
+ **Entanglement Quality:**
481
+ - Coincidence rate: 1000-10,000 pairs/second (typical)
482
+ - Heralding efficiency: 50-80%
483
+ - Entanglement fidelity: >95% achievable
484
+ - Coherence time: Limited by pump laser coherence (~ns to μs)
485
+
486
+ ### 3.2 Interferometer Configurations
487
+
488
+ **Signal Interferometer:**
489
+ ```
490
+ Signal Photon
491
+
492
+ Beam Splitter 1 (50:50)
493
+
494
+ Path A → Phase Shifter φ
495
+ Path B → (Reference)
496
+
497
+ Beam Splitter 2 (50:50)
498
+
499
+ Detector D_0, D_1
500
+ ```
501
+
502
+ **Idler Measurement:**
503
+ ```
504
+ Idler Photon
505
+
506
+ [Switchable Measurement Basis]
507
+ ├─ Which-Path: Measure in |0⟩, |1⟩ basis
508
+ └─ Eraser: Insert Beam Splitter → Measure in |+⟩, |−⟩ basis
509
+
510
+ Detector D_A, D_B
511
+ ```
512
+
513
+ **Key Components:**
514
+
515
+ 1. **Beam Splitters:**
516
+ - 50:50 non-polarizing cube beam splitters
517
+ - Quality: >99% splitting ratio stability
518
+ - AR coated for 810 nm
519
+
520
+ 2. **Phase Shifter:**
521
+ - Piezo-mounted mirror or electrooptic modulator
522
+ - Range: 0 to 2π
523
+ - Resolution: <λ/100
524
+ - Stability: <λ/50 drift over measurement time
525
+
526
+ 3. **Detectors:**
527
+ - Single-photon avalanche diodes (SPADs)
528
+ - Quantum efficiency: >50% at 810 nm
529
+ - Dark count rate: <100 counts/second
530
+ - Timing resolution: <500 ps
531
+ - Examples: PerkinElmer SPCM-AQRH, Excelitas SPCM-AQ4C
532
+
533
+ 4. **Coincidence Electronics:**
534
+ - Time-tagging module or coincidence counter
535
+ - Resolution: ≤1 ns
536
+ - Examples: PicoQuant HydraHarp, Swabian Time Tagger
537
+
538
+ ### 3.3 Observer Control Mechanism
539
+
540
+ **Critical Feature for Observer-Agnostic Test:**
541
+
542
+ The experiment MUST implement three types of controllers for the idler basis choice:
543
+
544
+ **Controller Type 1: Human Observer**
545
+ ```
546
+ ┌─────────────────────────────┐
547
+ │ Human presses button │
548
+ │ "Which-Path" or "Eraser" │
549
+ └────────────┬────────────────┘
550
+
551
+ Optical Switch / Flip Mirror
552
+
553
+ Idler Measurement Path
554
+ ```
555
+
556
+ **Controller Type 2: Hardware Random Number Generator**
557
+ ```
558
+ ┌─────────────────────────────┐
559
+ │ Quantum RNG (e.g., IDQ) │
560
+ │ or Cryptographic RNG │
561
+ └────────────┬────────────────┘
562
+
563
+ Microcontroller Decision
564
+
565
+ Motorized Flip Mirror
566
+
567
+ Idler Measurement Path
568
+ ```
569
+
570
+ **Controller Type 3: Deterministic Timer**
571
+ ```
572
+ ┌─────────────────────────────┐
573
+ │ Scheduled Pattern: │
574
+ │ t < 30s: Which-Path │
575
+ │ t ≥ 30s: Eraser │
576
+ └────────────┬────────────────┘
577
+
578
+ Computer-Controlled Switch
579
+
580
+ Idler Measurement Path
581
+ ```
582
+
583
+ **Implementation Requirements:**
584
+ - Controller identity must be BLINDED in data file
585
+ - Timestamp all events (signal detection, idler detection, controller decision)
586
+ - Record all metadata (temperature, alignment, laser power)
587
+ - Randomize controller order across runs
588
+
589
+ ### 3.4 Statistical Analysis Methods
590
+
591
+ **Primary Test: Chi-Squared Test**
592
+
593
+ **Purpose:** Test if signal singles distribution differs across controller types
594
+
595
+ **Hypothesis:**
596
+ - H₀: p(signal=0) = 0.5 for all controller types (observer-agnostic)
597
+ - H₁: p(signal=0) ≠ 0.5 for at least one controller type
598
+
599
+ **Implementation:**
600
+ ```rust
601
+ use statrs::distribution::{ChiSquared, ContinuousCDF};
602
+
603
+ pub fn chi_squared_test(
604
+ observed: &[u64], // [counts_0, counts_1] for each controller
605
+ expected: &[u64], // Expected counts under H₀
606
+ ) -> (f64, f64) {
607
+ let chi_squared = observed.iter()
608
+ .zip(expected.iter())
609
+ .map(|(&obs, &exp)| {
610
+ let diff = obs as f64 - exp as f64;
611
+ diff * diff / exp as f64
612
+ })
613
+ .sum::<f64>();
614
+
615
+ let df = (observed.len() - 1) as f64;
616
+ let dist = ChiSquared::new(df).unwrap();
617
+ let p_value = 1.0 - dist.cdf(chi_squared);
618
+
619
+ (chi_squared, p_value)
620
+ }
621
+ ```
622
+
623
+ **Secondary Test: TOST (Two One-Sided Tests) for Equivalence**
624
+
625
+ **Purpose:** Prove that controller types produce equivalent results within ε = 5×10⁻⁴
626
+
627
+ **Hypothesis:**
628
+ - H₀: |Δp| ≥ ε (distributions differ)
629
+ - H₁: |Δp| < ε (distributions equivalent)
630
+
631
+ **Implementation:**
632
+ ```rust
633
+ pub fn tost_equivalence_test(
634
+ p_human: f64,
635
+ n_human: u64,
636
+ p_rng: f64,
637
+ n_rng: u64,
638
+ epsilon: f64, // Equivalence margin (e.g., 5e-4)
639
+ ) -> (f64, f64) {
640
+ // Standard error
641
+ let se = ((p_human * (1.0 - p_human) / n_human as f64) +
642
+ (p_rng * (1.0 - p_rng) / n_rng as f64)).sqrt();
643
+
644
+ // Test 1: p_human - p_rng < epsilon
645
+ let t1 = ((p_human - p_rng) - epsilon) / se;
646
+
647
+ // Test 2: p_human - p_rng > -epsilon
648
+ let t2 = ((p_human - p_rng) + epsilon) / se;
649
+
650
+ // Both must be significant for equivalence
651
+ let p1 = normal_cdf(t1);
652
+ let p2 = 1.0 - normal_cdf(t2);
653
+
654
+ (t1.max(t2), p1.max(p2))
655
+ }
656
+ ```
657
+
658
+ **Power Analysis:**
659
+
660
+ To detect Δp = 10⁻³ at α = 0.01 with power 0.9:
661
+
662
+ ```rust
663
+ pub fn required_sample_size(
664
+ effect_size: f64, // Δp
665
+ alpha: f64, // Type I error rate
666
+ power: f64, // 1 - β
667
+ ) -> u64 {
668
+ // Simplified formula for equal sample sizes
669
+ let z_alpha = normal_quantile(1.0 - alpha / 2.0);
670
+ let z_beta = normal_quantile(power);
671
+
672
+ let n = 2.0 * (z_alpha + z_beta).powi(2) / effect_size.powi(2);
673
+ n.ceil() as u64
674
+ }
675
+
676
+ // For Δp = 0.001, α = 0.01, power = 0.9:
677
+ // n ≈ 850,000 events per controller type
678
+ ```
679
+
680
+ ---
681
+
682
+ ## 4. Best Practices: Pre-Registration and Reproducibility
683
+
684
+ ### 4.1 Pre-Registration Protocols
685
+
686
+ **Why Pre-Register?**
687
+ - Prevents p-hacking and HARKing (Hypothesizing After Results are Known)
688
+ - Establishes credibility of null results
689
+ - Standard practice in psychology, medicine; emerging in physics
690
+
691
+ **2024 Status in Physics:**
692
+ - Condensed matter physics: International Conference on Reproducibility (NSF-supported)
693
+ - Quantum mechanics: Some groups pre-registering for controversial tests
694
+ - High-energy physics: Pre-registration implicit in theory → experiment workflow
695
+
696
+ **Pre-Registration Template for Observer-Agnostic Experiment:**
697
+
698
+ ```yaml
699
+ title: "Observer-Agnostic Measurement and No-Retrocausal Marginals Theorem"
700
+ preregistration_date: "YYYY-MM-DD"
701
+ expected_completion: "YYYY-MM-DD"
702
+
703
+ hypotheses:
704
+ primary:
705
+ h0: "Singles probability p(signal|controller) is independent of controller type"
706
+ h1: "Singles probability differs across controller types"
707
+ prediction: "Null result: |Δp| < 5×10⁻⁴"
708
+
709
+ secondary:
710
+ h0: "Duality relation V² + D² ≤ 1 holds for all controller types"
711
+ h1: "Duality violation for at least one controller type"
712
+
713
+ experimental_design:
714
+ apparatus: "Photonic quantum eraser with SPDC, Type-II BBO crystal"
715
+ controllers:
716
+ - type: "human"
717
+ implementation: "Button press interface"
718
+ - type: "hardware_rng"
719
+ implementation: "IDQ Quantis QRNG"
720
+ - type: "deterministic"
721
+ implementation: "Timer-based schedule"
722
+
723
+ blinding:
724
+ data_collection: "Controller identity encoded, revealed only after analysis"
725
+ analysis: "Automated scripts with pre-defined thresholds"
726
+
727
+ randomization: "Controller order randomized per run, balanced across sessions"
728
+
729
+ sample_size:
730
+ calculation:
731
+ effect_size: 0.001
732
+ alpha: 0.01
733
+ power: 0.9
734
+ required_n_per_controller: 850000
735
+
736
+ stopping_rule:
737
+ type: "fixed_n"
738
+ justification: "Pre-computed sample size, no interim analyses"
739
+
740
+ statistical_analysis:
741
+ primary_test:
742
+ method: "Chi-squared test"
743
+ significance_level: 0.01
744
+ adjustment: "Bonferroni for 3 pairwise comparisons"
745
+
746
+ secondary_test:
747
+ method: "TOST equivalence test"
748
+ equivalence_margin: 5e-4
749
+ justification: "Instrument resolution limit"
750
+
751
+ exclusion_criteria:
752
+ - "Coincidence window > 2 ns (temporal mismatch)"
753
+ - "Dark count rate > 200 counts/s (detector malfunction)"
754
+ - "Laser power drift > 5% (stability issue)"
755
+ - "Temperature change > 2°C (thermal drift)"
756
+
757
+ falsification_criteria:
758
+ - "χ² test p-value < 0.01 AND |Δp| > 5×10⁻⁴ (reproducible across 3+ runs)"
759
+ - "Duality violation: V² + D² > 1.01 with error bars excluding 1.0"
760
+ - "Retrocausal signal: Correlation between delayed choice and earlier singles"
761
+
762
+ data_sharing:
763
+ repository: "Zenodo / OSF / arXiv"
764
+ format: "HDF5 with metadata, CSV summaries"
765
+ code: "GitHub repository with analysis scripts"
766
+ license: "MIT / CC-BY-4.0"
767
+ ```
768
+
769
+ ### 4.2 Reproducibility Standards
770
+
771
+ **Data Formats:**
772
+
773
+ ```rust
774
+ // HDF5 for raw data
775
+ [dependencies]
776
+ hdf5 = "0.8"
777
+
778
+ pub struct ExperimentalData {
779
+ pub timestamp: Vec<f64>, // Event time (ns)
780
+ pub signal_detector: Vec<u8>, // 0 or 1
781
+ pub idler_detector: Vec<u8>, // 0 or 1
782
+ pub controller_type: Vec<u8>, // Blinded: 1, 2, or 3
783
+ pub phase_setting: Vec<f64>, // Phase φ (radians)
784
+ pub laser_power: Vec<f32>, // mW
785
+ pub temperature: Vec<f32>, // °C
786
+ }
787
+
788
+ impl ExperimentalData {
789
+ pub fn save_hdf5(&self, path: &Path) -> Result<()> {
790
+ let file = hdf5::File::create(path)?;
791
+ file.new_dataset::<f64>()
792
+ .create("timestamp", self.timestamp.len())?
793
+ .write(&self.timestamp)?;
794
+ // ... save other fields
795
+ Ok(())
796
+ }
797
+ }
798
+ ```
799
+
800
+ **Code Archiving:**
801
+
802
+ ```toml
803
+ # Cargo.toml for reproducible builds
804
+ [package]
805
+ name = "observer-invariance"
806
+ version = "1.0.0"
807
+ edition = "2021"
808
+
809
+ # Pin all dependencies for reproducibility
810
+ [dependencies]
811
+ nalgebra = "=0.32.3"
812
+ num-complex = "=0.4.4"
813
+ statrs = "=0.16.0"
814
+ hdf5 = "=0.8.1"
815
+ plotters = "=0.3.5"
816
+
817
+ # Include data processing scripts
818
+ [[bin]]
819
+ name = "analyze"
820
+ path = "src/bin/analyze.rs"
821
+ ```
822
+
823
+ **Docker Container:**
824
+
825
+ ```dockerfile
826
+ # Reproducible analysis environment
827
+ FROM rust:1.75
828
+
829
+ RUN apt-get update && apt-get install -y \
830
+ libhdf5-dev \
831
+ python3-pip
832
+
833
+ COPY . /experiment
834
+ WORKDIR /experiment
835
+
836
+ RUN cargo build --release
837
+ RUN pip3 install numpy matplotlib jupyter
838
+
839
+ CMD ["cargo", "run", "--release", "--bin", "analyze"]
840
+ ```
841
+
842
+ ### 4.3 Error Analysis and Uncertainty Quantification
843
+
844
+ **Sources of Uncertainty:**
845
+
846
+ 1. **Photon Statistics (Poisson):**
847
+ ```rust
848
+ pub fn poisson_error(counts: u64) -> f64 {
849
+ (counts as f64).sqrt()
850
+ }
851
+ ```
852
+
853
+ 2. **Detector Efficiency:**
854
+ - Systematic: Calibrate against known source (±1-2%)
855
+ - Statistical: Bootstrap resampling
856
+
857
+ 3. **Alignment Drift:**
858
+ - Thermal: Monitor temperature, correct for drift
859
+ - Mechanical: Stabilize on optical table, vibration isolation
860
+
861
+ 4. **Background Counts:**
862
+ ```rust
863
+ pub fn signal_to_noise_ratio(signal: u64, background: u64, time: f64) -> f64 {
864
+ signal as f64 / (background as f64 * time).sqrt()
865
+ }
866
+ ```
867
+
868
+ **Monte Carlo Uncertainty Propagation:**
869
+
870
+ ```rust
871
+ use rand::thread_rng;
872
+ use rand_distr::{Normal, Distribution};
873
+
874
+ pub fn monte_carlo_error_propagation(
875
+ measured_p: f64,
876
+ n_samples: u64,
877
+ systematic_error: f64,
878
+ n_simulations: usize,
879
+ ) -> f64 {
880
+ let mut rng = thread_rng();
881
+ let dist = Normal::new(measured_p, systematic_error).unwrap();
882
+
883
+ let simulated: Vec<f64> = (0..n_simulations)
884
+ .map(|_| {
885
+ let p = dist.sample(&mut rng).max(0.0).min(1.0);
886
+ // Simulate binomial sampling
887
+ let successes: u64 = (0..n_samples)
888
+ .filter(|_| rng.gen::<f64>() < p)
889
+ .count() as u64;
890
+ successes as f64 / n_samples as f64
891
+ })
892
+ .collect();
893
+
894
+ // Standard deviation of simulated values
895
+ let mean = simulated.iter().sum::<f64>() / simulated.len() as f64;
896
+ let variance = simulated.iter()
897
+ .map(|&x| (x - mean).powi(2))
898
+ .sum::<f64>() / simulated.len() as f64;
899
+
900
+ variance.sqrt()
901
+ }
902
+ ```
903
+
904
+ ### 4.4 Falsification Criteria
905
+
906
+ **What Would Falsify the Theorem?**
907
+
908
+ 1. **Reproducible Controller Effect:**
909
+ - Condition: χ² test p < 0.01 AND |Δp| > 5×10⁻⁴
910
+ - Requirement: Replicated in 3+ independent runs
911
+ - Controls: Same apparatus, different operators
912
+
913
+ 2. **Duality Violation:**
914
+ - Condition: V² + D² > 1.0 + 3σ
915
+ - Requirement: Systematic, not due to misalignment
916
+ - Calibration: Verify with known coherent/incoherent sources
917
+
918
+ 3. **Retrocausal Signal:**
919
+ - Condition: Correlation between delayed idler choice and already-recorded signal singles
920
+ - Test: Time-resolved analysis with varying delay
921
+ - Control: Verify with dummy "random" controller (recorded, not causal)
922
+
923
+ **What Would NOT Falsify:**
924
+ - Single anomalous run (could be systematic error)
925
+ - Small effects comparable to drift (need better apparatus)
926
+ - Effects that disappear with better blinding (expectation bias)
927
+
928
+ ---
929
+
930
+ ## 5. Implementation Considerations: Scientific Rust Projects
931
+
932
+ ### 5.1 Project Structure
933
+
934
+ **Recommended Layout:**
935
+
936
+ ```
937
+ observer-invariance/
938
+ ├── Cargo.toml # Main manifest
939
+ ├── Cargo.lock # Lock file (commit for reproducibility)
940
+ ├── README.md # Project overview
941
+ ├── LICENSE # MIT or Apache-2.0
942
+
943
+ ├── src/
944
+ │ ├── lib.rs # Public API
945
+ │ ├── math.rs # Linear algebra utilities
946
+ │ ├── quantum.rs # Quantum state operations
947
+ │ ├── eraser.rs # Delayed-choice eraser simulation
948
+ │ ├── duality.rs # V² + D² ≤ 1 verification
949
+ │ ├── statistics.rs # Chi-squared, TOST, power analysis
950
+ │ ├── io.rs # Data import/export (HDF5, CSV)
951
+ │ └── bin/
952
+ │ ├── simulate.rs # Main simulation CLI
953
+ │ ├── analyze.rs # Data analysis CLI
954
+ │ └── visualize.rs # Plotting CLI
955
+
956
+ ├── tests/
957
+ │ ├── integration_tests.rs # End-to-end tests
958
+ │ ├── invariance_tests.rs # Observer-agnostic tests
959
+ │ ├── duality_tests.rs # Complementarity tests
960
+ │ └── statistical_tests.rs # Statistics validation
961
+
962
+ ├── benches/
963
+ │ ├── simulation.rs # Benchmark state evolution
964
+ │ └── analysis.rs # Benchmark statistical tests
965
+
966
+ ├── examples/
967
+ │ ├── basic_eraser.rs # Simple quantum eraser
968
+ │ ├── scan_phase.rs # φ sweep for fringes
969
+ │ └── controller_comparison.rs # Compare controller types
970
+
971
+ ├── data/
972
+ │ ├── raw/ # Experimental data (gitignored if large)
973
+ │ ├── processed/ # Analysis outputs
974
+ │ └── simulated/ # Simulation outputs
975
+
976
+ ├── docs/
977
+ │ ├── theory.md # Theorem and predictions
978
+ │ ├── implementation.md # Code documentation
979
+ │ └── analysis_protocol.md # Statistical analysis plan
980
+
981
+ └── scripts/
982
+ ├── preprocess.py # Optional: Python preprocessing
983
+ ├── plot_results.py # Matplotlib visualizations
984
+ └── generate_report.sh # Automated reporting
985
+ ```
986
+
987
+ **Cargo.toml Example:**
988
+
989
+ ```toml
990
+ [package]
991
+ name = "observer-invariance"
992
+ version = "0.1.0"
993
+ edition = "2021"
994
+ authors = ["Your Name <email@example.com>"]
995
+ license = "MIT OR Apache-2.0"
996
+ description = "Observer-Agnostic Quantum Measurement Simulation and Analysis"
997
+ repository = "https://github.com/user/observer-invariance"
998
+ keywords = ["quantum", "measurement", "delayed-choice", "quantum-eraser"]
999
+ categories = ["science", "simulation"]
1000
+
1001
+ [lib]
1002
+ name = "observer_invariance"
1003
+ path = "src/lib.rs"
1004
+
1005
+ [[bin]]
1006
+ name = "simulate"
1007
+ path = "src/bin/simulate.rs"
1008
+
1009
+ [[bin]]
1010
+ name = "analyze"
1011
+ path = "src/bin/analyze.rs"
1012
+
1013
+ [dependencies]
1014
+ # Core math
1015
+ nalgebra = "0.32"
1016
+ num-complex = "0.4"
1017
+
1018
+ # Random number generation
1019
+ rand = "0.8"
1020
+ rand_chacha = "0.3" # Deterministic RNG for tests
1021
+
1022
+ # Statistics
1023
+ statrs = "0.16"
1024
+
1025
+ # CLI
1026
+ clap = { version = "4.5", features = ["derive"] }
1027
+
1028
+ # Data formats
1029
+ serde = { version = "1.0", features = ["derive"] }
1030
+ serde_json = "1.0"
1031
+ csv = "1.3"
1032
+ hdf5 = { version = "0.8", optional = true } # Large data
1033
+
1034
+ # Visualization
1035
+ plotters = "0.3"
1036
+
1037
+ # Utilities
1038
+ anyhow = "1.0"
1039
+ thiserror = "1.0"
1040
+
1041
+ [dev-dependencies]
1042
+ approx = "0.5" # Floating-point comparisons
1043
+ proptest = "1.4" # Property-based testing
1044
+ criterion = { version = "0.5", features = ["html_reports"] }
1045
+
1046
+ [features]
1047
+ default = ["hdf5-io"]
1048
+ hdf5-io = ["hdf5"]
1049
+
1050
+ [profile.release]
1051
+ opt-level = 3
1052
+ lto = "fat"
1053
+ codegen-units = 1
1054
+
1055
+ [profile.bench]
1056
+ inherits = "release"
1057
+ ```
1058
+
1059
+ ### 5.2 Testing Strategies for Quantum Simulations
1060
+
1061
+ **Unit Tests: Verify Mathematical Correctness**
1062
+
1063
+ ```rust
1064
+ #[cfg(test)]
1065
+ mod tests {
1066
+ use super::*;
1067
+ use approx::assert_abs_diff_eq;
1068
+
1069
+ #[test]
1070
+ fn test_born_rule_normalization() {
1071
+ let psi = DVector::from_vec(vec![
1072
+ C64::new(0.6, 0.0),
1073
+ C64::new(0.8, 0.0),
1074
+ ]);
1075
+ let rho = density_matrix(&psi);
1076
+
1077
+ let p0 = born_probability(&rho, &projector(&ket0()));
1078
+ let p1 = born_probability(&rho, &projector(&ket1()));
1079
+
1080
+ // Probabilities must sum to 1
1081
+ assert_abs_diff_eq!(p0 + p1, 1.0, epsilon = 1e-12);
1082
+ }
1083
+
1084
+ #[test]
1085
+ fn test_partial_trace_identity() {
1086
+ // Tr_B(|00⟩⟨00|) = |0⟩⟨0|
1087
+ let psi = kron(&ket0(), &ket0());
1088
+ let rho = density_matrix(&psi);
1089
+ let rho_a = partial_trace_second(&rho);
1090
+
1091
+ let expected = projector(&ket0());
1092
+ assert_matrix_approx_eq(&rho_a, &expected, 1e-12);
1093
+ }
1094
+
1095
+ #[test]
1096
+ fn test_duality_relation() {
1097
+ for gamma in [0.0, 0.3, 0.5, 0.8, 1.0] {
1098
+ let (v, d) = visibility_distinguishability(gamma);
1099
+ assert!(v >= 0.0 && v <= 1.0);
1100
+ assert!(d >= 0.0 && d <= 1.0);
1101
+ assert_abs_diff_eq!(v.powi(2) + d.powi(2), 1.0, epsilon = 1e-10);
1102
+ }
1103
+ }
1104
+ }
1105
+ ```
1106
+
1107
+ **Property-Based Tests: Verify Physical Laws**
1108
+
1109
+ ```rust
1110
+ use proptest::prelude::*;
1111
+
1112
+ proptest! {
1113
+ #[test]
1114
+ fn prop_unitary_preserves_norm(
1115
+ theta in 0.0..std::f64::consts::TAU,
1116
+ phi in 0.0..std::f64::consts::TAU,
1117
+ ) {
1118
+ let psi_initial = arbitrary_qubit_state(theta, phi);
1119
+ let u = arbitrary_unitary();
1120
+ let psi_final = u * &psi_initial;
1121
+
1122
+ let norm_initial = psi_initial.norm();
1123
+ let norm_final = psi_final.norm();
1124
+
1125
+ prop_assert!((norm_initial - norm_final).abs() < 1e-10);
1126
+ }
1127
+
1128
+ #[test]
1129
+ fn prop_measurement_probabilities_sum_to_one(
1130
+ theta in 0.0..std::f64::consts::TAU,
1131
+ phi in 0.0..std::f64::consts::TAU,
1132
+ ) {
1133
+ let psi = arbitrary_qubit_state(theta, phi);
1134
+ let rho = density_matrix(&psi);
1135
+
1136
+ let p0 = born_probability(&rho, &projector(&ket0()));
1137
+ let p1 = born_probability(&rho, &projector(&ket1()));
1138
+
1139
+ prop_assert!((p0 + p1 - 1.0).abs() < 1e-10);
1140
+ }
1141
+
1142
+ #[test]
1143
+ fn prop_singles_invariant_under_idler_basis(
1144
+ phi in 0.0..std::f64::consts::TAU,
1145
+ ) {
1146
+ let eraser = QuantumEraser { phi };
1147
+
1148
+ let singles = eraser.singles_probability();
1149
+
1150
+ // Must be 0.5, 0.5 regardless of φ
1151
+ prop_assert!((singles[0] - 0.5).abs() < 1e-10);
1152
+ prop_assert!((singles[1] - 0.5).abs() < 1e-10);
1153
+ }
1154
+ }
1155
+ ```
1156
+
1157
+ **Integration Tests: End-to-End Simulation**
1158
+
1159
+ ```rust
1160
+ // tests/integration_tests.rs
1161
+ use observer_invariance::*;
1162
+
1163
+ #[test]
1164
+ fn test_complete_quantum_eraser_workflow() {
1165
+ // Setup
1166
+ let n_runs = 10000;
1167
+ let phi_values = linspace(0.0, 2.0 * PI, 32);
1168
+
1169
+ // Simulate with different controllers
1170
+ let controllers = vec![
1171
+ Controller::Human,
1172
+ Controller::HardwareRNG,
1173
+ Controller::Deterministic,
1174
+ ];
1175
+
1176
+ for controller in controllers {
1177
+ let mut singles_histogram = vec![0u64; 2];
1178
+
1179
+ for _ in 0..n_runs {
1180
+ let phi = *phi_values.choose(&mut rand::thread_rng()).unwrap();
1181
+ let eraser = QuantumEraser::new(phi);
1182
+
1183
+ // Simulate measurement
1184
+ let signal_outcome = eraser.measure_signal();
1185
+ singles_histogram[signal_outcome] += 1;
1186
+ }
1187
+
1188
+ // Verify singles are 50-50
1189
+ let p0 = singles_histogram[0] as f64 / n_runs as f64;
1190
+ let p1 = singles_histogram[1] as f64 / n_runs as f64;
1191
+
1192
+ assert!((p0 - 0.5).abs() < 0.01, "Controller {:?} failed", controller);
1193
+ assert!((p1 - 0.5).abs() < 0.01, "Controller {:?} failed", controller);
1194
+ }
1195
+ }
1196
+ ```
1197
+
1198
+ **Benchmark Tests: Performance Validation**
1199
+
1200
+ ```rust
1201
+ // benches/simulation.rs
1202
+ use criterion::{black_box, criterion_group, criterion_main, Criterion};
1203
+
1204
+ fn bench_quantum_state_evolution(c: &mut Criterion) {
1205
+ let mut group = c.benchmark_group("state_evolution");
1206
+
1207
+ group.bench_function("bell_state_creation", |b| {
1208
+ b.iter(|| {
1209
+ let eraser = QuantumEraser::new(black_box(1.0));
1210
+ black_box(eraser.bell_state_with_phase());
1211
+ });
1212
+ });
1213
+
1214
+ group.bench_function("partial_trace", |b| {
1215
+ let eraser = QuantumEraser::new(1.0);
1216
+ let psi = eraser.bell_state_with_phase();
1217
+ let rho = density_matrix(&psi);
1218
+
1219
+ b.iter(|| {
1220
+ black_box(partial_trace_second(&rho));
1221
+ });
1222
+ });
1223
+
1224
+ group.finish();
1225
+ }
1226
+
1227
+ criterion_group!(benches, bench_quantum_state_evolution);
1228
+ criterion_main!(benches);
1229
+ ```
1230
+
1231
+ ### 5.3 Visualization Tools
1232
+
1233
+ **plotters Crate (Recommended)**
1234
+
1235
+ ```rust
1236
+ use plotters::prelude::*;
1237
+
1238
+ pub fn plot_interference_pattern(
1239
+ phi_values: &[f64],
1240
+ probabilities: &[f64],
1241
+ output_path: &Path,
1242
+ ) -> Result<()> {
1243
+ let root = BitMapBackend::new(output_path, (800, 600)).into_drawing_area();
1244
+ root.fill(&WHITE)?;
1245
+
1246
+ let mut chart = ChartBuilder::on(&root)
1247
+ .caption("Quantum Eraser: Conditional Probabilities", ("sans-serif", 40))
1248
+ .margin(10)
1249
+ .x_label_area_size(40)
1250
+ .y_label_area_size(50)
1251
+ .build_cartesian_2d(0.0..2.0 * PI, 0.0..1.0)?;
1252
+
1253
+ chart.configure_mesh()
1254
+ .x_desc("Phase φ (radians)")
1255
+ .y_desc("Probability p(signal|idler)")
1256
+ .draw()?;
1257
+
1258
+ chart.draw_series(LineSeries::new(
1259
+ phi_values.iter().zip(probabilities).map(|(x, y)| (*x, *y)),
1260
+ &BLUE,
1261
+ ))?;
1262
+
1263
+ root.present()?;
1264
+ Ok(())
1265
+ }
1266
+
1267
+ pub fn plot_duality_relation(
1268
+ visibility: &[f64],
1269
+ distinguishability: &[f64],
1270
+ output_path: &Path,
1271
+ ) -> Result<()> {
1272
+ // Plot V² + D² vs parameter
1273
+ // Expected: constant line at 1.0
1274
+ todo!("Implementation")
1275
+ }
1276
+ ```
1277
+
1278
+ **Alternative: Python Integration**
1279
+
1280
+ ```rust
1281
+ // Generate CSV, plot with matplotlib (more features)
1282
+ pub fn export_for_python(data: &SimulationResults, path: &Path) -> Result<()> {
1283
+ let mut wtr = csv::Writer::from_path(path)?;
1284
+ wtr.write_record(&["phi", "p0", "p1", "controller"])?;
1285
+
1286
+ for (phi, p0, p1, controller) in data.iter() {
1287
+ wtr.write_record(&[
1288
+ phi.to_string(),
1289
+ p0.to_string(),
1290
+ p1.to_string(),
1291
+ controller.to_string(),
1292
+ ])?;
1293
+ }
1294
+
1295
+ wtr.flush()?;
1296
+ Ok(())
1297
+ }
1298
+ ```
1299
+
1300
+ ```python
1301
+ # scripts/plot_results.py
1302
+ import pandas as pd
1303
+ import matplotlib.pyplot as plt
1304
+ import numpy as np
1305
+
1306
+ def plot_quantum_eraser(csv_path):
1307
+ df = pd.read_csv(csv_path)
1308
+
1309
+ fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
1310
+
1311
+ # Singles distribution
1312
+ for controller in df['controller'].unique():
1313
+ subset = df[df['controller'] == controller]
1314
+ ax1.scatter(subset['phi'], subset['p0'],
1315
+ label=f'Controller: {controller}', alpha=0.6)
1316
+
1317
+ ax1.axhline(0.5, color='red', linestyle='--', label='Prediction')
1318
+ ax1.set_xlabel('Phase φ')
1319
+ ax1.set_ylabel('p(signal=0)')
1320
+ ax1.set_title('Singles Probability (Observer-Agnostic)')
1321
+ ax1.legend()
1322
+
1323
+ # Conditional fringes
1324
+ # (requires separate data for conditioning)
1325
+
1326
+ plt.tight_layout()
1327
+ plt.savefig('quantum_eraser_results.png', dpi=300)
1328
+ ```
1329
+
1330
+ ### 5.4 Documentation Standards
1331
+
1332
+ **Module-Level Documentation:**
1333
+
1334
+ ```rust
1335
+ //! # Quantum Eraser Simulation
1336
+ //!
1337
+ //! This module implements the delayed-choice quantum eraser experiment
1338
+ //! as described in the Observer-Agnostic Measurement Theorem.
1339
+ //!
1340
+ //! ## Theory
1341
+ //!
1342
+ //! The quantum eraser uses entangled photon pairs:
1343
+ //! ```text
1344
+ //! |ψ⟩ = (1/√2)(|00⟩ + e^(iφ)|11⟩)
1345
+ //! ```
1346
+ //!
1347
+ //! ## Key Predictions
1348
+ //!
1349
+ //! 1. Singles probability p(signal) = 0.5 for all φ, regardless of idler measurement
1350
+ //! 2. Conditional probability p(signal|idler) shows interference for eraser basis
1351
+ //! 3. No retrocausal effects: delayed idler choice doesn't affect signal singles
1352
+ //!
1353
+ //! ## Example
1354
+ //!
1355
+ //! ```rust
1356
+ //! use observer_invariance::QuantumEraser;
1357
+ //!
1358
+ //! let eraser = QuantumEraser::new(std::f64::consts::PI / 4.0);
1359
+ //! let singles = eraser.singles_probability();
1360
+ //! assert!((singles[0] - 0.5).abs() < 1e-10);
1361
+ //! ```
1362
+
1363
+ pub mod eraser;
1364
+ ```
1365
+
1366
+ **Function-Level Documentation:**
1367
+
1368
+ ```rust
1369
+ /// Calculate the probability of measurement outcome using Born rule.
1370
+ ///
1371
+ /// Given a quantum state ρ and a measurement operator M (POVM element),
1372
+ /// computes p = Tr(M ρ).
1373
+ ///
1374
+ /// # Arguments
1375
+ ///
1376
+ /// * `state` - Density matrix ρ representing the quantum state
1377
+ /// * `measurement` - POVM element M (positive semi-definite)
1378
+ ///
1379
+ /// # Returns
1380
+ ///
1381
+ /// Probability in [0, 1]. Values outside this range are clamped.
1382
+ ///
1383
+ /// # Example
1384
+ ///
1385
+ /// ```rust
1386
+ /// let rho = density_matrix(&ket0());
1387
+ /// let p0 = born_probability(&rho, &projector(&ket0()));
1388
+ /// assert!((p0 - 1.0).abs() < 1e-10);
1389
+ /// ```
1390
+ ///
1391
+ /// # Panics
1392
+ ///
1393
+ /// Panics if matrix dimensions are incompatible.
1394
+ pub fn born_probability(
1395
+ state: &DMatrix<C64>,
1396
+ measurement: &DMatrix<C64>,
1397
+ ) -> f64 {
1398
+ // Implementation...
1399
+ }
1400
+ ```
1401
+
1402
+ **README.md Structure:**
1403
+
1404
+ ```markdown
1405
+ # Observer-Agnostic Measurement Simulation
1406
+
1407
+ Rust implementation of the Observer-Agnostic Measurement and No-Retrocausal Marginals Theorem.
1408
+
1409
+ ## Installation
1410
+
1411
+ ```bash
1412
+ cargo build --release
1413
+ ```
1414
+
1415
+ ## Usage
1416
+
1417
+ ### Simulation
1418
+
1419
+ ```bash
1420
+ cargo run --release --bin simulate -- --phi-steps 64 --output eraser.csv
1421
+ ```
1422
+
1423
+ ### Analysis
1424
+
1425
+ ```bash
1426
+ cargo run --release --bin analyze -- --input experimental_data.hdf5
1427
+ ```
1428
+
1429
+ ### Visualization
1430
+
1431
+ ```bash
1432
+ python scripts/plot_results.py eraser.csv
1433
+ ```
1434
+
1435
+ ## Project Structure
1436
+
1437
+ - `src/math.rs` - Linear algebra utilities
1438
+ - `src/eraser.rs` - Quantum eraser simulation
1439
+ - `src/statistics.rs` - Statistical tests
1440
+
1441
+ ## Testing
1442
+
1443
+ ```bash
1444
+ cargo test
1445
+ cargo test --release # For property-based tests (slower)
1446
+ cargo bench # Performance benchmarks
1447
+ ```
1448
+
1449
+ ## Citation
1450
+
1451
+ If you use this code, please cite:
1452
+
1453
+ ```bibtex
1454
+ @article{observer-agnostic-2024,
1455
+ title={Observer-Agnostic Measurement and No-Retrocausal Marginals},
1456
+ author={...},
1457
+ year={2024}
1458
+ }
1459
+ ```
1460
+
1461
+ ## License
1462
+
1463
+ MIT OR Apache-2.0
1464
+ ```
1465
+
1466
+ ---
1467
+
1468
+ ## 6. Code Patterns for Quantum State Manipulation
1469
+
1470
+ ### 6.1 State Vector Operations
1471
+
1472
+ ```rust
1473
+ use nalgebra::{DVector, DMatrix};
1474
+ use num_complex::Complex64 as C64;
1475
+
1476
+ /// Computational basis states
1477
+ pub fn ket0() -> DVector<C64> {
1478
+ DVector::from_vec(vec![C64::new(1.0, 0.0), C64::new(0.0, 0.0)])
1479
+ }
1480
+
1481
+ pub fn ket1() -> DVector<C64> {
1482
+ DVector::from_vec(vec![C64::new(0.0, 0.0), C64::new(1.0, 0.0)])
1483
+ }
1484
+
1485
+ /// Superposition states
1486
+ pub fn ket_plus() -> DVector<C64> {
1487
+ let s = 1.0 / 2.0_f64.sqrt();
1488
+ DVector::from_vec(vec![C64::new(s, 0.0), C64::new(s, 0.0)])
1489
+ }
1490
+
1491
+ pub fn ket_minus() -> DVector<C64> {
1492
+ let s = 1.0 / 2.0_f64.sqrt();
1493
+ DVector::from_vec(vec![C64::new(s, 0.0), C64::new(-s, 0.0)])
1494
+ }
1495
+
1496
+ /// Arbitrary qubit state: |ψ⟩ = cos(θ/2)|0⟩ + e^(iφ)sin(θ/2)|1⟩
1497
+ pub fn bloch_sphere_state(theta: f64, phi: f64) -> DVector<C64> {
1498
+ DVector::from_vec(vec![
1499
+ C64::new((theta / 2.0).cos(), 0.0),
1500
+ C64::from_polar((theta / 2.0).sin(), phi),
1501
+ ])
1502
+ }
1503
+
1504
+ /// Normalize state vector
1505
+ pub fn normalize(psi: &mut DVector<C64>) {
1506
+ let norm = psi.norm();
1507
+ if norm > 1e-15 {
1508
+ *psi /= norm;
1509
+ }
1510
+ }
1511
+
1512
+ /// Inner product: ⟨ψ|φ⟩
1513
+ pub fn inner_product(psi: &DVector<C64>, phi: &DVector<C64>) -> C64 {
1514
+ psi.dotc(phi)
1515
+ }
1516
+
1517
+ /// Density matrix from pure state: ρ = |ψ⟩⟨ψ|
1518
+ pub fn density_matrix(psi: &DVector<C64>) -> DMatrix<C64> {
1519
+ let n = psi.len();
1520
+ let mut rho = DMatrix::zeros(n, n);
1521
+ for i in 0..n {
1522
+ for j in 0..n {
1523
+ rho[(i, j)] = psi[i] * psi[j].conj();
1524
+ }
1525
+ }
1526
+ rho
1527
+ }
1528
+
1529
+ /// Projector: P = |ψ⟩⟨ψ|
1530
+ pub fn projector(psi: &DVector<C64>) -> DMatrix<C64> {
1531
+ density_matrix(psi)
1532
+ }
1533
+ ```
1534
+
1535
+ ### 6.2 Quantum Gates and Operators
1536
+
1537
+ ```rust
1538
+ /// Pauli matrices
1539
+ pub fn sigma_x() -> DMatrix<C64> {
1540
+ DMatrix::from_row_slice(2, 2, &[
1541
+ C64::new(0.0, 0.0), C64::new(1.0, 0.0),
1542
+ C64::new(1.0, 0.0), C64::new(0.0, 0.0),
1543
+ ])
1544
+ }
1545
+
1546
+ pub fn sigma_y() -> DMatrix<C64> {
1547
+ DMatrix::from_row_slice(2, 2, &[
1548
+ C64::new(0.0, 0.0), C64::new(0.0, -1.0),
1549
+ C64::new(0.0, 1.0), C64::new(0.0, 0.0),
1550
+ ])
1551
+ }
1552
+
1553
+ pub fn sigma_z() -> DMatrix<C64> {
1554
+ DMatrix::from_row_slice(2, 2, &[
1555
+ C64::new(1.0, 0.0), C64::new(0.0, 0.0),
1556
+ C64::new(0.0, 0.0), C64::new(-1.0, 0.0),
1557
+ ])
1558
+ }
1559
+
1560
+ /// Hadamard gate: H = (1/√2)[1 1; 1 -1]
1561
+ pub fn hadamard() -> DMatrix<C64> {
1562
+ let s = 1.0 / 2.0_f64.sqrt();
1563
+ DMatrix::from_row_slice(2, 2, &[
1564
+ C64::new(s, 0.0), C64::new(s, 0.0),
1565
+ C64::new(s, 0.0), C64::new(-s, 0.0),
1566
+ ])
1567
+ }
1568
+
1569
+ /// Phase gate: P(φ) = [1 0; 0 e^(iφ)]
1570
+ pub fn phase_gate(phi: f64) -> DMatrix<C64> {
1571
+ DMatrix::from_row_slice(2, 2, &[
1572
+ C64::new(1.0, 0.0), C64::new(0.0, 0.0),
1573
+ C64::new(0.0, 0.0), C64::from_polar(1.0, phi),
1574
+ ])
1575
+ }
1576
+
1577
+ /// Rotation gates
1578
+ pub fn rotation_x(theta: f64) -> DMatrix<C64> {
1579
+ let c = (theta / 2.0).cos();
1580
+ let s = (theta / 2.0).sin();
1581
+ DMatrix::from_row_slice(2, 2, &[
1582
+ C64::new(c, 0.0), C64::new(0.0, -s),
1583
+ C64::new(0.0, -s), C64::new(c, 0.0),
1584
+ ])
1585
+ }
1586
+
1587
+ pub fn rotation_y(theta: f64) -> DMatrix<C64> {
1588
+ let c = (theta / 2.0).cos();
1589
+ let s = (theta / 2.0).sin();
1590
+ DMatrix::from_row_slice(2, 2, &[
1591
+ C64::new(c, 0.0), C64::new(-s, 0.0),
1592
+ C64::new(s, 0.0), C64::new(c, 0.0),
1593
+ ])
1594
+ }
1595
+
1596
+ pub fn rotation_z(theta: f64) -> DMatrix<C64> {
1597
+ DMatrix::from_row_slice(2, 2, &[
1598
+ C64::from_polar(1.0, -theta / 2.0), C64::new(0.0, 0.0),
1599
+ C64::new(0.0, 0.0), C64::from_polar(1.0, theta / 2.0),
1600
+ ])
1601
+ }
1602
+ ```
1603
+
1604
+ ### 6.3 Tensor Products and Entanglement
1605
+
1606
+ ```rust
1607
+ /// Kronecker product: A ⊗ B
1608
+ pub fn kron(a: &DMatrix<C64>, b: &DMatrix<C64>) -> DMatrix<C64> {
1609
+ let (ar, ac) = a.shape();
1610
+ let (br, bc) = b.shape();
1611
+ let mut out = DMatrix::zeros(ar * br, ac * bc);
1612
+
1613
+ for i in 0..ar {
1614
+ for j in 0..ac {
1615
+ let aij = a[(i, j)];
1616
+ for k in 0..br {
1617
+ for l in 0..bc {
1618
+ out[(i * br + k, j * bc + l)] = aij * b[(k, l)];
1619
+ }
1620
+ }
1621
+ }
1622
+ }
1623
+
1624
+ out
1625
+ }
1626
+
1627
+ /// Bell states
1628
+ pub fn bell_phi_plus() -> DVector<C64> {
1629
+ let s = 1.0 / 2.0_f64.sqrt();
1630
+ DVector::from_vec(vec![
1631
+ C64::new(s, 0.0), C64::new(0.0, 0.0),
1632
+ C64::new(0.0, 0.0), C64::new(s, 0.0),
1633
+ ])
1634
+ }
1635
+
1636
+ pub fn bell_phi_minus() -> DVector<C64> {
1637
+ let s = 1.0 / 2.0_f64.sqrt();
1638
+ DVector::from_vec(vec![
1639
+ C64::new(s, 0.0), C64::new(0.0, 0.0),
1640
+ C64::new(0.0, 0.0), C64::new(-s, 0.0),
1641
+ ])
1642
+ }
1643
+
1644
+ pub fn bell_psi_plus() -> DVector<C64> {
1645
+ let s = 1.0 / 2.0_f64.sqrt();
1646
+ DVector::from_vec(vec![
1647
+ C64::new(0.0, 0.0), C64::new(s, 0.0),
1648
+ C64::new(s, 0.0), C64::new(0.0, 0.0),
1649
+ ])
1650
+ }
1651
+
1652
+ pub fn bell_psi_minus() -> DVector<C64> {
1653
+ let s = 1.0 / 2.0_f64.sqrt();
1654
+ DVector::from_vec(vec![
1655
+ C64::new(0.0, 0.0), C64::new(s, 0.0),
1656
+ C64::new(-s, 0.0), C64::new(0.0, 0.0),
1657
+ ])
1658
+ }
1659
+
1660
+ /// Partial trace over second subsystem
1661
+ /// Input: 4×4 density matrix for system A⊗B
1662
+ /// Output: 2×2 density matrix for system A
1663
+ pub fn partial_trace_second(rho_ab: &DMatrix<C64>) -> DMatrix<C64> {
1664
+ let mut rho_a = DMatrix::zeros(2, 2);
1665
+
1666
+ // ρ_A = Tr_B(ρ_AB) = Σ_k ⟨k|_B ρ_AB |k⟩_B
1667
+ for i in 0..2 {
1668
+ for j in 0..2 {
1669
+ let mut sum = C64::new(0.0, 0.0);
1670
+ for k in 0..2 {
1671
+ let row = i * 2 + k;
1672
+ let col = j * 2 + k;
1673
+ sum += rho_ab[(row, col)];
1674
+ }
1675
+ rho_a[(i, j)] = sum;
1676
+ }
1677
+ }
1678
+
1679
+ rho_a
1680
+ }
1681
+
1682
+ /// Partial trace over first subsystem
1683
+ pub fn partial_trace_first(rho_ab: &DMatrix<C64>) -> DMatrix<C64> {
1684
+ let mut rho_b = DMatrix::zeros(2, 2);
1685
+
1686
+ for i in 0..2 {
1687
+ for j in 0..2 {
1688
+ let mut sum = C64::new(0.0, 0.0);
1689
+ for k in 0..2 {
1690
+ let row = k * 2 + i;
1691
+ let col = k * 2 + j;
1692
+ sum += rho_ab[(row, col)];
1693
+ }
1694
+ rho_b[(i, j)] = sum;
1695
+ }
1696
+ }
1697
+
1698
+ rho_b
1699
+ }
1700
+ ```
1701
+
1702
+ ### 6.4 Measurement Simulation
1703
+
1704
+ ```rust
1705
+ use rand::Rng;
1706
+
1707
+ /// Simulate projective measurement in computational basis
1708
+ pub fn measure_computational_basis<R: Rng>(
1709
+ psi: &DVector<C64>,
1710
+ rng: &mut R,
1711
+ ) -> (usize, DVector<C64>) {
1712
+ let n = psi.len();
1713
+ let probabilities: Vec<f64> = (0..n)
1714
+ .map(|i| (psi[i] * psi[i].conj()).re)
1715
+ .collect();
1716
+
1717
+ // Sample outcome
1718
+ let r: f64 = rng.gen();
1719
+ let mut cumsum = 0.0;
1720
+ let mut outcome = 0;
1721
+
1722
+ for (i, &p) in probabilities.iter().enumerate() {
1723
+ cumsum += p;
1724
+ if r < cumsum {
1725
+ outcome = i;
1726
+ break;
1727
+ }
1728
+ }
1729
+
1730
+ // Post-measurement state (collapsed)
1731
+ let mut psi_post = DVector::zeros(n);
1732
+ psi_post[outcome] = C64::new(1.0, 0.0);
1733
+
1734
+ (outcome, psi_post)
1735
+ }
1736
+
1737
+ /// Simulate POVM measurement
1738
+ pub fn measure_povm<R: Rng>(
1739
+ rho: &DMatrix<C64>,
1740
+ povm: &[DMatrix<C64>],
1741
+ rng: &mut R,
1742
+ ) -> usize {
1743
+ let probabilities: Vec<f64> = povm.iter()
1744
+ .map(|m| {
1745
+ let result = m * rho;
1746
+ result.trace().re.max(0.0)
1747
+ })
1748
+ .collect();
1749
+
1750
+ // Normalize (may have small numerical errors)
1751
+ let total: f64 = probabilities.iter().sum();
1752
+ let probabilities: Vec<f64> = probabilities.iter()
1753
+ .map(|&p| p / total)
1754
+ .collect();
1755
+
1756
+ // Sample
1757
+ let r: f64 = rng.gen();
1758
+ let mut cumsum = 0.0;
1759
+
1760
+ for (i, &p) in probabilities.iter().enumerate() {
1761
+ cumsum += p;
1762
+ if r < cumsum {
1763
+ return i;
1764
+ }
1765
+ }
1766
+
1767
+ povm.len() - 1 // Fallback (numerical edge case)
1768
+ }
1769
+ ```
1770
+
1771
+ ---
1772
+
1773
+ ## 7. Common Pitfalls and How to Avoid Them
1774
+
1775
+ ### 7.1 Numerical Stability Issues
1776
+
1777
+ **Problem:** Complex number arithmetic can accumulate errors
1778
+
1779
+ **Solution:**
1780
+ ```rust
1781
+ /// Check if two complex matrices are approximately equal
1782
+ pub fn matrix_approx_eq(a: &DMatrix<C64>, b: &DMatrix<C64>, epsilon: f64) -> bool {
1783
+ if a.shape() != b.shape() {
1784
+ return false;
1785
+ }
1786
+
1787
+ let diff = a - b;
1788
+ diff.norm() < epsilon
1789
+ }
1790
+
1791
+ /// Enforce hermiticity (for density matrices)
1792
+ pub fn enforce_hermitian(mut rho: DMatrix<C64>) -> DMatrix<C64> {
1793
+ let n = rho.nrows();
1794
+ for i in 0..n {
1795
+ for j in 0..i {
1796
+ let avg = (rho[(i, j)] + rho[(j, i)].conj()) / 2.0;
1797
+ rho[(i, j)] = avg;
1798
+ rho[(j, i)] = avg.conj();
1799
+ }
1800
+ // Diagonal must be real
1801
+ rho[(i, i)] = C64::new(rho[(i, i)].re, 0.0);
1802
+ }
1803
+ rho
1804
+ }
1805
+
1806
+ /// Enforce trace-1 normalization
1807
+ pub fn normalize_density_matrix(mut rho: DMatrix<C64>) -> DMatrix<C64> {
1808
+ let tr = rho.trace().re;
1809
+ if tr > 1e-15 {
1810
+ rho /= tr;
1811
+ }
1812
+ rho
1813
+ }
1814
+ ```
1815
+
1816
+ ### 7.2 Phase Convention Ambiguities
1817
+
1818
+ **Problem:** Global phases are unphysical but can cause test failures
1819
+
1820
+ **Solution:**
1821
+ ```rust
1822
+ /// Compare states up to global phase
1823
+ pub fn states_equal_up_to_phase(psi: &DVector<C64>, phi: &DVector<C64>, epsilon: f64) -> bool {
1824
+ if psi.len() != phi.len() {
1825
+ return false;
1826
+ }
1827
+
1828
+ // Find first non-zero element to fix phase
1829
+ let mut phase_factor = C64::new(1.0, 0.0);
1830
+ for i in 0..psi.len() {
1831
+ if psi[i].norm() > 1e-10 {
1832
+ phase_factor = phi[i] / psi[i];
1833
+ break;
1834
+ }
1835
+ }
1836
+
1837
+ // Multiply one state by phase and compare
1838
+ let phi_adjusted: DVector<C64> = phi.map(|x| x / phase_factor);
1839
+
1840
+ (psi - phi_adjusted).norm() < epsilon
1841
+ }
1842
+ ```
1843
+
1844
+ ### 7.3 Tensor Product Index Confusion
1845
+
1846
+ **Problem:** Indexing multi-qubit states is error-prone
1847
+
1848
+ **Solution:**
1849
+ ```rust
1850
+ /// Convert multi-qubit index to binary string
1851
+ pub fn index_to_binary(index: usize, n_qubits: usize) -> String {
1852
+ format!("{:0width$b}", index, width = n_qubits)
1853
+ }
1854
+
1855
+ /// Example: Two-qubit system
1856
+ /// |00⟩ → index 0
1857
+ /// |01⟩ → index 1
1858
+ /// |10⟩ → index 2
1859
+ /// |11⟩ → index 3
1860
+
1861
+ #[test]
1862
+ fn test_indexing() {
1863
+ assert_eq!(index_to_binary(0, 2), "00");
1864
+ assert_eq!(index_to_binary(1, 2), "01");
1865
+ assert_eq!(index_to_binary(2, 2), "10");
1866
+ assert_eq!(index_to_binary(3, 2), "11");
1867
+ }
1868
+ ```
1869
+
1870
+ ### 7.4 Measurement vs Observable Confusion
1871
+
1872
+ **Problem:** Mixing up measurement outcomes and expectation values
1873
+
1874
+ **Solution:**
1875
+ ```rust
1876
+ /// Measurement: Sample discrete outcome according to Born rule
1877
+ pub fn measure_observable<R: Rng>(
1878
+ psi: &DVector<C64>,
1879
+ observable: &DMatrix<C64>,
1880
+ rng: &mut R,
1881
+ ) -> (f64, DVector<C64>) {
1882
+ // 1. Diagonalize observable to get eigenvectors/eigenvalues
1883
+ let eigen = observable.hermitian_eigen();
1884
+ let eigenvalues = eigen.eigenvalues;
1885
+ let eigenvectors = eigen.eigenvectors;
1886
+
1887
+ // 2. Calculate probabilities
1888
+ let probabilities: Vec<f64> = (0..eigenvalues.len())
1889
+ .map(|i| {
1890
+ let eigvec = eigenvectors.column(i);
1891
+ let amplitude = eigvec.dotc(psi);
1892
+ (amplitude * amplitude.conj()).re
1893
+ })
1894
+ .collect();
1895
+
1896
+ // 3. Sample outcome
1897
+ let r: f64 = rng.gen();
1898
+ let mut cumsum = 0.0;
1899
+ let mut outcome_idx = 0;
1900
+
1901
+ for (i, &p) in probabilities.iter().enumerate() {
1902
+ cumsum += p;
1903
+ if r < cumsum {
1904
+ outcome_idx = i;
1905
+ break;
1906
+ }
1907
+ }
1908
+
1909
+ // 4. Return eigenvalue and collapsed state
1910
+ let eigenvalue = eigenvalues[outcome_idx].re;
1911
+ let collapsed_state = eigenvectors.column(outcome_idx).into_owned();
1912
+
1913
+ (eigenvalue, collapsed_state)
1914
+ }
1915
+
1916
+ /// Expectation value: ⟨O⟩ = ⟨ψ|O|ψ⟩
1917
+ pub fn expectation_value(
1918
+ psi: &DVector<C64>,
1919
+ observable: &DMatrix<C64>,
1920
+ ) -> f64 {
1921
+ let o_psi = observable * psi;
1922
+ let result = psi.dotc(&o_psi);
1923
+ result.re
1924
+ }
1925
+ ```
1926
+
1927
+ ---
1928
+
1929
+ ## 8. References to Similar Successful Projects
1930
+
1931
+ ### 8.1 Academic Quantum Simulation Projects
1932
+
1933
+ **QuEST (Quantum Exact Simulation Toolkit):**
1934
+ - Language: C with Python/Julia bindings
1935
+ - Features: 30+ qubit simulations, GPU acceleration
1936
+ - Citation: Jones et al., Scientific Reports (2019)
1937
+ - Relevance: Demonstrates rigorous testing and validation protocols
1938
+
1939
+ **ProjectQ:**
1940
+ - Language: Python + C++
1941
+ - Features: Circuit optimization, resource estimation
1942
+ - Relevance: Good example of modular architecture
1943
+
1944
+ **Qiskit:**
1945
+ - Language: Python with Rust/C++ backends
1946
+ - Features: Hardware integration, POVM toolbox
1947
+ - Relevance: Industry-standard documentation practices
1948
+
1949
+ ### 8.2 Rust Scientific Computing Exemplars
1950
+
1951
+ **ndarray-linalg:**
1952
+ - Domain: Linear algebra
1953
+ - Best Practice: Comprehensive benchmarking, BLAS integration
1954
+ - Relevant Pattern: Abstract backends for performance
1955
+
1956
+ **petgraph:**
1957
+ - Domain: Graph algorithms
1958
+ - Best Practice: Property-based testing with proptest
1959
+ - Relevant Pattern: Zero-cost abstractions
1960
+
1961
+ **bio:**
1962
+ - Domain: Bioinformatics
1963
+ - Best Practice: Scientific computing in Rust
1964
+ - Relevant Pattern: File format interoperability
1965
+
1966
+ ### 8.3 Open Quantum Experiments
1967
+
1968
+ **Delayed-Choice Quantum Eraser (Kim et al., 2000):**
1969
+ - First realization with entangled photons
1970
+ - Data archived at: arXiv:quant-ph/9903047
1971
+ - Lesson: Importance of coincidence counting and timing resolution
1972
+
1973
+ **Loophole-Free Bell Test (Hensen et al., Nature 2015):**
1974
+ - Gold standard for experimental rigor
1975
+ - Pre-registered hypotheses, blinded analysis
1976
+ - Lesson: Eliminate all alternative explanations before claiming new physics
1977
+
1978
+ **Quantum Eraser with Coherent Photons (Scientific Reports, 2023):**
1979
+ - Recent demonstration with classical light
1980
+ - Open data repository
1981
+ - Lesson: Modern reproducibility standards
1982
+
1983
+ ---
1984
+
1985
+ ## 9. Implementation Roadmap
1986
+
1987
+ ### Phase 1: Core Simulation (Weeks 1-2)
1988
+ - [ ] Implement quantum state operations (math.rs)
1989
+ - [ ] Implement POVM formalism
1990
+ - [ ] Implement quantum eraser logic (eraser.rs)
1991
+ - [ ] Unit tests for all mathematical operations
1992
+ - [ ] Verify singles invariance with property tests
1993
+
1994
+ ### Phase 2: Statistical Analysis (Week 3)
1995
+ - [ ] Implement chi-squared test
1996
+ - [ ] Implement TOST equivalence test
1997
+ - [ ] Power analysis calculator
1998
+ - [ ] Monte Carlo error propagation
1999
+ - [ ] Integration tests for statistical correctness
2000
+
2001
+ ### Phase 3: Experimental Interface (Week 4)
2002
+ - [ ] Data import (HDF5, CSV)
2003
+ - [ ] Controller type encoding/blinding
2004
+ - [ ] Coincidence counting simulation
2005
+ - [ ] Export to plotting formats
2006
+ - [ ] End-to-end workflow test
2007
+
2008
+ ### Phase 4: Visualization & Documentation (Week 5)
2009
+ - [ ] Interference pattern plots
2010
+ - [ ] Duality relation visualization
2011
+ - [ ] Statistical test results summary
2012
+ - [ ] Complete API documentation
2013
+ - [ ] Example notebooks/scripts
2014
+
2015
+ ### Phase 5: Optimization & Benchmarking (Week 6)
2016
+ - [ ] Profile hot paths
2017
+ - [ ] SIMD optimization for matrix operations
2018
+ - [ ] Parallel Monte Carlo simulations
2019
+ - [ ] Benchmark against RustQIP
2020
+ - [ ] Performance regression tests
2021
+
2022
+ ### Phase 6: Validation & Pre-Registration (Week 7)
2023
+ - [ ] Cross-validate with existing QM libraries
2024
+ - [ ] Reproduce published quantum eraser results
2025
+ - [ ] Finalize pre-registration document
2026
+ - [ ] Code review and security audit
2027
+ - [ ] Prepare for experimental deployment
2028
+
2029
+ ---
2030
+
2031
+ ## 10. Coordination Memory Storage
2032
+
2033
+ This comprehensive research will be stored in the coordination memory system for other agents:
2034
+
2035
+ ```bash
2036
+ npx claude-flow@alpha memory store \
2037
+ --key "quantum-research/literature-review" \
2038
+ --namespace "coordination" \
2039
+ --value "$(cat /workspaces/agentic-flow/docs/QUANTUM_RESEARCH_LITERATURE_REVIEW.md)" \
2040
+ --ttl 2592000 # 30 days
2041
+ ```
2042
+
2043
+ **Key Findings for Coordination:**
2044
+ 1. **Primary Library:** nalgebra + num-complex (matches existing research.md)
2045
+ 2. **Validation Library:** RustQIP (cross-check)
2046
+ 3. **Optimization:** rayon for parallelism, SimSIMD for production
2047
+ 4. **Statistical Testing:** statrs for chi-squared/TOST, proptest for property-based testing
2048
+ 5. **Visualization:** plotters (Rust-native) or matplotlib (Python export)
2049
+ 6. **Experimental Components:** Type-II BBO crystal, SPADs, time-tagging module
2050
+ 7. **Critical Requirement:** Blinded controller identity, pre-registration protocol
2051
+
2052
+ ---
2053
+
2054
+ ## Conclusion
2055
+
2056
+ This literature review provides a complete foundation for implementing the Observer-Agnostic Measurement experiment. The existing research.md already contains excellent theoretical grounding and simulation scaffolding. This review adds:
2057
+
2058
+ 1. **2024 quantum computing ecosystem context** - Latest library developments
2059
+ 2. **Experimental hardware specifics** - SPDC, BBO crystals, detector requirements
2060
+ 3. **Statistical rigor** - Chi-squared, TOST, power analysis implementations
2061
+ 4. **Software engineering best practices** - Testing strategies, documentation, reproducibility
2062
+ 5. **Performance optimization paths** - SIMD, parallelism, benchmarking
2063
+
2064
+ **Next Steps:**
2065
+ 1. Coder agent: Implement Phase 1 (core simulation) using nalgebra
2066
+ 2. Tester agent: Set up property-based tests with proptest
2067
+ 3. Reviewer agent: Validate against existing quantum mechanics predictions
2068
+ 4. Planner agent: Schedule experimental hardware procurement
2069
+
2070
+ **Falsifiable Prediction:**
2071
+ If |Δp| > 5×10⁻⁴ and reproducible across controller types, it would falsify standard quantum mechanics and suggest consciousness plays a causal role in measurement outcomes. This is testable, pre-registerable, and publishable.