r2rs-stats 0.1.1

Statistics programming for Rust based on R's stats package
Documentation
// "Whatever you do, work at it with all your heart, as working for the Lord,
// not for human masters, since you know that you will receive an inheritance
// from the Lord as a reward. It is the Lord Christ you are serving."
// (Col 3:23-24)

use std::error::Error;

use num_traits::Float;
use strafe_type::{Finite64, FloatConstraint};

use crate::funcs::{
    opt::{Optim, OptimOptions, OptimResponse},
    optimize::optimize,
};

pub struct Brent {
    pub lower_bound: Finite64,
    pub upper_bound: Finite64,
    pub optim_options: OptimOptions,
}

impl Default for Brent {
    fn default() -> Self {
        Self {
            lower_bound: (-100).into(),
            upper_bound: 100.into(),
            optim_options: OptimOptions {
                parscale: None,
                fnscale: 1.0,
                abstol: f64::neg_infinity(),
                reltol: f64::epsilon().sqrt(),
                maxit: 100,
            },
        }
    }
}

impl Optim for Brent {
    type ParameterType = f64;
    fn optim(
        &mut self,
        _par: Self::ParameterType,
        min_func: &dyn Fn(Self::ParameterType) -> f64,
    ) -> Result<OptimResponse<Self::ParameterType>, Box<dyn Error>> {
        let f = |p: f64| min_func(p) / self.optim_options.fnscale;
        let (par, val) = optimize(
            &f,
            self.lower_bound.unwrap(),
            self.upper_bound.unwrap(),
            self.optim_options.reltol,
            false,
        );
        // let parscale = if let Some(parscale) = &self.optim_options.parscale {
        //  parscale.clone()
        // } else {
        //  vec![1.0; npar]
        // };
        // let mut bvec = par
        //  .iter()
        //  .zip(parscale.iter())
        //  .map(|(par, scale)| par / scale)
        //  .collect::<Vec<_>>();
        // let ndeps = vec![1e-3; npar];
        // let bounds = None;
        //
        // let mut grcount = 0;
        // let mut fncount = 0;
        // let mut min = f64::nan();
        // let mut par_out = Vec::new();
        // let mut fail = true;
        //
        // (min, par_out, fncount, grcount, fail) = cgmin(
        //  npar,
        //  &mut bvec,
        //  min_func,
        //  self.grad_func.as_deref(),
        //  &ndeps,
        //  &parscale,
        //  self.optim_options.fnscale,
        //  bounds,
        //  self.optim_options.abstol,
        //  self.optim_options.reltol,
        //  self.calc_type,
        //  self.optim_options.maxit,
        // )?;
        //
        // for i in 0..npar {
        //  par_out[i] *= parscale[i];
        // }
        //
        Ok(OptimResponse {
            parameters: par,
            value: val * self.optim_options.fnscale,
            function_count: 0,
            gradient_count: 0,
            convergence: true,
        })
    }
}