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