1use super::F32;
4
5impl F32 {
6 pub fn log(self, base: Self) -> Self {
8 (Self::ONE / base.ln()) * self.ln()
9 }
10}
11
12#[cfg(test)]
13mod tests {
14 use super::F32;
15
16 pub(crate) const MAX_ERROR: f32 = 0.001;
17
18 pub(crate) const TEST_VECTORS_BASE3: &[(f32, f32)] = &[
20 (1e-20, -41.918_064),
21 (1e-19, -39.822_16),
22 (1e-18, -37.726_26),
23 (1e-17, -35.630_356),
24 (1e-16, -33.534_454),
25 (1e-15, -31.438_549),
26 (1e-14, -29.342_646),
27 (1e-13, -27.246_744),
28 (1e-12, -25.150_839),
29 (1e-11, -23.054_935),
30 (1e-10, -20.959_032),
31 (1e-09, -18.863_13),
32 (1e-08, -16.767_227),
33 (1e-07, -14.671_323),
34 (1e-06, -12.575_419),
35 (1e-05, -10.479_516),
36 (1e-04, -8.383_614),
37 (0.001, -6.287_709_7),
38 (0.01, -4.191_807),
39 (0.1, -2.095_903_4),
40 (10.0, 2.095_903_4),
41 (100.0, 4.191_807),
42 (1000.0, 6.287_709_7),
43 (10000.0, 8.383_614),
44 (100000.0, 10.479_516),
45 (1000000.0, 12.575_419),
46 (10000000.0, 14.671_323),
47 (100000000.0, 16.767_227),
48 (1000000000.0, 18.863_13),
49 (10000000000.0, 20.959_032),
50 (100000000000.0, 23.054_935),
51 (1000000000000.0, 25.150_839),
52 (10000000000000.0, 27.246_744),
53 (100000000000000.0, 29.342_646),
54 (1000000000000000.0, 31.438_549),
55 (1e+16, 33.534_454),
56 (1e+17, 35.630_356),
57 (1e+18, 37.726_26),
58 (1e+19, 39.822_16),
59 ];
60
61 pub(crate) const TEST_VECTORS_BASE5_5: &[(f32, f32)] = &[
63 (1e-20, -27.013_786),
64 (1e-19, -25.663_097),
65 (1e-18, -24.312_408),
66 (1e-17, -22.961_72),
67 (1e-16, -21.611_03),
68 (1e-15, -20.260_34),
69 (1e-14, -18.909_65),
70 (1e-13, -17.558_962),
71 (1e-12, -16.208_273),
72 (1e-11, -14.857_583),
73 (1e-10, -13.506_893),
74 (1e-09, -12.156_204),
75 (1e-08, -10.805_515),
76 (1e-07, -9.454_825),
77 (1e-06, -8.104_136),
78 (1e-05, -6.753_446_6),
79 (1e-04, -5.402_757_6),
80 (0.001, -4.052_068),
81 (0.01, -2.701_378_8),
82 (0.1, -1.350_689_4),
83 (10.0, 1.350_689_4),
84 (100.0, 2.701_378_8),
85 (1000.0, 4.052_068),
86 (10000.0, 5.402_757_6),
87 (100000.0, 6.753_446_6),
88 (1000000.0, 8.104_136),
89 (10000000.0, 9.454_825),
90 (100000000.0, 10.805_515),
91 (1000000000.0, 12.156_204),
92 (10000000000.0, 13.506_893),
93 (100000000000.0, 14.857_583),
94 (1000000000000.0, 16.208_273),
95 (10000000000000.0, 17.558_962),
96 (100000000000000.0, 18.909_65),
97 (1000000000000000.0, 20.260_34),
98 (1e+16, 21.611_03),
99 (1e+17, 22.961_72),
100 (1e+18, 24.312_408),
101 (1e+19, 25.663_097),
102 ];
103
104 pub(crate) const TEST_VECTORS_BASE12_7: &[(f32, f32)] = &[
106 (1e-20, -18.119_164),
107 (1e-19, -17.213_205),
108 (1e-18, -16.307_247),
109 (1e-17, -15.401_289),
110 (1e-16, -14.495_331),
111 (1e-15, -13.589_373),
112 (1e-14, -12.683_414),
113 (1e-13, -11.777_456),
114 (1e-12, -10.871_498),
115 (1e-11, -9.965_54),
116 (1e-10, -9.059_582),
117 (1e-09, -8.153_624),
118 (1e-08, -7.247_665_4),
119 (1e-07, -6.341_707),
120 (1e-06, -5.435_749),
121 (1e-05, -4.529_791),
122 (1e-04, -3.623_832_7),
123 (0.001, -2.717_874_5),
124 (0.01, -1.811_916_4),
125 (0.1, -0.905_958_2),
126 (10.0, 0.905_958_2),
127 (100.0, 1.811_916_4),
128 (1000.0, 2.717_874_5),
129 (10000.0, 3.623_832_7),
130 (100000.0, 4.529_791),
131 (1000000.0, 5.435_749),
132 (10000000.0, 6.341_707),
133 (100000000.0, 7.247_665_4),
134 (1000000000.0, 8.153_624),
135 (10000000000.0, 9.059_582),
136 (100000000000.0, 9.965_54),
137 (1000000000000.0, 10.871_498),
138 (10000000000000.0, 11.777_456),
139 (100000000000000.0, 12.683_414),
140 (1000000000000000.0, 13.589_373),
141 (1e+16, 14.495_331),
142 (1e+17, 15.401_289),
143 (1e+18, 16.307_247),
144 (1e+19, 17.213_205),
145 ];
146
147 #[test]
148 fn sanity_check() {
149 assert_eq!(F32::ONE.log(F32(3.0)), F32::ZERO);
150 assert_eq!(F32::ONE.log(F32(5.5)), F32::ZERO);
151 assert_eq!(F32::ONE.log(F32(12.7)), F32::ZERO);
152
153 for &(x, expected) in TEST_VECTORS_BASE3 {
154 let log_x = F32(x).log(F32(3.0));
155 let relative_error = (log_x - expected).abs() / expected;
156
157 assert!(
158 relative_error <= MAX_ERROR,
159 "relative_error {} too large: {} vs {}",
160 relative_error,
161 log_x,
162 expected
163 );
164 }
165
166 for &(x, expected) in TEST_VECTORS_BASE5_5 {
167 let log_x = F32(x).log(F32(5.5));
168 let relative_error = (log_x - expected).abs() / expected;
169
170 assert!(
171 relative_error <= MAX_ERROR,
172 "relative_error {} too large: {} vs {}",
173 relative_error,
174 log_x,
175 expected
176 );
177 }
178
179 for &(x, expected) in TEST_VECTORS_BASE12_7 {
180 let log_x = F32(x).log(F32(12.7));
181 let relative_error = (log_x - expected).abs() / expected;
182
183 assert!(
184 relative_error <= MAX_ERROR,
185 "relative_error {} too large: {} vs {}",
186 relative_error,
187 log_x,
188 expected
189 );
190 }
191 }
192}