1#![cfg_attr(feature="simd", feature(portable_simd))]
2
3use std::mem::swap;
4
5#[cfg(feature = "simd")]
6mod simd;
7
8
9pub fn trapezoidal(mut a: f64, mut b: f64, steps: usize, f: fn(f64) -> f64) -> f64 {
10 if a > b {
11 swap(&mut a, &mut b);
12 }
13
14 let h = (b - a) / steps as f64;
15
16 let mut sum = (f(a) + f(b)) / 2f64;
17 let mut x = a + h;
18 while x < b {
19 sum += f(x);
20 x += h;
21 }
22
23 return h * sum;
24}
25
26pub fn simpsons_one_third(mut a: f64, mut b: f64, steps: usize, f: fn(f64) -> f64) -> f64 {
27 let stepsf64 = steps as f64;
28
29 if a > b {
30 swap(&mut a, &mut b);
31 }
32
33 let h = (b - a) / (stepsf64);
34
35 let mut sum = (f(a) + f(b)) / 2f64;
36 let mut s_2 = 0f64;
37 let mut s_4 = 0f64;
38 let mut x = a + h;
39 let mut i = 0;
40 while x < b {
41 if (i + 1) % 2 == 1 {
42 s_4 += f(x);
43 } else {
44 s_2 += f(x);
45 }
46 x += h;
47 i += 1;
48 }
49 sum += (s_2 * 2f64) + (s_4 * 4f64);
50
51 return (h * sum) / 3f64;
52}
53
54pub fn simpsons_three_eights(mut a: f64, mut b: f64, steps: usize, f: fn(f64) -> f64) -> f64 {
55 let stepsf64 = steps as f64;
56
57 if a > b {
58 swap(&mut a, &mut b);
59 }
60
61 let h = (b - a) / stepsf64;
62
63 let mut sum = f(a) + f(b);
64 let mut s_2 = 0f64;
65 let mut s_3 = 0f64;
66 let mut x = a + h;
67 let mut i = 0;
68 while x < b {
69 if (i + 1) % 3 == 0 {
70 s_2 += f(x);
71 } else {
72 s_3 += f(x);
73 }
74 x += h;
75 i += 1;
76 }
77 sum += (s_2 * 2f64) + (s_3 * 3f64);
78
79 return h * sum * 3f64 / 8f64;
80}
81
82#[cfg(test)]
83mod tests {
84
85 use super::*;
86 #[test]
90 fn test_trapezoidal() {
91 println!(
92 "trapezoidal: {}",
93 trapezoidal(-1f64, 1f64, 600, |x| (1f64 - (x * x)).powf(0.5))
94 );
95 }
96
97 #[test]
98 fn test_simpsons_one_third() {
99 println!(
100 "one third: {}",
101 simpsons_one_third(-1f64, 1f64, 600, |x| (1f64 - (x * x)).powf(0.5))
102 );
103 }
104
105 #[test]
106 fn test_simpsons_three_eights() {
107 println!(
108 "three eights: {}",
109 simpsons_three_eights(-1f64, 1f64, 600, |x| (1f64 - (x * x)).powf(0.5))
110 );
111 }
112}