1use std::fmt::{Display, Formatter, Result as FmtResult};
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
14pub enum ComputationalComplexity {
15 Constant,
17 Logarithmic,
19 Linear,
21 Linearithmic,
23 Quadratic,
25 Cubic,
27 Exponential,
29}
30
31impl Display for ComputationalComplexity {
32 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
33 match self {
34 ComputationalComplexity::Constant => write!(f, "O(1)"),
35 ComputationalComplexity::Logarithmic => write!(f, "O(log n)"),
36 ComputationalComplexity::Linear => write!(f, "O(n)"),
37 ComputationalComplexity::Linearithmic => write!(f, "O(n log n)"),
38 ComputationalComplexity::Quadratic => write!(f, "O(n²)"),
39 ComputationalComplexity::Cubic => write!(f, "O(n³)"),
40 ComputationalComplexity::Exponential => write!(f, "O(2^n)"),
41 }
42 }
43}
44
45#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
47pub enum MemoryComplexity {
48 Constant,
50 Linear,
52 Quadratic,
54 Cubic,
56}
57
58impl Display for MemoryComplexity {
59 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
60 match self {
61 MemoryComplexity::Constant => write!(f, "O(1)"),
62 MemoryComplexity::Linear => write!(f, "O(n)"),
63 MemoryComplexity::Quadratic => write!(f, "O(n²)"),
64 MemoryComplexity::Cubic => write!(f, "O(n³)"),
65 }
66 }
67}
68
69#[derive(Debug, Clone)]
71pub struct PerformanceCharacteristics {
72 pub construction_complexity: ComputationalComplexity,
74 pub evaluation_complexity: ComputationalComplexity,
76 pub batch_evaluation_complexity: ComputationalComplexity,
78 pub memory_complexity: MemoryComplexity,
80 pub real_time_suitable: bool,
82 pub parallel_evaluation: bool,
84 pub numerically_stable: bool,
86 pub typical_accuracy: f64,
88}
89
90#[derive(Debug, Clone)]
92pub struct UsageRecommendation {
93 pub recommended_data_size: (usize, Option<usize>),
95 pub best_use_cases: Vec<String>,
97 pub avoid_when: Vec<String>,
99 pub alternatives: Vec<String>,
101 pub configuration_tips: Vec<String>,
103}
104
105#[derive(Debug, Clone)]
107pub struct MethodDocumentation {
108 pub method_name: String,
110 pub description: String,
112 pub performance: PerformanceCharacteristics,
114 pub usage: UsageRecommendation,
116 pub mathematical_background: String,
118 pub implementation_notes: Vec<String>,
120 pub references: Vec<String>,
122}
123
124#[allow(dead_code)]
126pub fn get_method_documentation(method_name: &str) -> Option<MethodDocumentation> {
127 match method_name {
128 "linear" => Some(linear_interpolation_docs()),
129 "cubic" => Some(cubic_interpolation_docs()),
130 "pchip" => Some(pchip_interpolation_docs()),
131 "bspline" => Some(bspline_interpolation_docs()),
132 "rbf" => Some(rbf_interpolation_docs()),
133 "kriging" => Some(kriging_interpolation_docs()),
134 "akima" => Some(akima_interpolation_docs()),
135 "hermite" => Some(hermite_interpolation_docs()),
136 _ => None,
137 }
138}
139
140#[allow(dead_code)]
142fn linear_interpolation_docs() -> MethodDocumentation {
143 MethodDocumentation {
144 method_name: "Linear Interpolation".to_string(),
145 description: "Piecewise linear interpolation connecting adjacent data points with straight lines".to_string(),
146 performance: PerformanceCharacteristics {
147 construction_complexity: ComputationalComplexity::Linear,
148 evaluation_complexity: ComputationalComplexity::Logarithmic,
149 batch_evaluation_complexity: ComputationalComplexity::Linearithmic,
150 memory_complexity: MemoryComplexity::Linear,
151 real_time_suitable: true,
152 parallel_evaluation: true,
153 numerically_stable: true,
154 typical_accuracy: 1e-2,
155 },
156 usage: UsageRecommendation {
157 recommended_data_size: (2, Some(1_000_000)),
158 best_use_cases: vec![
159 "Real-time applications".to_string(),
160 "Large datasets".to_string(),
161 "When simplicity is required".to_string(),
162 "Preserving monotonicity".to_string(),
163 ],
164 avoid_when: vec![
165 "High accuracy requirements".to_string(),
166 "Smooth derivatives needed".to_string(),
167 "Data has high curvature".to_string(),
168 ],
169 alternatives: vec![
170 "Cubic splines for smoothness".to_string(),
171 "PCHIP for shape preservation".to_string(),
172 "Akima for outlier robustness".to_string(),
173 ],
174 configuration_tips: vec![
175 "Ensure input data is sorted".to_string(),
176 "Consider preprocessing for noise reduction".to_string(),
177 ],
178 },
179 mathematical_background: "Given points (x₀,y₀)...(xₙ,yₙ), interpolates using f(x) = y₀ + (y₁-y₀)*(x-x₀)/(x₁-x₀) for x ∈ [x₀,x₁]".to_string(),
180 implementation_notes: vec![
181 "Uses binary search for interval location".to_string(),
182 "Supports extrapolation with constant or linear modes".to_string(),
183 "Vectorized implementation available for batch evaluation".to_string(),
184 ],
185 references: vec![
186 "Burden, R.L., Faires, J.D. (2010). Numerical Analysis, 9th Edition".to_string(),
187 ],
188 }
189}
190
191#[allow(dead_code)]
193fn cubic_interpolation_docs() -> MethodDocumentation {
194 MethodDocumentation {
195 method_name: "Cubic Spline Interpolation".to_string(),
196 description: "Smooth piecewise cubic polynomial interpolation with continuous first and second derivatives".to_string(),
197 performance: PerformanceCharacteristics {
198 construction_complexity: ComputationalComplexity::Linear,
199 evaluation_complexity: ComputationalComplexity::Logarithmic,
200 batch_evaluation_complexity: ComputationalComplexity::Linearithmic,
201 memory_complexity: MemoryComplexity::Linear,
202 real_time_suitable: false,
203 parallel_evaluation: true,
204 numerically_stable: true,
205 typical_accuracy: 1e-6,
206 },
207 usage: UsageRecommendation {
208 recommended_data_size: (4, Some(100_000)),
209 best_use_cases: vec![
210 "Smooth curve fitting".to_string(),
211 "Derivative estimation".to_string(),
212 "Integration applications".to_string(),
213 "Animation and graphics".to_string(),
214 ],
215 avoid_when: vec![
216 "Real-time constraints".to_string(),
217 "Non-smooth underlying functions".to_string(),
218 "Presence of outliers".to_string(),
219 ],
220 alternatives: vec![
221 "Linear for speed".to_string(),
222 "PCHIP for shape preservation".to_string(),
223 "B-splines for more control".to_string(),
224 ],
225 configuration_tips: vec![
226 "Choose appropriate boundary conditions".to_string(),
227 "Natural boundaries for unknown derivatives".to_string(),
228 "Clamped boundaries when derivatives are known".to_string(),
229 ],
230 },
231 mathematical_background: "Constructs cubic polynomials S(x) = aᵢ + bᵢ(x-xᵢ) + cᵢ(x-xᵢ)² + dᵢ(x-xᵢ)³ with C² continuity".to_string(),
232 implementation_notes: vec![
233 "Solves tridiagonal system for coefficients".to_string(),
234 "Supports multiple boundary conditions".to_string(),
235 "Provides derivative and integral methods".to_string(),
236 ],
237 references: vec![
238 "de Boor, C. (1978). A Practical Guide to Splines".to_string(),
239 "Burden, R.L., Faires, J.D. (2010). Numerical Analysis, 9th Edition".to_string(),
240 ],
241 }
242}
243
244#[allow(dead_code)]
246fn pchip_interpolation_docs() -> MethodDocumentation {
247 MethodDocumentation {
248 method_name: "PCHIP (Piecewise Cubic Hermite Interpolating Polynomial)".to_string(),
249 description: "Shape-preserving cubic interpolation that maintains monotonicity and avoids overshooting".to_string(),
250 performance: PerformanceCharacteristics {
251 construction_complexity: ComputationalComplexity::Linear,
252 evaluation_complexity: ComputationalComplexity::Logarithmic,
253 batch_evaluation_complexity: ComputationalComplexity::Linearithmic,
254 memory_complexity: MemoryComplexity::Linear,
255 real_time_suitable: false,
256 parallel_evaluation: true,
257 numerically_stable: true,
258 typical_accuracy: 1e-4,
259 },
260 usage: UsageRecommendation {
261 recommended_data_size: (3, Some(50_000)),
262 best_use_cases: vec![
263 "Monotonic data".to_string(),
264 "Avoiding oscillations".to_string(),
265 "Financial data interpolation".to_string(),
266 "Physical measurements".to_string(),
267 ],
268 avoid_when: vec![
269 "High-frequency oscillations needed".to_string(),
270 "Maximum smoothness required".to_string(),
271 ],
272 alternatives: vec![
273 "Cubic splines for smoothness".to_string(),
274 "Akima for outlier robustness".to_string(),
275 "Linear for simplicity".to_string(),
276 ],
277 configuration_tips: vec![
278 "Works best with monotonic data".to_string(),
279 "No additional parameters needed".to_string(),
280 ],
281 },
282 mathematical_background: "Uses Fritsch-Carlson method to compute derivatives that preserve shape, then builds cubic Hermite polynomials".to_string(),
283 implementation_notes: vec![
284 "Automatically computes shape-preserving derivatives".to_string(),
285 "Handles flat regions gracefully".to_string(),
286 "No oscillations near extrema".to_string(),
287 ],
288 references: vec![
289 "Fritsch, F.N., Carlson, R.E. (1980). Monotone Piecewise Cubic Interpolation".to_string(),
290 ],
291 }
292}
293
294#[allow(dead_code)]
296fn bspline_interpolation_docs() -> MethodDocumentation {
297 MethodDocumentation {
298 method_name: "B-spline Interpolation".to_string(),
299 description: "Flexible spline interpolation using basis functions with adjustable degree and knot placement".to_string(),
300 performance: PerformanceCharacteristics {
301 construction_complexity: ComputationalComplexity::Linear,
302 evaluation_complexity: ComputationalComplexity::Constant,
303 batch_evaluation_complexity: ComputationalComplexity::Linear,
304 memory_complexity: MemoryComplexity::Linear,
305 real_time_suitable: true,
306 parallel_evaluation: true,
307 numerically_stable: true,
308 typical_accuracy: 1e-8,
309 },
310 usage: UsageRecommendation {
311 recommended_data_size: (5, Some(1_000_000)),
312 best_use_cases: vec![
313 "CAD/CAM applications".to_string(),
314 "Computer graphics".to_string(),
315 "Signal processing".to_string(),
316 "Large datasets".to_string(),
317 ],
318 avoid_when: vec![
319 "Simple linear relationships".to_string(),
320 "When knot placement is unclear".to_string(),
321 ],
322 alternatives: vec![
323 "Cubic splines for automatic knot placement".to_string(),
324 "NURBS for rational curves".to_string(),
325 ],
326 configuration_tips: vec![
327 "Choose degree based on smoothness needs".to_string(),
328 "Use uniform knots for regular data".to_string(),
329 "Consider least-squares fitting for noisy data".to_string(),
330 ],
331 },
332 mathematical_background: "Constructs splines as linear combinations of B-spline basis functions: S(x) = Σ cᵢ Nᵢ,ₖ(x)".to_string(),
333 implementation_notes: vec![
334 "Uses de Boor's algorithm for evaluation".to_string(),
335 "Supports arbitrary degree and knot vectors".to_string(),
336 "Efficient derivative computation".to_string(),
337 ],
338 references: vec![
339 "de Boor, C. (1978). A Practical Guide to Splines".to_string(),
340 "Piegl, L., Tiller, W. (1997). The NURBS Book".to_string(),
341 ],
342 }
343}
344
345#[allow(dead_code)]
347fn rbf_interpolation_docs() -> MethodDocumentation {
348 MethodDocumentation {
349 method_name: "Radial Basis Function (RBF) Interpolation".to_string(),
350 description: "Meshfree interpolation method using radially symmetric basis functions centered at data points".to_string(),
351 performance: PerformanceCharacteristics {
352 construction_complexity: ComputationalComplexity::Cubic,
353 evaluation_complexity: ComputationalComplexity::Linear,
354 batch_evaluation_complexity: ComputationalComplexity::Quadratic,
355 memory_complexity: MemoryComplexity::Quadratic,
356 real_time_suitable: false,
357 parallel_evaluation: true,
358 numerically_stable: false, typical_accuracy: 1e-10,
360 },
361 usage: UsageRecommendation {
362 recommended_data_size: (5, Some(5_000)),
363 best_use_cases: vec![
364 "Scattered data interpolation".to_string(),
365 "Multivariate interpolation".to_string(),
366 "Irregular grids".to_string(),
367 "High accuracy requirements".to_string(),
368 ],
369 avoid_when: vec![
370 "Large datasets (>10,000 points)".to_string(),
371 "Real-time applications".to_string(),
372 "Ill-conditioned data".to_string(),
373 ],
374 alternatives: vec![
375 "Fast RBF for large datasets".to_string(),
376 "Kriging for uncertainty quantification".to_string(),
377 "Moving least squares for local approximation".to_string(),
378 ],
379 configuration_tips: vec![
380 "Choose shape parameter carefully".to_string(),
381 "Use regularization for stability".to_string(),
382 "Consider conditioning for large datasets".to_string(),
383 ],
384 },
385 mathematical_background: "Approximates f(x) = Σ λᵢ φ(||x - xᵢ||) where φ is the RBF and λᵢ are coefficients".to_string(),
386 implementation_notes: vec![
387 "Solves dense linear system Aλ = f".to_string(),
388 "Multiple kernel options available".to_string(),
389 "Supports polynomial augmentation".to_string(),
390 ],
391 references: vec![
392 "Buhmann, M.D. (2003). Radial Basis Functions: Theory and Implementations".to_string(),
393 "Fasshauer, G.E. (2007). Meshfree Approximation Methods with MATLAB".to_string(),
394 ],
395 }
396}
397
398#[allow(dead_code)]
400fn kriging_interpolation_docs() -> MethodDocumentation {
401 MethodDocumentation {
402 method_name: "Kriging (Gaussian Process Regression)".to_string(),
403 description: "Statistical interpolation method that provides uncertainty estimates along with predictions".to_string(),
404 performance: PerformanceCharacteristics {
405 construction_complexity: ComputationalComplexity::Cubic,
406 evaluation_complexity: ComputationalComplexity::Linear,
407 batch_evaluation_complexity: ComputationalComplexity::Quadratic,
408 memory_complexity: MemoryComplexity::Quadratic,
409 real_time_suitable: false,
410 parallel_evaluation: true,
411 numerically_stable: false, typical_accuracy: 1e-8,
413 },
414 usage: UsageRecommendation {
415 recommended_data_size: (5, Some(3_000)),
416 best_use_cases: vec![
417 "Uncertainty quantification".to_string(),
418 "Noisy data".to_string(),
419 "Spatial statistics".to_string(),
420 "Optimization (Bayesian)".to_string(),
421 ],
422 avoid_when: vec![
423 "Large datasets".to_string(),
424 "Deterministic data".to_string(),
425 "Real-time requirements".to_string(),
426 ],
427 alternatives: vec![
428 "Fast kriging for larger datasets".to_string(),
429 "RBF for deterministic interpolation".to_string(),
430 "Enhanced kriging for better conditioning".to_string(),
431 ],
432 configuration_tips: vec![
433 "Choose covariance function based on data characteristics".to_string(),
434 "Use nugget effect for noisy data".to_string(),
435 "Consider anisotropy for directional data".to_string(),
436 ],
437 },
438 mathematical_background: "Models data as realization of Gaussian process: f(x) ~ GP(μ(x), k(x,x')) with covariance function k".to_string(),
439 implementation_notes: vec![
440 "Provides prediction variance".to_string(),
441 "Multiple covariance functions supported".to_string(),
442 "Can handle trend functions".to_string(),
443 ],
444 references: vec![
445 "Cressie, N. (1993). Statistics for Spatial Data".to_string(),
446 "Rasmussen, C.E., Williams, C.K.I. (2006). Gaussian Processes for Machine Learning".to_string(),
447 ],
448 }
449}
450
451#[allow(dead_code)]
453fn akima_interpolation_docs() -> MethodDocumentation {
454 MethodDocumentation {
455 method_name: "Akima Spline Interpolation".to_string(),
456 description: "Robust piecewise cubic interpolation that reduces oscillations and is less sensitive to outliers".to_string(),
457 performance: PerformanceCharacteristics {
458 construction_complexity: ComputationalComplexity::Linear,
459 evaluation_complexity: ComputationalComplexity::Logarithmic,
460 batch_evaluation_complexity: ComputationalComplexity::Linearithmic,
461 memory_complexity: MemoryComplexity::Linear,
462 real_time_suitable: false,
463 parallel_evaluation: true,
464 numerically_stable: true,
465 typical_accuracy: 1e-5,
466 },
467 usage: UsageRecommendation {
468 recommended_data_size: (5, Some(50_000)),
469 best_use_cases: vec![
470 "Data with outliers".to_string(),
471 "Irregular spacing".to_string(),
472 "Avoiding oscillations".to_string(),
473 "Geophysical data".to_string(),
474 ],
475 avoid_when: vec![
476 "Maximum smoothness required".to_string(),
477 "High-frequency content".to_string(),
478 ],
479 alternatives: vec![
480 "Cubic splines for smoothness".to_string(),
481 "PCHIP for monotonicity".to_string(),
482 "Robust splines for heavy outliers".to_string(),
483 ],
484 configuration_tips: vec![
485 "No parameters to tune".to_string(),
486 "Works well with default settings".to_string(),
487 ],
488 },
489 mathematical_background: "Uses local polynomial fitting with weighted averages to estimate derivatives, reducing oscillations".to_string(),
490 implementation_notes: vec![
491 "Estimates derivatives using Akima's method".to_string(),
492 "Less sensitive to isolated outliers".to_string(),
493 "Maintains local shape characteristics".to_string(),
494 ],
495 references: vec![
496 "Akima, H. (1970). A New Method of Interpolation and Smooth Curve Fitting".to_string(),
497 ],
498 }
499}
500
501#[allow(dead_code)]
503fn hermite_interpolation_docs() -> MethodDocumentation {
504 MethodDocumentation {
505 method_name: "Hermite Interpolation".to_string(),
506 description: "Polynomial interpolation that matches both function values and derivatives at specified points".to_string(),
507 performance: PerformanceCharacteristics {
508 construction_complexity: ComputationalComplexity::Quadratic,
509 evaluation_complexity: ComputationalComplexity::Linear,
510 batch_evaluation_complexity: ComputationalComplexity::Quadratic,
511 memory_complexity: MemoryComplexity::Quadratic,
512 real_time_suitable: false,
513 parallel_evaluation: true,
514 numerically_stable: false, typical_accuracy: 1e-12,
516 },
517 usage: UsageRecommendation {
518 recommended_data_size: (2, Some(1_000)),
519 best_use_cases: vec![
520 "Known derivatives".to_string(),
521 "Boundary value problems".to_string(),
522 "Animation interpolation".to_string(),
523 "Small datasets".to_string(),
524 ],
525 avoid_when: vec![
526 "Large datasets".to_string(),
527 "Unknown derivatives".to_string(),
528 "Risk of oscillations".to_string(),
529 ],
530 alternatives: vec![
531 "Cubic splines for large datasets".to_string(),
532 "PCHIP for automatic derivatives".to_string(),
533 "B-splines for better conditioning".to_string(),
534 ],
535 configuration_tips: vec![
536 "Provide accurate derivatives".to_string(),
537 "Consider piecewise approach for large intervals".to_string(),
538 ],
539 },
540 mathematical_background: "Constructs polynomial of degree 2n-1 to interpolate n points with specified derivatives".to_string(),
541 implementation_notes: vec![
542 "Supports cubic and quintic variants".to_string(),
543 "Multiple derivative specification methods".to_string(),
544 "Direct polynomial evaluation".to_string(),
545 ],
546 references: vec![
547 "Burden, R.L., Faires, J.D. (2010). Numerical Analysis, 9th Edition".to_string(),
548 ],
549 }
550}
551
552#[allow(dead_code)]
554pub fn print_method_comparison() {
555 let methods = [
556 "linear", "cubic", "pchip", "bspline", "rbf", "kriging", "akima", "hermite",
557 ];
558
559 println!("# Interpolation Methods Comparison\n");
560
561 for method in &methods {
562 if let Some(doc) = get_method_documentation(method) {
563 println!("## {}\n", doc.method_name);
564 println!("{}\n", doc.description);
565
566 println!("**Performance Characteristics:**");
567 println!(
568 "- Construction: {}",
569 doc.performance.construction_complexity
570 );
571 println!("- Evaluation: {}", doc.performance.evaluation_complexity);
572 println!("- Memory: {}", doc.performance.memory_complexity);
573 println!(
574 "- Real-time suitable: {}",
575 doc.performance.real_time_suitable
576 );
577 println!(
578 "- Typical accuracy: {:.0e}\n",
579 doc.performance.typical_accuracy
580 );
581
582 println!("**Best for:** {}\n", doc.usage.best_use_cases.join(", "));
583 println!("**Avoid when:** {}\n", doc.usage.avoid_when.join(", "));
584 println!("---\n");
585 }
586 }
587}
588
589#[cfg(test)]
590mod tests {
591 use super::*;
592
593 #[test]
594 fn test_complexity_display() {
595 assert_eq!(ComputationalComplexity::Linear.to_string(), "O(n)");
596 assert_eq!(ComputationalComplexity::Quadratic.to_string(), "O(n²)");
597 assert_eq!(MemoryComplexity::Linear.to_string(), "O(n)");
598 }
599
600 #[test]
601 fn test_method_documentation_available() {
602 assert!(get_method_documentation("linear").is_some());
603 assert!(get_method_documentation("cubic").is_some());
604 assert!(get_method_documentation("unknown").is_none());
605 }
606}