File indexing completed on 2025-02-21 10:16:42
0001
0002
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 #ifndef LOG_H_
0028 #define LOG_H_
0029
0030 #include "vdtcore_common.h"
0031 #include <limits>
0032
0033 namespace vdt{
0034
0035
0036 namespace details{
0037
0038 const double LOG_UPPER_LIMIT = 1e307;
0039 const double LOG_LOWER_LIMIT = 0;
0040
0041 const double SQRTH = 0.70710678118654752440;
0042
0043 inline double get_log_px(const double x){
0044 const double PX1log = 1.01875663804580931796E-4;
0045 const double PX2log = 4.97494994976747001425E-1;
0046 const double PX3log = 4.70579119878881725854E0;
0047 const double PX4log = 1.44989225341610930846E1;
0048 const double PX5log = 1.79368678507819816313E1;
0049 const double PX6log = 7.70838733755885391666E0;
0050
0051 double px = PX1log;
0052 px *= x;
0053 px += PX2log;
0054 px *= x;
0055 px += PX3log;
0056 px *= x;
0057 px += PX4log;
0058 px *= x;
0059 px += PX5log;
0060 px *= x;
0061 px += PX6log;
0062 return px;
0063
0064 }
0065
0066 inline double get_log_qx(const double x){
0067 const double QX1log = 1.12873587189167450590E1;
0068 const double QX2log = 4.52279145837532221105E1;
0069 const double QX3log = 8.29875266912776603211E1;
0070 const double QX4log = 7.11544750618563894466E1;
0071 const double QX5log = 2.31251620126765340583E1;
0072
0073 double qx = x;
0074 qx += QX1log;
0075 qx *=x;
0076 qx += QX2log;
0077 qx *=x;
0078 qx += QX3log;
0079 qx *=x;
0080 qx += QX4log;
0081 qx *=x;
0082 qx += QX5log;
0083 return qx;
0084 }
0085
0086 }
0087
0088
0089 inline double fast_log(double x){
0090
0091 const double original_x = x;
0092
0093
0094 double fe;
0095 x = details::getMantExponent(x,fe);
0096
0097
0098 x > details::SQRTH? fe+=1. : x+=x ;
0099 x -= 1.0;
0100
0101
0102 double px = details::get_log_px(x);
0103
0104
0105 const double x2 = x*x;
0106 px *= x;
0107 px *= x2;
0108
0109 const double qx = details::get_log_qx(x);
0110
0111 double res = px / qx ;
0112
0113 res -= fe * 2.121944400546905827679e-4;
0114 res -= 0.5 * x2 ;
0115
0116 res = x + res;
0117 res += fe * 0.693359375;
0118
0119 if (original_x > details::LOG_UPPER_LIMIT)
0120 res = std::numeric_limits<double>::infinity();
0121 if (original_x < details::LOG_LOWER_LIMIT)
0122 res = - std::numeric_limits<double>::quiet_NaN();
0123
0124 return res;
0125
0126 }
0127
0128
0129
0130
0131
0132 namespace details{
0133
0134 const float LOGF_UPPER_LIMIT = MAXNUMF;
0135 const float LOGF_LOWER_LIMIT = 0;
0136
0137 const float PX1logf = 7.0376836292E-2f;
0138 const float PX2logf = -1.1514610310E-1f;
0139 const float PX3logf = 1.1676998740E-1f;
0140 const float PX4logf = -1.2420140846E-1f;
0141 const float PX5logf = 1.4249322787E-1f;
0142 const float PX6logf = -1.6668057665E-1f;
0143 const float PX7logf = 2.0000714765E-1f;
0144 const float PX8logf = -2.4999993993E-1f;
0145 const float PX9logf = 3.3333331174E-1f;
0146
0147 inline float get_log_poly(const float x){
0148 float y = x*PX1logf;
0149 y += PX2logf;
0150 y *= x;
0151 y += PX3logf;
0152 y *= x;
0153 y += PX4logf;
0154 y *= x;
0155 y += PX5logf;
0156 y *= x;
0157 y += PX6logf;
0158 y *= x;
0159 y += PX7logf;
0160 y *= x;
0161 y += PX8logf;
0162 y *= x;
0163 y += PX9logf;
0164 return y;
0165 }
0166
0167 const float SQRTHF = 0.707106781186547524f;
0168
0169 }
0170
0171
0172 inline float fast_logf( float x ) {
0173
0174 const float original_x = x;
0175
0176 float fe;
0177 x = details::getMantExponentf( x, fe);
0178
0179 x > details::SQRTHF? fe+=1.f : x+=x ;
0180 x -= 1.0f;
0181
0182 const float x2 = x*x;
0183
0184 float res = details::get_log_poly(x);
0185 res *= x2*x;
0186
0187 res += -2.12194440e-4f * fe;
0188 res += -0.5f * x2;
0189
0190 res= x + res;
0191
0192 res += 0.693359375f * fe;
0193
0194 if (original_x > details::LOGF_UPPER_LIMIT)
0195 res = std::numeric_limits<float>::infinity();
0196 if (original_x < details::LOGF_LOWER_LIMIT)
0197 res = -std::numeric_limits<float>::quiet_NaN();
0198
0199 return res;
0200 }
0201
0202
0203
0204
0205 void logv(const uint32_t size, double const * __restrict__ iarray, double* __restrict__ oarray);
0206 void fast_logv(const uint32_t size, double const * __restrict__ iarray, double* __restrict__ oarray);
0207 void logfv(const uint32_t size, float const * __restrict__ iarray, float* __restrict__ oarray);
0208 void fast_logfv(const uint32_t size, float const * __restrict__ iarray, float* __restrict__ oarray);
0209
0210 }
0211
0212 #endif