/rust/registry/src/index.crates.io-1949cf8c6b5b557f/pxfm-0.1.25/src/bessel/i1e.rs
Line | Count | Source |
1 | | /* |
2 | | * // Copyright (c) Radzivon Bartoshyk 7/2025. All rights reserved. |
3 | | * // |
4 | | * // Redistribution and use in source and binary forms, with or without modification, |
5 | | * // are permitted provided that the following conditions are met: |
6 | | * // |
7 | | * // 1. Redistributions of source code must retain the above copyright notice, this |
8 | | * // list of conditions and the following disclaimer. |
9 | | * // |
10 | | * // 2. Redistributions in binary form must reproduce the above copyright notice, |
11 | | * // this list of conditions and the following disclaimer in the documentation |
12 | | * // and/or other materials provided with the distribution. |
13 | | * // |
14 | | * // 3. Neither the name of the copyright holder nor the names of its |
15 | | * // contributors may be used to endorse or promote products derived from |
16 | | * // this software without specific prior written permission. |
17 | | * // |
18 | | * // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
19 | | * // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
20 | | * // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
21 | | * // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
22 | | * // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
23 | | * // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
24 | | * // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
25 | | * // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
26 | | * // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
27 | | * // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | | */ |
29 | | use crate::bessel::i0::bessel_rsqrt_hard; |
30 | | use crate::bessel::i0_exp; |
31 | | use crate::bessel::i1::i1_0_to_7p75; |
32 | | use crate::common::f_fmla; |
33 | | use crate::double_double::DoubleDouble; |
34 | | use crate::dyadic_float::{DyadicFloat128, DyadicSign}; |
35 | | |
36 | | /// Modified exponentially scaled Bessel of the first kind of order 1 |
37 | | /// |
38 | | /// Computes exp(-|x|)*I1(x) |
39 | 0 | pub fn f_i1e(x: f64) -> f64 { |
40 | 0 | let ux = x.to_bits().wrapping_shl(1); |
41 | | |
42 | 0 | if ux >= 0x7ffu64 << 53 || ux <= 0x7960000000000000u64 { |
43 | | // |x| <= f64::EPSILON, |x| == inf, x == NaN |
44 | 0 | if ux <= 0x760af31dc4611874u64 { |
45 | | // |x| <= 2.2204460492503131e-24 |
46 | 0 | return x * 0.5; |
47 | 0 | } |
48 | 0 | if ux <= 0x7960000000000000u64 { |
49 | | // |x| <= f64::EPSILON |
50 | | // Power series of I1(x)*exp(-|x|) ~ x/2 - x^2/2 + O(x^3) |
51 | 0 | return f_fmla(x, -x * 0.5, x * 0.5); |
52 | 0 | } |
53 | 0 | if x.is_infinite() { |
54 | 0 | return 0.; |
55 | 0 | } |
56 | 0 | return x + f64::NAN; // x == NaN |
57 | 0 | } |
58 | | |
59 | 0 | let xb = x.to_bits() & 0x7fff_ffff_ffff_ffff; |
60 | | |
61 | | static SIGN: [f64; 2] = [1., -1.]; |
62 | | |
63 | 0 | let sign_scale = SIGN[x.is_sign_negative() as usize]; |
64 | | |
65 | 0 | if xb < 0x401f000000000000u64 { |
66 | | // |x| <= 7.75 |
67 | 0 | let v_exp = i0_exp(-f64::from_bits(xb)); |
68 | 0 | let vi1 = i1_0_to_7p75(f64::from_bits(xb)); |
69 | 0 | let r = DoubleDouble::quick_mult(vi1, v_exp); |
70 | 0 | return f64::copysign(r.to_f64(), sign_scale); |
71 | 0 | } |
72 | | |
73 | 0 | i1e_asympt(f64::from_bits(xb), sign_scale) |
74 | 0 | } |
75 | | |
76 | | /** |
77 | | Asymptotic expansion for I1. |
78 | | |
79 | | Computes: |
80 | | sqrt(x) * exp(-x) * I1(x) = Pn(1/x)/Qn(1/x) |
81 | | hence: |
82 | | I1(x)exp(-|x|) = Pn(1/x)/Qm(1/x)/sqrt(x) |
83 | | |
84 | | Generated by Wolfram Mathematica: |
85 | | ```text |
86 | | <<FunctionApproximations` |
87 | | ClearAll["Global`*"] |
88 | | f[x_]:=Sqrt[x] Exp[-x] BesselI[1,x] |
89 | | g[z_]:=f[1/z] |
90 | | {err,approx}=MiniMaxApproximation[g[z],{z,{1/713.98,1/7.75},11,11},WorkingPrecision->120] |
91 | | poly=Numerator[approx][[1]]; |
92 | | coeffs=CoefficientList[poly,z]; |
93 | | TableForm[Table[Row[{"'",NumberForm[coeffs[[i+1]],{50,50},ExponentFunction->(Null&)],"',"}],{i,0,Length[coeffs]-1}]] |
94 | | poly=Denominator[approx][[1]]; |
95 | | coeffs=CoefficientList[poly,z]; |
96 | | TableForm[Table[Row[{"'",NumberForm[coeffs[[i+1]],{50,50},ExponentFunction->(Null&)],"',"}],{i,0,Length[coeffs]-1}]] |
97 | | ``` |
98 | | **/ |
99 | | #[inline] |
100 | 0 | fn i1e_asympt(x: f64, sign_scale: f64) -> f64 { |
101 | 0 | let dx = x; |
102 | 0 | let recip = DoubleDouble::from_quick_recip(x); |
103 | | const P: [(u64, u64); 12] = [ |
104 | | (0xbc73a823f28a2f5e, 0x3fd9884533d43651), |
105 | | (0x3cc0d5bb78e674b3, 0xc0354325c8029263), |
106 | | (0x3d20e1155aaaa283, 0x4080c09b027c46a4), |
107 | | (0xbd5b90dcf81b99c1, 0xc0bfc1311090c839), |
108 | | (0xbd98f2fda9e8fa1b, 0x40f3bb81bb190ae2), |
109 | | (0xbdcec960752b60da, 0xc1207c0bbbc31cd9), |
110 | | (0x3dd3c9a299c9c41f, 0x414253e25c4584af), |
111 | | (0xbde82e7b9a3e1acc, 0xc159a656aece377c), |
112 | | (0x3e0d3d30d701a8ab, 0x416398df24c74ef2), |
113 | | (0xbdf57b85ab7006e2, 0xc151fd119be1702b), |
114 | | (0x3dd760928f4515fd, 0xc1508327e42639bc), |
115 | | (0x3dc09e71bc648589, 0x4143e4933afa621c), |
116 | | ]; |
117 | | |
118 | 0 | let x2 = DoubleDouble::quick_mult(recip, recip); |
119 | 0 | let x4 = DoubleDouble::quick_mult(x2, x2); |
120 | 0 | let x8 = DoubleDouble::quick_mult(x4, x4); |
121 | | |
122 | 0 | let e0 = DoubleDouble::mul_add( |
123 | 0 | recip, |
124 | 0 | DoubleDouble::from_bit_pair(P[1]), |
125 | 0 | DoubleDouble::from_bit_pair(P[0]), |
126 | | ); |
127 | 0 | let e1 = DoubleDouble::mul_add( |
128 | 0 | recip, |
129 | 0 | DoubleDouble::from_bit_pair(P[3]), |
130 | 0 | DoubleDouble::from_bit_pair(P[2]), |
131 | | ); |
132 | 0 | let e2 = DoubleDouble::mul_add( |
133 | 0 | recip, |
134 | 0 | DoubleDouble::from_bit_pair(P[5]), |
135 | 0 | DoubleDouble::from_bit_pair(P[4]), |
136 | | ); |
137 | 0 | let e3 = DoubleDouble::mul_add( |
138 | 0 | recip, |
139 | 0 | DoubleDouble::from_bit_pair(P[7]), |
140 | 0 | DoubleDouble::from_bit_pair(P[6]), |
141 | | ); |
142 | 0 | let e4 = DoubleDouble::mul_add( |
143 | 0 | recip, |
144 | 0 | DoubleDouble::from_bit_pair(P[9]), |
145 | 0 | DoubleDouble::from_bit_pair(P[8]), |
146 | | ); |
147 | 0 | let e5 = DoubleDouble::mul_add( |
148 | 0 | recip, |
149 | 0 | DoubleDouble::from_bit_pair(P[11]), |
150 | 0 | DoubleDouble::from_bit_pair(P[10]), |
151 | | ); |
152 | | |
153 | 0 | let f0 = DoubleDouble::mul_add(x2, e1, e0); |
154 | 0 | let f1 = DoubleDouble::mul_add(x2, e3, e2); |
155 | 0 | let f2 = DoubleDouble::mul_add(x2, e5, e4); |
156 | | |
157 | 0 | let g0 = DoubleDouble::mul_add(x4, f1, f0); |
158 | | |
159 | 0 | let p_num = DoubleDouble::mul_add(x8, f2, g0); |
160 | | |
161 | | const Q: [(u64, u64); 12] = [ |
162 | | (0x0000000000000000, 0x3ff0000000000000), |
163 | | (0xbcb334d5a476d9ad, 0xc04a75f94c1a0c1a), |
164 | | (0xbd324d58ed98bfae, 0x4094b00e60301c42), |
165 | | (0x3d7c8725666c4360, 0xc0d36b9d28d45928), |
166 | | (0x3d7f8457c2945822, 0x4107d6c398a174ed), |
167 | | (0x3dbc655ea216594b, 0xc1339393e6776e38), |
168 | | (0xbdebb5dffef78272, 0x415537198d23f6a1), |
169 | | (0xbdb577f8abad883e, 0xc16c6c399dcd6949), |
170 | | (0x3e14261c5362f109, 0x4173c02446576949), |
171 | | (0x3dc382ededad42c5, 0xc1547dff5770f4ec), |
172 | | (0xbe05c0f74d4c7956, 0xc165c88046952562), |
173 | | (0xbdbf9145927aa2c7, 0x414395e46bc45d5b), |
174 | | ]; |
175 | | |
176 | 0 | let e0 = DoubleDouble::mul_add_f64( |
177 | 0 | recip, |
178 | 0 | DoubleDouble::from_bit_pair(Q[1]), |
179 | 0 | f64::from_bits(0x3ff0000000000000), |
180 | | ); |
181 | 0 | let e1 = DoubleDouble::mul_add( |
182 | 0 | recip, |
183 | 0 | DoubleDouble::from_bit_pair(Q[3]), |
184 | 0 | DoubleDouble::from_bit_pair(Q[2]), |
185 | | ); |
186 | 0 | let e2 = DoubleDouble::mul_add( |
187 | 0 | recip, |
188 | 0 | DoubleDouble::from_bit_pair(Q[5]), |
189 | 0 | DoubleDouble::from_bit_pair(Q[4]), |
190 | | ); |
191 | 0 | let e3 = DoubleDouble::mul_add( |
192 | 0 | recip, |
193 | 0 | DoubleDouble::from_bit_pair(Q[7]), |
194 | 0 | DoubleDouble::from_bit_pair(Q[6]), |
195 | | ); |
196 | 0 | let e4 = DoubleDouble::mul_add( |
197 | 0 | recip, |
198 | 0 | DoubleDouble::from_bit_pair(Q[9]), |
199 | 0 | DoubleDouble::from_bit_pair(Q[8]), |
200 | | ); |
201 | 0 | let e5 = DoubleDouble::mul_add( |
202 | 0 | recip, |
203 | 0 | DoubleDouble::from_bit_pair(Q[11]), |
204 | 0 | DoubleDouble::from_bit_pair(Q[10]), |
205 | | ); |
206 | | |
207 | 0 | let f0 = DoubleDouble::mul_add(x2, e1, e0); |
208 | 0 | let f1 = DoubleDouble::mul_add(x2, e3, e2); |
209 | 0 | let f2 = DoubleDouble::mul_add(x2, e5, e4); |
210 | | |
211 | 0 | let g0 = DoubleDouble::mul_add(x4, f1, f0); |
212 | | |
213 | 0 | let p_den = DoubleDouble::mul_add(x8, f2, g0); |
214 | | |
215 | 0 | let z = DoubleDouble::div(p_num, p_den); |
216 | | |
217 | 0 | let r_sqrt = DoubleDouble::from_rsqrt_fast(dx); |
218 | | |
219 | 0 | let r = z * r_sqrt; |
220 | | |
221 | 0 | let err = f_fmla( |
222 | 0 | r.hi, |
223 | 0 | f64::from_bits(0x3c40000000000000), // 2^-59 |
224 | 0 | f64::from_bits(0x3ba0000000000000), // 2^-69 |
225 | | ); |
226 | 0 | let up = r.hi + (r.lo + err); |
227 | 0 | let lb = r.hi + (r.lo - err); |
228 | 0 | if up == lb { |
229 | 0 | return f64::copysign(r.to_f64(), sign_scale); |
230 | 0 | } |
231 | 0 | i1e_asympt_hard(x, sign_scale) |
232 | 0 | } |
233 | | |
234 | | /** |
235 | | Asymptotic expansion for I1. |
236 | | |
237 | | Computes: |
238 | | sqrt(x) * exp(-x) * I1(x) = Pn(1/x)/Qn(1/x) |
239 | | hence: |
240 | | I1(x)exp(-|x|) = Pn(1/x)/Qm(1/x)/sqrt(x) |
241 | | |
242 | | Generated by Wolfram Mathematica: |
243 | | ```text |
244 | | <<FunctionApproximations` |
245 | | ClearAll["Global`*"] |
246 | | f[x_]:=Sqrt[x] Exp[-x] BesselI[1,x] |
247 | | g[z_]:=f[1/z] |
248 | | {err,approx}=MiniMaxApproximation[g[z],{z,{1/713.98,1/7.75},15,15},WorkingPrecision->120] |
249 | | poly=Numerator[approx][[1]]; |
250 | | coeffs=CoefficientList[poly,z]; |
251 | | TableForm[Table[Row[{"'",NumberForm[coeffs[[i+1]],{50,50},ExponentFunction->(Null&)],"',"}],{i,0,Length[coeffs]-1}]] |
252 | | poly=Denominator[approx][[1]]; |
253 | | coeffs=CoefficientList[poly,z]; |
254 | | TableForm[Table[Row[{"'",NumberForm[coeffs[[i+1]],{50,50},ExponentFunction->(Null&)],"',"}],{i,0,Length[coeffs]-1}]] |
255 | | ``` |
256 | | **/ |
257 | | #[cold] |
258 | | #[inline(never)] |
259 | 0 | fn i1e_asympt_hard(x: f64, sign_scale: f64) -> f64 { |
260 | | static P: [DyadicFloat128; 16] = [ |
261 | | DyadicFloat128 { |
262 | | sign: DyadicSign::Pos, |
263 | | exponent: -129, |
264 | | mantissa: 0xcc42299e_a1b28468_bea7da47_28f13acc_u128, |
265 | | }, |
266 | | DyadicFloat128 { |
267 | | sign: DyadicSign::Neg, |
268 | | exponent: -124, |
269 | | mantissa: 0xda979406_3df6e66f_cf31c3f5_f194b48c_u128, |
270 | | }, |
271 | | DyadicFloat128 { |
272 | | sign: DyadicSign::Neg, |
273 | | exponent: -120, |
274 | | mantissa: 0xd60b7b96_c958929b_cabe1d8c_3d874767_u128, |
275 | | }, |
276 | | DyadicFloat128 { |
277 | | sign: DyadicSign::Pos, |
278 | | exponent: -113, |
279 | | mantissa: 0xd27aad9a_8fb38d56_46ab4510_8479306e_u128, |
280 | | }, |
281 | | DyadicFloat128 { |
282 | | sign: DyadicSign::Neg, |
283 | | exponent: -108, |
284 | | mantissa: 0xe0167305_c451bd1f_d2f17b68_5c62e2ff_u128, |
285 | | }, |
286 | | DyadicFloat128 { |
287 | | sign: DyadicSign::Pos, |
288 | | exponent: -103, |
289 | | mantissa: 0x8f6d238f_c80d8e4a_08c130f6_24e1c925_u128, |
290 | | }, |
291 | | DyadicFloat128 { |
292 | | sign: DyadicSign::Neg, |
293 | | exponent: -100, |
294 | | mantissa: 0xfe32280f_2ea99024_d9924472_92d7ac8f_u128, |
295 | | }, |
296 | | DyadicFloat128 { |
297 | | sign: DyadicSign::Pos, |
298 | | exponent: -96, |
299 | | mantissa: 0xa48815ac_d265609f_da4ace94_811390b2_u128, |
300 | | }, |
301 | | DyadicFloat128 { |
302 | | sign: DyadicSign::Neg, |
303 | | exponent: -93, |
304 | | mantissa: 0x9ededfe5_833b4cc1_731efd5c_f8729c6c_u128, |
305 | | }, |
306 | | DyadicFloat128 { |
307 | | sign: DyadicSign::Pos, |
308 | | exponent: -91, |
309 | | mantissa: 0xe5b43203_2784ae6a_f7458556_0a8308ea_u128, |
310 | | }, |
311 | | DyadicFloat128 { |
312 | | sign: DyadicSign::Neg, |
313 | | exponent: -89, |
314 | | mantissa: 0xf5df279a_3fb4ef60_8d10adee_7dd2f47b_u128, |
315 | | }, |
316 | | DyadicFloat128 { |
317 | | sign: DyadicSign::Pos, |
318 | | exponent: -87, |
319 | | mantissa: 0xbdb59963_7a757ed1_87280e0e_7f93ca2b_u128, |
320 | | }, |
321 | | DyadicFloat128 { |
322 | | sign: DyadicSign::Neg, |
323 | | exponent: -86, |
324 | | mantissa: 0xc87fdea5_53177ca8_c91de5fb_3f8f78d3_u128, |
325 | | }, |
326 | | DyadicFloat128 { |
327 | | sign: DyadicSign::Pos, |
328 | | exponent: -85, |
329 | | mantissa: 0x846d16a7_4663ef5d_ad42d599_5bc726b8_u128, |
330 | | }, |
331 | | DyadicFloat128 { |
332 | | sign: DyadicSign::Neg, |
333 | | exponent: -86, |
334 | | mantissa: 0xb3ed2055_74262d95_389f33e4_2ac3774a_u128, |
335 | | }, |
336 | | DyadicFloat128 { |
337 | | sign: DyadicSign::Pos, |
338 | | exponent: -88, |
339 | | mantissa: 0xa511aa32_c18c34e4_3d029a90_a71b7a55_u128, |
340 | | }, |
341 | | ]; |
342 | | static Q: [DyadicFloat128; 16] = [ |
343 | | DyadicFloat128 { |
344 | | sign: DyadicSign::Pos, |
345 | | exponent: -127, |
346 | | mantissa: 0x80000000_00000000_00000000_00000000_u128, |
347 | | }, |
348 | | DyadicFloat128 { |
349 | | sign: DyadicSign::Neg, |
350 | | exponent: -122, |
351 | | mantissa: 0x877b771a_ad8f5fd3_5aacf5f9_f04ee9de_u128, |
352 | | }, |
353 | | DyadicFloat128 { |
354 | | sign: DyadicSign::Neg, |
355 | | exponent: -118, |
356 | | mantissa: 0x89475ecd_9c84361e_800c8a3a_c8af23bf_u128, |
357 | | }, |
358 | | DyadicFloat128 { |
359 | | sign: DyadicSign::Pos, |
360 | | exponent: -111, |
361 | | mantissa: 0x837d1196_cf2723f1_23b54da8_225efe05_u128, |
362 | | }, |
363 | | DyadicFloat128 { |
364 | | sign: DyadicSign::Neg, |
365 | | exponent: -106, |
366 | | mantissa: 0x8ae3aecb_15355751_a9ee12e5_a4dd9dde_u128, |
367 | | }, |
368 | | DyadicFloat128 { |
369 | | sign: DyadicSign::Pos, |
370 | | exponent: -102, |
371 | | mantissa: 0xb0886afa_bc13f996_ab45d252_75c8f587_u128, |
372 | | }, |
373 | | DyadicFloat128 { |
374 | | sign: DyadicSign::Neg, |
375 | | exponent: -98, |
376 | | mantissa: 0x9b37d7cd_b114b86b_7d14a389_26599aa1_u128, |
377 | | }, |
378 | | DyadicFloat128 { |
379 | | sign: DyadicSign::Pos, |
380 | | exponent: -95, |
381 | | mantissa: 0xc716bf54_09d5dd9f_bc16679b_93aaeca4_u128, |
382 | | }, |
383 | | DyadicFloat128 { |
384 | | sign: DyadicSign::Neg, |
385 | | exponent: -92, |
386 | | mantissa: 0xbe0cd82e_c8af8371_ab028ed9_c7902dd2_u128, |
387 | | }, |
388 | | DyadicFloat128 { |
389 | | sign: DyadicSign::Pos, |
390 | | exponent: -89, |
391 | | mantissa: 0x875f8d91_8ef5d434_a39d00f9_2aed3d2a_u128, |
392 | | }, |
393 | | DyadicFloat128 { |
394 | | sign: DyadicSign::Neg, |
395 | | exponent: -87, |
396 | | mantissa: 0x8e030781_5aa4ce7f_70156b82_8b216b7c_u128, |
397 | | }, |
398 | | DyadicFloat128 { |
399 | | sign: DyadicSign::Pos, |
400 | | exponent: -86, |
401 | | mantissa: 0xd4dd2687_92646fbd_5ea2d422_da64fc0b_u128, |
402 | | }, |
403 | | DyadicFloat128 { |
404 | | sign: DyadicSign::Neg, |
405 | | exponent: -85, |
406 | | mantissa: 0xd6d72ab3_64b4a827_0499af0f_13a51a80_u128, |
407 | | }, |
408 | | DyadicFloat128 { |
409 | | sign: DyadicSign::Pos, |
410 | | exponent: -84, |
411 | | mantissa: 0x828f4e8b_728747a9_2cebe54a_810e2681_u128, |
412 | | }, |
413 | | DyadicFloat128 { |
414 | | sign: DyadicSign::Neg, |
415 | | exponent: -85, |
416 | | mantissa: 0x91570096_36a3fcfb_6b936d44_68dda1be_u128, |
417 | | }, |
418 | | DyadicFloat128 { |
419 | | sign: DyadicSign::Pos, |
420 | | exponent: -89, |
421 | | mantissa: 0xf082ad00_86024ed4_dd31613b_ec41e3f8_u128, |
422 | | }, |
423 | | ]; |
424 | | |
425 | 0 | let recip = DyadicFloat128::accurate_reciprocal(x); |
426 | | |
427 | 0 | let mut p_num = P[15]; |
428 | 0 | for i in (0..15).rev() { |
429 | 0 | p_num = recip * p_num + P[i]; |
430 | 0 | } |
431 | 0 | let mut p_den = Q[15]; |
432 | 0 | for i in (0..15).rev() { |
433 | 0 | p_den = recip * p_den + Q[i]; |
434 | 0 | } |
435 | 0 | let z = p_num * p_den.reciprocal(); |
436 | 0 | let r_sqrt = bessel_rsqrt_hard(x, recip); |
437 | 0 | (z * r_sqrt).fast_as_f64() * sign_scale |
438 | 0 | } |
439 | | |
440 | | #[cfg(test)] |
441 | | mod tests { |
442 | | use super::*; |
443 | | #[test] |
444 | | fn test_fi1e() { |
445 | | assert_eq!(f_i1e(f64::EPSILON), 1.1102230246251563e-16); |
446 | | assert_eq!(f_i1e(7.750000000757874), 0.13605110007443239); |
447 | | assert_eq!(f_i1e(7.482812501363189), 0.13818116726273896); |
448 | | assert_eq!(f_i1e(-7.750000000757874), -0.13605110007443239); |
449 | | assert_eq!(f_i1e(-7.482812501363189), -0.13818116726273896); |
450 | | assert!(f_i1e(f64::NAN).is_nan()); |
451 | | assert_eq!(f_i1e(f64::INFINITY), 0.); |
452 | | assert_eq!(f_i1e(f64::NEG_INFINITY), 0.); |
453 | | assert_eq!(f_i1e(0.01), 0.004950311047118276); |
454 | | assert_eq!(f_i1e(-0.01), -0.004950311047118276); |
455 | | assert_eq!(f_i1e(-9.01), -0.12716101566063667); |
456 | | assert_eq!(f_i1e(9.01), 0.12716101566063667); |
457 | | assert_eq!(f_i1e(763.), 0.014435579051182581); |
458 | | assert_eq!(i1e_asympt_hard(9.01, 1.), 0.12716101566063667); |
459 | | } |
460 | | } |