LCOV - code coverage report
Current view: top level - tools - Random.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 45 80 56.2 %
Date: 2018-12-19 07:49:13 Functions: 7 12 58.3 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2012-2018 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             : 
      28             : namespace PLMD {
      29             : 
      30             : const double Random::fact=5.9604644775390625e-8;     /* 1 / 2^24  */
      31             : const double Random::EPS=3.0e-16;
      32             : const double Random::AM=1.0/IM;
      33             : const double Random::RNMX=(1.0-EPS); // 1.0-EPS;
      34         841 : const std::string Random::noname="noname";
      35             : 
      36        1461 : Random::Random(const std::string & name):
      37             :   switchGaussian(false),
      38             :   saveGaussian(0.0),
      39             : // this is required because if a Random object is created during
      40             : // initialization than Random::noname could still be initialized.
      41             : // In practice: without this it is not possible to declare
      42             : // a static Random object without enforcing the order of the
      43             : // static constructors.
      44        1461 :   name(&name!=&noname?name:"noname")
      45             : {
      46        1461 :   iy=0;
      47        1461 :   iv[0]=0;
      48        1461 :   setSeed(0);
      49        1461 : }
      50             : 
      51        1472 : void Random::setSeed(int idum_) {
      52        1472 :   idum=idum_;
      53        1472 :   incPrec=false;
      54        1472 : }
      55             : 
      56      196335 : double Random::RandU01 ()
      57             : {
      58      196335 :   if (incPrec)
      59           0 :     return U01d();
      60             :   else
      61      196335 :     return U01();
      62             : }
      63             : 
      64             : 
      65           0 : double Random::U01d ()
      66             : {
      67             :   double u;
      68           0 :   u = U01();
      69           0 :   u += U01() * fact;
      70           0 :   return (u < 1.0) ? u : (u - 1.0);
      71             : }
      72             : 
      73             : 
      74     3932722 : double Random::U01() {
      75             :   int j,k;
      76             :   double temp;
      77     3932722 :   if (idum <= 0 || !iy) {
      78         265 :     if (-idum < 1) idum=1;
      79           7 :     else idum = -idum;
      80       10865 :     for (j=NTAB+7; j>=0; j--) {
      81       10600 :       k=idum/IQ;
      82       10600 :       idum=IA*(idum-k*IQ)-IR*k;
      83       10600 :       if (idum < 0) idum += IM;
      84       10600 :       if (j < NTAB) iv[j] = idum;
      85             :     }
      86         265 :     iy=iv[0];
      87             :   }
      88     3932722 :   k=idum/IQ;
      89     3932722 :   idum=IA*(idum-k*IQ)-IR*k;
      90     3932722 :   if (idum < 0) idum += IM;
      91     3932722 :   j=iy/NDIV;
      92     3932722 :   iy=iv[j];
      93     3932722 :   iv[j] = idum;
      94     3932722 :   if ((temp=AM*iy) > RNMX) return RNMX;
      95     3932722 :   else return temp;
      96             : }
      97             : 
      98           0 : void Random::WriteStateFull(std::ostream & out)const {
      99           0 :   out<<name<<std::endl;
     100           0 :   out<<idum<<" "<<iy;
     101           0 :   for(int i=0; i<NTAB; i++) {
     102           0 :     out<<" "<<iv[i];
     103             :   };
     104           0 :   out<<" "<<switchGaussian;
     105           0 :   out<<" "<<saveGaussian;
     106           0 :   out<<std::endl;
     107           0 : }
     108             : 
     109           0 : void Random::ReadStateFull (std::istream & in) {
     110           0 :   getline(in,name);
     111           0 :   in>>idum>>iy;
     112           0 :   for (int i = 0; i < NTAB; i++) in>>iv[i];
     113           0 :   in>>switchGaussian;
     114           0 :   in>>saveGaussian;
     115           0 : }
     116             : 
     117           0 : void Random::toString(std::string & str)const {
     118           0 :   std::ostringstream ostr;
     119           0 :   ostr<<idum<<"|"<<iy;
     120           0 :   for(int i=0; i<NTAB; i++) {
     121           0 :     ostr<<"|"<<iv[i];
     122             :   };
     123           0 :   str=ostr.str();
     124           0 : }
     125             : 
     126           0 : void Random::fromString(const std::string & str) {
     127           0 :   std::string s=str;
     128           0 :   for(unsigned i=0; i<s.length(); i++) if(s[i]=='|') s[i]=' ';
     129           0 :   std::istringstream istr(s.c_str());
     130           0 :   istr>>idum>>iy;
     131           0 :   for (int i = 0; i < NTAB; i++) istr>>iv[i];
     132           0 : }
     133             : 
     134             : // This allows to have the same stream of random numbers
     135             : // with different compilers:
     136             : #ifdef __INTEL_COMPILER
     137             : #pragma intel optimization_level 0
     138             : #endif
     139             : 
     140      154287 : double Random::Gaussian() {
     141             :   double v1,v2,rsq;
     142      154287 :   if(switchGaussian) {
     143       77143 :     switchGaussian=false;
     144       77143 :     return saveGaussian;
     145             :   }
     146             :   while(true) {
     147       98167 :     v1=2.0*RandU01()-1.0;
     148       98167 :     v2=2.0*RandU01()-1.0;
     149       98167 :     rsq=v1*v1+v2*v2;
     150       98167 :     if(rsq<1.0 && rsq>0.0) break;
     151             :   }
     152       77144 :   double fac=sqrt(-2.*std::log(rsq)/rsq);
     153       77144 :   saveGaussian=v1*fac;
     154       77144 :   switchGaussian=true;
     155       98167 :   return v2*fac;
     156             : }
     157             : 
     158        2523 : }

Generated by: LCOV version 1.13