RandomNumberGenerator.cpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2009
00004 
00005 University of Oxford means the Chancellor, Masters and Scholars of the
00006 University of Oxford, having an administrative office at Wellington
00007 Square, Oxford OX1 2JD, UK.
00008 
00009 This file is part of Chaste.
00010 
00011 Chaste is free software: you can redistribute it and/or modify it
00012 under the terms of the GNU Lesser General Public License as published
00013 by the Free Software Foundation, either version 2.1 of the License, or
00014 (at your option) any later version.
00015 
00016 Chaste is distributed in the hope that it will be useful, but WITHOUT
00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00019 License for more details. The offer of Chaste under the terms of the
00020 License is subject to the License being interpreted in accordance with
00021 English Law and subject to any action against the University of Oxford
00022 being under the jurisdiction of the English Courts.
00023 
00024 You should have received a copy of the GNU Lesser General Public License
00025 along with Chaste. If not, see <http://www.gnu.org/licenses/>.
00026 
00027 */
00028 
00029 
00030 #include "RandomNumberGenerator.hpp"
00031 
00032 
00034 RandomNumberGenerator* RandomNumberGenerator::mpInstance = NULL;
00035 
00040 RandomNumberGenerator* RandomNumberGenerator::Instance()
00041 {
00042     if (mpInstance == NULL)
00043     {
00044         mpInstance = new RandomNumberGenerator();
00045     }
00046     return mpInstance;
00047 }
00048 
00056 void RandomNumberGenerator::Destroy()
00057 {
00058     if (mpInstance)
00059     {
00060         delete mpInstance;
00061         mpInstance = NULL;
00062     }
00063 }
00064 
00069 unsigned RandomNumberGenerator::randMod(unsigned base)
00070 {
00071     mTimesCalled++;
00072     return (random()%base);
00073 }
00074 
00078 double RandomNumberGenerator::ranf(void)
00079 {
00080     mTimesCalled++;
00081     return (double)random() / RAND_MAX;
00082 }
00083 
00088 double RandomNumberGenerator::NormalRandomDeviate(double mean, double sd)
00089 {
00090     return sd * StandardNormalRandomDeviate() + mean;
00091 }
00092 
00093 
00100 void RandomNumberGenerator::Shuffle(unsigned num, std::vector<unsigned>& rValues)
00101 {
00102     rValues.resize(num);
00103     for (unsigned i=0; i<num; i++)
00104     {
00105         rValues[i] = i;
00106     }
00107         
00108     for (unsigned end=num; end>0; end--)
00109     {
00110         // Pick a random integer from {0,..,end-1}
00111         unsigned k = RandomNumberGenerator::Instance()->randMod(end); 
00112         unsigned temp = rValues[end-1];
00113         rValues[end-1] = rValues[k];
00114         rValues[k] = temp;
00115     }
00116 }     
00117 
00118 
00146 double RandomNumberGenerator::StandardNormalRandomDeviate(void)
00147 {
00148     static double a[32] =
00149         {
00150             0.0,3.917609E-2,7.841241E-2,0.11777,0.1573107,0.1970991,0.2372021,0.2776904,
00151             0.3186394,0.36013,0.4022501,0.4450965,0.4887764,0.5334097,0.5791322,
00152             0.626099,0.6744898,0.7245144,0.7764218,0.8305109,0.8871466,0.9467818,
00153             1.00999,1.077516,1.150349,1.229859,1.318011,1.417797,1.534121,1.67594,
00154             1.862732,2.153875
00155         };
00156     static double d[31] =
00157         {
00158             0.0,0.0,0.0,0.0,0.0,0.2636843,0.2425085,0.2255674,0.2116342,0.1999243,
00159             0.1899108,0.1812252,0.1736014,0.1668419,0.1607967,0.1553497,0.1504094,
00160             0.1459026,0.14177,0.1379632,0.1344418,0.1311722,0.128126,0.1252791,
00161             0.1226109,0.1201036,0.1177417,0.1155119,0.1134023,0.1114027,0.1095039
00162         };
00163     static double t[31] =
00164         {
00165             7.673828E-4,2.30687E-3,3.860618E-3,5.438454E-3,7.0507E-3,8.708396E-3,
00166             1.042357E-2,1.220953E-2,1.408125E-2,1.605579E-2,1.81529E-2,2.039573E-2,
00167             2.281177E-2,2.543407E-2,2.830296E-2,3.146822E-2,3.499233E-2,3.895483E-2,
00168             4.345878E-2,4.864035E-2,5.468334E-2,6.184222E-2,7.047983E-2,8.113195E-2,
00169             9.462444E-2,0.1123001,0.136498,0.1716886,0.2276241,0.330498,0.5847031
00170         };
00171     static double h[31] =
00172         {
00173             3.920617E-2,3.932705E-2,3.951E-2,3.975703E-2,4.007093E-2,4.045533E-2,
00174             4.091481E-2,4.145507E-2,4.208311E-2,4.280748E-2,4.363863E-2,4.458932E-2,
00175             4.567523E-2,4.691571E-2,4.833487E-2,4.996298E-2,5.183859E-2,5.401138E-2,
00176             5.654656E-2,5.95313E-2,6.308489E-2,6.737503E-2,7.264544E-2,7.926471E-2,
00177             8.781922E-2,9.930398E-2,0.11556,0.1404344,0.1836142,0.2790016,0.7010474
00178         };
00179 
00180     // this code does not have to be covered, being written by someone else and containing
00181     // goto's anyway..
00182     #define COVERAGE_IGNORE
00183 
00184     static long i;
00185     static double snorm,u,s,ustar,aa,w,y,tt;
00186     u = ranf();
00187     s = 0.0;
00188     if (u > 0.5) s = 1.0;
00189     u += (u-s);
00190     u = 32.0*u;
00191     i = (long) (u);
00192     if (i == 32) i = 31;
00193     if (i == 0) goto S100;
00194     /*
00195                                     START CENTER
00196     */
00197     ustar = u-(double)i;
00198     aa = *(a+i-1);
00199 S40:
00200     if (ustar <= *(t+i-1)) goto S60;
00201     w = (ustar-*(t+i-1))**(h+i-1);
00202 S50:
00203     /*
00204                                     EXIT   (BOTH CASES)
00205     */
00206     y = aa+w;
00207     snorm = y;
00208     if (s == 1.0) snorm = -y;
00209     return snorm;
00210 S60:
00211     /*
00212                                     CENTER CONTINUED
00213     */
00214     u = ranf();
00215     w = u*(*(a+i)-aa);
00216     tt = (0.5*w+aa)*w;
00217     goto S80;
00218 S70:
00219     tt = u;
00220     ustar = ranf();
00221 S80:
00222     if (ustar > tt) goto S50;
00223     u = ranf();
00224     if (ustar >= u) goto S70;
00225     ustar = ranf();
00226     goto S40;
00227 S100:
00228     /*
00229                                     START TAIL
00230     */
00231     i = 6;
00232     aa = *(a+31);
00233     goto S120;
00234 S110:
00235     aa += *(d+i-1);
00236     i += 1;
00237 S120:
00238     u += u;
00239     if (u < 1.0) goto S110;
00240     u -= 1.0;
00241 S140:
00242     w = u**(d+i-1);
00243     tt = (0.5*w+aa)*w;
00244     goto S160;
00245 S150:
00246     tt = u;
00247 S160:
00248     ustar = ranf();
00249     if (ustar > tt) goto S50;
00250     u = ranf();
00251     if (ustar >= u) goto S150;
00252     u = ranf();
00253     goto S140;
00254     #undef COVERAGE_IGNORE
00255 }

Generated on Wed Mar 18 12:51:50 2009 for Chaste by  doxygen 1.5.5