/// <summary> /// Returns the time until the next asteroid should be detected. Does not throw exceptions. /// </summary> /// <returns>The number of seconds before an asteroid detection, or infinity if asteroids /// should not spawn.</returns> private static double asteroidWaitTime() { double rate = AsteroidManager.spawnRate(); // asteroids per day if (rate > 0.0) { // Waiting time in a Poisson process follows an exponential distribution rate /= SECONDS_PER_EARTH_DAY; // asteroids per second return(RandomDist.drawExponential(1.0 / rate)); } else { return(double.PositiveInfinity); } }
/// <summary> /// Generates a random number consistent with the distribution. The program state shall be /// unchanged in the event of an exception. /// </summary> /// <returns>The desired random variate. The distribution depends on this object's internal /// data.</returns> /// /// <exception cref="ArgumentException">Thrown if the parameters are inappropriate /// for the distribution.</exception> /// <exception cref="InvalidOperationException">Thrown if the distribution is /// invalid.</exception> internal double draw() { switch (dist) { case Distribution.Uniform: return(RandomDist.drawUniform(min, max)); case Distribution.LogUniform: return(RandomDist.drawLogUniform(min, max)); case Distribution.Gaussian: case Distribution.Normal: return(RandomDist.drawNormal(avg, stdDev)); case Distribution.LogNormal: if (avg <= 0.0) { throw new ArgumentException( Localizer.Format("#autoLOC_CustomAsteroids_ErrorLogNormMean", avg)); } if (stdDev <= 0.0) { throw new ArgumentException( Localizer.Format("#autoLOC_CustomAsteroids_ErrorLogNormStd", stdDev)); } double quad = Math.Sqrt(avg * avg + stdDev * stdDev); double mu = Math.Log(avg * avg / quad); double sigma = Math.Sqrt(2 * Math.Log(quad / avg)); return(RandomDist.drawLognormal(mu, sigma)); case Distribution.Rayleigh: return(RandomDist.drawRayleigh(avg * Math.Sqrt(2.0 / Math.PI))); case Distribution.Exponential: return(RandomDist.drawExponential(avg)); case Distribution.Gamma: if (avg <= 0.0) { throw new ArgumentException( Localizer.Format("#autoLOC_CustomAsteroids_ErrorGammaMean", avg)); } if (stdDev <= 0.0) { throw new ArgumentException( Localizer.Format("#autoLOC_CustomAsteroids_ErrorGammaStd", stdDev)); } double k = (avg / stdDev); k = k * k; double theta = stdDev * stdDev / avg; return(RandomDist.drawGamma(k, theta)); case Distribution.Beta: if (avg <= min || avg >= max) { throw new ArgumentException( Localizer.Format("#autoLOC_CustomAsteroids_ErrorBetaMean", min, avg, max)); } if (stdDev <= 0.0) { throw new ArgumentException( Localizer.Format("#autoLOC_CustomAsteroids_ErrorBetaStd", stdDev)); } double scaledMean = (avg - min) / (max - min); double scaledStdDev = stdDev / (max - min); double scaledVar = scaledStdDev * scaledStdDev; double factor = (scaledMean - scaledMean * scaledMean - scaledVar) / scaledVar; double alpha = scaledMean * factor; double beta = (1.0 - scaledMean) * factor; return(min + (max - min) * RandomDist.drawBeta(alpha, beta)); case Distribution.Isotropic: return(RandomDist.drawIsotropic()); default: throw new InvalidOperationException( Localizer.Format("#autoLOC_CustomAsteroids_ErrorBadDistribution", dist)); } }