Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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# include "G4IEEE754.hh"
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
82 {
83 const G4double PX1log = 1.01875663804580931796E-4;
84 const G4double PX2log = 4.97494994976747001425E-1;
85 const G4double PX3log = 4.70579119878881725854E0;
86 const G4double PX4log = 1.44989225341610930846E1;
87 const G4double PX5log = 1.79368678507819816313E1;
88 const G4double PX6log = 7.70838733755885391666E0;
89
90 G4double px = PX1log;
91 px *= x;
92 px += PX2log;
93 px *= x;
94 px += PX3log;
95 px *= x;
96 px += PX4log;
97 px *= x;
98 px += PX5log;
99 px *= x;
100 px += PX6log;
101 return px;
102 }
103
105 {
106 const G4double QX1log = 1.12873587189167450590E1;
107 const G4double QX2log = 4.52279145837532221105E1;
108 const G4double QX3log = 8.29875266912776603211E1;
109 const G4double QX4log = 7.11544750618563894466E1;
110 const G4double QX5log = 2.31251620126765340583E1;
111
112 G4double qx = x;
113 qx += QX1log;
114 qx *= x;
115 qx += QX2log;
116 qx *= x;
117 qx += QX3log;
118 qx *= x;
119 qx += QX4log;
120 qx *= x;
121 qx += QX5log;
122 return qx;
123 }
124
125 //----------------------------------------------------------------------------
126 /// Like frexp but vectorising and the exponent is a double.
128 {
129 uint64_t n = G4IEEE754::dp2uint64(x);
130
131 // Shift to the right up to the beginning of the exponent.
132 // Then with a mask, cut off the sign bit
133 uint64_t le = (n >> 52);
134
135 // chop the head of the number: an int contains more than 11 bits (32)
136 int32_t e =
137 (int32_t)le; // This is important since sums on uint64_t do not vectorise
138 fe = e - 1023;
139
140 // This puts to 11 zeroes the exponent
141 n &= 0x800FFFFFFFFFFFFFULL;
142 // build a mask which is 0.5, i.e. an exponent equal to 1022
143 // which means *2, see the above +1.
144 const uint64_t p05 = 0x3FE0000000000000ULL; // dp2uint64(0.5);
145 n |= p05;
146
147 return G4IEEE754::uint642dp(n);
148 }
149
150 //----------------------------------------------------------------------------
151 /// Like frexp but vectorising and the exponent is a float.
153 {
154 uint32_t n = G4IEEE754::sp2uint32(x);
155 int32_t e = (n >> 23) - 127;
156 fe = e;
157
158 // fractional part
159 const uint32_t p05f = 0x3f000000; // //sp2uint32(0.5);
160 n &= 0x807fffff; // ~0x7f800000;
161 n |= p05f;
162
163 return G4IEEE754::uint322sp(n);
164 }
165} // namespace G4LogConsts
166
167// Log double precision --------------------------------------------------------
168
170{
171 const G4double original_x = x;
172
173 /* separate mantissa from exponent */
174 G4double fe;
176
177 // blending
178 x > G4LogConsts::SQRTH ? fe += 1. : x += x;
179 x -= 1.0;
180
181 /* rational form */
183
184 // for the final formula
185 const G4double x2 = x * x;
186 px *= x;
187 px *= x2;
188
189 const G4double qx = G4LogConsts::get_log_qx(x);
190
191 G4double res = px / qx;
192
193 res -= fe * 2.121944400546905827679e-4;
194 res -= 0.5 * x2;
195
196 res = x + res;
197 res += fe * 0.693359375;
198
199 if(original_x > G4LogConsts::LOG_UPPER_LIMIT)
200 res = std::numeric_limits<G4double>::infinity();
201 if(original_x < G4LogConsts::LOG_LOWER_LIMIT) // THIS IS NAN!
202 res = -std::numeric_limits<G4double>::quiet_NaN();
203
204 return res;
205}
206
207// Log single precision --------------------------------------------------------
208
209namespace G4LogConsts
210{
213
214 const G4float PX1logf = 7.0376836292E-2f;
215 const G4float PX2logf = -1.1514610310E-1f;
216 const G4float PX3logf = 1.1676998740E-1f;
217 const G4float PX4logf = -1.2420140846E-1f;
218 const G4float PX5logf = 1.4249322787E-1f;
219 const G4float PX6logf = -1.6668057665E-1f;
220 const G4float PX7logf = 2.0000714765E-1f;
221 const G4float PX8logf = -2.4999993993E-1f;
222 const G4float PX9logf = 3.3333331174E-1f;
223
225 {
226 G4float y = x * PX1logf;
227 y += PX2logf;
228 y *= x;
229 y += PX3logf;
230 y *= x;
231 y += PX4logf;
232 y *= x;
233 y += PX5logf;
234 y *= x;
235 y += PX6logf;
236 y *= x;
237 y += PX7logf;
238 y *= x;
239 y += PX8logf;
240 y *= x;
241 y += PX9logf;
242 return y;
243 }
244
245 const G4float SQRTHF = 0.707106781186547524f;
246} // namespace G4LogConsts
247
248// Log single precision --------------------------------------------------------
249
251{
252 const G4float original_x = x;
253
254 G4float fe;
256
257 x > G4LogConsts::SQRTHF ? fe += 1.f : x += x;
258 x -= 1.0f;
259
260 const G4float x2 = x * x;
261
263 res *= x2 * x;
264
265 res += -2.12194440e-4f * fe;
266 res += -0.5f * x2;
267
268 res = x + res;
269
270 res += 0.693359375f * fe;
271
272 if(original_x > G4LogConsts::LOGF_UPPER_LIMIT)
273 res = std::numeric_limits<G4float>::infinity();
274 if(original_x < G4LogConsts::LOGF_LOWER_LIMIT)
275 res = -std::numeric_limits<G4float>::quiet_NaN();
276
277 return res;
278}
279
280#endif /* WIN32 */
281
282#endif /* LOG_H_ */
G4fissionEvent * fe
G4float G4Logf(G4float x)
Definition G4Log.hh:250
G4double G4Log(G4double x)
Definition G4Log.hh:169
float G4float
Definition G4Types.hh:84
double G4double
Definition G4Types.hh:83
G4double uint642dp(uint64_t ll)
Definition G4IEEE754.hh:66
uint32_t sp2uint32(G4float x)
Definition G4IEEE754.hh:86
uint64_t dp2uint64(G4double x)
Definition G4IEEE754.hh:56
G4float uint322sp(G4int x)
Definition G4IEEE754.hh:76
G4float getMantExponentf(const G4float x, G4float &fe)
Like frexp but vectorising and the exponent is a float.
Definition G4Log.hh:152
const G4float PX1logf
Definition G4Log.hh:214
G4double get_log_px(const G4double x)
Definition G4Log.hh:81
const G4double LOG_LOWER_LIMIT
Definition G4Log.hh:76
const G4float LOGF_UPPER_LIMIT
Definition G4Log.hh:211
const G4float LOGF_LOWER_LIMIT
Definition G4Log.hh:212
const G4float PX8logf
Definition G4Log.hh:221
const G4float PX6logf
Definition G4Log.hh:219
G4float get_log_poly(const G4float x)
Definition G4Log.hh:224
const G4float PX3logf
Definition G4Log.hh:216
const G4float MAXNUMF
Definition G4Log.hh:79
const G4double LOG_UPPER_LIMIT
Definition G4Log.hh:75
const G4float PX9logf
Definition G4Log.hh:222
G4double getMantExponent(const G4double x, G4double &fe)
Like frexp but vectorising and the exponent is a double.
Definition G4Log.hh:127
const G4float PX2logf
Definition G4Log.hh:215
const G4float PX5logf
Definition G4Log.hh:218
G4double get_log_qx(const G4double x)
Definition G4Log.hh:104
const G4float PX7logf
Definition G4Log.hh:220
const G4float SQRTHF
Definition G4Log.hh:245
const G4float PX4logf
Definition G4Log.hh:217
const G4double SQRTH
Definition G4Log.hh:78