MDA
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups
fast_math.hpp
1 /*
2  * fast_math.h
3  *
4  * Created on: Nov 11, 2012
5  * Author: ck
6  */
7 
8 #ifndef FAST_MATH_HPP_
9 #define FAST_MATH_HPP_
10 
11 #include <cfloat>
12 #include <cmath>
13 
14 namespace MDAT
15 {
16 
17 
18 //based on ProbCons calculation
19 
20 const float EXP_UNDERFLOW_THRESHOLD = -4.60f;
21 const float LOG_UNDERFLOW_THRESHOLD = 7.50f;
22 const float LOG_ZERO = -FLT_MAX;
23 const float LOG_ONE = 0.0f;
24 
25 static inline double EXP (float x){
26  //return exp(x);
27  if (x > -2)
28  {
29  if (x > -0.5)
30  {
31  if (x > 0)
32  return exp(x);
33  return (((0.03254409303190190000*x + 0.16280432765779600000)*x + 0.49929760485974900000)*x + 0.99995149601363700000)*x + 0.99999925508501600000;
34  }
35  if (x > -1)
36  return (((0.01973899026052090000*x + 0.13822379685007000000)*x + 0.48056651562365000000)*x + 0.99326940370383500000)*x + 0.99906756856399500000;
37  return (((0.00940528203591384000*x + 0.09414963667859410000)*x + 0.40825793595877300000)*x + 0.93933625499130400000)*x + 0.98369508190545300000;
38  }
39  if (x > -8){
40  if (x > -4)
41  return (((0.00217245711583303000*x + 0.03484829428350620000)*x + 0.22118199801337800000)*x + 0.67049462206469500000)*x + 0.83556950223398500000;
42  return (((0.00012398771025456900*x + 0.00349155785951272000)*x + 0.03727721426017900000)*x + 0.17974997741536900000)*x + 0.33249299994217400000;
43  }
44  if (x > -16)
45  return (((0.00000051741713416603*x + 0.00002721456879608080)*x + 0.00053418601865636800)*x + 0.00464101989351936000)*x + 0.01507447981459420000;
46  return 0;
47 }
48 
49 static inline float LOOKUP (float x){
50 
51  if (x <= 1.00f)
52  return ((-0.009350833524763f * x + 0.130659527668286f) * x + 0.498799810682272f) * x + 0.693203116424741f;
53  if (x <= 2.50f)
54  return ((-0.014532321752540f * x + 0.139942324101744f) * x + 0.495635523139337f) * x + 0.692140569840976f;
55  if (x <= 4.50f)
56  return ((-0.004605031767994f * x + 0.063427417320019f) * x + 0.695956496475118f) * x + 0.514272634594009f;
57  return ((-0.000458661602210f * x + 0.009695946122598f) * x + 0.930734667215156f) * x + 0.168037164329057f;
58 }
59 
60 static inline void LOG_PLUS_EQUALS (float &x, float y)
61 {
62  if (x < y)
63  x = ((x == LOG_ZERO) || ((y - x) >= LOG_UNDERFLOW_THRESHOLD)) ? y : LOOKUP(y-x) + x;
64  else
65  x = ((y == LOG_ZERO) || ((x - y) >= LOG_UNDERFLOW_THRESHOLD)) ? x : LOOKUP(x-y) + y;
66 }
67 
68 static inline float LOG_ADD (float x, float y)
69 {
70  if (x < y)
71  return (x == LOG_ZERO || y - x >= LOG_UNDERFLOW_THRESHOLD) ? y : LOOKUP((y-x)) + x;
72  return (y == LOG_ZERO || x - y >= LOG_UNDERFLOW_THRESHOLD) ? x : LOOKUP((x-y)) + y;
73 }
74 
75 }
76 
77 #endif /* FAST_MATH_HPP_ */