use crate::estimation::recipe::ResidualNormRecipe;
#[inline]
pub(crate) fn normalized_residual(recipe: ResidualNormRecipe, value: f64, weight: f64) -> f64 {
match recipe {
ResidualNormRecipe::RtkInverseVarianceInnovation
| ResidualNormRecipe::RtkInverseSigmaResidual => value * weight,
ResidualNormRecipe::PppInverseSigmaMagnitude => value.abs() * weight,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn rtk_inverse_variance_innovation_is_a_product() {
let value = -2.0_f64;
let weight = 0.25_f64;
let normalized = normalized_residual(
ResidualNormRecipe::RtkInverseVarianceInnovation,
value,
weight,
);
assert_eq!(normalized.to_bits(), (value * weight).to_bits());
assert_eq!(normalized.abs().to_bits(), (value * weight).abs().to_bits());
}
#[test]
fn rtk_inverse_sigma_residual_is_a_product() {
let value = -2.0_f64;
let weight = 0.5_f64;
let normalized =
normalized_residual(ResidualNormRecipe::RtkInverseSigmaResidual, value, weight);
assert_eq!(normalized.to_bits(), (value * weight).to_bits());
}
#[test]
fn ppp_inverse_sigma_magnitude_studentizes_the_residual() {
let value = -3.0_f64;
let weight = 0.5_f64; let normalized =
normalized_residual(ResidualNormRecipe::PppInverseSigmaMagnitude, value, weight);
assert_eq!(normalized.to_bits(), (value.abs() * weight).to_bits());
assert_eq!(normalized, 1.5);
}
}