NormRnd - standard normal random number (a tiny module)

Started by eri0o, Fri 11/08/2017 02:10:38

Previous topic - Next topic

eri0o

NormRnd

NormRnd is a tiny (2.1kB) module adding a standard normal random number function. It uses Box-Muller method, which should be reasonably fast.

It exposes two functions:

float normrnd_unitary()
Returns a standard normal random number, as a float, with median 0, and variance 1.

int normrnd_asint(int median, int sigma, int clamp_ceil,  int clamp_floor)
Returns a standard normal random number, as a int, requires passing a defined median and sigma. It also allow clamping to restrict the possible returning values. If clamp_ceil and clamp_floor are equal, clamping is disabled.

NormRnd.asc

Spoiler
Code: ags

// normrnd
//
// This module allows returning standard Normal random number.
// This code is based on Box-Muller method, implemented in C
// by Prof Darren Wilkinson here:
//
// http://www.mas.ncl.ac.uk/~ndjw1/teaching/sim/transf/norm.html
//
// My work was porting to AGS and giving utilitary functions
// Author: Erico Porto
//

float surand()
{
  return ( IntToFloat(Random(1000))/1000.0 );
}

float urand(float low, float high)
{
  return(low+(high-low)*surand());
}

float genexp(float lambda)
{
  float u,x;
  u=surand();
  x=(-1.0/lambda)*Maths.Log(u);
  return(x);
}

float gennor()
{
  float theta,rsq,x;
  theta=urand(0.0,2.0*Maths.Pi);
  rsq=genexp(0.5);
  x=Maths.Sqrt(rsq)*Maths.Cos(theta);
  return(x);
}

//normrnd_unitary
//
// returns a float that is a standard Normal random number
float normrnd_unitary(){
  return gennor();
}

// returns an int that is a standard Normal random number
// first paramter, median, is the median of the distribution
// second parameter, sigma, is proportional to the variance of the distribution
// third and fourth parameter allow clamping the result if a hard limit is desired
int normrnd_asint(int median, int sigma, int clamp_ceil,  int clamp_floor){
  int return_value = FloatToInt(gennor()*IntToFloat(sigma)+IntToFloat(median));
  if( clamp_ceil != clamp_floor && clamp_ceil > clamp_floor){
    if (return_value > clamp_ceil){
      return_value = clamp_ceil;
    }
    if (return_value < clamp_floor){
      return_value = clamp_floor;
    }
  }
  
  return return_value;
}
[close]

NormRnd.ash

Spoiler
Code: ags

// normrnd
//
// This module allows returning standard Normal random number.
// This code is based on Box-Muller method, implemented in C
// by Prof Darren Wilkinson here:
//
// http://www.mas.ncl.ac.uk/~ndjw1/teaching/sim/transf/norm.html
//
// My work was porting to AGS and giving utilitary functions
// Author: Erico Porto
//
import float normrnd_unitary();
import int normrnd_asint(int median, int sigma, int clamp_ceil = 0,  int clamp_floor = 0);
[close]

Download NormRnd.scm here

Doc website

Github Repository

vga256

So glad you wrote this. Just saved me a ton of time redoing the same work!

SMF spam blocked by CleanTalk