#ifndef lint
#ifdef __GNUC__
#define ATTRIBUTE(attrs) __attribute__(attrs)
#else
#define ATTRIBUTE(attrs)
#endif
static char Rcs_Id[] ATTRIBUTE((used)) =
"$Id: rdcctest.cc,v 1.7 2012-12-30 16:24:49-08 geoff Exp $";
#endif
/*
* Test the random-distribution library. Usage:
*
* rdcctest seed how_many distribution [params...]
*
* where:
*
* seed is the random seed. If seed is zero, the package's
* automatic seed generator is used.
* how_many
* is how many random numbers to generate.
* distribution
* is the distribution to draw from (see below).
* params are the parameters to the distribution (see below).
*
* Distributions supported:
*
* iuniform A uniform distribution of integers on the interval [p1, p2).
* uniform A uniform distribution on the interval [p1, p2).
* exponential Exponential with mean p1, default 1.
* erlang p1-Erlang with mean p2.
* weibull Weibull with shape parameter p1 and scale parameter p2.
* normal Normal with mean p1 and standard deviation p2.
* lognormal Lognormal with scale parameter p1 and shape parameter p2.
* triangular Triangular on the interval (p1, p2) with mode at p3.
* empirical p1 with probability p2, p3 with probability p4, ...,
* p(2n+1) with probability p(2n). Actually, the
* "probabilities" are
* weights, and do not need to sum to 1.
* continuous_empirical
* p1 to p3 with probability p2, p3 to p5 with
* probability p4, ..., p(2n+1) to p(2n+2) with
* probability p(2n). Actually, the "probabilities" are
* weights, and do not need to sum to 1.
*
* $Log: rdcctest.cc,v $
* Revision 1.7 2012-12-30 16:24:49-08 geoff
* Use gcc attributes to suppress warnings on Rcs_Id.
*
* Revision 1.6 2010-12-10 03:28:19-08 geoff
* Support the new empirical_distribution interface.
*
* Revision 1.5 2010-06-24 19:29:38+12 geoff
* Include string.h to get rid of some warnings.
*
* Revision 1.4 2008-07-25 16:34:01-07 geoff
* Fix notation for intervals in commentary.
*
* Revision 1.3 2004/03/30 07:29:43 geoff
* Document the program better, and allow the random seed to be
* controlled for verification testing.
*
* Revision 1.2 2003/09/11 05:50:53 geoff
* Use the standard namespace.
*
* Revision 1.1 2001/06/18 10:09:35 geoff
* Initial revision
*
*/
#include "randistrs.h"
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <vector>
using namespace std;
int main(int argc, char* argv[]);
static void usage();
#define SEED_PARAM 1 /* Offset of seed param in argv */
#define COUNT_PARAM 2 /* Offset of count param in argv */
#define DISTR_PARAM 3 /* Offset of distr param in argv */
#define PARAM_OFFSET 4 /* Offset of params in argv */
int main(
int argc, /* Argument count */
char* argv[]) /* Argument vector */
{
if (argc <= PARAM_OFFSET)
usage();
int seed = atoi (argv[SEED_PARAM]);
size_t how_many = atoi(argv[COUNT_PARAM]);
size_t n_params = argc - PARAM_OFFSET;
double* params = new double[n_params];
mt_empirical_distribution* empirical = NULL;
size_t needed_params = 0; /* Number of params needed by distr */
size_t n_probs = 0; /* Number of empirical probabilites */
for (size_t i = 0; i < n_params; i++)
params[i] = atof(argv[i + PARAM_OFFSET]);
if (strcmp(argv[DISTR_PARAM], "iuniform") == 0)
needed_params = 2;
else if (strcmp(argv[DISTR_PARAM], "uniform") == 0)
needed_params = 2;
else if (strcmp(argv[DISTR_PARAM], "exponential") == 0)
needed_params = 1;
else if (strcmp(argv[DISTR_PARAM], "erlang") == 0)
{
if (n_params < 2 || params[0] < 1.0)
usage();
needed_params = 2;
}
else if (strcmp(argv[DISTR_PARAM], "weibull") == 0)
needed_params = 2;
else if (strcmp(argv[DISTR_PARAM], "normal") == 0)
needed_params = 2;
else if (strcmp(argv[DISTR_PARAM], "lognormal") == 0)
needed_params = 2;
else if (strcmp(argv[DISTR_PARAM], "triangular") == 0)
needed_params = 3;
else if (strcmp(argv[DISTR_PARAM], "empirical") == 0)
{
if (n_params % 2 != 0 || n_params < 4)
usage();
n_probs = n_params / 2;
vector<double> probs;
vector<double> values;
for (size_t i = 0; i < n_probs; i++)
{
values.push_back(params[i * 2]);
probs.push_back(params[i * 2 + 1]);
if (probs[i] < 0)
{
(void)fprintf(stderr, "rdcctest: negative probability given\n");
exit(2);
}
}
values.push_back(0.0);
needed_params = n_params;
empirical = new mt_empirical_distribution(probs, values);
}
else if (strcmp(argv[DISTR_PARAM], "continuous_empirical") == 0)
{
if (n_params % 2 == 0 || n_params < 5)
usage();
n_probs = (n_params - 1) / 2;
vector<double> probs;
vector<double> values;
for (size_t i = 0; i < n_probs; i++)
{
values.push_back(params[i * 2]);
probs.push_back(params[i * 2 + 1]);
if (probs[i] < 0)
{
(void)fprintf(stderr, "rdcctest: negative probability given\n");
exit(2);
}
}
values.push_back(params[n_probs * 2]);
needed_params = n_params;
empirical = new mt_empirical_distribution(probs, values);
}
else
usage();
if (n_params != needed_params)
usage();
/*
* Create a generator and seed it.
*/
mt_distribution distr(seed == 0);
if (seed != 0)
distr.seed32(seed);
for (size_t i = 0; i < how_many; i++)
{
double ran_value = 0.0;
if (strcmp(argv[DISTR_PARAM], "iuniform") == 0)
ran_value = distr.iuniform((long)params[0], (long)params[1]);
else if (strcmp(argv[DISTR_PARAM], "uniform") == 0)
ran_value = distr.uniform(params[0], params[1]);
else if (strcmp(argv[DISTR_PARAM], "exponential") == 0)
ran_value = distr.exponential(params[0]);
else if (strcmp(argv[DISTR_PARAM], "erlang") == 0)
ran_value = distr.erlang((int) params[0], params[1]);
else if (strcmp(argv[DISTR_PARAM], "weibull") == 0)
ran_value = distr.weibull(params[0], params[1]);
else if (strcmp(argv[DISTR_PARAM], "normal") == 0)
ran_value = distr.normal(params[0], params[1]);
else if (strcmp(argv[DISTR_PARAM], "lognormal") == 0)
ran_value = distr.lognormal(params[0], params[1]);
else if (strcmp(argv[DISTR_PARAM], "triangular") == 0)
ran_value = distr.triangular(params[0], params[1], params[2]);
else if (strcmp(argv[DISTR_PARAM], "empirical") == 0)
ran_value = empirical->double_empirical(distr);
else if (strcmp(argv[DISTR_PARAM], "continuous_empirical") == 0)
ran_value = empirical->continuous_empirical(distr);
cout << ran_value << '\n';
}
return 0;
}
static void usage()
{
cerr << "Usage: rdcctest count distribution p0 ...\n";
cerr << "Distributions:\n";
cerr << "\tiuniform lower upper\n";
cerr << "\tuniform lower upper\n";
cerr << "\texponential mean\n";
cerr << "\terlang p mean\n";
cerr << "\tweibull shape scale\n";
cerr << "\tnormal mean sigma\n";
cerr << "\tlognormal shape scale\n";
cerr << "\ttriangular lower upper mode\n";
cerr << "\tempirical v0 p0 v1 p1 ... vn-1 pn-1\n";
cerr << "\tcontinuous_empirical v0 p0 v1 p1 ... vn-1 pn-1 vn\n";
exit(2);
}