agentic-flow 1.5.12 → 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.
- package/CHANGELOG.md +199 -0
- package/README.md +43 -23
- package/dist/cli-proxy.js +195 -1
- package/dist/config/quic.js +6 -0
- package/dist/reasoningbank/backend-selector.js +145 -0
- package/dist/reasoningbank/index.js +4 -0
- package/dist/transport/quic.js +43 -0
- package/dist/utils/cli.js +5 -0
- package/docs/.claude-flow/metrics/performance.json +80 -2
- package/docs/.claude-flow/metrics/task-metrics.json +3 -3
- package/docs/INDEX.md +55 -9
- package/docs/INTEGRATION-COMPLETE.md +291 -0
- package/docs/QUIC_FINAL_STATUS.md +399 -0
- package/docs/README_QUIC_PHASE1.md +117 -0
- package/docs/integration-docs/CLAUDE-FLOW-INTEGRATION-ANALYSIS.md +653 -0
- package/docs/integration-docs/IMPLEMENTATION_SUMMARY.md +369 -0
- package/docs/integration-docs/INTEGRATION-QUICK-SUMMARY.md +249 -0
- package/docs/integration-docs/INTEGRATION-STATUS-CORRECTED.md +488 -0
- package/docs/integration-docs/README.md +61 -0
- package/docs/quantum-goap/DEPENDENCY_GRAPH.mermaid +133 -0
- package/docs/quantum-goap/EXECUTION_SUMMARY.md +199 -0
- package/docs/quantum-goap/GOAP_IMPLEMENTATION_PLAN.md +2406 -0
- package/docs/quantum-goap/QUICK_START.md +301 -0
- package/docs/quantum-research/QUANTUM_RESEARCH_LITERATURE_REVIEW.md +2071 -0
- package/docs/quantum-research/README.md +94 -0
- package/docs/reasoningbank/MEMORY_VALIDATION_REPORT.md +417 -0
- package/docs/reasoningbank/README.md +43 -0
- package/docs/reasoningbank/REASONINGBANK_ARCHITECTURE.md +663 -0
- package/docs/reasoningbank/REASONINGBANK_BACKENDS.md +375 -0
- package/docs/reasoningbank/REASONINGBANK_FIXES.md +455 -0
- package/docs/reasoningbank/REASONINGBANK_INVESTIGATION.md +380 -0
- package/docs/releases/v1.5.14-QUIC-TRANSPORT.md +201 -0
- package/docs/validation-reports/BENCHMARK_AND_OPTIMIZATION_REPORT.md +470 -0
- package/docs/validation-reports/DOCKER_VALIDATION_RESULTS.md +391 -0
- package/docs/validation-reports/NO_REGRESSIONS_CONFIRMED.md +384 -0
- package/docs/validation-reports/NPM-PACKAGE-ANALYSIS-FINAL.md +543 -0
- package/docs/validation-reports/README.md +43 -0
- package/docs/validation-reports/V2.7.0-ALPHA.10_FINAL_VALIDATION.md +817 -0
- package/docs/validation-reports/V2.7.0-ALPHA.9_VALIDATION.md +546 -0
- package/docs/validation-reports/v1.6.0-QUIC-CLI-VALIDATION.md +558 -0
- package/docs/version-releases/README.md +82 -0
- package/package.json +15 -1
- package/validation/docker/Dockerfile.reasoningbank-local +24 -0
- package/validation/docker/Dockerfile.reasoningbank-test +21 -0
- package/validation/docker/README.md +234 -0
- package/validation/docker/docker-compose.yml +29 -0
- package/validation/docker/test-reasoningbank-npx.mjs +442 -0
- package/validation/docker-quic-test.sh +42 -0
- package/validation/docker-quic-validation.sh +60 -0
- package/validation/quic-deep-validation.ts +304 -0
- package/validation/test-quic-wasm.ts +94 -0
- package/validation/test-regression.mjs +246 -0
- package/wasm/quic/README.md +75 -0
- package/wasm/quic/agentic_flow_quic.d.ts +37 -0
- package/wasm/quic/agentic_flow_quic.js +779 -0
- package/wasm/quic/agentic_flow_quic_bg.wasm +0 -0
- package/wasm/quic/agentic_flow_quic_bg.wasm.d.ts +19 -0
- package/wasm/quic/package.json +20 -0
- /package/docs/{PACKAGE_STRUCTURE.md → architecture/PACKAGE_STRUCTURE.md} +0 -0
- /package/docs/{MODEL-ID-MAPPING.md → guides/MODEL-ID-MAPPING.md} +0 -0
- /package/docs/{ONNX-PROXY-IMPLEMENTATION.md → guides/ONNX-PROXY-IMPLEMENTATION.md} +0 -0
- /package/docs/{STANDALONE_PROXY_GUIDE.md → guides/STANDALONE_PROXY_GUIDE.md} +0 -0
- /package/docs/{AGENT-BOOSTER-INTEGRATION.md → integration-docs/AGENT-BOOSTER-INTEGRATION.md} +0 -0
- /package/docs/{CLI-INTEGRATION-COMPLETE.md → integration-docs/CLI-INTEGRATION-COMPLETE.md} +0 -0
- /package/docs/{INTEGRATION_COMPLETE_SUMMARY.md → integration-docs/INTEGRATION_COMPLETE_SUMMARY.md} +0 -0
- /package/docs/{WASM_ESM_FIX.md → integration-docs/WASM_ESM_FIX.md} +0 -0
- /package/docs/{WASM_INTEGRATION_COMPLETE.md → integration-docs/WASM_INTEGRATION_COMPLETE.md} +0 -0
- /package/docs/{REASONING-AGENTS.md → reasoningbank/REASONING-AGENTS.md} +0 -0
- /package/docs/{REASONINGBANK-BENCHMARK-RESULTS.md → reasoningbank/REASONINGBANK-BENCHMARK-RESULTS.md} +0 -0
- /package/docs/{REASONINGBANK-BENCHMARK.md → reasoningbank/REASONINGBANK-BENCHMARK.md} +0 -0
- /package/docs/{REASONINGBANK-CLI-INTEGRATION.md → reasoningbank/REASONINGBANK-CLI-INTEGRATION.md} +0 -0
- /package/docs/{REASONINGBANK-DEMO.md → reasoningbank/REASONINGBANK-DEMO.md} +0 -0
- /package/docs/{REASONINGBANK-VALIDATION.md → reasoningbank/REASONINGBANK-VALIDATION.md} +0 -0
- /package/docs/{REASONINGBANK_IMPLEMENTATION_STATUS.md → reasoningbank/REASONINGBANK_IMPLEMENTATION_STATUS.md} +0 -0
- /package/docs/{REASONINGBANK_INTEGRATION_PLAN.md → reasoningbank/REASONINGBANK_INTEGRATION_PLAN.md} +0 -0
- /package/docs/{PUBLICATION_REPORT_v1.5.11.md → version-releases/PUBLICATION_REPORT_v1.5.11.md} +0 -0
- /package/docs/{v1.5.9-DOCKER-VERIFICATION.md → version-releases/v1.5.9-DOCKER-VERIFICATION.md} +0 -0
- /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.
|