@@ -376,30 +376,16 @@ public TimeSpan RandExponential(TimeSpan mean) {
376
376
/// from two uniform random distributed values.
377
377
/// </summary>
378
378
/// <remarks>
379
- /// A spare random variable is generated from the second uniformly
380
- /// distributed value. Thus, the two calls to the uniform random number
381
- /// generator will be made only every second call .
379
+ /// Unlike <see cref="RandNormal(double, double)"/> this method does not
380
+ /// make use of a spare random variable. It discards the spare and thus
381
+ /// requires twice the number of calls to the underlying IRandom instance .
382
382
/// </remarks>
383
383
/// <param name="random">The random number generator to use.</param>
384
384
/// <param name="mu">The mean of the normal distribution.</param>
385
385
/// <param name="sigma">The standard deviation of the normal distribution.</param>
386
386
/// <returns>A number that is normal distributed.</returns>
387
387
public virtual double RandNormal ( IRandom random , double mu , double sigma ) {
388
- if ( useSpareNormal ) {
389
- useSpareNormal = false ;
390
- return spareNormal * sigma + mu ;
391
- } else {
392
- double u , v , s ;
393
- do {
394
- u = random . NextDouble ( ) * 2 - 1 ;
395
- v = random . NextDouble ( ) * 2 - 1 ;
396
- s = u * u + v * v ;
397
- } while ( s >= 1 || s == 0 ) ;
398
- var mul = Math . Sqrt ( - 2.0 * Math . Log ( s ) / s ) ;
399
- spareNormal = v * mul ;
400
- useSpareNormal = true ;
401
- return mu + sigma * u * mul ;
402
- }
388
+ return MarsagliaPolar ( random , mu , sigma , out _ ) ; // do not reuse the spare normal in this case, because it could be from a different RNG
403
389
}
404
390
/// <summary>
405
391
/// Uses the Marsaglia polar method to generate a random variable
@@ -413,8 +399,25 @@ public virtual double RandNormal(IRandom random, double mu, double sigma) {
413
399
/// <param name="mu">The mean of the normal distribution.</param>
414
400
/// <param name="sigma">The standard deviation of the normal distribution.</param>
415
401
/// <returns>A number that is normal distributed.</returns>
416
- public double RandNormal ( double mu , double sigma ) {
417
- return RandNormal ( Random , mu , sigma ) ;
402
+ public virtual double RandNormal ( double mu , double sigma ) {
403
+ if ( useSpareNormal ) {
404
+ useSpareNormal = false ;
405
+ return spareNormal * sigma + mu ;
406
+ } else {
407
+ useSpareNormal = true ;
408
+ return MarsagliaPolar ( Random , mu , sigma , out spareNormal ) ;
409
+ }
410
+ }
411
+ private double MarsagliaPolar ( IRandom random , double mu , double sigma , out double spare ) {
412
+ double u , v , s ;
413
+ do {
414
+ u = random . NextDouble ( ) * 2 - 1 ;
415
+ v = random . NextDouble ( ) * 2 - 1 ;
416
+ s = u * u + v * v ;
417
+ } while ( s > 1 || s == 0 ) ;
418
+ var mul = Math . Sqrt ( - 2.0 * Math . Log ( s ) / s ) ;
419
+ spare = v * mul ;
420
+ return mu + sigma * u * mul ;
418
421
}
419
422
420
423
/// <summary>
@@ -879,6 +882,9 @@ public Environment(DateTime initialDateTime, int randomSeed, TimeSpan? defaultSt
879
882
}
880
883
881
884
protected static readonly double NormalMagicConst = 4 * Math . Exp ( - 0.5 ) / Math . Sqrt ( 2.0 ) ;
885
+ public override double RandNormal ( double mu , double sigma ) {
886
+ return RandNormal ( Random , mu , sigma ) ;
887
+ }
882
888
public override double RandNormal ( IRandom random , double mu , double sigma ) {
883
889
double z , zz , u1 , u2 ;
884
890
do {
0 commit comments