pub mod avci_2015;
pub mod boona_2014;
pub mod cornelissen_2015;
pub mod demidov_2006;
pub mod garello_2013;
pub mod liu_2012;
pub mod miron_2011;
pub mod mosendz_2010;
pub mod nakayama_2013;
pub mod nogues_1999;
pub mod saitoh_2006;
pub mod uchida_2008;
pub mod woo_2016;
#[derive(Debug, Clone)]
pub struct ValidationResult {
pub name: String,
pub max_relative_error: f64,
pub mean_relative_error: f64,
pub n_points: usize,
pub tolerance: f64,
pub passed: bool,
}
impl ValidationResult {
pub fn new(name: impl Into<String>, errors: &[f64], tolerance: f64) -> Self {
let n_points = errors.len();
let (max_relative_error, mean_relative_error) = if n_points == 0 {
(0.0, 0.0)
} else {
let max = errors.iter().copied().fold(0.0_f64, f64::max);
let mean = errors.iter().sum::<f64>() / (n_points as f64);
(max, mean)
};
let passed = max_relative_error <= tolerance;
Self {
name: name.into(),
max_relative_error,
mean_relative_error,
n_points,
tolerance,
passed,
}
}
pub fn summary(&self) -> String {
format!(
"{}: max={:.4}, mean={:.4} over {} pts (tol={:.2}) -> {}",
self.name,
self.max_relative_error,
self.mean_relative_error,
self.n_points,
self.tolerance,
if self.passed { "PASS" } else { "FAIL" }
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_validation_result_pass() {
let errors = vec![0.05, 0.10, 0.15, 0.08];
let result = ValidationResult::new("test", &errors, 0.30);
assert_eq!(result.n_points, 4);
assert!((result.max_relative_error - 0.15).abs() < 1e-12);
assert!((result.mean_relative_error - 0.095).abs() < 1e-12);
assert!(result.passed);
}
#[test]
fn test_validation_result_fail() {
let errors = vec![0.05, 0.40];
let result = ValidationResult::new("test", &errors, 0.30);
assert!(!result.passed);
assert!((result.max_relative_error - 0.40).abs() < 1e-12);
}
#[test]
fn test_validation_result_empty() {
let errors: Vec<f64> = vec![];
let result = ValidationResult::new("empty", &errors, 0.30);
assert_eq!(result.n_points, 0);
assert_eq!(result.max_relative_error, 0.0);
assert_eq!(result.mean_relative_error, 0.0);
assert!(result.passed); }
#[test]
fn test_summary_format() {
let errors = vec![0.10, 0.20];
let result = ValidationResult::new("foo", &errors, 0.30);
let s = result.summary();
assert!(s.contains("foo"));
assert!(s.contains("PASS"));
assert!(s.contains("max="));
assert!(s.contains("mean="));
}
}