[Algorithm] Normal random in ACS
Posted: Sat Dec 05, 2015 2:01 am
This is an algorithm for calculating random variables that approximately conform to the normal distribution. That is to say you can make bell curves with it in ACS. The library consists of two functions:
NormalVariate(fixed mean, fixed deviance)
Calculates a bell-curved random variable. This is probably what you want to use here. mean specifies the peak of the curve (i.e. the most common value) while deviance specifies how random the result is.
At 90% chance the result of NormalVariate() will be at most probit(0.95) * deviance = 1.644 * deviance away from the mean. That is, a NormalVariate(5.0, 2.5) will, at 95% chance return a number between [0.887, 9.112]. Respectively, at 75% chance the result will be at most probit(0.875) * deviance = 1.15 * deviance away from the mean.
Probit(fixed x)
Quickly calculates the x-quantile of the standard normal distribution. You probably won't be very interested in this one but it's the heart and soul of NormalVariate(). Uses two large lookup tables and a single iteration of Newton's method to find an approximate result efficiently.
Note that due to the corner cutting used in the implementation of Probit(x) the bell curve is an approximation. If x is not a multiple of 0.005 the result will be slightly off and if x is less than 0.0025 or greater than 0.9975 the result is flatly clamped to ±2.8 because the algorithm simply cannot handle such values.
This means that NormalVariate() will never provide values that are any further away from mean than 2.8 * deviance, even though a precise bell curve would yield such results in rare cases! Though I guess if you're using it for a mod the precision provided should be OK enough. However, also due to the corner cutting it's efficient enough to calculate 5,000 normal random values (20,000 in Zandronum 3.x and ZDoom) without hitting the runaway limit.
You may use it freely in mods but give credit for its use or I shall find you down and stuff something really normally random down your neck.
Download (v1)
NormalVariate(fixed mean, fixed deviance)
Calculates a bell-curved random variable. This is probably what you want to use here. mean specifies the peak of the curve (i.e. the most common value) while deviance specifies how random the result is.
At 90% chance the result of NormalVariate() will be at most probit(0.95) * deviance = 1.644 * deviance away from the mean. That is, a NormalVariate(5.0, 2.5) will, at 95% chance return a number between [0.887, 9.112]. Respectively, at 75% chance the result will be at most probit(0.875) * deviance = 1.15 * deviance away from the mean.
Probit(fixed x)
Quickly calculates the x-quantile of the standard normal distribution. You probably won't be very interested in this one but it's the heart and soul of NormalVariate(). Uses two large lookup tables and a single iteration of Newton's method to find an approximate result efficiently.
Note that due to the corner cutting used in the implementation of Probit(x) the bell curve is an approximation. If x is not a multiple of 0.005 the result will be slightly off and if x is less than 0.0025 or greater than 0.9975 the result is flatly clamped to ±2.8 because the algorithm simply cannot handle such values.
This means that NormalVariate() will never provide values that are any further away from mean than 2.8 * deviance, even though a precise bell curve would yield such results in rare cases! Though I guess if you're using it for a mod the precision provided should be OK enough. However, also due to the corner cutting it's efficient enough to calculate 5,000 normal random values (20,000 in Zandronum 3.x and ZDoom) without hitting the runaway limit.
You may use it freely in mods but give credit for its use or I shall find you down and stuff something really normally random down your neck.
Download (v1)