use super::Factor;
use faer::prelude::ReborrowMut;
use nalgebra::DVector;
#[derive(Debug, Clone)]
pub struct PriorFactor {
pub data: DVector<f64>,
}
impl Factor for PriorFactor {
fn linearize(
&self,
params: &[&[f64]],
residual: &mut [f64],
jacobian: Option<faer::mat::MatMut<'_, f64>>,
) {
let n = self.data.len();
for i in 0..n {
residual[i] = params[0][i] - self.data[i];
}
if let Some(mut jac) = jacobian {
for i in 0..n {
*jac.rb_mut().get_mut(i, i) = 1.0;
}
}
}
fn residual_dim(&self) -> usize {
self.data.len()
}
fn jacobian_shape(&self) -> (usize, usize) {
let n = self.data.len();
(n, n)
}
}
#[cfg(test)]
mod tests {
use super::*;
use nalgebra::dvector;
#[test]
fn test_prior_factor_residual() {
let prior = PriorFactor {
data: dvector![1.0, 2.0],
};
let current = dvector![1.5f64, 2.3f64];
let params: Vec<&[f64]> = vec![current.as_slice()];
let mut residual = vec![0.0f64; 2];
prior.linearize(¶ms, &mut residual, None);
assert!((residual[0] - 0.5).abs() < 1e-10);
assert!((residual[1] - 0.3).abs() < 1e-10);
}
#[test]
fn test_prior_factor_jacobian_identity() {
let prior = PriorFactor {
data: dvector![1.0, 2.0],
};
let current = dvector![1.5f64, 2.3f64];
let params: Vec<&[f64]> = vec![current.as_slice()];
let mut residual = vec![0.0f64; 2];
let mut jac_buf = vec![0.0f64; 4];
let jac_mut = faer::mat::MatMut::from_column_major_slice_mut(&mut jac_buf, 2, 2);
prior.linearize(¶ms, &mut residual, Some(jac_mut));
assert!((jac_buf[0] - 1.0).abs() < 1e-10); assert!((jac_buf[3] - 1.0).abs() < 1e-10); assert!(jac_buf[1].abs() < 1e-10); assert!(jac_buf[2].abs() < 1e-10); }
#[test]
fn test_prior_factor_residual_dim() {
let prior = PriorFactor {
data: dvector![0.0, 0.0, 0.0],
};
assert_eq!(prior.residual_dim(), 3);
}
#[test]
fn test_prior_factor_jacobian_shape() {
let prior = PriorFactor {
data: dvector![0.0, 0.0],
};
assert_eq!(prior.jacobian_shape(), (2, 2));
}
}