1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
const EPSILON: f64 = 0.0000001; type TypeFn = fn(x: f64) -> f64; pub struct Formula { pub current_x: f64, pub stop: f64, pub start: f64, pub step: f64, pub f: TypeFn, } impl Formula { pub fn new(start: f64, stop: f64, step: f64, f: TypeFn) -> Self { Formula { current_x: start, stop: stop, start: start, step: step, f: f, } } } impl Iterator for Formula { type Item = (f64, f64); #[inline] fn next(&mut self) -> Option<(f64, f64)> { if self.start < self.stop { if self.current_x < self.stop { let x = self.current_x; self.current_x += self.step; Some((x, (self.f)(x))) } else if (self.stop - self.current_x).abs() < EPSILON { let x = self.stop; self.current_x += self.step; Some((x, (self.f)(x))) } else { None } } else if self.current_x > self.stop { let x = self.current_x; self.current_x -= self.step; Some((x, (self.f)(x))) } else if (self.stop - self.current_x).abs() < EPSILON { let x = self.stop; self.current_x -= self.step; Some((x, (self.f)(x))) } else { None } } } impl Copy for Formula {} impl Clone for Formula { fn clone(&self) -> Self { *self } } #[macro_export] macro_rules! formula { ( y($x:ident) = $form:expr, x = [$start:expr, $stop:expr; $step:expr] ) => { { fn f($x: f64) -> f64 { $form } let start = $start as f64; let stop = $stop as f64; let step = $step as f64; Formula::new(start, stop, step, f) }}; } #[test] fn macros_test() { let points = formula!(y(x) = x.powi(2), x = [1, 1; 0.1]); let pp: Vec<_> = points.collect(); assert_eq!(pp, vec![(1f64, 1f64)]); }