File indexing completed on 2025-01-18 09:58:38
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
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057 #ifndef G4Log_hh
0058 #define G4Log_hh 1
0059
0060 #ifdef WIN32
0061
0062 # define G4Log std::log
0063
0064 #else
0065
0066 # include "G4Types.hh"
0067
0068 # include <cstdint>
0069 # include <limits>
0070
0071
0072
0073 namespace G4LogConsts
0074 {
0075 const G4double LOG_UPPER_LIMIT = 1e307;
0076 const G4double LOG_LOWER_LIMIT = 0;
0077
0078 const G4double SQRTH = 0.70710678118654752440;
0079 const G4float MAXNUMF = 3.4028234663852885981170418348451692544e38f;
0080
0081
0082
0083
0084
0085 union ieee754
0086 {
0087 ieee754()= default;
0088 ieee754(G4double thed) { d = thed; };
0089 ieee754(uint64_t thell) { ll = thell; };
0090 ieee754(G4float thef) { f[0] = thef; };
0091 ieee754(uint32_t thei) { i[0] = thei; };
0092 G4double d;
0093 G4float f[2];
0094 uint32_t i[2];
0095 uint64_t ll;
0096 uint16_t s[4];
0097 };
0098
0099 inline G4double get_log_px(const G4double x)
0100 {
0101 const G4double PX1log = 1.01875663804580931796E-4;
0102 const G4double PX2log = 4.97494994976747001425E-1;
0103 const G4double PX3log = 4.70579119878881725854E0;
0104 const G4double PX4log = 1.44989225341610930846E1;
0105 const G4double PX5log = 1.79368678507819816313E1;
0106 const G4double PX6log = 7.70838733755885391666E0;
0107
0108 G4double px = PX1log;
0109 px *= x;
0110 px += PX2log;
0111 px *= x;
0112 px += PX3log;
0113 px *= x;
0114 px += PX4log;
0115 px *= x;
0116 px += PX5log;
0117 px *= x;
0118 px += PX6log;
0119 return px;
0120 }
0121
0122 inline G4double get_log_qx(const G4double x)
0123 {
0124 const G4double QX1log = 1.12873587189167450590E1;
0125 const G4double QX2log = 4.52279145837532221105E1;
0126 const G4double QX3log = 8.29875266912776603211E1;
0127 const G4double QX4log = 7.11544750618563894466E1;
0128 const G4double QX5log = 2.31251620126765340583E1;
0129
0130 G4double qx = x;
0131 qx += QX1log;
0132 qx *= x;
0133 qx += QX2log;
0134 qx *= x;
0135 qx += QX3log;
0136 qx *= x;
0137 qx += QX4log;
0138 qx *= x;
0139 qx += QX5log;
0140 return qx;
0141 }
0142
0143
0144
0145
0146 inline uint64_t dp2uint64(G4double x)
0147 {
0148 ieee754 tmp;
0149 tmp.d = x;
0150 return tmp.ll;
0151 }
0152
0153
0154
0155
0156 inline G4double uint642dp(uint64_t ll)
0157 {
0158 ieee754 tmp;
0159 tmp.ll = ll;
0160 return tmp.d;
0161 }
0162
0163
0164
0165
0166 inline G4float uint322sp(G4int x)
0167 {
0168 ieee754 tmp;
0169 tmp.i[0] = x;
0170 return tmp.f[0];
0171 }
0172
0173
0174
0175
0176 inline uint32_t sp2uint32(G4float x)
0177 {
0178 ieee754 tmp;
0179 tmp.f[0] = x;
0180 return tmp.i[0];
0181 }
0182
0183
0184
0185 inline G4double getMantExponent(const G4double x, G4double& fe)
0186 {
0187 uint64_t n = dp2uint64(x);
0188
0189
0190
0191 uint64_t le = (n >> 52);
0192
0193
0194 int32_t e =
0195 (int32_t)le;
0196 fe = e - 1023;
0197
0198
0199 n &= 0x800FFFFFFFFFFFFFULL;
0200
0201
0202 const uint64_t p05 = 0x3FE0000000000000ULL;
0203 n |= p05;
0204
0205 return uint642dp(n);
0206 }
0207
0208
0209
0210 inline G4float getMantExponentf(const G4float x, G4float& fe)
0211 {
0212 uint32_t n = sp2uint32(x);
0213 int32_t e = (n >> 23) - 127;
0214 fe = e;
0215
0216
0217 const uint32_t p05f = 0x3f000000;
0218 n &= 0x807fffff;
0219 n |= p05f;
0220
0221 return uint322sp(n);
0222 }
0223 }
0224
0225
0226
0227 inline G4double G4Log(G4double x)
0228 {
0229 const G4double original_x = x;
0230
0231
0232 G4double fe;
0233 x = G4LogConsts::getMantExponent(x, fe);
0234
0235
0236 x > G4LogConsts::SQRTH ? fe += 1. : x += x;
0237 x -= 1.0;
0238
0239
0240 G4double px = G4LogConsts::get_log_px(x);
0241
0242
0243 const G4double x2 = x * x;
0244 px *= x;
0245 px *= x2;
0246
0247 const G4double qx = G4LogConsts::get_log_qx(x);
0248
0249 G4double res = px / qx;
0250
0251 res -= fe * 2.121944400546905827679e-4;
0252 res -= 0.5 * x2;
0253
0254 res = x + res;
0255 res += fe * 0.693359375;
0256
0257 if(original_x > G4LogConsts::LOG_UPPER_LIMIT)
0258 res = std::numeric_limits<G4double>::infinity();
0259 if(original_x < G4LogConsts::LOG_LOWER_LIMIT)
0260 res = -std::numeric_limits<G4double>::quiet_NaN();
0261
0262 return res;
0263 }
0264
0265
0266
0267 namespace G4LogConsts
0268 {
0269 const G4float LOGF_UPPER_LIMIT = MAXNUMF;
0270 const G4float LOGF_LOWER_LIMIT = 0;
0271
0272 const G4float PX1logf = 7.0376836292E-2f;
0273 const G4float PX2logf = -1.1514610310E-1f;
0274 const G4float PX3logf = 1.1676998740E-1f;
0275 const G4float PX4logf = -1.2420140846E-1f;
0276 const G4float PX5logf = 1.4249322787E-1f;
0277 const G4float PX6logf = -1.6668057665E-1f;
0278 const G4float PX7logf = 2.0000714765E-1f;
0279 const G4float PX8logf = -2.4999993993E-1f;
0280 const G4float PX9logf = 3.3333331174E-1f;
0281
0282 inline G4float get_log_poly(const G4float x)
0283 {
0284 G4float y = x * PX1logf;
0285 y += PX2logf;
0286 y *= x;
0287 y += PX3logf;
0288 y *= x;
0289 y += PX4logf;
0290 y *= x;
0291 y += PX5logf;
0292 y *= x;
0293 y += PX6logf;
0294 y *= x;
0295 y += PX7logf;
0296 y *= x;
0297 y += PX8logf;
0298 y *= x;
0299 y += PX9logf;
0300 return y;
0301 }
0302
0303 const G4float SQRTHF = 0.707106781186547524f;
0304 }
0305
0306
0307
0308 inline G4float G4Logf(G4float x)
0309 {
0310 const G4float original_x = x;
0311
0312 G4float fe;
0313 x = G4LogConsts::getMantExponentf(x, fe);
0314
0315 x > G4LogConsts::SQRTHF ? fe += 1.f : x += x;
0316 x -= 1.0f;
0317
0318 const G4float x2 = x * x;
0319
0320 G4float res = G4LogConsts::get_log_poly(x);
0321 res *= x2 * x;
0322
0323 res += -2.12194440e-4f * fe;
0324 res += -0.5f * x2;
0325
0326 res = x + res;
0327
0328 res += 0.693359375f * fe;
0329
0330 if(original_x > G4LogConsts::LOGF_UPPER_LIMIT)
0331 res = std::numeric_limits<G4float>::infinity();
0332 if(original_x < G4LogConsts::LOGF_LOWER_LIMIT)
0333 res = -std::numeric_limits<G4float>::quiet_NaN();
0334
0335 return res;
0336 }
0337
0338
0339
0340 void logv(const uint32_t size, G4double const* __restrict__ iarray,
0341 G4double* __restrict__ oarray);
0342 void G4Logv(const uint32_t size, G4double const* __restrict__ iarray,
0343 G4double* __restrict__ oarray);
0344 void logfv(const uint32_t size, G4float const* __restrict__ iarray,
0345 G4float* __restrict__ oarray);
0346 void G4Logfv(const uint32_t size, G4float const* __restrict__ iarray,
0347 G4float* __restrict__ oarray);
0348
0349 #endif
0350
0351 #endif