From d29bb3dcebdc2e087f4bfd0b5457ed9866e38cb4 Mon Sep 17 00:00:00 2001 From: Thomas Forbriger Date: Fri, 1 Nov 2019 19:26:09 +0100 Subject: [PATCH] randomseries [FEATURE]: provide new random time series generator --- src/synt/misc/randomseries.cc | 151 ++++++++++++++++++++++++++++------ 1 file changed, 128 insertions(+), 23 deletions(-) diff --git a/src/synt/misc/randomseries.cc b/src/synt/misc/randomseries.cc index 4264dafe..adf1be2d 100644 --- a/src/synt/misc/randomseries.cc +++ b/src/synt/misc/randomseries.cc @@ -19,14 +19,33 @@ "RANDOMSERIES V1.0 provide time series of incoherent random numbers" #include +#include +#include +#include #include #include +#include +#include +#include +#include #include using std::cout; using std::cerr; using std::endl; +/* ---------------------------------------------------------------------- */ + +struct Options { + bool verbose, overwrite; + std::string rngtype, filename, filetype; + int nseries, nsamples; + double std, mean, dt; + long unsigned int seed; +}; // struct Options + +/* ---------------------------------------------------------------------- */ + int main(int iargc, char* argv[]) { @@ -35,10 +54,9 @@ int main(int iargc, char* argv[]) { RANDOMSERIES_VERSION "\n" "usage: randomseries filename [-v] [-t type] [-o]" "\n" - " [-nseries n] [-nsamples n]" "\n" + " [-nseries n] [-nsamples n] [-dt v]" "\n" " [-std v] [-mean v] [-seed n]" "\n" " or: randomseries --help|-h" "\n" - " or: randomseries --help|-h" "\n" " or: randomseries --xhelp[=type]\n" }; @@ -46,8 +64,13 @@ int main(int iargc, char* argv[]) char help_text[]= { "-help print description\n" - "-xhelp[=type] print detailed information regarding file formats\n" - " if 'type' is specified, just print text for file format 'type'\n" + "-xhelp[=type] print detailed information\n" + " if 'type' is not specfied, or equals 'all', print\n" + " information regarding all supported file formats\n" + " if 'type' is specified, just print text for file\n" + " format 'type'\n" + " if 'type' is 'gslrng' print recommendations regarding\n" + " random number generator type\n" "\n" "filename name of output file\n" "-v be verbose\n" @@ -55,9 +78,22 @@ int main(int iargc, char* argv[]) "-t type select output file type\n" "-nseries n produce 'n' time series\n" "-nsamples n produce 'n' samples per series\n" + "-dt v set sampling interval to 'v' seconds\n" "-seed n initialize random number generator with 'n'\n" "-std v set standard deviation to 'v'\n" "-mean v set mean value of samples to 'v'\n" + "\n" + "The program uses the GSL (GNU Scientific Library) random number\n" + "generators. See https://www.gnu.org/software/gsl/doc/html/rng.html\n" + "\n" + "The programs main purpose is to provide several time series\n" + "which are incoherent (as far as possible). All samples are taken\n" + "sequentially from the random number generator with the generator\n" + "being seeded only at the very beginning. If several (incoherent)\n" + "time series should be computed by individual calls to a random\n" + "number generator program, this would require careful seeding\n" + "for each program invocation to make sure that different sequences\n" + "of samples are indeed independent or at least incoherent.\n" }; // define commandline options @@ -77,13 +113,17 @@ int main(int iargc, char* argv[]) // 5: select output file type {"nsamples",arg_yes,"10000"}, // 6: select output file type - {"seed",arg_yes,"1"}, + {"seed",arg_yes,"0"}, // 7: select output file type {"std",arg_yes,"1."}, // 8: select output file type {"mean",arg_yes,"0."}, // 9: output file format {"xhelp",arg_opt,"all"}, + // 10: output file format + {"rngtype",arg_yes,"default"}, + // 11: sampling interval + {"dt",arg_yes,"1."}, {NULL} }; @@ -119,6 +159,13 @@ int main(int iargc, char* argv[]) { datrw::online_help(cerr); } + else if (cmdline.string_arg(9) == "gslrng") + { + cerr << tfxx::numeric::RNGgaussian::comment_gsl_rng_ranlux << endl; + cerr << endl; + cerr << "Available random number generator types:" << endl; + tfxx::numeric::RNGgaussian::rng_list_types(cerr); + } else { datrw::online_help(cmdline.string_arg(9), cerr); @@ -126,27 +173,85 @@ int main(int iargc, char* argv[]) exit(0); } - // dummy operation: print option settings - for (int iopt=0; iopt<2; iopt++) + TFXX_assert(cmdline.extra(), "Missing file name"); + + // extract command line options + Options opt; + + opt.filename=cmdline.next(); + opt.verbose=cmdline.optset(1); + opt.overwrite=cmdline.optset(2); + opt.filetype=cmdline.string_arg(3); + opt.nseries=cmdline.int_arg(4); + opt.nsamples=cmdline.int_arg(5); + opt.seed=cmdline.int_arg(6); + opt.std=cmdline.double_arg(7); + opt.mean=cmdline.double_arg(8); + opt.rngtype=cmdline.string_arg(10); + opt.dt=cmdline.double_arg(11); + + // check parameters + TFXX_assert(opt.nseries>0, "number of series must be positive"); + TFXX_assert(opt.nsamples>0, "number of samples must be positive"); + TFXX_assert(opt.seed>=0, "number of samples must be non-negative"); + TFXX_assert(opt.dt>0, "sampling interval must be positive"); + + if (opt.verbose) + { + cout << RANDOMSERIES_VERSION << endl; + } + + // open output file + if (opt.verbose) + { + cout << "open output file " << opt.filename + << " with format " << opt.filetype << endl; + } + if (!opt.overwrite) { datrw::abort_if_exists(opt.filename); } + std::ofstream ofs(opt.filename.c_str(), + datrw::oanystream::openmode(opt.filetype)); + datrw::oanystream os(ofs, opt.filetype); + + // create random number generator + tfxx::numeric::RNGgaussian rng(opt.std, opt.mean, opt.rngtype.c_str()); + + if (opt.verbose) { - cout << "option: '" << options[iopt].opt_string << "'" << endl; - if (cmdline.optset(iopt)) { cout << " option was set"; } - else { cout << "option was not set"; } - cout << endl; - cout << " argument (string): '" << cmdline.string_arg(iopt) << "'" << endl; - cout << " argument (int): '" << cmdline.int_arg(iopt) << "'" << endl; - cout << " argument (long): '" << cmdline.long_arg(iopt) << "'" << endl; - cout << " argument (float): '" << cmdline.float_arg(iopt) << "'" << endl; - cout << " argument (double): '" << cmdline.double_arg(iopt) << "'" << endl; - cout << " argument (bool): '"; - if (cmdline.bool_arg(iopt)) - { cout << "true"; } else { cout << "false"; } - cout << "'" << endl; + cout << "RNG parameters:\n" + << " type: " << rng.type() << "\n" + << " seed: " << rng.seed() << "\n" + << " mean: " << rng.mean() << "\n" + << " std: " << rng.std() << endl; + cout << "produce " << opt.nseries << " traces with " + << opt.nsamples << " samples each" << endl; + cout << "set sampling interval to " << opt.dt << " seconds" << endl; } - while (cmdline.extra()) { cout << cmdline.next() << endl; } - // dummy operation: print rest of command line - while (cmdline.extra()) { cout << cmdline.next() << endl; } + sff::WID2 wid2; + wid2.nsamples=opt.nsamples; + wid2.instype=opt.rngtype; + wid2.station="RNG"; + wid2.dt=opt.dt; + + aff::Series series(opt.nsamples); + for (int iseries=0; iseries > CS(series); + while (CS.valid()) + { + *CS = rng.value(); + ++CS; + } + std::ostringstream oss; + oss << iseries+1; + wid2.channel=oss.str(); + os << wid2; + os << series; + } } /* ----- END OF randomseries.cc ----- */ -- GitLab