LCOV - code coverage report
Current view: top level - tools - Random.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 45 81 55.6 %
Date: 2020-11-18 11:20:57 Functions: 7 13 53.8 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2012-2019 The plumed team
       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
       4             : 
       5             :    See http://www.plumed.org for more information.
       6             : 
       7             :    This file is part of plumed, version 2.
       8             : 
       9             :    plumed is free software: you can redistribute it and/or modify
      10             :    it under the terms of the GNU Lesser General Public License as published by
      11             :    the Free Software Foundation, either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    plumed is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    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 plumed.  If not, see <http://www.gnu.org/licenses/>.
      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
      22             : #include "Random.h"
      23             : #include <cmath>
      24             : #include <cstdlib>
      25             : #include <sstream>
      26             : #include <iostream>
      27             : #include <iterator>
      28             : #include <functional>
      29             : 
      30             : namespace PLMD {
      31             : 
      32             : const double Random::fact=5.9604644775390625e-8;     /* 1 / 2^24  */
      33             : const double Random::EPS=3.0e-16;
      34             : const double Random::AM=1.0/IM;
      35             : const double Random::RNMX=(1.0-EPS); // 1.0-EPS;
      36        1613 : const std::string Random::noname="noname";
      37             : 
      38        3074 : Random::Random(const std::string & name):
      39             :   switchGaussian(false),
      40             :   saveGaussian(0.0),
      41             : // this is required because if a Random object is created during
      42             : // initialization than Random::noname could still be initialized.
      43             : // In practice: without this it is not possible to declare
      44             : // a static Random object without enforcing the order of the
      45             : // static constructors.
      46        6148 :   name(&name!=&noname?name:"noname")
      47             : {
      48        3074 :   iy=0;
      49        3074 :   iv[0]=0;
      50        3074 :   setSeed(0);
      51        3074 : }
      52             : 
      53        3331 : void Random::setSeed(int idum_) {
      54        3331 :   idum=idum_;
      55        3331 :   incPrec=false;
      56        3331 : }
      57             : 
      58      269584 : double Random::RandU01 ()
      59             : {
      60      269584 :   if (incPrec)
      61           0 :     return U01d();
      62             :   else
      63      269584 :     return U01();
      64             : }
      65             : 
      66             : 
      67           0 : double Random::U01d ()
      68             : {
      69             :   double u;
      70           0 :   u = U01();
      71           0 :   u += U01() * fact;
      72           0 :   return (u < 1.0) ? u : (u - 1.0);
      73             : }
      74             : 
      75     4046460 : double Random::U01() {
      76             :   int j,k;
      77             :   double temp;
      78     4046460 :   if (idum <= 0 || !iy) {
      79         579 :     if (-idum < 1) idum=1;
      80         116 :     else idum = -idum;
      81       46899 :     for (j=NTAB+7; j>=0; j--) {
      82       23160 :       k=idum/IQ;
      83       23160 :       idum=IA*(idum-k*IQ)-IR*k;
      84       23160 :       if (idum < 0) idum += IM;
      85       23160 :       if (j < NTAB) iv[j] = idum;
      86             :     }
      87         579 :     iy=iv[0];
      88             :   }
      89     4046460 :   k=idum/IQ;
      90     4046460 :   idum=IA*(idum-k*IQ)-IR*k;
      91     4046460 :   if (idum < 0) idum += IM;
      92     4046460 :   j=iy/NDIV;
      93     4046460 :   iy=iv[j];
      94     4046460 :   iv[j] = idum;
      95     4046460 :   if ((temp=AM*iy) > RNMX) return RNMX;
      96     4046460 :   else return temp;
      97             : }
      98             : 
      99           0 : void Random::WriteStateFull(std::ostream & out)const {
     100             :   out<<name<<std::endl;
     101           0 :   out<<idum<<" "<<iy;
     102           0 :   for(int i=0; i<NTAB; i++) {
     103           0 :     out<<" "<<iv[i];
     104             :   };
     105           0 :   out<<" "<<switchGaussian;
     106           0 :   out<<" "<<saveGaussian;
     107             :   out<<std::endl;
     108           0 : }
     109             : 
     110           0 : void Random::ReadStateFull (std::istream & in) {
     111           0 :   getline(in,name);
     112           0 :   in>>idum>>iy;
     113           0 :   for (int i = 0; i < NTAB; i++) in>>iv[i];
     114           0 :   in>>switchGaussian;
     115           0 :   in>>saveGaussian;
     116           0 : }
     117             : 
     118           0 : void Random::toString(std::string & str)const {
     119           0 :   std::ostringstream ostr;
     120           0 :   ostr<<idum<<"|"<<iy;
     121           0 :   for(int i=0; i<NTAB; i++) {
     122           0 :     ostr<<"|"<<iv[i];
     123             :   };
     124           0 :   str=ostr.str();
     125           0 : }
     126             : 
     127           0 : void Random::fromString(const std::string & str) {
     128             :   std::string s=str;
     129           0 :   for(unsigned i=0; i<s.length(); i++) if(s[i]=='|') s[i]=' ';
     130           0 :   std::istringstream istr(s.c_str());
     131           0 :   istr>>idum>>iy;
     132           0 :   for (int i = 0; i < NTAB; i++) istr>>iv[i];
     133           0 : }
     134             : 
     135             : // This allows to have the same stream of random numbers
     136             : // with different compilers:
     137             : #ifdef __INTEL_COMPILER
     138             : #pragma intel optimization_level 0
     139             : #endif
     140             : 
     141      211896 : double Random::Gaussian() {
     142             :   double v1,v2,rsq;
     143      211896 :   if(switchGaussian) {
     144      105925 :     switchGaussian=false;
     145      105925 :     return saveGaussian;
     146             :   }
     147             :   while(true) {
     148      134753 :     v1=2.0*RandU01()-1.0;
     149      134753 :     v2=2.0*RandU01()-1.0;
     150      134753 :     rsq=v1*v1+v2*v2;
     151      134753 :     if(rsq<1.0 && rsq>0.0) break;
     152             :   }
     153      105971 :   double fac=sqrt(-2.*std::log(rsq)/rsq);
     154      105971 :   saveGaussian=v1*fac;
     155      105971 :   switchGaussian=true;
     156      105971 :   return v2*fac;
     157             : }
     158             : 
     159           0 : void Random::Shuffle(std::vector<unsigned>& vec) {
     160             :   std::iterator_traits<std::vector<unsigned>::iterator >::difference_type i, n;
     161             :   n = vec.end() - vec.begin();
     162           0 :   for(i=n-1; i>0; --i) {
     163           0 :     std::swap(vec[i], vec[(int)round(RandU01() * IM) % i]);
     164             :   }
     165           0 : }
     166             : 
     167             : 
     168        4839 : }

Generated by: LCOV version 1.13