From: alberto sartori Date: Tue, 9 Feb 2016 11:58:47 +0000 (+0100) Subject: added rand and rand_seed functions to FunctionParser X-Git-Tag: v8.4.0-rc2~20^2 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F2149%2Fhead;p=dealii.git added rand and rand_seed functions to FunctionParser --- diff --git a/doc/news/changes.h b/doc/news/changes.h index eb4562206c..4f2b68b021 100644 --- a/doc/news/changes.h +++ b/doc/news/changes.h @@ -512,7 +512,14 @@ inconvenience this causes. -
    +
      +
    1. New: FunctionParser now supports rand() and + rand_seed(number), which return a random value in the + range [0,1]. +
      + (Wolfgang Bangerth, Luca Heltai, Alberto Sartori, 2016/02/09) +
    2. +
    3. Fixed: FullMatrix::TmTmult for matrix multiplication used to compute wrong results for larger matrix sizes where external BLAS is called. This has been fixed. diff --git a/source/base/function_parser.cc b/source/base/function_parser.cc index badd034b01..d5ff52133e 100644 --- a/source/base/function_parser.cc +++ b/source/base/function_parser.cc @@ -16,9 +16,11 @@ #include #include +#include #include #include - +#include +#include #ifdef DEAL_II_WITH_MUPARSER DEAL_II_DISABLE_EXTRA_DIAGNOSTICS @@ -26,6 +28,8 @@ DEAL_II_DISABLE_EXTRA_DIAGNOSTICS DEAL_II_ENABLE_EXTRA_DIAGNOSTICS #else + + namespace fparser { class FunctionParser @@ -176,6 +180,36 @@ namespace internal { return erfc(value); } + + // returns a random value in the range [0,1] initializing the generator + // with the given seed + double mu_rand_seed(double seed) + { + static Threads::Mutex rand_mutex; + Threads::Mutex::ScopedLock lock(rand_mutex); + + static boost::random::uniform_real_distribution<> uniform_distribution(0,1); + + // for each seed an unique random number generator is created, + // which is initialized with the seed itself + static std::map rng_map; + + if (rng_map.find(seed) == rng_map.end()) + rng_map[seed] = boost::random::mt19937(static_cast(seed)); + + return uniform_distribution(rng_map[seed]); + } + + // returns a random value in the range [0,1] + double mu_rand() + { + static Threads::Mutex rand_mutex; + Threads::Mutex::ScopedLock lock(rand_mutex); + static boost::random::uniform_real_distribution<> uniform_distribution(0,1); + static boost::random::mt19937 rng(static_cast(std::time(0))); + return uniform_distribution(rng); + } + } @@ -215,6 +249,8 @@ void FunctionParser:: init_muparser() const fp.get()[component].DefineFun("log", internal::mu_log, true); fp.get()[component].DefineFun("pow", internal::mu_pow, true); fp.get()[component].DefineFun("erfc", internal::mu_erfc, true); + fp.get()[component].DefineFun("rand_seed", internal::mu_rand_seed, true); + fp.get()[component].DefineFun("rand", internal::mu_rand, true); try { @@ -265,7 +301,9 @@ void FunctionParser:: init_muparser() const "floor", "sec", "pow", - "erfc" + "erfc", + "rand", + "rand_seed" }; for (unsigned int f=0; f +#include +#include +#include +#include +#include +#include + + +double eval(const std::string &exp) +{ + std::string variables = "x,y"; + std::map constants; + + FunctionParser<2> fp(1); + fp.initialize(variables, + exp, + constants); + + Point<2> p; + + return fp.value(p); +} + + +int main() +{ + initlog(); + + double random = eval("rand()"); //random seed + + if (0.0 <= random && random <= 1.0) + deallog << "OK" << std::endl; + + deallog << eval("rand_seed(10)") << std::endl; + +} diff --git a/tests/base/function_parser_09.output b/tests/base/function_parser_09.output new file mode 100644 index 0000000000..59f845a429 --- /dev/null +++ b/tests/base/function_parser_09.output @@ -0,0 +1,3 @@ + +DEAL::OK +DEAL::0.771321