///|
pub fn summarize_errors(points : Array[ForecastPoint]) -> ErrorSummary {
if points.length() == 0 {
{ count: 0, mae: 0.0, rmse: 0.0, mape: 0.0, max_error: 0.0 }
} else {
let mut abs_total = 0.0
let mut squared_total = 0.0
let mut percentage_total = 0.0
let mut max_error = 0.0
for point in points {
let error = abs_double(point.predicted - point.actual)
abs_total += error
squared_total += square(error)
percentage_total += safe_div(error, point.actual, 0.0)
if error > max_error {
max_error = error
}
}
let n = points.length().to_double()
{
count: points.length(),
mae: abs_total / n,
rmse: (squared_total / n).sqrt(),
mape: percentage_total / n,
max_error,
}
}
}
///|
pub fn eta_results_to_points(
results : Array[EtaResult],
actuals : Array[Double],
) -> Array[ForecastPoint] {
let points : Array[ForecastPoint] = []
let limit = if results.length() < actuals.length() {
results.length()
} else {
actuals.length()
}
for i in 0..