Computes an approximation to the modified Bessel function of the first kind, zeroth order. The following implementation follows Cephes' F32 and F64 implementation of i0e.
| 1407 | // The following implementation follows Cephes' F32 and F64 implementation of |
| 1408 | // i0e. |
| 1409 | static XlaOp I0eImpl32(XlaOp x) { |
| 1410 | static const std::array<float, 18> kI0eCoeffsA{ |
| 1411 | -1.30002500998624804212E-8f, 6.04699502254191894932E-8f, |
| 1412 | -2.67079385394061173391E-7f, 1.11738753912010371815E-6f, |
| 1413 | -4.41673835845875056359E-6f, 1.64484480707288970893E-5f, |
| 1414 | -5.75419501008210370398E-5f, 1.88502885095841655729E-4f, |
| 1415 | -5.76375574538582365885E-4f, 1.63947561694133579842E-3f, |
| 1416 | -4.32430999505057594430E-3f, 1.05464603945949983183E-2f, |
| 1417 | -2.37374148058994688156E-2f, 4.93052842396707084878E-2f, |
| 1418 | -9.49010970480476444210E-2f, 1.71620901522208775349E-1f, |
| 1419 | -3.04682672343198398683E-1f, 6.76795274409476084995E-1f}; |
| 1420 | |
| 1421 | static const std::array<float, 7> kI0eCoeffsB{ |
| 1422 | 3.39623202570838634515E-9f, 2.26666899049817806459E-8f, |
| 1423 | 2.04891858946906374183E-7f, 2.89137052083475648297E-6f, |
| 1424 | 6.88975834691682398426E-5f, 3.36911647825569408990E-3f, |
| 1425 | 8.04490411014108831608E-1f}; |
| 1426 | |
| 1427 | x = Abs(x); |
| 1428 | auto half = xla::ScalarLike(x, 0.5); |
| 1429 | auto two = xla::ScalarLike(x, 2.0); |
| 1430 | auto thirty_two = xla::ScalarLike(x, 32.0); |
| 1431 | auto result_le_8 = |
| 1432 | EvaluateChebyshevPolynomial<float>(half * x - two, kI0eCoeffsA); |
| 1433 | auto result_gt_8 = |
| 1434 | EvaluateChebyshevPolynomial<float>(thirty_two / x - two, kI0eCoeffsB) / |
| 1435 | Sqrt(x); |
| 1436 | return Select(Le(x, xla::ScalarLike(x, 8.0)), result_le_8, result_gt_8); |
| 1437 | } |
| 1438 | |
| 1439 | static XlaOp I0eImpl64(XlaOp x) { |
| 1440 | static const std::array<double, 30> kI0eCoeffsA{ |