Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4Log.hh
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// G4Log
27//
28// Class description:
29//
30// The basic idea is to exploit Pade polynomials.
31// A lot of ideas were inspired by the cephes math library
32// (by Stephen L. Moshier moshier@na-net.ornl.gov) as well as actual code.
33// The Cephes library can be found here: http://www.netlib.org/cephes/
34// Code and algorithms for G4Exp have been extracted and adapted for Geant4
35// from the original implementation in the VDT mathematical library
36// (https://svnweb.cern.ch/trac/vdt), version 0.3.7.
37
38// Original implementation created on: Jun 23, 2012
39// Author: Danilo Piparo, Thomas Hauth, Vincenzo Innocente
40//
41// --------------------------------------------------------------------
42/*
43 * VDT is free software: you can redistribute it and/or modify
44 * it under the terms of the GNU Lesser Public License as published by
45 * the Free Software Foundation, either version 3 of the License, or
46 * (at your option) any later version.
47 *
48 * This program is distributed in the hope that it will be useful,
49 * but WITHOUT ANY WARRANTY; without even the implied warranty of
50 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
51 * GNU Lesser Public License for more details.
52 *
53 * You should have received a copy of the GNU Lesser Public License
54 * along with this program. If not, see <http://www.gnu.org/licenses/>.
55 */
56// --------------------------------------------------------------------
57#ifndef G4Log_hh
58#define G4Log_hh 1
59
60#ifdef WIN32
61
62# define G4Log std::log
63
64#else
65
66# include "G4Types.hh"
67
68# include <cstdint>
69# include <limits>
70
71// local namespace for the constants/functions which are necessary only here
72//
73namespace G4LogConsts
74{
77
78 const G4double SQRTH = 0.70710678118654752440;
79 const G4float MAXNUMF = 3.4028234663852885981170418348451692544e38f;
80
81 //----------------------------------------------------------------------------
82 // Used to switch between different type of interpretations of the data
83 // (64 bits)
84 //
85 union ieee754
86 {
87 ieee754()= default;
88 ieee754(G4double thed) { d = thed; };
89 ieee754(uint64_t thell) { ll = thell; };
90 ieee754(G4float thef) { f[0] = thef; };
91 ieee754(uint32_t thei) { i[0] = thei; };
94 uint32_t i[2];
95 uint64_t ll;
96 uint16_t s[4];
97 };
98
100 {
101 const G4double PX1log = 1.01875663804580931796E-4;
102 const G4double PX2log = 4.97494994976747001425E-1;
103 const G4double PX3log = 4.70579119878881725854E0;
104 const G4double PX4log = 1.44989225341610930846E1;
105 const G4double PX5log = 1.79368678507819816313E1;
106 const G4double PX6log = 7.70838733755885391666E0;
107
108 G4double px = PX1log;
109 px *= x;
110 px += PX2log;
111 px *= x;
112 px += PX3log;
113 px *= x;
114 px += PX4log;
115 px *= x;
116 px += PX5log;
117 px *= x;
118 px += PX6log;
119 return px;
120 }
121
123 {
124 const G4double QX1log = 1.12873587189167450590E1;
125 const G4double QX2log = 4.52279145837532221105E1;
126 const G4double QX3log = 8.29875266912776603211E1;
127 const G4double QX4log = 7.11544750618563894466E1;
128 const G4double QX5log = 2.31251620126765340583E1;
129
130 G4double qx = x;
131 qx += QX1log;
132 qx *= x;
133 qx += QX2log;
134 qx *= x;
135 qx += QX3log;
136 qx *= x;
137 qx += QX4log;
138 qx *= x;
139 qx += QX5log;
140 return qx;
141 }
142
143 //----------------------------------------------------------------------------
144 // Converts a double to an unsigned long long
145 //
146 inline uint64_t dp2uint64(G4double x)
147 {
148 ieee754 tmp;
149 tmp.d = x;
150 return tmp.ll;
151 }
152
153 //----------------------------------------------------------------------------
154 // Converts an unsigned long long to a double
155 //
156 inline G4double uint642dp(uint64_t ll)
157 {
158 ieee754 tmp;
159 tmp.ll = ll;
160 return tmp.d;
161 }
162
163 //----------------------------------------------------------------------------
164 // Converts an int to a float
165 //
167 {
168 ieee754 tmp;
169 tmp.i[0] = x;
170 return tmp.f[0];
171 }
172
173 //----------------------------------------------------------------------------
174 // Converts a float to an int
175 //
176 inline uint32_t sp2uint32(G4float x)
177 {
178 ieee754 tmp;
179 tmp.f[0] = x;
180 return tmp.i[0];
181 }
182
183 //----------------------------------------------------------------------------
184 /// Like frexp but vectorising and the exponent is a double.
186 {
187 uint64_t n = dp2uint64(x);
188
189 // Shift to the right up to the beginning of the exponent.
190 // Then with a mask, cut off the sign bit
191 uint64_t le = (n >> 52);
192
193 // chop the head of the number: an int contains more than 11 bits (32)
194 int32_t e =
195 (int32_t)le; // This is important since sums on uint64_t do not vectorise
196 fe = e - 1023;
197
198 // This puts to 11 zeroes the exponent
199 n &= 0x800FFFFFFFFFFFFFULL;
200 // build a mask which is 0.5, i.e. an exponent equal to 1022
201 // which means *2, see the above +1.
202 const uint64_t p05 = 0x3FE0000000000000ULL; // dp2uint64(0.5);
203 n |= p05;
204
205 return uint642dp(n);
206 }
207
208 //----------------------------------------------------------------------------
209 /// Like frexp but vectorising and the exponent is a float.
211 {
212 uint32_t n = sp2uint32(x);
213 int32_t e = (n >> 23) - 127;
214 fe = e;
215
216 // fractional part
217 const uint32_t p05f = 0x3f000000; // //sp2uint32(0.5);
218 n &= 0x807fffff; // ~0x7f800000;
219 n |= p05f;
220
221 return uint322sp(n);
222 }
223} // namespace G4LogConsts
224
225// Log double precision --------------------------------------------------------
226
228{
229 const G4double original_x = x;
230
231 /* separate mantissa from exponent */
232 G4double fe;
234
235 // blending
236 x > G4LogConsts::SQRTH ? fe += 1. : x += x;
237 x -= 1.0;
238
239 /* rational form */
241
242 // for the final formula
243 const G4double x2 = x * x;
244 px *= x;
245 px *= x2;
246
247 const G4double qx = G4LogConsts::get_log_qx(x);
248
249 G4double res = px / qx;
250
251 res -= fe * 2.121944400546905827679e-4;
252 res -= 0.5 * x2;
253
254 res = x + res;
255 res += fe * 0.693359375;
256
257 if(original_x > G4LogConsts::LOG_UPPER_LIMIT)
258 res = std::numeric_limits<G4double>::infinity();
259 if(original_x < G4LogConsts::LOG_LOWER_LIMIT) // THIS IS NAN!
260 res = -std::numeric_limits<G4double>::quiet_NaN();
261
262 return res;
263}
264
265// Log single precision --------------------------------------------------------
266
267namespace G4LogConsts
268{
271
272 const G4float PX1logf = 7.0376836292E-2f;
273 const G4float PX2logf = -1.1514610310E-1f;
274 const G4float PX3logf = 1.1676998740E-1f;
275 const G4float PX4logf = -1.2420140846E-1f;
276 const G4float PX5logf = 1.4249322787E-1f;
277 const G4float PX6logf = -1.6668057665E-1f;
278 const G4float PX7logf = 2.0000714765E-1f;
279 const G4float PX8logf = -2.4999993993E-1f;
280 const G4float PX9logf = 3.3333331174E-1f;
281
283 {
284 G4float y = x * PX1logf;
285 y += PX2logf;
286 y *= x;
287 y += PX3logf;
288 y *= x;
289 y += PX4logf;
290 y *= x;
291 y += PX5logf;
292 y *= x;
293 y += PX6logf;
294 y *= x;
295 y += PX7logf;
296 y *= x;
297 y += PX8logf;
298 y *= x;
299 y += PX9logf;
300 return y;
301 }
302
303 const G4float SQRTHF = 0.707106781186547524f;
304} // namespace G4LogConsts
305
306// Log single precision --------------------------------------------------------
307
309{
310 const G4float original_x = x;
311
312 G4float fe;
314
315 x > G4LogConsts::SQRTHF ? fe += 1.f : x += x;
316 x -= 1.0f;
317
318 const G4float x2 = x * x;
319
321 res *= x2 * x;
322
323 res += -2.12194440e-4f * fe;
324 res += -0.5f * x2;
325
326 res = x + res;
327
328 res += 0.693359375f * fe;
329
330 if(original_x > G4LogConsts::LOGF_UPPER_LIMIT)
331 res = std::numeric_limits<G4float>::infinity();
332 if(original_x < G4LogConsts::LOGF_LOWER_LIMIT)
333 res = -std::numeric_limits<G4float>::quiet_NaN();
334
335 return res;
336}
337
338//------------------------------------------------------------------------------
339
340void logv(const uint32_t size, G4double const* __restrict__ iarray,
341 G4double* __restrict__ oarray);
342void G4Logv(const uint32_t size, G4double const* __restrict__ iarray,
343 G4double* __restrict__ oarray);
344void logfv(const uint32_t size, G4float const* __restrict__ iarray,
345 G4float* __restrict__ oarray);
346void G4Logfv(const uint32_t size, G4float const* __restrict__ iarray,
347 G4float* __restrict__ oarray);
348
349#endif /* WIN32 */
350
351#endif /* LOG_H_ */
G4fissionEvent * fe
G4float G4Logf(G4float x)
Definition: G4Log.hh:308
void logfv(const uint32_t size, G4float const *__restrict__ iarray, G4float *__restrict__ oarray)
void G4Logfv(const uint32_t size, G4float const *__restrict__ iarray, G4float *__restrict__ oarray)
void logv(const uint32_t size, G4double const *__restrict__ iarray, G4double *__restrict__ oarray)
void G4Logv(const uint32_t size, G4double const *__restrict__ iarray, G4double *__restrict__ oarray)
G4double G4Log(G4double x)
Definition: G4Log.hh:227
float G4float
Definition: G4Types.hh:84
double G4double
Definition: G4Types.hh:83
int G4int
Definition: G4Types.hh:85
G4float getMantExponentf(const G4float x, G4float &fe)
Like frexp but vectorising and the exponent is a float.
Definition: G4Log.hh:210
const G4float PX1logf
Definition: G4Log.hh:272
G4double get_log_px(const G4double x)
Definition: G4Log.hh:99
const G4double LOG_LOWER_LIMIT
Definition: G4Log.hh:76
uint64_t dp2uint64(G4double x)
Definition: G4Log.hh:146
const G4float LOGF_UPPER_LIMIT
Definition: G4Log.hh:269
const G4float LOGF_LOWER_LIMIT
Definition: G4Log.hh:270
const G4float PX8logf
Definition: G4Log.hh:279
const G4float PX6logf
Definition: G4Log.hh:277
G4float get_log_poly(const G4float x)
Definition: G4Log.hh:282
const G4float PX3logf
Definition: G4Log.hh:274
const G4float MAXNUMF
Definition: G4Log.hh:79
const G4double LOG_UPPER_LIMIT
Definition: G4Log.hh:75
const G4float PX9logf
Definition: G4Log.hh:280
G4double getMantExponent(const G4double x, G4double &fe)
Like frexp but vectorising and the exponent is a double.
Definition: G4Log.hh:185
const G4float PX2logf
Definition: G4Log.hh:273
const G4float PX5logf
Definition: G4Log.hh:276
G4double get_log_qx(const G4double x)
Definition: G4Log.hh:122
const G4float PX7logf
Definition: G4Log.hh:278
const G4float SQRTHF
Definition: G4Log.hh:303
G4float uint322sp(G4int x)
Definition: G4Log.hh:166
G4double uint642dp(uint64_t ll)
Definition: G4Log.hh:156
const G4float PX4logf
Definition: G4Log.hh:275
uint32_t sp2uint32(G4float x)
Definition: G4Log.hh:176
const G4double SQRTH
Definition: G4Log.hh:78
ieee754(uint32_t thei)
Definition: G4Log.hh:91
ieee754(G4float thef)
Definition: G4Log.hh:90
uint16_t s[4]
Definition: G4Log.hh:96
ieee754(uint64_t thell)
Definition: G4Log.hh:89
ieee754(G4double thed)
Definition: G4Log.hh:88
uint32_t i[2]
Definition: G4Log.hh:94
G4float f[2]
Definition: G4Log.hh:93