diff options
author | Determinant <[email protected]> | 2015-05-29 23:06:58 +0800 |
---|---|---|
committer | Determinant <[email protected]> | 2015-05-29 23:06:58 +0800 |
commit | 74b9f7cb88cd21cfac3c2e50c8efb802485df0c5 (patch) | |
tree | bd6e583088a086144acc2d8af3eaca59691194ff /tnet_io/KaldiLib/MathAux.h |
init
Diffstat (limited to 'tnet_io/KaldiLib/MathAux.h')
-rw-r--r-- | tnet_io/KaldiLib/MathAux.h | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/tnet_io/KaldiLib/MathAux.h b/tnet_io/KaldiLib/MathAux.h new file mode 100644 index 0000000..c08e836 --- /dev/null +++ b/tnet_io/KaldiLib/MathAux.h @@ -0,0 +1,117 @@ +#ifndef TNet_MathAux_h +#define TNet_MathAux_h + +#include <cmath> + + +#if !defined(SQR) +# define SQR(x) ((x) * (x)) +#endif + + +#if !defined(LOG_0) +# define LOG_0 (-1.0e10) +#endif + +#if !defined(LOG_MIN) +# define LOG_MIN (0.5 * LOG_0) +#endif + + +#ifndef DBL_EPSILON +#define DBL_EPSILON 2.2204460492503131e-16 +#endif + + +#ifndef M_PI +# define M_PI 3.1415926535897932384626433832795 +#endif + +#define M_LOG_2PI 1.8378770664093454835606594728112 + + +#if DOUBLEPRECISION +# define FLOAT double +# define EPSILON DBL_EPSILON +# define FLOAT_FMT "%lg" +# define swapFLOAT swap8 +# define _ABS fabs +# define _COS cos +# define _EXP exp +# define _LOG log +# define _SQRT sqrt +#else +# define FLOAT float +# define EPSILON FLT_EPSILON +# define FLOAT_FMT "%g" +# define swapFLOAT swap4 +# define _ABS fabsf +# define _COS cosf +# define _EXP expf +# define _LOG logf +# define _SQRT sqrtf +#endif + +namespace TNet +{ + inline float frand(){ // random between 0 and 1. + return (float(rand()) + 1.0f) / (float(RAND_MAX)+2.0f); + } + inline float gauss_rand(){ + return _SQRT( -2.0f * _LOG(frand()) ) * _COS(2.0f*float(M_PI)*frand()); + } + + static const double gMinLogDiff = log(DBL_EPSILON); + + //*************************************************************************** + //*************************************************************************** + inline double + LogAdd(double x, double y) + { + double diff; + + if (x < y) { + diff = x - y; + x = y; + } else { + diff = y - x; + } + + double res; + if (x >= LOG_MIN) { + if (diff >= gMinLogDiff) { + res = x + log(1.0 + exp(diff)); + } else { + res = x; + } + } else { + res = LOG_0; + } + return res; + } + + + //*************************************************************************** + //*************************************************************************** + inline double + LogSub(double x, double y) // returns exp(x) - exp(y). Throws exception if y>=x. + { + + if(y >= x){ + if(y==x) return LOG_0; + else throw std::runtime_error("LogSub: cannot subtract a larger from a smaller number."); + } + + double diff = y - x; // Will be negative. + + double res = x + log(1.0 - exp(diff)); + + if(res != res) // test for res==NaN.. could happen if diff ~0.0, so 1.0-exp(diff) == 0.0 to machine precision. + res = LOG_0; + return res; + } + +} // namespace TNet + + +#endif |