mathpack 0.1.8

General Mathematics Library for Rust
Documentation
#![allow(dead_code)]
use crate::linalg::vector::Vector;
#[allow(unused_imports, unused_attributes)]
#[macro_use]
use crate::{equality_test, inequality_test, panic_test, abs_approx_test};

pub fn diff(f: &dyn Fn(&Vec<f64>) -> f64, position: &[f64], step: f64) -> Vector {
    let mut ret = Vec::with_capacity(position.len());
    for i in 0..position.len() {
        let mut plus = position.to_owned();
        plus[i] += step;
        let mut minus = position.to_owned();
        minus[i] -= step;
        ret.push((f(&plus) - f(&minus)) / (2.0 * step));
    }
    Vector { data: ret }
}


#[cfg(test)]
mod tests {
    use super::*;
    fn diff_test(f: &dyn Fn(&Vec<f64>) -> f64, position: &[f64], var: usize) -> f64 {
        let a = diff(&f, position, 0.01);
        print!("{:?}", a);
        assert!(a.len() > var);
        a[var]
    }

    abs_approx_test!(quad_test, diff_test,
        &|var: &Vec<f64>| var[0]* var[0] + 7.0, &[2.0], 0 => 4.0, 0.0001
    );

    #[test]
    fn test_circle() {
        let f: fn(&Vec<f64>) -> f64 = |v| v[0] * v[0] + v[1] * v[1];
        let a = diff(&f, &[2.0, 2.0], 0.01);
        print!("{:?}", a);
        assert!((a[0] - 4.0).abs() < 0.0001);
    }

    #[test]
    fn test_pow4() {
        let f: fn(&Vec<f64>) -> f64 = |v| v[0].powf(4.0) + v[1] * v[1];
        let a = diff(&f, &[2.0, 2.0], 0.01);
        print!("{:?}", a);
        assert!((a[0] - 32.0).abs() < 0.001);
    }

    #[test]
    fn test_exp() {
        let f: fn(&Vec<f64>) -> f64 = |v| f64::exp(v[0]);
        let a = diff(&f, &[2.0], 0.001);
        print!("{:?}", a);
        assert!((a[0] - 2.0_f64.exp()).abs() < 0.001);
    }
}