1use crate::core::Expression;
8use std::collections::HashMap;
9
10pub struct AccuracyVerifier {
15 verified_constants: HashMap<String, VerifiedConstant>,
17
18 verified_relationships: HashMap<String, VerifiedRelationship>,
20
21 accuracy_thresholds: HashMap<String, f64>,
23}
24
25#[derive(Debug, Clone)]
27pub struct VerifiedConstant {
28 pub name: String,
30
31 pub value: Expression,
33
34 pub reference: String,
36
37 pub precision: u32,
39
40 pub alternative_forms: Vec<Expression>,
42}
43
44#[derive(Debug, Clone)]
46pub struct VerifiedRelationship {
47 pub name: String,
49
50 pub formula: String,
52
53 pub expression: Expression,
55
56 pub reference: String,
58
59 pub domain: String,
61
62 pub test_points: Vec<(Vec<f64>, f64)>,
64}
65
66impl Default for AccuracyVerifier {
67 fn default() -> Self {
68 Self::new()
69 }
70}
71
72impl AccuracyVerifier {
73 pub fn new() -> Self {
75 let mut verifier = Self {
76 verified_constants: HashMap::with_capacity(64),
77 verified_relationships: HashMap::with_capacity(128),
78 accuracy_thresholds: HashMap::with_capacity(32),
79 };
80
81 verifier.initialize_verified_constants();
82 verifier.initialize_verified_relationships();
83 verifier.initialize_accuracy_thresholds();
84
85 verifier
86 }
87
88 fn initialize_verified_constants(&mut self) {
92 self.verified_constants.insert(
94 "pi".to_owned(),
95 VerifiedConstant {
96 name: "π".to_owned(),
97 value: Expression::pi(),
98 reference: "NIST CODATA 2018, Archimedes ~250 BC".to_owned(),
99 precision: 50, alternative_forms: vec![
101 Expression::function("leibniz_pi_series", vec![]),
103 Expression::function("machin_pi_formula", vec![]),
105 Expression::function("basel_pi_formula", vec![]),
107 ],
108 },
109 );
110
111 self.verified_constants.insert(
113 "e".to_owned(),
114 VerifiedConstant {
115 name: "e".to_owned(),
116 value: Expression::e(),
117 reference: "Euler 1748, NIST mathematical constants".to_owned(),
118 precision: 50,
119 alternative_forms: vec![
120 Expression::function("euler_e_series", vec![]),
122 Expression::function("euler_e_limit", vec![]),
124 ],
125 },
126 );
127
128 self.verified_constants.insert(
130 "euler_gamma".to_owned(),
131 VerifiedConstant {
132 name: "γ".to_owned(),
133 value: Expression::euler_gamma(),
134 reference: "Euler 1761, Mascheroni 1790, OEIS A001620".to_owned(),
135 precision: 50,
136 alternative_forms: vec![
137 Expression::function("euler_gamma_limit", vec![]),
139 Expression::function("euler_gamma_integral", vec![]),
141 ],
142 },
143 );
144
145 self.verified_constants.insert(
147 "golden_ratio".to_owned(),
148 VerifiedConstant {
149 name: "φ".to_owned(),
150 value: Expression::golden_ratio(),
151 reference: "Euclid ~300 BC, Fibonacci sequence analysis".to_owned(),
152 precision: 50,
153 alternative_forms: vec![
154 Expression::function("golden_ratio_formula", vec![]),
156 Expression::function("golden_ratio_continued_fraction", vec![]),
158 ],
159 },
160 );
161
162 self.verified_constants.insert(
164 "catalan".to_owned(),
165 VerifiedConstant {
166 name: "G".to_owned(),
167 value: Expression::function("catalan_constant", vec![]),
168 reference: "Catalan 1865, OEIS A006752".to_owned(),
169 precision: 50,
170 alternative_forms: vec![
171 Expression::function("catalan_series", vec![]),
173 Expression::function("catalan_integral", vec![]),
175 ],
176 },
177 );
178 }
179
180 fn initialize_verified_relationships(&mut self) {
184 self.verified_relationships.insert(
186 "euler_identity".to_owned(),
187 VerifiedRelationship {
188 name: "Euler's Identity".to_owned(),
189 formula: "e^(iπ) + 1 = 0".to_owned(),
190 expression: Expression::add(vec![
191 Expression::function(
192 "exp",
193 vec![Expression::mul(vec![Expression::i(), Expression::pi()])],
194 ),
195 Expression::integer(1),
196 ]),
197 reference: "Euler 1748, 'most beautiful equation in mathematics'".to_owned(),
198 domain: "Complex numbers".to_owned(),
199 test_points: vec![], },
201 );
202
203 self.verified_relationships.insert(
205 "stirling_approximation".to_owned(),
206 VerifiedRelationship {
207 name: "Stirling's Approximation".to_owned(),
208 formula: "n! ≈ √(2πn) (n/e)^n".to_owned(),
209 expression: Expression::function("stirling_formula", vec![Expression::symbol("n")]),
210 reference: "Stirling 1730, Abramowitz & Stegun 6.1.37".to_owned(),
211 domain: "n → ∞, n ∈ ℕ".to_owned(),
212 test_points: vec![
213 (vec![10.0], 3628800.0), (vec![20.0], 2.43290200817664e18), ],
216 },
217 );
218
219 self.verified_relationships.insert(
221 "basel_problem".to_owned(),
222 VerifiedRelationship {
223 name: "Basel Problem Solution".to_owned(),
224 formula: "ζ(2) = π²/6 = Σ(1/n²)".to_owned(),
225 expression: Expression::function("riemann_zeta", vec![Expression::integer(2)]),
226 reference: "Euler 1734, Basel problem solution".to_owned(),
227 domain: "Convergent infinite series".to_owned(),
228 test_points: vec![
229 (vec![2.0], 1.6449340668482264), ],
231 },
232 );
233
234 self.verified_relationships.insert(
236 "gamma_reflection".to_owned(),
237 VerifiedRelationship {
238 name: "Gamma Function Reflection Formula".to_owned(),
239 formula: "Γ(z)Γ(1-z) = π/sin(πz)".to_owned(),
240 expression: Expression::function(
241 "gamma_reflection_formula",
242 vec![Expression::symbol("z")],
243 ),
244 reference: "Euler 1729, Abramowitz & Stegun 6.1.17".to_owned(),
245 domain: "z ∉ ℤ".to_owned(),
246 test_points: vec![
247 (vec![0.5], std::f64::consts::PI), ],
249 },
250 );
251
252 self.verified_relationships.insert(
254 "jacobi_triple_product".to_owned(),
255 VerifiedRelationship {
256 name: "Jacobi Triple Product".to_owned(),
257 formula: "∏(1-q^{2n})(1+q^{2n-1}z)(1+q^{2n-1}/z) = Σ q^{n²} z^n".to_owned(),
258 expression: Expression::function(
259 "jacobi_triple_product",
260 vec![Expression::symbol("q"), Expression::symbol("z")],
261 ),
262 reference: "Jacobi 1829, Whittaker & Watson 21.1".to_owned(),
263 domain: "|q| < 1, z ≠ 0".to_owned(),
264 test_points: vec![], },
266 );
267 }
268
269 fn initialize_accuracy_thresholds(&mut self) {
271 self.accuracy_thresholds
273 .insert("elementary".to_owned(), 1e-15);
274
275 self.accuracy_thresholds.insert("special".to_owned(), 1e-12);
277
278 self.accuracy_thresholds
280 .insert("polynomial".to_owned(), 1e-14);
281
282 self.accuracy_thresholds
284 .insert("hypergeometric".to_owned(), 1e-10);
285
286 self.accuracy_thresholds
288 .insert("elliptic".to_owned(), 1e-11);
289 }
290
291 pub fn verify_accuracy(&self, function_class: &str, computed: f64, expected: f64) -> bool {
295 if let Some(&threshold) = self.accuracy_thresholds.get(function_class) {
296 let relative_error = ((computed - expected) / expected).abs();
297 relative_error < threshold
298 } else {
299 let relative_error = ((computed - expected) / expected).abs();
301 relative_error < 1e-12
302 }
303 }
304
305 pub fn get_verified_constant(&self, name: &str) -> Option<&VerifiedConstant> {
307 self.verified_constants.get(name)
308 }
309
310 pub fn get_verified_relationship(&self, name: &str) -> Option<&VerifiedRelationship> {
312 self.verified_relationships.get(name)
313 }
314
315 pub fn generate_accuracy_report(&self) -> String {
317 let mut report = String::new();
318
319 report.push_str("# Mathematical Accuracy Verification Report\n\n");
320
321 report.push_str("## Verified Constants\n");
322 for (name, constant) in &self.verified_constants {
323 report.push_str(&format!(
324 "- **{}**: {} (Precision: {} digits, Reference: {})\n",
325 name, constant.name, constant.precision, constant.reference
326 ));
327 }
328
329 report.push_str("\n## Verified Relationships\n");
330 for (name, relationship) in &self.verified_relationships {
331 report.push_str(&format!(
332 "- **{}**: {} (Domain: {}, Reference: {})\n",
333 name, relationship.formula, relationship.domain, relationship.reference
334 ));
335 }
336
337 report.push_str("\n## Accuracy Thresholds\n");
338 for (class, threshold) in &self.accuracy_thresholds {
339 report.push_str(&format!(
340 "- **{}**: {:.0e} relative error\n",
341 class, threshold
342 ));
343 }
344
345 report
346 }
347}
348
349use once_cell::sync::Lazy;
351pub static ACCURACY_VERIFIER: Lazy<AccuracyVerifier> = Lazy::new(AccuracyVerifier::new);