/// `slope` for functions that can fail.
`slope` for functions that can fail.
` slope ` for functions that can fail .
pub fn try_slope<E, F>(
    step: f64,
    kind: Option<DerivativeKind>,
    point: f64,
    value_fn: F,
) -> Result<f64, E>
where
    F: FnMut(f64) -> Result<f64, E>,
{
    // http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/central-differences/
    match kind.unwrap_or_default() {
        DerivativeKind::Stencil(3) => {
            let numer = stencil_sum!(value_fn, point, step, [
                (offset: -1.0, coeff: -1.0),
                (offset: +1.0, coeff: +1.0),
            ]);
            let denom = 2.0 * step;
            Ok(numer / denom)
        },
        DerivativeKind::Stencil(5) => {
            let numer = stencil_sum!(value_fn, point, step, [
                (offset: -2.0, coeff: +1.0),
                (offset: -1.0, coeff: -8.0),
                (offset: +1.0, coeff: +8.0),
                (offset: +2.0, coeff: -1.0),
            ]);
            let denom = 12.0 * step;
            Ok(numer / denom)
        },
        DerivativeKind::Stencil(7) => {
            let numer = stencil_sum!(value_fn, point, step, [
                (offset: -3.0, coeff: -1.0),
                (offset: -2.0, coeff: +9.0),
                (offset: -1.0, coeff: -45.0),
                (offset: +1.0, coeff: +45.0),
                (offset: +2.0, coeff: -9.0),
                (offset: +3.0, coeff: +1.0),
            ]);
            let denom = 60.0 * step;
            Ok(numer / denom)
        },
        DerivativeKind::Stencil(9) => {
            let numer = stencil_sum!(value_fn, point, step, [
                (offset: -4.0, coeff: +3.0),
                (offset: -3.0, coeff: -32.0),
                (offset: -2.0, coeff: +168.0),
                (offset: -1.0, coeff: -672.0),
                (offset: +1.0, coeff: +672.0),
                (offset: +2.0, coeff: -168.0),
                (offset: +3.0, coeff: +32.0),
                (offset: +4.0, coeff: -3.0),
            ]);
            let denom = 840.0 * step;
            Ok(numer / denom)
        },
        DerivativeKind::Stencil(n@0) |
        DerivativeKind::Stencil(n@1) |
        DerivativeKind::Stencil(n) if n % 2 == 0 => {
            panic!("{}-point stencil does not exist", n);
        },
        DerivativeKind::Stencil(n) => {
            panic!("{}-point stencil is not implemented", n);
        },
    }
}
pub fn try_slope < E , F > ( step : f64 , kind : Option < DerivativeKind > , point : f64 , value_fn : F , ) -> Result < f64 , E > where F : FnMut ( f64 ) -> Result < f64 , E > , { // http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/central-differences/ match kind . unwrap_or_default ( ) { DerivativeKind :: Stencil ( 3 ) => { let numer = stencil_sum ! ( value_fn point step [ ( offset 1.0 coeff 1.0 ) ( offset 1.0 coeff 1.0 ) ] ) ; let denom = 2.0 * step ; Ok ( numer / denom ) } , DerivativeKind :: Stencil ( 5 ) => { let numer = stencil_sum ! ( value_fn point step [ ( offset 2.0 coeff 1.0 ) ( offset 1.0 coeff 8.0 ) ( offset 1.0 coeff 8.0 ) ( offset 2.0 coeff 1.0 ) ] ) ; let denom = 12.0 * step ; Ok ( numer / denom ) } , DerivativeKind :: Stencil ( 7 ) => { let numer = stencil_sum ! ( value_fn point step [ ( offset 3.0 coeff 1.0 ) ( offset 2.0 coeff 9.0 ) ( offset 1.0 coeff 45.0 ) ( offset 1.0 coeff 45.0 ) ( offset 2.0 coeff 9.0 ) ( offset 3.0 coeff 1.0 ) ] ) ; let denom = 60.0 * step ; Ok ( numer / denom ) } , DerivativeKind :: Stencil ( 9 ) => { let numer = stencil_sum ! ( value_fn point step [ ( offset 4.0 coeff 3.0 ) ( offset 3.0 coeff 32.0 ) ( offset 2.0 coeff 168.0 ) ( offset 1.0 coeff 672.0 ) ( offset 1.0 coeff 672.0 ) ( offset 2.0 coeff 168.0 ) ( offset 3.0 coeff 32.0 ) ( offset 4.0 coeff 3.0 ) ] ) ; let denom = 840.0 * step ; Ok ( numer / denom ) } , DerivativeKind :: Stencil ( n @ 0 ) | DerivativeKind :: Stencil ( n @ 1 ) | DerivativeKind :: Stencil ( n ) if n % 2 == 0 => { panic ! ( " " n ) ; } , DerivativeKind :: Stencil ( n ) => { panic ! ( " " n ) ; } , } }
`slope` for functions that can fail.
` slope ` for functions that can fail .
step
f64
kind
Option<DerivativeKind>
point
f64
value_fn
F