File indexing completed on 2024-07-18 23:17:37
0001 #ifndef DataFormatsMathAPPROX_LOG_H
0002 #define DataFormatsMathAPPROX_LOG_H
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 #include "DataFormats/Math/interface/approx_math.h"
0030
0031 template <int DEGREE>
0032 constexpr float approx_logf_P(float p);
0033
0034
0035
0036
0037 template <>
0038 constexpr float approx_logf_P<2>(float y) {
0039 return y * (float(0x1.0671c4p0) + y * (float(-0x7.27744p-4)));
0040 }
0041
0042
0043 template <>
0044 constexpr float approx_logf_P<3>(float y) {
0045 return y * (float(0x1.013354p0) + y * (-float(0x8.33006p-4) + y * float(0x4.0d16cp-4)));
0046 }
0047
0048
0049 template <>
0050 constexpr float approx_logf_P<4>(float y) {
0051 return y *
0052 (float(0xf.ff5bap-4) + y * (-float(0x8.13e5ep-4) + y * (float(0x5.826ep-4) + y * (-float(0x2.e87fb8p-4)))));
0053 }
0054
0055
0056 template <>
0057 constexpr float approx_logf_P<5>(float y) {
0058 return y * (float(0xf.ff652p-4) +
0059 y * (-float(0x8.0048ap-4) +
0060 y * (float(0x5.72782p-4) + y * (-float(0x4.20904p-4) + y * float(0x2.1d7fd8p-4)))));
0061 }
0062
0063
0064 template <>
0065 constexpr float approx_logf_P<6>(float y) {
0066 return y * (float(0xf.fff14p-4) +
0067 y * (-float(0x7.ff4bfp-4) +
0068 y * (float(0x5.582f6p-4) +
0069 y * (-float(0x4.1dcf2p-4) + y * (float(0x3.3863f8p-4) + y * (-float(0x1.9288d4p-4)))))));
0070 }
0071
0072
0073 template <>
0074 constexpr float approx_logf_P<7>(float y) {
0075 return y * (float(0x1.000034p0) +
0076 y * (-float(0x7.ffe57p-4) +
0077 y * (float(0x5.5422ep-4) +
0078 y * (-float(0x4.037a6p-4) +
0079 y * (float(0x3.541c88p-4) + y * (-float(0x2.af842p-4) + y * float(0x1.48b3d8p-4)))))));
0080 }
0081
0082
0083 template <>
0084 constexpr float approx_logf_P<8>(float y) {
0085 return y *
0086 (float(0x1.00000cp0) +
0087 y * (float(-0x8.0003p-4) +
0088 y * (float(0x5.55087p-4) +
0089 y * (float(-0x3.fedcep-4) +
0090 y * (float(0x3.3a1dap-4) +
0091 y * (float(-0x2.cb55fp-4) + y * (float(0x2.38831p-4) + y * (float(-0xf.e87cap-8)))))))));
0092 }
0093
0094 template <int DEGREE>
0095 constexpr float unsafe_logf_impl(float x) {
0096 using namespace approx_math;
0097
0098 binary32 xx, m;
0099 xx.f = x;
0100
0101
0102 int e = (((xx.i32) >> 23) & 0xFF) - 127;
0103 m.i32 = (xx.i32 & 0x007FFFFF) | 0x3F800000;
0104
0105 int adjust = (xx.i32 >> 22) & 1;
0106 m.i32 -= adjust << 23;
0107 e += adjust;
0108
0109
0110 float y = m.f - 1.0f;
0111
0112
0113
0114 float p = approx_logf_P<DEGREE>(y);
0115
0116 constexpr float Log2 = 0xb.17218p-4;
0117 return float(e) * Log2 + p;
0118 }
0119
0120 #ifndef NO_APPROX_MATH
0121 template <int DEGREE>
0122 constexpr float unsafe_logf(float x) {
0123 return unsafe_logf_impl<DEGREE>(x);
0124 }
0125
0126 template <int DEGREE>
0127 constexpr float approx_logf(float x) {
0128 using namespace approx_math;
0129
0130 constexpr float MAXNUMF = 3.4028234663852885981170418348451692544e38f;
0131
0132
0133 float res = unsafe_logf<DEGREE>(x);
0134 res = (x < MAXNUMF) ? res : std::numeric_limits<float>::max();
0135 return (x > 0) ? res : std::numeric_limits<float>::quiet_NaN();
0136 }
0137
0138 #else
0139 template <int DEGREE>
0140 constexpr float unsafe_logf(float x) {
0141 return std::log(x);
0142 }
0143
0144 template <int DEGREE>
0145 constexpr float approx_logf(float x) {
0146 return std::log(x);
0147 }
0148
0149 #endif
0150
0151 #endif