pub mod advanced;
pub mod config;
pub mod core;
pub mod types;
pub mod factory;
pub mod physics;
pub use types::{
ARFittingMethod, AdaptiveSelectionCriterion, BoundaryType, DataCharacteristics,
EnsembleCombinationStrategy, ExtrapolationDirection, ExtrapolationMethod, PhysicsLaw,
};
pub use config::{
AdaptiveExtrapolationConfig, AutoregressiveExtrapolationConfig, ConfidenceExtrapolationConfig,
ConfidenceExtrapolationResult, EnsembleExtrapolationConfig, ExtrapolationConfig,
ExtrapolationConfigBuilder, ExtrapolationParameters,
};
pub use advanced::AdvancedExtrapolator;
pub use core::Extrapolator;
pub use factory::{
make_adaptive_extrapolator, make_autoregressive_extrapolator, make_confidence_extrapolator,
make_conservative_extrapolator, make_cubic_extrapolator, make_ensemble_extrapolator,
make_exponential_extrapolator, make_high_confidence_extrapolator, make_linear_extrapolator,
make_monotonic_extrapolator, make_nearest_extrapolator, make_oscillatory_extrapolator,
make_periodic_extrapolator, make_power_law_extrapolator, make_reflection_extrapolator,
make_robust_ensemble_extrapolator, make_smooth_function_extrapolator, make_zeros_extrapolator,
};
pub use physics::{
analyze_physics_characteristics, make_boundary_layer_extrapolator,
make_boundary_preserving_extrapolator, make_conservation_law_extrapolator,
make_constrained_extrapolator, make_diffusion_equation_extrapolator,
make_physics_informed_extrapolator, make_smart_adaptive_extrapolator,
make_wave_equation_extrapolator,
};
pub use advanced::AdvancedExtrapolator as AdvancedExtrapolationEngine;
pub use core::Extrapolator as ExtrapolationEngine;
pub fn create_basic_extrapolator<T: scirs2_core::numeric::Float + std::fmt::Display>(
lower_bound: T,
upper_bound: T,
lower_value: T,
upper_value: T,
) -> Extrapolator<T> {
use crate::extrapolation_modules::factory::make_linear_extrapolator;
let domain_width = upper_bound - lower_bound;
let slope = (upper_value - lower_value) / domain_width;
make_linear_extrapolator(
lower_bound,
upper_bound,
lower_value,
upper_value,
slope,
slope,
)
}
pub fn create_robust_extrapolator<
T: scirs2_core::numeric::Float + std::fmt::Display + std::default::Default + std::ops::AddAssign,
>(
lower_bound: T,
upper_bound: T,
lower_value: T,
upper_value: T,
lower_derivative: T,
upper_derivative: T,
) -> AdvancedExtrapolator<T> {
use crate::extrapolation_modules::factory::make_robust_ensemble_extrapolator;
make_robust_ensemble_extrapolator(
lower_bound,
upper_bound,
lower_value,
upper_value,
lower_derivative,
upper_derivative,
)
}
pub fn create_smart_extrapolator<
T: scirs2_core::numeric::Float
+ scirs2_core::numeric::FromPrimitive
+ std::fmt::Display
+ std::default::Default
+ std::ops::AddAssign,
>(
lower_bound: T,
upper_bound: T,
lower_value: T,
upper_value: T,
lower_derivative: T,
upper_derivative: T,
data_characteristics: &DataCharacteristics<T>,
) -> AdvancedExtrapolator<T> {
use crate::extrapolation_modules::physics::make_smart_adaptive_extrapolator;
make_smart_adaptive_extrapolator(
lower_bound,
upper_bound,
lower_value,
upper_value,
lower_derivative,
upper_derivative,
data_characteristics,
)
}
pub fn analyze_data_for_extrapolation<
T: scirs2_core::numeric::Float + scirs2_core::numeric::FromPrimitive,
>(
values: &[T],
gradients: Option<&[T]>,
) -> DataCharacteristics<T> {
use crate::extrapolation_modules::physics::analyze_physics_characteristics;
analyze_physics_characteristics(values, gradients, None)
}
#[cfg(test)]
mod tests {
use super::*;
use approx::assert_abs_diff_eq;
#[test]
fn test_basic_extrapolator_creation() {
let extrapolator = create_basic_extrapolator(0.0, 10.0, 0.0, 10.0);
assert_eq!(extrapolator.lower_bound(), 0.0);
assert_eq!(extrapolator.upper_bound(), 10.0);
}
#[test]
fn test_linear_extrapolation() {
let extrapolator = make_linear_extrapolator(0.0, 10.0, 0.0, 10.0, 1.0, 1.0);
let result = extrapolator.extrapolate(-5.0).expect("Operation failed");
assert_abs_diff_eq!(result, -5.0, epsilon = 1e-10);
let result = extrapolator.extrapolate(15.0).expect("Operation failed");
assert_abs_diff_eq!(result, 15.0, epsilon = 1e-10);
}
#[test]
fn test_constant_extrapolation() {
let extrapolator = Extrapolator::new(
0.0,
10.0,
5.0,
15.0,
ExtrapolationMethod::Constant,
ExtrapolationMethod::Constant,
);
let result = extrapolator.extrapolate(-5.0).expect("Operation failed");
assert_abs_diff_eq!(result, 5.0, epsilon = 1e-10);
let result = extrapolator.extrapolate(15.0).expect("Operation failed");
assert_abs_diff_eq!(result, 15.0, epsilon = 1e-10);
}
#[test]
fn test_zeros_extrapolation() {
let extrapolator = make_zeros_extrapolator(0.0, 10.0);
let result = extrapolator.extrapolate(-5.0).expect("Operation failed");
assert_abs_diff_eq!(result, 0.0, epsilon = 1e-10);
let result = extrapolator.extrapolate(15.0).expect("Operation failed");
assert_abs_diff_eq!(result, 0.0, epsilon = 1e-10);
}
#[test]
fn test_periodic_extrapolation() {
let extrapolator = make_periodic_extrapolator(0.0, 1.0, Some(1.0));
let result = extrapolator.extrapolate(-0.3);
assert!(result.is_ok());
let result = extrapolator.extrapolate(1.3);
assert!(result.is_ok());
}
#[test]
fn test_data_characteristics_analysis() {
let values = vec![1.0, 2.0, 3.0, 4.0, 5.0];
let gradient_vec = vec![1.0, 1.0, 1.0, 1.0];
let gradients = Some(gradient_vec.as_slice());
let characteristics = analyze_data_for_extrapolation(&values, gradients);
assert!(characteristics.is_monotonic);
assert!(!characteristics.is_periodic);
assert!(!characteristics.is_oscillatory);
}
#[test]
fn test_robust_extrapolator_creation() {
let extrapolator = create_robust_extrapolator(0.0, 10.0, 0.0, 10.0, 1.0, 1.0);
assert!(extrapolator.has_ensemble());
let result = extrapolator.extrapolate_advanced(-5.0);
assert!(result.is_ok());
}
#[test]
fn test_domain_checking() {
let extrapolator = create_basic_extrapolator(0.0, 10.0, 0.0, 10.0);
assert!(extrapolator.is_in_domain(5.0));
assert!(!extrapolator.is_in_domain(-1.0));
assert!(!extrapolator.is_in_domain(11.0));
assert_abs_diff_eq!(extrapolator.domain_width(), 10.0, epsilon = 1e-10);
}
}