use super::{nearest_distance, validate_dimension_consistency, validate_non_empty};
use crate::error::GaError;
pub fn generational_distance(
approx_front: &[Vec<f64>],
true_front: &[Vec<f64>],
power: f64,
) -> Result<f64, GaError> {
validate_non_empty("approx_front", approx_front)?;
validate_non_empty("true_front", true_front)?;
let approx_dim = validate_dimension_consistency(approx_front)?;
let true_dim = validate_dimension_consistency(true_front)?;
if approx_dim != true_dim {
return Err(GaError::InvalidIndicatorConfiguration(format!(
"Dimension mismatch: approx_front has {} dimensions, true_front has {}",
approx_dim, true_dim,
)));
}
if power <= 0.0 {
return Err(GaError::InvalidIndicatorConfiguration(
"Power must be positive".to_string(),
));
}
let sum: f64 = approx_front
.iter()
.map(|point| nearest_distance(point, true_front, power))
.sum();
let mean = sum / approx_front.len() as f64;
Ok(mean.powf(1.0 / power))
}