Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2019 Jakub Rydzewski (jr@fizyka.umk.pl). All rights reserved. 3 : 4 : See http://www.maze-code.github.io for more information. 5 : 6 : This file is part of maze. 7 : 8 : maze is free software: you can redistribute it and/or modify it under the 9 : terms of the GNU Lesser General Public License as published by the Free 10 : Software Foundation, either version 3 of the License, or (at your option) 11 : any later version. 12 : 13 : maze is distributed in the hope that it will be useful, but WITHOUT ANY 14 : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 : FOR A PARTICULAR PURPOSE. 16 : 17 : See the GNU Lesser General Public License for more details. 18 : 19 : You should have received a copy of the GNU Lesser General Public License 20 : along with maze. If not, see <https://www.gnu.org/licenses/>. 21 : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ 22 : #ifndef __PLUMED_maze_Random_MT_h 23 : #define __PLUMED_maze_Random_MT_h 24 : 25 : /** 26 : * @file Random_MT.h 27 : * 28 : * @author J. Rydzewski (jr@fizyka.umk.pl) 29 : */ 30 : 31 : #include "Core.h" 32 : 33 : namespace PLMD { 34 : namespace maze { 35 : 36 : /** 37 : * @class rnd Random_MT.h "maze/Random_MT.h" 38 : * 39 : * @brief Mersenne Twister sampler for random variables. 40 : * 41 : * Supports generating integers, doubles, and std::vectors and PLMD::Vectors 42 : * within a given range. 43 : */ 44 : class rnd { 45 : public: 46 : /** 47 : * Initialize MT sampler engine based on std::mt19937_64. 48 : */ 49 : static std::mt19937_64& mt_eng(); 50 : 51 : /** 52 : * Feed a random seed. 53 : */ 54 : static void randomize(); 55 : 56 : /** 57 : * Returns a random double from the Cauchy distribution. 58 : * 59 : * @param m mean 60 : * @param s spread 61 : */ 62 : static double next_cauchy(double m, double s); 63 : 64 : /** 65 : * Returns a random int from the uniform distribution from a [f, e) range. 66 : * 67 : * @param f begin 68 : * @param e end 69 : */ 70 : static int next_int(int f, int e); 71 : static int next_int(int e); 72 : 73 : /** 74 : * Returns a random double from the uniform distribution from a [f, e) range. 75 : */ 76 : static double next_double(double f, double e); 77 : static double next_double(double e); 78 : static double next_double(); 79 : 80 : /** 81 : * Returns a random vector<double> from the uniform distribution from a [f, e) 82 : * range of length n. 83 : */ 84 : static std::vector<double> next_double(double f, double e, std::size_t n); 85 : 86 : /** 87 : * Returns a random PLMD::Vector of length r. 88 : */ 89 : static Vector next_plmd_vector(); 90 : static Vector next_plmd_vector(double r); 91 : 92 : /** 93 : * Returns a random std::vector of length r. 94 : */ 95 : static std::vector<double> next_std_vector(); 96 : static std::vector<double> next_std_vector(double r); 97 : }; 98 : 99 66 : inline Vector rnd::next_plmd_vector(double r) { 100 66 : return next_plmd_vector() * r; 101 : } 102 : 103 : inline std::vector<double> rnd::next_std_vector(double r) { 104 : double t = next_double() * 2.0 * pi; 105 : double p = next_double() * pi; 106 : 107 : return std::vector<double> { 108 : r * std::sin(p) * std::cos(t), 109 : r * std::sin(t) * std::sin(p), 110 : r * std::cos(p) 111 : }; 112 : } 113 : 114 0 : inline std::vector<double> rnd::next_double(double f, double e, size_t n) { 115 0 : std::vector<double> t(n); 116 0 : for (std::size_t i=0; i < n; ++i) { 117 0 : t[i] = next_double(f, e); 118 : } 119 : 120 0 : return t; 121 : } 122 : 123 73 : inline Vector rnd::next_plmd_vector() { 124 73 : double t = next_double() * 2.0 * pi; 125 73 : double p = next_double() * pi; 126 : 127 : return Vector( 128 73 : std::sin(p) * std::cos(t), 129 73 : std::sin(t) * std::sin(p), 130 : std::cos(p) 131 73 : ); 132 : } 133 : 134 : inline std::vector<double> rnd::next_std_vector() { 135 : double t = next_double() * 2.0 * pi; 136 : double p = next_double() * pi; 137 : 138 : return std::vector<double> { 139 : std::sin(p) * std::cos(t), 140 : std::sin(t) * std::sin(p), 141 : std::cos(p) 142 : }; 143 : } 144 : 145 : inline double rnd::next_double(double e) { 146 246 : return next_double(0, e); 147 : } 148 : 149 7 : inline void rnd::randomize() { 150 7 : mt_eng().seed(time(0)); 151 7 : } 152 : 153 : } // namespace maze 154 : } // namespace PLMD 155 : 156 : #endif // __PLUMED_maze_Random_MT_h