Last active
August 29, 2015 14:18
-
-
Save AJLeuer/3eb618f93c4045b47219 to your computer and use it in GitHub Desktop.
C++ random generator class (written on top of the standard library's <random> facility)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
C++ random generator class (written on top of the standard library's <random> facility) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Random.cpp | |
// | |
// | |
// Created by Adam James Leuer on 7/22/14. | |
// Copyright (c) 2014 Adam James Leuer. All rights reserved. | |
// | |
#include "Random.hpp" | |
FastRand<float> FastRand<float>::defaultRandom(std::numeric_limits<float>::min(), std::numeric_limits<float>::max()) ; | |
FastRand<float>::FastRand(float _min, float _max) : | |
minimum(_min), | |
maximum(_max) | |
{ | |
//dev ; | |
dist = uniform_real_distribution<float>(minimum, maximum) ; | |
rndm.seed(dev()) ; | |
} | |
FastRand<float>::FastRand(const FastRand<float> & other) | |
{ | |
std::random_device dev2 ; | |
dist = uniform_real_distribution<float>(other.minimum, other.maximum) ; | |
rndm.seed(dev2()) ; | |
} | |
FastRand<float>::~FastRand(){} | |
FastRand<float> & FastRand<float>::operator=(const FastRand<float> & rhs) | |
{ | |
if (this != &rhs) { | |
std::random_device dev2 ; | |
dist = uniform_real_distribution<float>(rhs.minimum, rhs.maximum) ; | |
rndm.seed(dev2()) ; | |
} | |
return *this ; | |
} | |
float FastRand<float>::nextValue() { | |
return dist(rndm) ; | |
} | |
float FastRand<float>::nextValue(float minimum, float maximum) { | |
std::uniform_real_distribution<float> dif_dist{minimum, maximum} ; | |
return dif_dist(rndm) ; | |
} | |
float FastRand<float>::operator()() { | |
return nextValue() ; | |
} | |
float FastRand<float>::operator()(float minimum, float maximum) { | |
return nextValue(minimum, maximum) ; | |
} | |
template<typename R> | |
R FastRand<float>::nextValue(R _min, R _max) { | |
std::uniform_real_distribution<R> dif_dist{_min, _max} ; | |
return dif_dist(rndm) ; | |
} | |
FastRand<double> FastRand<double>::defaultRandom(std::numeric_limits<double>::min(), std::numeric_limits<double>::max()) ; | |
FastRand<double>::FastRand(double _min, double _max) : | |
minimum(_min), | |
maximum(_max) | |
{ | |
//dev ; | |
dist = uniform_real_distribution<double>(minimum, maximum) ; | |
rndm.seed(dev()) ; | |
} | |
FastRand<double>::FastRand(const FastRand<double> & other) | |
{ | |
std::random_device dev2 ; | |
dist = uniform_real_distribution<double>(other.minimum, other.maximum) ; | |
rndm.seed(dev2()) ; | |
} | |
FastRand<double>::~FastRand(){} | |
FastRand<double> & FastRand<double>::operator=(const FastRand<double> & rhs) | |
{ | |
if (this != &rhs) { | |
std::random_device dev2 ; | |
dist = uniform_real_distribution<double>(rhs.minimum, rhs.maximum) ; | |
rndm.seed(dev2()) ; | |
} | |
return *this ; | |
} | |
double FastRand<double>::nextValue() { | |
return dist(rndm) ; | |
} | |
double FastRand<double>::nextValue(double minimum, double maximum) { | |
std::uniform_real_distribution<double> dif_dist{minimum, maximum} ; | |
return dif_dist(rndm) ; | |
} | |
double FastRand<double>::operator()() { | |
return nextValue() ; | |
} | |
double FastRand<double>::operator()(double minimum, double maximum) { | |
return nextValue(minimum, maximum) ; | |
} | |
template<typename R> | |
R FastRand<double>::nextValue(R _min, R _max) { | |
std::uniform_real_distribution<R> dif_dist{_min, _max} ; | |
return dif_dist(rndm) ; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Random.hpp | |
// | |
// | |
// Created by Adam James Leuer on 6/28/14. | |
// Copyright (c) 2014 Adam James Leuer. All rights reserved. | |
// | |
#include <iostream> | |
#include <limits> | |
#include <random> | |
#include <cmath> | |
using namespace std ; | |
template<typename N> | |
class FastRand { | |
protected: | |
std::random_device dev ; | |
std::uniform_int_distribution<N> dist ; | |
std::default_random_engine rndm = std::default_random_engine(dev()) ; | |
N minimum ; | |
N maximum ; | |
/* A conveniance random object that won't require initialization. | |
* Especially useful in constructors and initializing static values. | |
* A superior replacement for calling rand() | |
*/ | |
public: | |
static FastRand defaultRandom ; | |
FastRand(N _min, N _max) ; | |
FastRand(const FastRand<N> & other) ; | |
template<typename M> | |
FastRand(const FastRand<M> & other) ; | |
FastRand & operator=(const FastRand<N> & rhs) ; | |
~FastRand() ; | |
N nextValue() ; | |
N nextValue(N minimum, N maximum) ; | |
template<typename R> R nextValue(R _min, R _max) ; | |
N operator()() ; | |
N operator()(N minimum, N maximum) ; | |
} ; | |
template<> | |
class FastRand<float> { | |
protected: | |
std::random_device dev ; | |
std::uniform_real_distribution<float> dist ; | |
std::default_random_engine rndm = std::default_random_engine(dev()) ; | |
float minimum ; | |
float maximum ; | |
public: | |
static FastRand defaultRandom ; | |
static FastRand * randPositionSetter ; | |
FastRand(float _min, float _max) ; | |
FastRand(const FastRand<float> & other) ; | |
FastRand & operator=(const FastRand<float> & rhs) ; | |
~FastRand() ; | |
float nextValue() ; | |
float nextValue(float minimum, float maximum) ; | |
template<typename R> R nextValue(R _min, R _max) ; | |
float operator()() ; | |
float operator()(float minimum, float maximum) ; | |
} ; | |
template<> | |
class FastRand<double> { | |
protected: | |
static FastRand<double> defaultRandom ; | |
std::random_device dev ; | |
std::uniform_real_distribution<double> dist ; | |
std::default_random_engine rndm = std::default_random_engine(dev()) ; | |
double minimum ; | |
double maximum ; | |
public: | |
FastRand(double _min, double _max) ; | |
FastRand(const FastRand<double> & other) ; | |
FastRand & operator=(const FastRand<double> & rhs) ; | |
~FastRand() ; | |
double nextValue() ; | |
double nextValue(double minimum, double maximum) ; | |
template<typename R> R nextValue(R _min, R _max) ; | |
double operator()() ; | |
double operator()(double minimum, double maximum) ; | |
} ; | |
template<typename N> | |
FastRand<N>::FastRand(N _min, N _max) : | |
minimum(_min), | |
maximum(_max) | |
{ | |
//dev ; | |
dist = uniform_int_distribution<N>(minimum, maximum) ; | |
rndm.seed(dev()) ; | |
} | |
template<typename N> | |
FastRand<N>::FastRand(const FastRand<N> & other) | |
{ | |
std::random_device dev2 ; | |
dist = uniform_int_distribution<N>(other.minimum, other.maximum) ; | |
rndm.seed(dev2()) ; | |
} | |
template<typename N> | |
template<typename M> | |
FastRand<N>::FastRand(const FastRand<M> & other) { | |
this->minimum(static_cast<N>(other.minimum)) ; | |
this->maximum(static_cast<N>(other.maximum)) ; | |
dist = uniform_int_distribution<N>(minimum, maximum) ; | |
rndm.seed(dev()) ; | |
} | |
template<typename N> | |
FastRand<N>::~FastRand(){} | |
template<typename N> | |
FastRand<N> & FastRand<N>::operator=(const FastRand<N> & rhs) | |
{ | |
if (this != &rhs) { | |
std::random_device dev2 ; | |
dist = uniform_int_distribution<N>(rhs.minimum, rhs.maximum) ; | |
rndm.seed(dev2()) ; | |
} | |
return *this ; | |
} | |
template<typename N> | |
N FastRand<N>::nextValue() { | |
return dist(rndm) ; | |
} | |
template<typename N> | |
N FastRand<N>::nextValue(N minimum, N maximum) { | |
std::uniform_int_distribution<N> dif_dist{minimum, maximum} ; | |
return dif_dist(rndm) ; | |
} | |
template<typename N> | |
N FastRand<N>::operator()() { | |
return nextValue() ; | |
} | |
template<typename N> | |
N FastRand<N>::operator()(N minimum, N maximum) { | |
return nextValue(minimum, maximum) ; | |
} | |
template<typename N> | |
template<typename R> | |
R FastRand<N>::nextValue(R _min, R _max) { | |
std::uniform_int_distribution<R> dif_dist{_min, _max} ; | |
return dif_dist(rndm) ; | |
} | |
/* | |
template<typename N> | |
FastRand<N> * FastRand<N>::randPositionSetter = initRandPosSetter() ; | |
template<typename N> | |
FastRand<N> * FastRand<N>::initRandPosSetter() { | |
return new FastRand<N>(0, findLargest<N>({static_cast<N>(globalMaxX()), static_cast<N>(globalMaxY())})) ; | |
} */ | |
template<typename N> | |
FastRand<N> FastRand<N>::defaultRandom(std::numeric_limits<N>::min(), std::numeric_limits<N>::max()) ; | |
/* more useful random functions: */ | |
template<typename N> | |
N randSignFlip(N n) { | |
FastRand<unsigned short> rand(0, 1) ; | |
bool pos = rand.nextValue() % 2 ; | |
if (pos) { | |
return n ; | |
} | |
else { | |
return (n * -1) ; | |
} | |
} | |
template <typename T> | |
T chooseAtRand(T t1, T t2) { | |
FastRand<unsigned long> rand(0, 1) ; | |
bool first = rand.nextValue() ; | |
if (first) { | |
return t1 ; | |
} | |
else { | |
return t2 ; | |
} | |
} | |
/** | |
* Returns a random enumeration of enum type | |
* SomeEnum. SomeEnum should ideally use integer values starting | |
* at zero as the underlying value for its enumerations. | |
* | |
* @param SomeEnum An enumeration type | |
* @param N Some integer or floating point type | |
* @param maximum The numerical value of the maximum enum of type SomeEnum | |
*/ | |
template<typename SomeEnum, typename N> | |
SomeEnum randomEnumeration(N maximum) { | |
FastRand<N> randm(0, maximum) ; | |
N num = randm() ; | |
return SomeEnum(num) ; | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment