Warning, file /include/vdt/log.h was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
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