File indexing completed on 2025-01-18 09:58:16
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 G4Exp_hh
0058 #define G4Exp_hh 1
0059
0060 #ifdef WIN32
0061
0062 # define G4Exp std::exp
0063
0064 #else
0065
0066 # include "G4Types.hh"
0067
0068 # include <cstdint>
0069 # include <limits>
0070
0071 namespace G4ExpConsts
0072 {
0073 const G4double EXP_LIMIT = 708;
0074
0075 const G4double PX1exp = 1.26177193074810590878E-4;
0076 const G4double PX2exp = 3.02994407707441961300E-2;
0077 const G4double PX3exp = 9.99999999999999999910E-1;
0078 const G4double QX1exp = 3.00198505138664455042E-6;
0079 const G4double QX2exp = 2.52448340349684104192E-3;
0080 const G4double QX3exp = 2.27265548208155028766E-1;
0081 const G4double QX4exp = 2.00000000000000000009E0;
0082
0083 const G4double LOG2E = 1.4426950408889634073599;
0084
0085 const G4float MAXLOGF = 88.72283905206835f;
0086 const G4float MINLOGF = -88.f;
0087
0088 const G4float C1F = 0.693359375f;
0089 const G4float C2F = -2.12194440e-4f;
0090
0091 const G4float PX1expf = 1.9875691500E-4f;
0092 const G4float PX2expf = 1.3981999507E-3f;
0093 const G4float PX3expf = 8.3334519073E-3f;
0094 const G4float PX4expf = 4.1665795894E-2f;
0095 const G4float PX5expf = 1.6666665459E-1f;
0096 const G4float PX6expf = 5.0000001201E-1f;
0097
0098 const G4float LOG2EF = 1.44269504088896341f;
0099
0100
0101
0102
0103
0104 union ieee754
0105 {
0106 ieee754()= default;
0107 ieee754(G4double thed) { d = thed; };
0108 ieee754(uint64_t thell) { ll = thell; };
0109 ieee754(G4float thef) { f[0] = thef; };
0110 ieee754(uint32_t thei) { i[0] = thei; };
0111 G4double d;
0112 G4float f[2];
0113 uint32_t i[2];
0114 uint64_t ll;
0115 uint16_t s[4];
0116 };
0117
0118
0119
0120
0121 inline G4double uint642dp(uint64_t ll)
0122 {
0123 ieee754 tmp;
0124 tmp.ll = ll;
0125 return tmp.d;
0126 }
0127
0128
0129
0130
0131 inline G4float uint322sp(G4int x)
0132 {
0133 ieee754 tmp;
0134 tmp.i[0] = x;
0135 return tmp.f[0];
0136 }
0137
0138
0139
0140
0141 inline uint32_t sp2uint32(G4float x)
0142 {
0143 ieee754 tmp;
0144 tmp.f[0] = x;
0145 return tmp.i[0];
0146 }
0147
0148
0149
0150
0151
0152
0153
0154 inline G4double fpfloor(const G4double x)
0155 {
0156
0157
0158 int32_t ret = int32_t(x);
0159 ret -= (sp2uint32(x) >> 31);
0160 return ret;
0161 }
0162
0163
0164
0165
0166
0167
0168
0169 inline G4float fpfloor(const G4float x)
0170 {
0171 int32_t ret = int32_t(x);
0172 ret -= (sp2uint32(x) >> 31);
0173 return ret;
0174 }
0175 }
0176
0177
0178
0179
0180 inline G4double G4Exp(G4double initial_x)
0181 {
0182 G4double x = initial_x;
0183 G4double px = G4ExpConsts::fpfloor(G4ExpConsts::LOG2E * x + 0.5);
0184
0185 const int32_t n = int32_t(px);
0186
0187 x -= px * 6.93145751953125E-1;
0188 x -= px * 1.42860682030941723212E-6;
0189
0190 const G4double xx = x * x;
0191
0192
0193 px = G4ExpConsts::PX1exp;
0194 px *= xx;
0195 px += G4ExpConsts::PX2exp;
0196 px *= xx;
0197 px += G4ExpConsts::PX3exp;
0198 px *= x;
0199
0200
0201 G4double qx = G4ExpConsts::QX1exp;
0202 qx *= xx;
0203 qx += G4ExpConsts::QX2exp;
0204 qx *= xx;
0205 qx += G4ExpConsts::QX3exp;
0206 qx *= xx;
0207 qx += G4ExpConsts::QX4exp;
0208
0209
0210 x = px / (qx - px);
0211 x = 1.0 + 2.0 * x;
0212
0213
0214 x *= G4ExpConsts::uint642dp((((uint64_t) n) + 1023) << 52);
0215
0216 if(initial_x > G4ExpConsts::EXP_LIMIT)
0217 x = std::numeric_limits<G4double>::infinity();
0218 if(initial_x < -G4ExpConsts::EXP_LIMIT)
0219 x = 0.;
0220
0221 return x;
0222 }
0223
0224
0225
0226
0227 inline G4float G4Expf(G4float initial_x)
0228 {
0229 G4float x = initial_x;
0230
0231 G4float z =
0232 G4ExpConsts::fpfloor(G4ExpConsts::LOG2EF * x +
0233 0.5f);
0234
0235 x -= z * G4ExpConsts::C1F;
0236 x -= z * G4ExpConsts::C2F;
0237 const int32_t n = int32_t(z);
0238
0239 const G4float x2 = x * x;
0240
0241 z = x * G4ExpConsts::PX1expf;
0242 z += G4ExpConsts::PX2expf;
0243 z *= x;
0244 z += G4ExpConsts::PX3expf;
0245 z *= x;
0246 z += G4ExpConsts::PX4expf;
0247 z *= x;
0248 z += G4ExpConsts::PX5expf;
0249 z *= x;
0250 z += G4ExpConsts::PX6expf;
0251 z *= x2;
0252 z += x + 1.0f;
0253
0254
0255 z *= G4ExpConsts::uint322sp((n + 0x7f) << 23);
0256
0257 if(initial_x > G4ExpConsts::MAXLOGF)
0258 z = std::numeric_limits<G4float>::infinity();
0259 if(initial_x < G4ExpConsts::MINLOGF)
0260 z = 0.f;
0261
0262 return z;
0263 }
0264
0265
0266
0267 void expv(const uint32_t size, G4double const* __restrict__ iarray,
0268 G4double* __restrict__ oarray);
0269 void G4Expv(const uint32_t size, G4double const* __restrict__ iarray,
0270 G4double* __restrict__ oarray);
0271 void expfv(const uint32_t size, G4float const* __restrict__ iarray,
0272 G4float* __restrict__ oarray);
0273 void G4Expfv(const uint32_t size, G4float const* __restrict__ iarray,
0274 G4float* __restrict__ oarray);
0275
0276 #endif
0277
0278 #endif