Skip to main content

sublinear_solver/temporal_nexus/quantum/
physics_validation.rs

1//! Physics Constants and Computational Bounds Validation
2//!
3//! This module provides comprehensive validation of physical constants
4//! and computational bounds used throughout the quantum validation framework.
5//! It ensures that all constants are within accepted ranges and that
6//! computational algorithms are numerically stable.
7
8use super::constants;
9use std::f64::consts::PI;
10
11/// Physics constants validation report
12#[derive(Debug, Clone)]
13pub struct PhysicsValidationReport {
14    pub constants_valid: bool,
15    pub computational_bounds_valid: bool,
16    pub numerical_stability_valid: bool,
17    pub issues: Vec<String>,
18    pub warnings: Vec<String>,
19    pub recommendations: Vec<String>,
20}
21
22/// Comprehensive physics validation suite
23pub struct PhysicsValidator;
24
25impl PhysicsValidator {
26    /// Validate all physics constants against known values
27    pub fn validate_constants() -> PhysicsValidationReport {
28        let mut report = PhysicsValidationReport {
29            constants_valid: true,
30            computational_bounds_valid: true,
31            numerical_stability_valid: true,
32            issues: Vec::new(),
33            warnings: Vec::new(),
34            recommendations: Vec::new(),
35        };
36
37        // Validate fundamental constants
38        Self::validate_planck_constants(&mut report);
39        Self::validate_boltzmann_constant(&mut report);
40        Self::validate_speed_of_light(&mut report);
41        Self::validate_electron_volt_conversion(&mut report);
42        Self::validate_derived_constants(&mut report);
43        Self::validate_consciousness_constants(&mut report);
44        Self::validate_computational_bounds(&mut report);
45        Self::validate_numerical_stability(&mut report);
46
47        report
48    }
49
50    /// Validate Planck constants
51    fn validate_planck_constants(report: &mut PhysicsValidationReport) {
52        // CODATA 2018 values
53        let expected_h = 6.626_070_15e-34;
54        let expected_hbar = expected_h / (2.0 * PI);
55
56        // Validate Planck constant
57        if (constants::PLANCK_H - expected_h).abs() > 1e-42 {
58            report.issues.push(format!(
59                "Planck constant deviation: expected {:.10e}, got {:.10e}",
60                expected_h, constants::PLANCK_H
61            ));
62            report.constants_valid = false;
63        }
64
65        // Validate reduced Planck constant
66        if (constants::PLANCK_HBAR - expected_hbar).abs() > 1e-42 {
67            report.issues.push(format!(
68                "Reduced Planck constant deviation: expected {:.10e}, got {:.10e}",
69                expected_hbar, constants::PLANCK_HBAR
70            ));
71            report.constants_valid = false;
72        }
73
74        // Validate the relationship ℏ = h/(2π). The absolute tolerance was
75        // 1e-50 — five orders of magnitude tighter than f64 can represent
76        // at these scales (ULP at ~1e-34 is ≈ 2e-50, but the stored ℏ has
77        // only ~10 significant digits, so realistic error is ~6e-44).
78        // Use a relative tolerance instead, matched to the precision of
79        // the stored constant.
80        let calculated_hbar = constants::PLANCK_H / (2.0 * PI);
81        let rel_err = (constants::PLANCK_HBAR - calculated_hbar).abs() / calculated_hbar;
82        if rel_err > 1e-9 {
83            report.issues.push(format!(
84                "Planck constant relationship violated: ℏ ≠ h/(2π), relative error = {:.2e}",
85                rel_err
86            ));
87            report.constants_valid = false;
88        }
89
90        // Validate positivity
91        if constants::PLANCK_H <= 0.0 || constants::PLANCK_HBAR <= 0.0 {
92            report.issues.push("Planck constants must be positive".to_string());
93            report.constants_valid = false;
94        }
95    }
96
97    /// Validate Boltzmann constant
98    fn validate_boltzmann_constant(report: &mut PhysicsValidationReport) {
99        let expected_kb = 1.380_649e-23; // CODATA 2018
100
101        if (constants::BOLTZMANN_K - expected_kb).abs() > 1e-31 {
102            report.issues.push(format!(
103                "Boltzmann constant deviation: expected {:.10e}, got {:.10e}",
104                expected_kb, constants::BOLTZMANN_K
105            ));
106            report.constants_valid = false;
107        }
108
109        if constants::BOLTZMANN_K <= 0.0 {
110            report.issues.push("Boltzmann constant must be positive".to_string());
111            report.constants_valid = false;
112        }
113    }
114
115    /// Validate speed of light
116    fn validate_speed_of_light(report: &mut PhysicsValidationReport) {
117        let expected_c = 299_792_458.0; // Exact by definition
118
119        if (constants::SPEED_OF_LIGHT - expected_c).abs() > 1e-6 {
120            report.issues.push(format!(
121                "Speed of light deviation: expected {:.1}, got {:.1}",
122                expected_c, constants::SPEED_OF_LIGHT
123            ));
124            report.constants_valid = false;
125        }
126
127        if constants::SPEED_OF_LIGHT <= 0.0 {
128            report.issues.push("Speed of light must be positive".to_string());
129            report.constants_valid = false;
130        }
131    }
132
133    /// Validate electron volt conversion
134    fn validate_electron_volt_conversion(report: &mut PhysicsValidationReport) {
135        let expected_ev_to_j = 1.602_176_634e-19; // CODATA 2018
136
137        if (constants::EV_TO_JOULES - expected_ev_to_j).abs() > 1e-27 {
138            report.issues.push(format!(
139                "eV to Joules conversion deviation: expected {:.10e}, got {:.10e}",
140                expected_ev_to_j, constants::EV_TO_JOULES
141            ));
142            report.constants_valid = false;
143        }
144
145        if constants::EV_TO_JOULES <= 0.0 {
146            report.issues.push("eV to Joules conversion must be positive".to_string());
147            report.constants_valid = false;
148        }
149    }
150
151    /// Validate derived constants
152    fn validate_derived_constants(report: &mut PhysicsValidationReport) {
153        // Validate room temperature (should be reasonable)
154        if constants::ROOM_TEMPERATURE_K < 250.0 || constants::ROOM_TEMPERATURE_K > 350.0 {
155            report.warnings.push(format!(
156                "Room temperature seems unusual: {:.1} K",
157                constants::ROOM_TEMPERATURE_K
158            ));
159        }
160
161        // Validate thermal energy at room temperature
162        let thermal_energy = constants::BOLTZMANN_K * constants::ROOM_TEMPERATURE_K;
163        let thermal_energy_ev = thermal_energy / constants::EV_TO_JOULES;
164
165        if thermal_energy_ev < 0.020 || thermal_energy_ev > 0.030 {
166            report.warnings.push(format!(
167                "Room temperature thermal energy unusual: {:.3} eV (expected ~0.025 eV)",
168                thermal_energy_ev
169            ));
170        }
171
172        // Validate minimum uncertainty product
173        let min_uncertainty = constants::PLANCK_HBAR / 2.0;
174        if min_uncertainty <= 0.0 {
175            report.issues.push("Minimum uncertainty product must be positive".to_string());
176            report.constants_valid = false;
177        }
178    }
179
180    /// Validate consciousness-specific constants
181    fn validate_consciousness_constants(report: &mut PhysicsValidationReport) {
182        // Validate attosecond energy requirement
183        if constants::ATTOSECOND_ENERGY_KEV <= 0.0 {
184            report.issues.push("Attosecond energy requirement must be positive".to_string());
185            report.constants_valid = false;
186        }
187
188        if constants::ATTOSECOND_ENERGY_KEV < 0.5 || constants::ATTOSECOND_ENERGY_KEV > 5.0 {
189            report.warnings.push(format!(
190                "Attosecond energy requirement seems unusual: {:.2} keV",
191                constants::ATTOSECOND_ENERGY_KEV
192            ));
193        }
194
195        // Validate consciousness scale
196        if constants::CONSCIOUSNESS_SCALE_NS != 1e-9 {
197            report.issues.push(format!(
198                "Consciousness scale incorrect: expected 1e-9, got {:.2e}",
199                constants::CONSCIOUSNESS_SCALE_NS
200            ));
201            report.constants_valid = false;
202        }
203
204        // Validate that attosecond operation requires substantial energy
205        let attosecond_energy_j = constants::ATTOSECOND_ENERGY_KEV * 1000.0 * constants::EV_TO_JOULES;
206        let thermal_energy_j = constants::BOLTZMANN_K * constants::ROOM_TEMPERATURE_K;
207        let energy_ratio = attosecond_energy_j / thermal_energy_j;
208
209        if energy_ratio < 1000.0 {
210            report.warnings.push(format!(
211                "Attosecond energy only {:.0}x thermal energy (expected >1000x)",
212                energy_ratio
213            ));
214        }
215    }
216
217    /// Validate computational bounds
218    fn validate_computational_bounds(report: &mut PhysicsValidationReport) {
219        // Test Margolus-Levitin bound calculation
220        let test_energy = 1e-15; // 1 fJ
221        let min_time = constants::PLANCK_H / (4.0 * test_energy);
222
223        if min_time <= 0.0 || !min_time.is_finite() {
224            report.issues.push("Margolus-Levitin calculation produces invalid result".to_string());
225            report.computational_bounds_valid = false;
226        }
227
228        if min_time > 1e-15 {
229            report.warnings.push(format!(
230                "Margolus-Levitin time seems large for 1 fJ: {:.2e} s",
231                min_time
232            ));
233        }
234
235        // Test uncertainty principle calculation
236        let uncertainty_product = test_energy * min_time;
237        let min_uncertainty = constants::PLANCK_HBAR / 2.0;
238
239        if uncertainty_product < min_uncertainty {
240            report.issues.push(format!(
241                "Uncertainty principle violation in test: ΔE·Δt = {:.2e} < ℏ/2 = {:.2e}",
242                uncertainty_product, min_uncertainty
243            ));
244            report.computational_bounds_valid = false;
245        }
246
247        // Test energy scale boundaries
248        let max_reasonable_energy = 1e-12; // 1 pJ
249        let min_reasonable_energy = 1e-21; // 1 zJ
250
251        if constants::PLANCK_H / (4.0 * max_reasonable_energy) > 1e-18 {
252            report.warnings.push("Maximum energy bound may be too restrictive".to_string());
253        }
254
255        if constants::PLANCK_H / (4.0 * min_reasonable_energy) < 1e-15 {
256            report.warnings.push("Minimum energy bound may be too permissive".to_string());
257        }
258    }
259
260    /// Validate numerical stability
261    fn validate_numerical_stability(report: &mut PhysicsValidationReport) {
262        // Test precision at extreme scales
263        let very_small = 1e-30;
264        let very_large = 1e30;
265
266        // Test that calculations don't overflow/underflow
267        let product: f64 = very_small * very_large;
268        if !product.is_finite() || product == 0.0 {
269            report.issues.push("Numerical instability in extreme scale calculations".to_string());
270            report.numerical_stability_valid = false;
271        }
272
273        // Test floating point precision near physical constants
274        let h_plus_epsilon = constants::PLANCK_H + 1e-50;
275        if h_plus_epsilon == constants::PLANCK_H {
276            report.warnings.push("Limited floating point precision near Planck constant".to_string());
277        }
278
279        // Test reciprocal calculations
280        let energy = 1e-15;
281        let time1 = constants::PLANCK_H / (4.0 * energy);
282        let energy_back = constants::PLANCK_H / (4.0 * time1);
283        let relative_error = (energy - energy_back).abs() / energy;
284
285        if relative_error > 1e-14 {
286            report.warnings.push(format!(
287                "Numerical precision loss in reciprocal calculations: {:.2e} relative error",
288                relative_error
289            ));
290        }
291
292        // Test trigonometric precision in hbar calculation
293        let hbar_calculated = constants::PLANCK_H / (2.0 * PI);
294        let relative_error_hbar = (constants::PLANCK_HBAR - hbar_calculated).abs() / constants::PLANCK_HBAR;
295
296        if relative_error_hbar > 1e-15 {
297            report.warnings.push(format!(
298                "Numerical precision loss in ℏ calculation: {:.2e} relative error",
299                relative_error_hbar
300            ));
301        }
302    }
303
304    /// Generate physics validation summary
305    pub fn generate_summary(report: &PhysicsValidationReport) -> String {
306        let mut summary = String::new();
307
308        summary.push_str("🔬 Physics Constants & Computational Bounds Validation\\n");
309        summary.push_str("=====================================================\\n\\n");
310
311        // Overall status
312        if report.constants_valid && report.computational_bounds_valid && report.numerical_stability_valid {
313            summary.push_str("✅ Overall Status: PASS\\n");
314        } else {
315            summary.push_str("❌ Overall Status: FAIL\\n");
316        }
317
318        summary.push_str(&format!("   Constants Valid: {}\\n",
319                                 if report.constants_valid { "✅" } else { "❌" }));
320        summary.push_str(&format!("   Computational Bounds Valid: {}\\n",
321                                 if report.computational_bounds_valid { "✅" } else { "❌" }));
322        summary.push_str(&format!("   Numerical Stability Valid: {}\\n\\n",
323                                 if report.numerical_stability_valid { "✅" } else { "❌" }));
324
325        // Issues
326        if !report.issues.is_empty() {
327            summary.push_str("🚨 Issues:\\n");
328            for issue in &report.issues {
329                summary.push_str(&format!("   • {}\\n", issue));
330            }
331            summary.push_str("\\n");
332        }
333
334        // Warnings
335        if !report.warnings.is_empty() {
336            summary.push_str("⚠️  Warnings:\\n");
337            for warning in &report.warnings {
338                summary.push_str(&format!("   • {}\\n", warning));
339            }
340            summary.push_str("\\n");
341        }
342
343        // Recommendations
344        if !report.recommendations.is_empty() {
345            summary.push_str("💡 Recommendations:\\n");
346            for rec in &report.recommendations {
347                summary.push_str(&format!("   • {}\\n", rec));
348            }
349            summary.push_str("\\n");
350        }
351
352        // Physical constant values
353        summary.push_str("📏 Physical Constants:\\n");
354        summary.push_str(&format!("   Planck constant (h): {:.10e} J⋅s\\n", constants::PLANCK_H));
355        summary.push_str(&format!("   Reduced Planck (ℏ): {:.10e} J⋅s\\n", constants::PLANCK_HBAR));
356        summary.push_str(&format!("   Boltzmann (kB): {:.10e} J/K\\n", constants::BOLTZMANN_K));
357        summary.push_str(&format!("   Speed of light (c): {:.0} m/s\\n", constants::SPEED_OF_LIGHT));
358        summary.push_str(&format!("   eV to Joules: {:.10e}\\n", constants::EV_TO_JOULES));
359        summary.push_str(&format!("   Room temperature: {:.1} K\\n", constants::ROOM_TEMPERATURE_K));
360        summary.push_str(&format!("   Attosecond energy: {:.2} keV\\n", constants::ATTOSECOND_ENERGY_KEV));
361        summary.push_str(&format!("   Consciousness scale: {:.0e} s\\n", constants::CONSCIOUSNESS_SCALE_NS));
362
363        // Computational bounds
364        summary.push_str("\\n🧮 Computational Bounds:\\n");
365        let test_energy = 1e-15;
366        let min_time = constants::PLANCK_H / (4.0 * test_energy);
367        let min_uncertainty = constants::PLANCK_HBAR / 2.0;
368        let thermal_energy = constants::BOLTZMANN_K * constants::ROOM_TEMPERATURE_K;
369
370        summary.push_str(&format!("   Min time (1 fJ): {:.2e} s\\n", min_time));
371        summary.push_str(&format!("   Min uncertainty: {:.2e} J⋅s\\n", min_uncertainty));
372        summary.push_str(&format!("   Thermal energy: {:.2e} J ({:.1} meV)\\n",
373                                 thermal_energy, thermal_energy / constants::EV_TO_JOULES * 1000.0));
374
375        summary
376    }
377
378    /// Quick validation check for runtime use
379    pub fn quick_check() -> bool {
380        // Essential checks that must pass
381        constants::PLANCK_H > 0.0 &&
382        constants::PLANCK_HBAR > 0.0 &&
383        constants::BOLTZMANN_K > 0.0 &&
384        constants::SPEED_OF_LIGHT > 0.0 &&
385        constants::EV_TO_JOULES > 0.0 &&
386        (constants::PLANCK_HBAR - constants::PLANCK_H / (2.0 * PI)).abs() < 1e-40 &&
387        constants::CONSCIOUSNESS_SCALE_NS == 1e-9
388    }
389}
390
391#[cfg(test)]
392mod tests {
393    use super::*;
394
395    #[test]
396    fn test_physics_validation() {
397        let report = PhysicsValidator::validate_constants();
398
399        // Print full report for debugging
400        if !report.constants_valid || !report.computational_bounds_valid || !report.numerical_stability_valid {
401            println!("{}", PhysicsValidator::generate_summary(&report));
402        }
403
404        assert!(report.constants_valid, "Physics constants must be valid");
405        assert!(report.computational_bounds_valid, "Computational bounds must be valid");
406        assert!(report.numerical_stability_valid, "Numerical calculations must be stable");
407    }
408
409    #[test]
410    fn test_quick_check() {
411        assert!(PhysicsValidator::quick_check(), "Quick physics check must pass");
412    }
413
414    #[test]
415    fn test_constant_relationships() {
416        // Test fundamental relationships
417        let calculated_hbar = constants::PLANCK_H / (2.0 * PI);
418        assert!((constants::PLANCK_HBAR - calculated_hbar).abs() < 1e-40);
419
420        // Test unit conversions
421        let one_ev_in_joules = constants::EV_TO_JOULES;
422        assert!(one_ev_in_joules > 1e-20 && one_ev_in_joules < 1e-18);
423
424        // Test energy scales
425        let thermal_energy = constants::BOLTZMANN_K * constants::ROOM_TEMPERATURE_K;
426        let thermal_ev = thermal_energy / constants::EV_TO_JOULES;
427        assert!(thermal_ev > 0.02 && thermal_ev < 0.03); // ~25 meV
428
429        // Test attosecond energy
430        let attosecond_energy_j = constants::ATTOSECOND_ENERGY_KEV * 1000.0 * constants::EV_TO_JOULES;
431        assert!(attosecond_energy_j > thermal_energy * 1000.0);
432    }
433
434    #[test]
435    fn test_numerical_precision() {
436        // Test that we can distinguish small differences
437        let base = constants::PLANCK_H;
438        let epsilon = base * 1e-15;
439        assert!(base + epsilon > base);
440
441        // Test reciprocal precision
442        let energy = 1e-15;
443        let time = constants::PLANCK_H / (4.0 * energy);
444        let energy_back = constants::PLANCK_H / (4.0 * time);
445        let relative_error = (energy - energy_back).abs() / energy;
446        assert!(relative_error < 1e-12);
447    }
448
449    #[test]
450    fn test_physical_reasonableness() {
451        // Test that calculated times are physically reasonable
452        let femtojoule = 1e-15;
453        let min_time = constants::PLANCK_H / (4.0 * femtojoule);
454        assert!(min_time > 1e-25); // Much larger than Planck time
455        assert!(min_time < 1e-15); // Much smaller than femtosecond
456
457        // Test that uncertainty product is reasonable
458        let uncertainty_product = femtojoule * min_time;
459        let min_uncertainty = constants::PLANCK_HBAR / 2.0;
460        assert!(uncertainty_product >= min_uncertainty);
461
462        // Test consciousness time scale
463        assert_eq!(constants::CONSCIOUSNESS_SCALE_NS, 1e-9);
464        let ns_energy = constants::PLANCK_H / (4.0 * constants::CONSCIOUSNESS_SCALE_NS);
465        let ns_energy_ev = ns_energy / constants::EV_TO_JOULES;
466        assert!(ns_energy_ev < 1.0); // Should be sub-eV
467    }
468}