1use std::iter::Iterator;
2use std::ops::{Div, Sub};
3
4pub 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 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}