Commit b1ee9b85 authored by Dan Povey's avatar Dan Povey
Browse files

trunk: minor change to RandGauss2() and similar functions, to use log,logf...

trunk: minor change to RandGauss2() and similar functions, to use log,logf instead of std::log and similar functions (there was some performance issue in the past with functions like std::log).

git-svn-id: https://svn.code.sf.net/p/kaldi/code/trunk@4297 5e6a8d80-dfce-4ca6-a32a-6e07a63d50c8
parent 863a3a9a
......@@ -77,6 +77,16 @@ void UnitTestRand() {
if (std::abs(sum) < 0.5*sqrt((double)j)) break;
}
}
{ // test RandGauss.
float sum = RandGauss();
for (int j = 0; ; j++) {
float a, b;
RandGauss2(&a, &b);
if (i % 2 == 0) sum += a;
else sum += b;
if (std::abs(sum) < 0.5*sqrt((double)j)) break;
}
}
{ // test poisson_Rand().
KALDI_ASSERT(RandPoisson(3.0) >= 0);
KALDI_ASSERT(RandPoisson(0.0) == 0);
......
......@@ -134,22 +134,21 @@ void RandGauss2(float *a, float *b, RandomState *state)
KALDI_ASSERT(b);
float u1 = RandUniform(state);
float u2 = RandUniform(state);
u1 = std::sqrt(-2.0f * std::log(u1));
u1 = sqrtf(-2.0f * logf(u1));
u2 = 2.0f * M_PI * u2;
*a = u1 * std::cos(u2);
*b = u1 * std::sin(u2);
*a = u1 * cosf(u2);
*b = u1 * sinf(u2);
}
void RandGauss2(double *a, double *b, RandomState *state)
{
KALDI_ASSERT(a);
KALDI_ASSERT(b);
double u1 = RandUniform(state);
double u2 = RandUniform(state);
u1 = std::sqrt(-2.0 * std::log(u1));
u2 = 2.0 * M_PI * u2;
*a = u1 * std::cos(u2);
*b = u1 * std::sin(u2);
float a_float, b_float;
// Just because we're using doubles doesn't mean we need super-high-quality
// random numbers, so we just use the floating-point version internally.
RandGauss2(&a_float, &b_float);
*a = a_float; *b = b_float;
}
......
......@@ -104,13 +104,14 @@ bool WithProb(BaseFloat prob, struct RandomState* state=NULL); // Returns true w
// Internally calls Rand(). This function is carefully implemented so
// that it should work even if prob is very small.
inline float RandUniform(struct RandomState* state=NULL) { // random intended to be strictly between 0 and 1.
return static_cast<float>((Rand(state) + 1.0) / (RAND_MAX+2.0));
/// Returns a random number strictly between 0 and 1.
inline float RandUniform(struct RandomState* state = NULL) {
return static_cast<float>((Rand(state) + 1.0) / (RAND_MAX+2.0));
}
inline float RandGauss(struct RandomState* state=NULL) {
return static_cast<float>(sqrt (-2 * std::log(RandUniform(state)))
* cos(2*M_PI*RandUniform(state)));
inline float RandGauss(struct RandomState* state = NULL) {
return static_cast<float>(sqrtf (-2 * logf(RandUniform(state)))
* cosf(2*M_PI*RandUniform(state)));
}
// Returns poisson-distributed random number. Uses Knuth's algorithm.
......@@ -138,7 +139,6 @@ inline Float RandPrune(Float post, BaseFloat prune_thresh, struct RandomState* s
static const double kMinLogDiffDouble = std::log(DBL_EPSILON); // negative!
static const float kMinLogDiffFloat = std::log(FLT_EPSILON); // negative!
inline double LogAdd(double x, double y) {
double diff;
if (x < y) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment