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