generic_newton/
lib.rs

1use std::iter::Iterator;
2use std::ops::{Div, Sub};
3
4/// An iterator that returns successive iterations of the Newton's method.
5///
6/// This iterator is generic over it's entry, and allows to freely use the Newton method on
7/// arbitrary types.
8///
9/// # Example
10///
11/// ```
12/// use generic_newton::Newton;
13///
14/// fn main() {
15///     let mut n = Newton::<f64>::new(
16///         0.5, // Initial guess
17///         |x| x.cos() - x.powi(3), // The actual function
18///         |x| -(x.sin() + 3. * x.powi(2)), // Its derivative
19///     );
20///
21///     assert!((n.nth(1000).unwrap() - 0.865474033102).abs() < 1E-11)
22/// }
23/// ```
24pub struct Newton<T>
25where
26    T: Div<Output = T> + Sub<Output = T> + Copy,
27{
28    current: T,
29    func: fn(T) -> T,
30    derivative: fn(T) -> T,
31}
32
33impl<T> Newton<T>
34where
35    T: Div<Output = T> + Sub<Output = T> + Copy,
36{
37    /// Creates a new `Newton` iterator.
38    ///
39    /// - `func` is the actual function to find the root of
40    /// - `derivative` is it's derivative.
41    pub fn new(initial_guess: T, func: fn(T) -> T, derivative: fn(T) -> T) -> Self {
42        Newton {
43            current: initial_guess,
44            func,
45            derivative,
46        }
47    }
48}
49
50impl<T> Iterator for Newton<T>
51where
52    T: Div<Output = T> + Sub<Output = T> + Copy,
53{
54    type Item = T;
55    fn next(&mut self) -> Option<Self::Item> {
56        let func = self.func;
57        let deriv = self.derivative;
58
59        let next = self.current - (func(self.current) / deriv(self.current));
60        let prev = self.current;
61
62        self.current = next;
63
64        Some(prev)
65    }
66}
67
68#[cfg(test)]
69mod tests {
70
71    use super::Newton;
72
73    #[test]
74    fn is_generic() {
75        let mut n = Newton::new(0, |x| x - 1, |_| 1);
76        assert_eq!(n.nth(5).unwrap(), 1);
77
78        let mut n = Newton::new(0., |x| x - 1., |_| 1.);
79        assert_eq!(n.nth(5).unwrap(), 1.);
80    }
81}