use ceres_solver_sys::cxx::UniquePtr;
use ceres_solver_sys::ffi;
pub type LossFunctionType = Box<dyn Fn(f64, &mut [f64; 3])>;
pub struct LossFunction(UniquePtr<ffi::LossFunction>);
impl LossFunction {
pub fn custom(func: impl Into<LossFunctionType>) -> Self {
let safe_func = func.into();
let rust_func: Box<dyn Fn(f64, *mut f64)> = Box::new(move |sq_norm, out_ptr| {
let out = unsafe { &mut *(out_ptr as *mut [f64; 3]) };
safe_func(sq_norm, out);
});
let inner = ffi::new_callback_loss_function(Box::new(rust_func.into()));
Self(inner)
}
pub fn huber(a: f64) -> Self {
Self(ffi::new_huber_loss(a))
}
pub fn soft_l1(a: f64) -> Self {
Self(ffi::new_soft_l_one_loss(a))
}
pub fn cauchy(a: f64) -> Self {
Self(ffi::new_cauchy_loss(a))
}
pub fn arctan(a: f64) -> Self {
Self(ffi::new_arctan_loss(a))
}
pub fn tolerant(a: f64, b: f64) -> Self {
Self(ffi::new_tolerant_loss(a, b))
}
pub fn tukey(a: f64) -> Self {
Self(ffi::new_tukey_loss(a))
}
pub fn into_inner(self) -> UniquePtr<ffi::LossFunction> {
self.0
}
}