rust_finprim/utils/
newton_raphson.rs

1use crate::error::RootFindingError;
2use crate::FinPrimError;
3use crate::FloatLike;
4
5pub fn newton_raphson<T: FloatLike, F, D>(
6    guess: T,
7    f: F,
8    f_prime: D,
9    tolerance: T,
10    max_iter: u16,
11) -> Result<T, FinPrimError<T>>
12where
13    F: Fn(T) -> T,
14    D: Fn(T) -> T,
15{
16    let mut x = guess;
17    let mut fx = f(x);
18    for _ in 0..max_iter {
19        if fx.abs() < tolerance {
20            return Ok(x);
21        }
22        let f_prime_x = f_prime(x);
23        if f_prime_x.is_zero() {
24            return Err(FinPrimError::RootFindingError(RootFindingError::DivideByZero {
25                last_x: x,
26                last_fx: fx,
27            }));
28        }
29        x -= fx / f_prime_x;
30        fx = f(x);
31    }
32    Err(FinPrimError::RootFindingError(RootFindingError::FailedToConverge {
33        last_x: x,
34        last_fx: fx,
35    }))
36}