Initial commit
This commit is contained in:
213
ZUtil/ZRandomGenerator.cpp
Normal file
213
ZUtil/ZRandomGenerator.cpp
Normal file
@@ -0,0 +1,213 @@
|
||||
#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!");
|
||||
}
|
||||
Reference in New Issue
Block a user