rustyqlib/core/solvers/
newton_raphson.rs1use super::solver_1d::{Root, Solver1d};
5
6pub fn newton_raphson(
9 cfg: &Solver1d,
10 f: impl Fn(f64) -> f64,
11 df: impl Fn(f64) -> f64,
12 x0: f64,
13) -> Root {
14 let mut x = x0;
15 for i in 0..cfg.max_iter {
16 let fx = f(x);
17 if fx.abs() <= cfg.tol {
18 return Root { x, iterations: i, converged: true };
19 }
20 let dfx = df(x);
21 if dfx == 0.0 || !dfx.is_finite() {
22 return Root { x, iterations: i, converged: false };
23 }
24 x -= fx / dfx;
25 }
26 Root { x, iterations: cfg.max_iter, converged: f(x).abs() <= cfg.tol }
27}
28
29#[cfg(test)]
30mod tests {
31 use super::*;
32
33 #[test]
34 fn finds_sqrt_two() {
35 let r = newton_raphson(&Solver1d::default(), |x| x * x - 2.0, |x| 2.0 * x, 1.0);
36 assert!(r.converged && (r.x - std::f64::consts::SQRT_2).abs() < 1e-12, "{r:?}");
37 }
38
39 #[test]
40 fn reports_failure_on_zero_derivative() {
41 let r = newton_raphson(&Solver1d::default(), |x| x * x - 2.0, |x| 2.0 * x, 0.0);
43 assert!(!r.converged);
44 }
45}