[Add] Documentation for random number generations.

This commit is contained in:
Allanis 2013-10-10 20:34:58 +01:00
parent 8feb19e20c
commit 833283add0
2 changed files with 90 additions and 18 deletions

View File

@ -1,3 +1,11 @@
/**
* @file rng.c
*
* @brief Handle all the random number logic.
*
* Random numbers are currently generated using the mersenne twister.
*/
#include <stdint.h>
#include <math.h>
#include <unistd.h>
@ -12,9 +20,9 @@
#include "lephisto.h"
#include "rng.h"
static uint32_t MT[624];
static uint32_t mt_y;
static int mt_pos = 0; /* Current number. */
static uint32_t MT[624]; /**< Mersenne twister state. */
static uint32_t mt_y; /**< Internal mersenne twister variable. */
static int mt_pos = 0; /**< Current number being used. */
static uint32_t rng_timeEntropy(void);
/* Mersenne twister. */
@ -22,6 +30,11 @@ static void mt_initArray(uint32_t seed);
static void mt_genArray(void);
static uint32_t mt_getInt(void);
/**
* @fn void rng_init(void)
*
* @brief Initialize the random subsystem.
*/
void rng_init(void) {
uint32_t i;
int need_init;
@ -49,7 +62,12 @@ void rng_init(void) {
mt_genArray();
}
/* Use the time as source of entropy. */
/**
* @fn static uint32_t rng_timeEntropy(void)
*
* @brief Use time as a source of entropy.
* @return A 4 byte entopy seed.
*/
static uint32_t rng_timeEntropy(void) {
int i;
@ -65,7 +83,11 @@ static uint32_t rng_timeEntropy(void) {
return i;
}
/* Generates the initial mersenne twister based on seed. */
/**
* @fn static void mt_initArray(uint32_t seed)
*
* @brief Generate the initial mersenne twister based on seed.
*/
static void mt_initArray(uint32_t seed) {
int i;
MT[0] = seed;
@ -74,7 +96,11 @@ static void mt_initArray(uint32_t seed) {
mt_pos = 0;
}
/* Generate an array of numbers. */
/**
* @fn static void mt_genArray(void)
*
* @brief Generate a new set of random numbers for the mersenne twister.
*/
static void mt_genArray(void) {
int i;
for(i = 0; i < 624; i++) {
@ -89,7 +115,10 @@ static void mt_genArray(void) {
mt_pos = 0;
}
/* Get the next int. */
/**
* @fn static uint32_t mt_getInt(void)
* @return A random 4 byte number.
*/
static uint32_t mt_getInt(void) {
if(mt_pos >= 624) mt_genArray();
@ -102,19 +131,33 @@ static uint32_t mt_getInt(void) {
return mt_y;
}
/* Return a random int. */
/**
* @fn unsigned int randint(void)
*
* @brief Get a random integer.
* @return A random integer.
*/
unsigned int randint(void) {
return mt_getInt();
}
/* Return a random double. */
static double m_div = (double)(0xFFFFFFFF);
/**
* @fn double randfp(void)
*
* @brief Get a random float between 0 and 1 (inclusive).
* @return A random float between 0 and 1 (inclusive).
*/
static double m_div = (double)(0xFFFFFFFF); /**< Number to divide by. */
double randfp(void) {
double m = (double)mt_getInt();
return m / m_div;
}
/*
/**
* @fn double Normal(double x)
*
* @brief Calculates the normal distribution.
*
* Calculate N(x) where N is the normal distribution.
*
* Approximates to a power series:
@ -123,6 +166,9 @@ double randfp(void) {
* where t = 1 / (1 + 0.2316419*x)
*
* Maximum absolute error is 7.5e^-8.
*
* @param x Value to calculate the normal of.
* @return The value of the Normal.
*/
double Normal(double x) {
double t;
@ -142,7 +188,11 @@ double Normal(double x) {
return (x > 0.) ? 1. - series : series;
}
/*
/**
* @fn double NormalInverse(double p)
*
* @brief Calculate the inverse of the normal.
*
* Lower tail quantile for standard disribution function.
*
* This function returns an approximation of the inverse cumulative
@ -162,7 +212,7 @@ static const double a[] = {
1.383577518672690e+02,
-3.066479806614716e+01,
2.506628277459239e+00
};
}; /**< Inverse normal coefficients. */
static const double b[] = {
-5.447609879822406e+01,
@ -170,7 +220,7 @@ static const double b[] = {
-1.556989798598866e+02,
6.680131188771972e+01,
-1.328068155288572e+01
};
}; /**< Inverse normal coefficients. */
static const double c[] = {
-7.784894002430293e-03,
@ -179,17 +229,18 @@ static const double c[] = {
-2.549732539343734e+00,
4.374664141464968e+00,
2.938163982698783e+00
};
}; /**< Inverse normal coefficients. */
static const double d[] = {
7.784695709041462e-03,
3.224671290700398e-01,
2.445134137142996e+00,
3.754408661907416e+00
};
}; /**< Inverse normal coefficients. */
#define LOW 0.02425
#define HIGH 0.97575
#define LOW 0.02425 /**< Low area threshold. */
#define HIGH 0.97575 /**< High area threshold. */
double NormalInverse( double p ) {
double x, e, u, q, r;

View File

@ -1,7 +1,28 @@
#pragma once
/**
* @def RNG(L,H)
*
* @brief Get a random number between L and H (L <= RNG <= H).
*
* If L is bigger than H it inverts the roles.
*/
#define RNG(L,H) (((L)>(H)) ? RNG_SANE((H), (L)) : RNG_SANE((L),(H)))
/**
* @def RNG_SANE(L,H)
*
* @brief Get a number between L and H (L <= RNG <= H).
*
* Result unspecified if L is bigger than H.
*/
#define RNG_SANE(L,H) ((int)L + (int)((double)(H-L+1) * randfp())) /* L <= RNG <= H */
/**
* @def RNGF()
*
* @brief Get a random float between 0 and 1 (0. <= RNGF <= 1.).
*/
#define RNGF() (randfp()) /* 0. <= RNGF <= 1. */
/* Init. */