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)

Definition at line 183 of file approx_exp.h.

References ALPAKA_ACCELERATOR_NAMESPACE::brokenline::constexpr(), ALCARECOEcalPhiSym_cff::float, WZElectronSkims53X_cff::max, SiStripPI::min, alignCSCRings::r, and x.

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

◆ approx_expf_P()

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

◆ approx_expf_P< 2 >()

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

◆ approx_expf_P< 3 >()

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

Definition at line 48 of file approx_exp.h.

References ALCARECOEcalPhiSym_cff::float, testProducerWithPsetDescEmpty_cfi::x1, testProducerWithPsetDescEmpty_cfi::x2, and relval_data_highstats::y.

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 }

◆ approx_expf_P< 4 >()

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

◆ approx_expf_P< 5 >()

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

◆ approx_expf_P< 6 >()

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

Definition at line 72 of file approx_exp.h.

References ALCARECOEcalPhiSym_cff::float, AlCaHLTBitMon_ParallelJobs::p, testProducerWithPsetDescEmpty_cfi::x1, testProducerWithPsetDescEmpty_cfi::x2, relval_data_highstats::y, and testProducerWithPsetDescEmpty_cfi::y2.

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 }

◆ approx_expf_P< 7 >()

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

Definition at line 93 of file approx_exp.h.

References ALCARECOEcalPhiSym_cff::float, testProducerWithPsetDescEmpty_cfi::x1, testProducerWithPsetDescEmpty_cfi::x2, and relval_data_highstats::y.

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 }

◆ unsafe_expf()

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

Definition at line 178 of file approx_exp.h.

References x.

178  {
179  return unsafe_expf_impl<DEGREE>(x);
180 }
float x

◆ unsafe_expf_impl()

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

Definition at line 132 of file approx_exp.h.

References ALPAKA_ACCELERATOR_NAMESPACE::brokenline::constexpr(), MillePedeFileConverter_cfg::e, f, ALCARECOEcalPhiSym_cff::float, approx_math::fpfloor(), AlCaHLTBitMon_ParallelJobs::p, and x.

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