RealType nextGamma ( RealType const alpha ) { assert( alpha > 0 ); if( alpha < 1.0 ) { // See the note on Page 9 of the above reference. The method only // works for alpha > 1.0, but you can do this trick to work around the // problem. RealType tmp_gamma = ( RealType )nextGamma( alpha + 1.0 ); RealType U = ( RealType )nextUniform(); return ( tmp_gamma * ( pow( U, ( 1.0 / alpha ) ) ) ); } RealType d = alpha - ( 1.0 / 3.0 ); RealType c = ( 1.0 / sqrt( 9.0 * d ) ); RealType x,v,U; RealType x_squared; while( true ) { // Keep trying until we draw a variate. (Acceptance rate // is high, above .9 for at least alpha < 100) // get x and v do { x = ( RealType )nextNormal(); v = 1.0 + ( c * x ); } while( v <= 0.0 ); v = ( v * v * v ); // Use them for acceptance-rejection x_squared = ( x * x ); U = ( RealType )nextUniform(); // Cheaper 'squeeze method' if( U < ( 1.0 - ( .0331 * ( x_squared * x_squared ) ) ) ) { return ( d * v ); } // If that doesn't work, try version with logs. if( log( U ) < ( ( 0.5 * x_squared ) + ( d * ( 1.0 - v + log( v ) ) ) ) ) { return ( d * v ); } } // Until we get a variate... } // nextGamma( RealType )
double nextGaussian(double mean, double stdev) { return mean + stdev * nextNormal(); }