#include #include #include /* sine and other functions */ #include /* 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!"); }