214 lines
5.4 KiB
C++
214 lines
5.4 KiB
C++
#include <ZUtil/ZRandomGenerator.hpp>
|
|
|
|
#include <ZUtil/ZAssert.hpp>
|
|
|
|
#include <math.h> /* sine and other functions */
|
|
#include <time.h> /* time function */
|
|
|
|
//Helper Function that returns a float distributed normally between a float min and max using random numbers r1, r2
|
|
float getGaussianHelper(float _min, float _max, float _r1, float _r2)
|
|
{
|
|
float deltamid, delta;
|
|
|
|
deltamid = (float)(((_max - _min) / 2) * sin(_r1 * 3.14159f)); /* absolute delta from middle value */
|
|
delta = _max - _min - (2 * deltamid); /* calculate the actual delta */
|
|
|
|
return (_min + deltamid + (_r2 * delta));
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
ZRandomGenerator::ZRandomGenerator()
|
|
: Type(SST_PRNG_SMALLPRNG), Seed((uint32_t)time(0)), Sequence(0), RNG(NULL)
|
|
{
|
|
RNG = SST_Random_CreatePRNGFromSeed(Type, Seed);
|
|
|
|
ZASSERT_RUNTIME(RNG != NULL, "ZRandomGenerator: Failure to initialize SST_PRNG instance!");
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
ZRandomGenerator::ZRandomGenerator(SST_PRNG_TYPE _type, uint32_t _seed, uint64_t _sequence )
|
|
: Type(_type), Seed(_seed), Sequence(_sequence), RNG(SST_Random_CreatePRNGFromSeed(_type, _seed))
|
|
{
|
|
ZASSERT_RUNTIME(RNG != NULL, "ZRandomGenerator: Failure to initialize SST_PRNG instance!");
|
|
|
|
//Generate and discard a number of times equal to Sequence
|
|
for (uint64_t i = 0; i < Sequence; i++)
|
|
SST_Random_GetPRNGInt(RNG, 0, 1);
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
ZRandomGenerator::~ZRandomGenerator()
|
|
{
|
|
if (RNG != NULL)
|
|
SST_Random_DestroyPRNG(RNG);
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
float ZRandomGenerator::GetFloat()
|
|
{
|
|
++Sequence;
|
|
|
|
return SST_Random_GetPRNGFloat(RNG, 0, 1);
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
void ZRandomGenerator::GetFloatArray( float *_array, size_t _count )
|
|
{
|
|
Sequence += _count;
|
|
|
|
return SST_Random_GetPRNGFloatArray(RNG, _array, _count, 0, 1);
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
float ZRandomGenerator::GetFloatInRange( float _min, float _max )
|
|
{
|
|
++Sequence;
|
|
|
|
return SST_Random_GetPRNGFloat(RNG, _min, _max);
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
void ZRandomGenerator::GetFloatArrayInRange( float *_array, size_t _count, float _min, float _max )
|
|
{
|
|
Sequence += _count;
|
|
|
|
return SST_Random_GetPRNGFloatArray(RNG, _array, _count, _min, _max);
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
float ZRandomGenerator::GetGaussianFloat( float _min, float _max )
|
|
{
|
|
float r1, r2;
|
|
|
|
r1 = GetFloat();
|
|
r2 = GetFloat();
|
|
|
|
return getGaussianHelper(_min, _max, r1, r2);
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
void ZRandomGenerator::GetGaussianFloatArray( float *_array, size_t _count, float _min, float _max )
|
|
{
|
|
size_t i;
|
|
float r1, r2;
|
|
|
|
for (i = 0; i < _count; ++i)
|
|
{
|
|
r1 = GetFloat();
|
|
r2 = GetFloat();
|
|
|
|
_array[i] = getGaussianHelper(_min, _max, r1, r2);
|
|
}
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
int ZRandomGenerator::GetGaussianInt( int _min, int _max )
|
|
{
|
|
return (int)GetGaussianFloat((float)_min + 0.5f, (float)_max + 0.5f);
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
void ZRandomGenerator::GetGaussianIntArray( int *_array, size_t _count, int _min, int _max )
|
|
{
|
|
size_t i;
|
|
float r1, r2;
|
|
|
|
for (i = 0; i < _count; ++i)
|
|
{
|
|
r1 = GetFloat();
|
|
r2 = GetFloat();
|
|
|
|
_array[i] = (int)getGaussianHelper((float)_min + 0.5f, (float)_max + 0.5f, r1, r2);
|
|
}
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
int ZRandomGenerator::GetInt()
|
|
{
|
|
++Sequence;
|
|
|
|
return SST_Random_GetPRNGInt(RNG, STDINT_MIN, STDINT_MAX);
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
void ZRandomGenerator::GetIntArray( int *_array, size_t _count )
|
|
{
|
|
Sequence += _count;
|
|
|
|
return SST_Random_GetPRNGIntArray(RNG, _array, _count, STDINT_MIN, STDINT_MAX);
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
int ZRandomGenerator::GetIntInRange( int _min, int _max )
|
|
{
|
|
++Sequence;
|
|
|
|
return SST_Random_GetPRNGInt(RNG, _min, _max);
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
void ZRandomGenerator::GetIntArrayInRange( int *_array, size_t _count, int _min, int _max )
|
|
{
|
|
Sequence += _count;
|
|
|
|
return SST_Random_GetPRNGIntArray(RNG, _array, _count, _min, _max);
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
uint32_t ZRandomGenerator::GetSeed()
|
|
{
|
|
return Seed;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
uint64_t ZRandomGenerator::GetSequence()
|
|
{
|
|
return Sequence;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
void ZRandomGenerator::SetSequence( uint64_t _seq )
|
|
{
|
|
//If less than, new instance
|
|
if (_seq < Sequence)
|
|
SetSeed(Seed);
|
|
|
|
while (Sequence < _seq)
|
|
{
|
|
SST_Random_GetPRNGInt(RNG, 0, 1);
|
|
++Sequence;
|
|
}
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
void ZRandomGenerator::SetSeed( uint32_t _seed )
|
|
{
|
|
if (RNG != NULL) SST_Random_DestroyPRNG(RNG);
|
|
|
|
Seed = _seed;
|
|
Sequence = 0;
|
|
|
|
RNG = SST_Random_CreatePRNGFromSeed(Type, Seed);
|
|
|
|
ZASSERT_RUNTIME(RNG != NULL, "ZRandomGenerator: Failure to initialize SST_PRNG_Instance!");
|
|
}
|