CMS 3D CMS Logo

Functions
approx_exp.h File Reference
#include "DataFormats/Math/interface/approx_math.h"

Go to the source code of this file.

Functions

template<int DEGREE>
constexpr float approx_expf (float x)
 
template<int DEGREE>
constexpr float approx_expf_P (float p)
 
template<>
constexpr float approx_expf_P< 2 > (float y)
 
template<>
constexpr float approx_expf_P< 3 > (float y)
 
template<>
constexpr float approx_expf_P< 4 > (float y)
 
template<>
constexpr float approx_expf_P< 5 > (float y)
 
template<>
constexpr float approx_expf_P< 6 > (float y)
 
template<>
constexpr float approx_expf_P< 7 > (float y)
 
template<int DEGREE>
constexpr float unsafe_expf (float x)
 
template<int DEGREE>
constexpr float unsafe_expf_impl (float x)
 

Function Documentation

◆ approx_expf()

template<int DEGREE>
constexpr float approx_expf ( float  x)
constexpr

Definition at line 176 of file approx_exp.h.

176  {
177  constexpr float inf_threshold = float(0x5.8b90cp4);
178  // log of the smallest normal
179  constexpr float zero_threshold_ftz = -float(0x5.75628p4); // sollya: single(log(1b-126));
180  // flush to zero on the output
181  // manage infty output:
182  // faster than directly on output!
183  x = std::min(std::max(x, zero_threshold_ftz), inf_threshold);
184  float r = unsafe_expf<DEGREE>(x);
185 
186  return r;
187 }

References dqmMemoryStats::float, SiStripPI::max, min(), alignCSCRings::r, and vertices_cff::x.

◆ approx_expf_P()

template<int DEGREE>
constexpr float approx_expf_P ( float  p)
constexpr

◆ approx_expf_P< 2 >()

template<>
constexpr float approx_expf_P< 2 > ( float  y)
constexpr

Definition at line 43 of file approx_exp.h.

43  {
44  return float(0x2.p0) + y * (float(0x2.07b99p0) + y * float(0x1.025b84p0));
45 }

References dqmMemoryStats::float, testProducerWithPsetDescEmpty_cfi::x1, testProducerWithPsetDescEmpty_cfi::x2, and detailsBasic3DVector::y.

◆ approx_expf_P< 3 >()

template<>
constexpr float approx_expf_P< 3 > ( float  y)
constexpr

Definition at line 48 of file approx_exp.h.

48  {
49 #ifdef HORNER // HORNER
50  return float(0x2.p0) + y * (float(0x1.fff798p0) + y * (float(0x1.02249p0) + y * float(0x5.62042p-4)));
51 #else // ESTRIN
52  float p23 = (float(0x1.02249p0) + y * float(0x5.62042p-4));
53  float p01 = float(0x2.p0) + y * float(0x1.fff798p0);
54  return p01 + y * y * p23;
55 #endif
56 }

References dqmMemoryStats::float, testProducerWithPsetDescEmpty_cfi::x1, testProducerWithPsetDescEmpty_cfi::x2, and detailsBasic3DVector::y.

◆ approx_expf_P< 4 >()

template<>
constexpr float approx_expf_P< 4 > ( float  y)
constexpr

Definition at line 59 of file approx_exp.h.

59  {
60  return float(0x2.p0) +
61  y * (float(0x1.fffb1p0) + y * (float(0xf.ffe84p-4) + y * (float(0x5.5f9c1p-4) + y * float(0x1.57755p-4))));
62 }

References dqmMemoryStats::float, testProducerWithPsetDescEmpty_cfi::x1, testProducerWithPsetDescEmpty_cfi::x2, and detailsBasic3DVector::y.

◆ approx_expf_P< 5 >()

template<>
constexpr float approx_expf_P< 5 > ( float  y)
constexpr

Definition at line 65 of file approx_exp.h.

65  {
66  return float(0x2.p0) +
67  y * (float(0x2.p0) + y * (float(0xf.ffed8p-4) +
68  y * (float(0x5.5551cp-4) + y * (float(0x1.5740d8p-4) + y * float(0x4.49368p-8)))));
69 }

References dqmMemoryStats::float, testProducerWithPsetDescEmpty_cfi::x1, testProducerWithPsetDescEmpty_cfi::x2, and detailsBasic3DVector::y.

◆ approx_expf_P< 6 >()

template<>
constexpr float approx_expf_P< 6 > ( float  y)
constexpr

Definition at line 72 of file approx_exp.h.

72  {
73 #ifdef HORNER // HORNER
74  float p =
75  float(0x2.p0) +
76  y * (float(0x2.p0) +
77  y * (float(0x1.p0) + y * (float(0x5.55523p-4) + y * (float(0x1.5554dcp-4) +
78  y * (float(0x4.48f41p-8) + y * float(0xb.6ad4p-12))))));
79 #else // ESTRIN does seem to save a cycle or two
80  float p56 = float(0x4.48f41p-8) + y * float(0xb.6ad4p-12);
81  float p34 = float(0x5.55523p-4) + y * float(0x1.5554dcp-4);
82  float y2 = y * y;
83  float p12 = float(0x2.p0) + y; // By chance we save one operation here! Funny.
84  float p36 = p34 + y2 * p56;
85  float p16 = p12 + y2 * p36;
86  float p = float(0x2.p0) + y * p16;
87 #endif
88  return p;
89 }

References dqmMemoryStats::float, AlCaHLTBitMon_ParallelJobs::p, testProducerWithPsetDescEmpty_cfi::x1, testProducerWithPsetDescEmpty_cfi::x2, detailsBasic3DVector::y, and testProducerWithPsetDescEmpty_cfi::y2.

◆ approx_expf_P< 7 >()

template<>
constexpr float approx_expf_P< 7 > ( float  y)
constexpr

Definition at line 93 of file approx_exp.h.

93  {
94  return float(0x2.p0) +
95  y * (float(0x2.p0) +
96  y * (float(0x1.p0) +
97  y * (float(0x5.55555p-4) +
98  y * (float(0x1.5554e4p-4) +
99  y * (float(0x4.444adp-8) + y * (float(0xb.6a8a6p-12) + y * float(0x1.9ec814p-12)))))));
100 }

References dqmMemoryStats::float, testProducerWithPsetDescEmpty_cfi::x1, testProducerWithPsetDescEmpty_cfi::x2, and detailsBasic3DVector::y.

◆ unsafe_expf()

template<int DEGREE>
constexpr float unsafe_expf ( float  x)
constexpr

Definition at line 171 of file approx_exp.h.

171  {
172  return unsafe_expf_impl<DEGREE>(x);
173 }

References vertices_cff::x.

◆ unsafe_expf_impl()

template<int DEGREE>
constexpr float unsafe_expf_impl ( float  x)
constexpr

Definition at line 125 of file approx_exp.h.

125  {
126  using namespace approx_math;
127  /* Sollya for the following constants:
128  display=hexadecimal;
129  1b23+1b22;
130  single(1/log(2));
131  log2H=round(log(2), 16, RN);
132  log2L = single(log(2)-log2H);
133  log2H; log2L;
134 
135  */
136  // constexpr float rnd_cst = float(0xc.p20);
137  constexpr float inv_log2f = float(0x1.715476p0);
138  constexpr float log2H = float(0xb.172p-4);
139  constexpr float log2L = float(0x1.7f7d1cp-20);
140 
141  float y = x;
142  // This is doing round(x*inv_log2f) to the nearest integer
143  float z = fpfloor((x * inv_log2f) + 0.5f);
144  // Cody-and-Waite accurate range reduction. FMA-safe.
145  y -= z * log2H;
146  y -= z * log2L;
147  // exponent
148  int32_t e = z;
149 
150  // we want RN above because it centers the interval around zero
151  // but then we could have 2^e = below being infinity when it shouldn't
152  // (when e=128 but p<1)
153  // so we avoid this case by reducing e and evaluating a polynomial for 2*exp
154  e -= 1;
155 
156  // NaN inputs will propagate to the output as expected
157 
158  float p = approx_expf_P<DEGREE>(y);
159 
160  // cout << "x=" << x << " e=" << e << " y=" << y << " p=" << p <<"\n";
161  binary32 ef;
162  uint32_t biased_exponent = e + 127;
163  ef.ui32 = (biased_exponent << 23);
164 
165  return p * ef.f;
166 }

References MillePedeFileConverter_cfg::e, approx_math::binary32::f, f, dqmMemoryStats::float, approx_math::fpfloor(), AlCaHLTBitMon_ParallelJobs::p, approx_math::binary32::ui32, and testProducerWithPsetDescEmpty_cfi::x1.

dqmMemoryStats.float
float
Definition: dqmMemoryStats.py:127
approx_math::binary32::ui32
uint32_t ui32
Definition: approx_math.h:18
approx_math::binary32
Definition: approx_math.h:12
f
double f[11][100]
Definition: MuScleFitUtils.cc:78
detailsBasic3DVector::z
float float float z
Definition: extBasic3DVector.h:14
min
T min(T a, T b)
Definition: MathUtil.h:58
testProducerWithPsetDescEmpty_cfi.x2
x2
Definition: testProducerWithPsetDescEmpty_cfi.py:28
AlCaHLTBitMon_ParallelJobs.p
p
Definition: AlCaHLTBitMon_ParallelJobs.py:153
testProducerWithPsetDescEmpty_cfi.x1
x1
Definition: testProducerWithPsetDescEmpty_cfi.py:33
vertices_cff.x
x
Definition: vertices_cff.py:29
approx_math::binary32::f
float f
Definition: approx_math.h:20
testProducerWithPsetDescEmpty_cfi.y2
y2
Definition: testProducerWithPsetDescEmpty_cfi.py:30
SiStripPI::max
Definition: SiStripPayloadInspectorHelper.h:169
approx_math::fpfloor
constexpr float fpfloor(float x)
Definition: approx_math.h:25
alignCSCRings.r
r
Definition: alignCSCRings.py:93
approx_math
Definition: approx_math.h:9
detailsBasic3DVector::y
float float y
Definition: extBasic3DVector.h:14
MillePedeFileConverter_cfg.e
e
Definition: MillePedeFileConverter_cfg.py:37