double RandomSource_nextGaussian(double* seed, boolean* haveNextNextGaussian, double* nextNextGaussian) { double multiplier; double v1; double v2; double s; if (*haveNextNextGaussian) { *haveNextNextGaussian = false; return *nextNextGaussian; } else { do { v1 = 2 * RandomSource_nextDouble(seed) - 1; // between -1.0 and 1.0 v2 = 2 * RandomSource_nextDouble(seed) - 1; // between -1.0 and 1.0 s = v1 * v1 + v2 * v2; } while (s >= 1 || s == 0); multiplier = sqrt(-2 * log(s)/s); *nextNextGaussian = v2 * multiplier; *haveNextNextGaussian = true; return v1 * multiplier; } }
/*** sharedBlock2 ***/ double DiscreteRandomSource_rand(double* seed, Token pmf, Token values) { int i; double randomValue; double cdf = 0.0; // Generate a double between 0 and 1, uniformly distributed. randomValue = RandomSource_nextDouble(seed); for (i = 0; i < pmf.payload.Array->size; i++) { cdf += Array_get(pmf, i).payload.Double; if (randomValue <= cdf) { return Array_get(values, i).payload.Double; } } // We shouldn't get here, but if we do, we output the last value. return Array_get(values, pmf.payload.Array->size - 1).payload.Double; }