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

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

Definition at line 176 of file approx_exp.h.

References constexpr, JetChargeProducer_cfi::exp, dqmMemoryStats::float, SiStripPI::max, min(), alignCSCRings::r, and unsafe_expf().

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 }
T min(T a, T b)
Definition: MathUtil.h:58
#define constexpr
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)

Definition at line 48 of file approx_exp.h.

References dqmMemoryStats::float, testProducerWithPsetDescEmpty_cfi::x1, testProducerWithPsetDescEmpty_cfi::x2, and detailsBasic3DVector::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 }
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)

Definition at line 72 of file approx_exp.h.

References dqmMemoryStats::float, AlCaHLTBitMon_ParallelJobs::p, testProducerWithPsetDescEmpty_cfi::x1, testProducerWithPsetDescEmpty_cfi::x2, detailsBasic3DVector::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 }
template<>
constexpr float approx_expf_P< 7 > ( float  y)

Definition at line 93 of file approx_exp.h.

References dqmMemoryStats::float, testProducerWithPsetDescEmpty_cfi::x1, testProducerWithPsetDescEmpty_cfi::x2, and detailsBasic3DVector::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 }
template<int DEGREE>
constexpr float unsafe_expf ( float  x)

Definition at line 171 of file approx_exp.h.

Referenced by approx_expf().

171  {
172  return unsafe_expf_impl<DEGREE>(x);
173 }
template<int DEGREE>
constexpr float unsafe_expf_impl ( float  x)

Definition at line 125 of file approx_exp.h.

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

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 }
constexpr float fpfloor(float x)
Definition: approx_math.h:25
float float float z
double f[11][100]
#define constexpr