1use std::f64::consts::PI;
2
3const STEP: f64 = 0.001;
4
5fn main() {
6 println!(
7 "{:<7}|{:>12}|{:>11}|{:>15}",
8 "Func", "Total Tests", "Diff Count", "Max Diff"
9 );
10 let tests = [
11 CompareArgs {
12 name: "acos".to_string(),
13 start: -1.0,
14 stop: 1.0,
15 step: STEP,
16 std_fn: |x| x.acos(),
17 const_fn: |x: f64| trig_const::acos(x),
18 },
19 CompareArgs {
20 name: "acosh".to_string(),
21 start: 1.0,
22 stop: 100.0,
23 step: STEP,
24 std_fn: |x| x.acosh(),
25 const_fn: |x: f64| trig_const::acosh(x),
26 },
27 CompareArgs {
28 name: "asin".to_string(),
29 start: -1.0,
30 stop: 1.0,
31 step: STEP,
32 std_fn: |x| x.asin(),
33 const_fn: |x: f64| trig_const::asin(x),
34 },
35 CompareArgs {
36 name: "asinh".to_string(),
37 start: 1.0,
38 stop: 100.0,
39 step: STEP,
40 std_fn: |x| x.asinh(),
41 const_fn: |x: f64| trig_const::asinh(x),
42 },
43 CompareArgs {
44 name: "atan".to_string(),
45 start: -8.0 * PI,
46 stop: 8.0 * PI,
47 step: STEP,
48 std_fn: |x| x.atan(),
49 const_fn: |x: f64| trig_const::atan(x),
50 },
51 CompareArgs {
52 name: "atanh".to_string(),
53 start: -1.0 + STEP,
54 stop: 1.0 - STEP,
55 step: STEP,
56 std_fn: |x| x.atanh(),
57 const_fn: |x| trig_const::atanh(x),
58 },
59 CompareArgs {
60 name: "cos".to_string(),
61 start: -8.0 * PI,
62 stop: 8.0 * PI,
63 step: STEP,
64 std_fn: |x| x.cos(),
65 const_fn: |x: f64| trig_const::cos(x),
66 },
67 CompareArgs {
68 name: "cosh".to_string(),
69 start: -4.0 * PI,
70 stop: 4.0 * PI,
71 step: STEP,
72 std_fn: |x| x.cosh(),
73 const_fn: |x| trig_const::cosh(x),
74 },
75 CompareArgs {
76 name: "ln".to_string(),
77 start: 0.001,
78 stop: 100.0,
79 step: STEP,
80 std_fn: |x| x.ln(),
81 const_fn: |x: f64| trig_const::ln(x),
82 },
83 CompareArgs {
84 name: "exp".to_string(),
85 start: -10.0,
86 stop: 10.0,
87 step: STEP,
88 std_fn: |x| x.exp(),
89 const_fn: |x: f64| trig_const::exp(x),
90 },
91 CompareArgs {
92 name: "fabs".to_string(),
93 start: -10.0,
94 stop: 10.0,
95 step: STEP,
96 std_fn: |x| x.abs(),
97 const_fn: |x: f64| trig_const::fabs(x),
98 },
99 CompareArgs {
100 name: "floor".to_string(),
101 start: -10.0,
102 stop: 10.0,
103 step: STEP,
104 std_fn: |x| x.floor(),
105 const_fn: |x: f64| trig_const::floor(x),
106 },
107 CompareArgs {
108 name: "sin".to_string(),
109 start: -8.0 * PI,
110 stop: 8.0 * PI,
111 step: STEP,
112 std_fn: |x| x.sin(),
113 const_fn: |x: f64| trig_const::sin(x),
114 },
115 CompareArgs {
116 name: "sinh".to_string(),
117 start: -4.0 * PI,
118 stop: 4.0 * PI,
119 step: STEP,
120 std_fn: |x| x.sinh(),
121 const_fn: |x| trig_const::sinh(x),
122 },
123 CompareArgs {
124 name: "sqrt".to_string(),
125 start: 0.0,
126 stop: 10.0,
127 step: STEP,
128 std_fn: |x| x.sqrt(),
129 const_fn: |x: f64| trig_const::sqrt(x),
130 },
131 CompareArgs {
132 name: "tan".to_string(),
133 start: -8.0 * PI,
134 stop: 8.0 * PI,
135 step: STEP,
136 std_fn: |x| x.tan(),
137 const_fn: |x: f64| trig_const::tan(x),
138 },
139 ];
140
141 for test in tests {
142 let diff = compare_functions(&test);
143 println!(
144 "{:<7}|{:>12}|{:>11}|{:>15.5e}",
145 test.name, diff.total_tests, diff.diff_tests, diff.max_diff
146 );
147 }
148}
149
150fn compare_functions(c: &CompareArgs) -> DiffCounter {
151 let mut const_metric = DiffCounter::default();
152
153 for x in float_loop(c.start, c.stop, c.step) {
154 let real = (c.std_fn)(x);
155 let const_result = (c.const_fn)(x);
156
157 const_metric.add_metric(real, const_result);
158 }
159
160 const_metric
161}
162
163#[derive(Debug, Default)]
164struct DiffCounter {
165 total_tests: usize,
166 diff_tests: usize,
167 max_diff: f64,
168}
169
170impl DiffCounter {
171 fn add_metric(&mut self, real: f64, actual: f64) {
172 self.total_tests += 1;
173 let diff = (real - actual).abs();
174 if diff != 0.0 {
175 self.diff_tests += 1;
176 self.max_diff = f64::max(self.max_diff, diff);
177 }
178 }
179}
180
181fn float_loop(start: f64, stop: f64, step: f64) -> impl Iterator<Item = f64> {
182 core::iter::successors(Some(start), move |prev| {
183 let next = prev + step;
184 (next < stop).then_some(next)
185 })
186}
187
188struct CompareArgs {
189 name: String,
190 start: f64,
191 stop: f64,
192 step: f64,
193 std_fn: fn(f64) -> f64,
194 const_fn: fn(f64) -> f64,
195}