H
Hans Mull
Hi!
I'm working on a random number generator which makes use of
Boost::random. I have to write a function that gets 2 int-parameters
from the GUI. One is a number that indicates which algorithm to use and
the other shows which distribution we have to use. Boost uses templates
so I cannot use polymorphism (Or is there a way to use polymorphism even
if the classes aren't derivated from a base class?). I tried to use a
template function, but I don't know the types when I call the fuction
(xxParam are static variables):
template<class boostEngine, class boostDistribution>
void GenRandBoost()
{
///Cache parameters
ulong amount = amountParam;
ulong ulSeed = seedParam;
string filename = filenameParam;
double ulDouble = ulDoubleParam;
double llDouble = llDoubleParam;
int distributionSelection = distributionSelectionParam;
int algorithmSelection = algorithmSelectionParam;
ulong bits = bitsParam;
///Initialize template pointers
boostEngine *algorithm;
boostDistribution *distribution;
///Open fstream
fstream f(filename.c_str(), fstream:ut);
//Initialize counter
ulong i;
///Switch distribution
switch(algorithmSelection)
{
case 0: ///MT 19937
{
mt19937 mersenne(ulSeed);
algorithm = &mersenne;
break;
}
case 1: ///Linear congruential
{
minstd_rand0 linCongr(ulSeed);
algorithm = &linCongr;
break;
}
case 2: ///Additive combine
{
ecuyer1988 addComb(ulSeed);
algorithm = &addComb;
break;
}
case 3: ///Inverse congruential
{
hellekalek1995 invCongr(ulSeed);
algorithm = &invCongr;
break;
}
case 4: ///Shuffle output
{
kreutzer1986 shOut(ulSeed);
algorithm = &shOut;
break;
}
// case 5: ///Lagged Fibonacci
// {
// lagged_fibonacci lagFib(ulSeed);
// algorithm = &lagFib;
// break;
// }
default: break;
}
///Switch distribution
switch(distributionSelection)
{
case 0: ///Uniform small int
{
uniform_smallint<double> smallInt(llDouble, ulDouble);
distribution = &smallInt;
}
case 1: ///Uniform integer
{
uniform_int<double> uniInt(llDouble, ulDouble);
distribution = &uniInt;
}
case 2: ///Uniform 01
{
//uniform_01<double, double> uni01(llDouble, ulDouble);
//distribution = &uni01;
}
case 3: ///Uniform real
{
uniform_real<double> uniReal(llDouble, ulDouble);
distribution = &uniReal;
}
case 4: ///Triangle
{
triangle_distribution<double> triangle(llDouble,
ulDouble);
distribution = ▵
}
case 5: ///Bernoulli
{
bernoulli_distribution<double> bernoulli(llDouble,
ulDouble);
distribution = &bernoulli;
}
case 6: ///Cauchy
{
cauchy_distribution<double> cauchy(llDouble, ulDouble);
distribution = &cauchy;
}
case 7: ///Exponential
{
exponential_distribution<double>
exponential(llDouble, ulDouble);
distribution = &exponential;
}
case 8: ///Geometric
{
geometric_distribution<double> geometric(llDouble,
ulDouble);
distribution = &geometric;
}
case 9: ///Normal
{
normal_distribution<double> normal(llDouble, ulDouble);
distribution = &normal;
}
case 10: ///Lognormal
{
lognormal_distribution<double> lognormal(llDouble,
ulDouble);
distribution = &lognormal;
}
case 11: ///Uniform on Sphere
{
uniform_on_sphere<double> uniSphere(llDouble, ulDouble);
distribution = &uniSphere;
}
default: {break;}
}
///Variate Generator
variate_generator<boostEngine, boostDistribution>
generator(algorithm, distribution);
///TODO: Main loop
for(;i < amount;i++)
{
f << generator() << endl;
}
}
I don't want to have a distributionSelection switch in each
algorithmSelection case statement.
Do you have any ideas?
Thanks in advance, Hans
I'm working on a random number generator which makes use of
Boost::random. I have to write a function that gets 2 int-parameters
from the GUI. One is a number that indicates which algorithm to use and
the other shows which distribution we have to use. Boost uses templates
so I cannot use polymorphism (Or is there a way to use polymorphism even
if the classes aren't derivated from a base class?). I tried to use a
template function, but I don't know the types when I call the fuction
(xxParam are static variables):
template<class boostEngine, class boostDistribution>
void GenRandBoost()
{
///Cache parameters
ulong amount = amountParam;
ulong ulSeed = seedParam;
string filename = filenameParam;
double ulDouble = ulDoubleParam;
double llDouble = llDoubleParam;
int distributionSelection = distributionSelectionParam;
int algorithmSelection = algorithmSelectionParam;
ulong bits = bitsParam;
///Initialize template pointers
boostEngine *algorithm;
boostDistribution *distribution;
///Open fstream
fstream f(filename.c_str(), fstream:ut);
//Initialize counter
ulong i;
///Switch distribution
switch(algorithmSelection)
{
case 0: ///MT 19937
{
mt19937 mersenne(ulSeed);
algorithm = &mersenne;
break;
}
case 1: ///Linear congruential
{
minstd_rand0 linCongr(ulSeed);
algorithm = &linCongr;
break;
}
case 2: ///Additive combine
{
ecuyer1988 addComb(ulSeed);
algorithm = &addComb;
break;
}
case 3: ///Inverse congruential
{
hellekalek1995 invCongr(ulSeed);
algorithm = &invCongr;
break;
}
case 4: ///Shuffle output
{
kreutzer1986 shOut(ulSeed);
algorithm = &shOut;
break;
}
// case 5: ///Lagged Fibonacci
// {
// lagged_fibonacci lagFib(ulSeed);
// algorithm = &lagFib;
// break;
// }
default: break;
}
///Switch distribution
switch(distributionSelection)
{
case 0: ///Uniform small int
{
uniform_smallint<double> smallInt(llDouble, ulDouble);
distribution = &smallInt;
}
case 1: ///Uniform integer
{
uniform_int<double> uniInt(llDouble, ulDouble);
distribution = &uniInt;
}
case 2: ///Uniform 01
{
//uniform_01<double, double> uni01(llDouble, ulDouble);
//distribution = &uni01;
}
case 3: ///Uniform real
{
uniform_real<double> uniReal(llDouble, ulDouble);
distribution = &uniReal;
}
case 4: ///Triangle
{
triangle_distribution<double> triangle(llDouble,
ulDouble);
distribution = ▵
}
case 5: ///Bernoulli
{
bernoulli_distribution<double> bernoulli(llDouble,
ulDouble);
distribution = &bernoulli;
}
case 6: ///Cauchy
{
cauchy_distribution<double> cauchy(llDouble, ulDouble);
distribution = &cauchy;
}
case 7: ///Exponential
{
exponential_distribution<double>
exponential(llDouble, ulDouble);
distribution = &exponential;
}
case 8: ///Geometric
{
geometric_distribution<double> geometric(llDouble,
ulDouble);
distribution = &geometric;
}
case 9: ///Normal
{
normal_distribution<double> normal(llDouble, ulDouble);
distribution = &normal;
}
case 10: ///Lognormal
{
lognormal_distribution<double> lognormal(llDouble,
ulDouble);
distribution = &lognormal;
}
case 11: ///Uniform on Sphere
{
uniform_on_sphere<double> uniSphere(llDouble, ulDouble);
distribution = &uniSphere;
}
default: {break;}
}
///Variate Generator
variate_generator<boostEngine, boostDistribution>
generator(algorithm, distribution);
///TODO: Main loop
for(;i < amount;i++)
{
f << generator() << endl;
}
}
I don't want to have a distributionSelection switch in each
algorithmSelection case statement.
Do you have any ideas?
Thanks in advance, Hans