Chaste Release::3.1
RandomNumberGenerator.hpp
00001 /*
00002 
00003 Copyright (c) 2005-2012, University of Oxford.
00004 All rights reserved.
00005 
00006 University of Oxford means the Chancellor, Masters and Scholars of the
00007 University of Oxford, having an administrative office at Wellington
00008 Square, Oxford OX1 2JD, UK.
00009 
00010 This file is part of Chaste.
00011 
00012 Redistribution and use in source and binary forms, with or without
00013 modification, are permitted provided that the following conditions are met:
00014  * Redistributions of source code must retain the above copyright notice,
00015    this list of conditions and the following disclaimer.
00016  * Redistributions in binary form must reproduce the above copyright notice,
00017    this list of conditions and the following disclaimer in the documentation
00018    and/or other materials provided with the distribution.
00019  * Neither the name of the University of Oxford nor the names of its
00020    contributors may be used to endorse or promote products derived from this
00021    software without specific prior written permission.
00022 
00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033 
00034 */
00035 
00036 #ifndef RANDOMNUMBERGENERATORS_HPP_
00037 #define RANDOMNUMBERGENERATORS_HPP_
00038 
00039 #include <boost/shared_ptr.hpp>
00040 
00041 #include "ChasteSerialization.hpp"
00042 #include "SerializableSingleton.hpp"
00043 #include <boost/serialization/split_member.hpp>
00044 
00049 class RandomNumberGenerator : public SerializableSingleton<RandomNumberGenerator>
00050 {
00051 private:
00052 
00054     int mSeed;
00055 
00057     long unsigned mTimesCalled;
00058 
00060     static RandomNumberGenerator* mpInstance;
00061 
00063     double mWorkingMem1;
00064 
00066     double mWorkingMem2;
00067 
00069     double mWorkingMemW;
00070 
00072     double mRandNum2;
00073 
00075     bool mUseLastNum;
00076 
00077     friend class boost::serialization::access;
00087     template<class Archive>
00088     void save(Archive & archive, const unsigned int version) const
00089     {
00090         archive & mSeed;
00091         archive & mTimesCalled;
00092         archive & mUseLastNum;
00093         archive & mRandNum2;
00094     }
00095 
00105     template<class Archive>
00106     void load(Archive & archive, const unsigned int version)
00107     {
00108         archive & mSeed;
00109         archive & mTimesCalled;
00110         archive & mUseLastNum;
00111         archive & mRandNum2;
00112 
00113         // Reset the random number generator to use the correct seed
00114         srandom(mSeed);
00115 
00116         /*
00117          * Call it the correct number of times to put it in the same state
00118          * as it used to be.
00119          */
00120         for (long unsigned i=0; i<mTimesCalled; i++)
00121         {
00122             random();
00123         }
00124     }
00125     BOOST_SERIALIZATION_SPLIT_MEMBER()
00126 
00127 protected:
00128 
00133     RandomNumberGenerator();
00134 
00135 public:
00136 
00146     double StandardNormalRandomDeviate();
00147 
00155     double NormalRandomDeviate(double mean, double sd);
00156 
00160     double ranf();
00161 
00168     unsigned randMod(unsigned base);
00169 
00170 
00179     template <class T>
00180     void Shuffle(std::vector<boost::shared_ptr<T> >& rValues)
00181     {
00182         unsigned num = rValues.size();
00183         if (num == 0)
00184         {
00185             return;
00186         }
00187         for (unsigned end=num-1; end>0; end--)
00188         {
00189             // Pick a random integer from {0,..,end}
00190             unsigned k = RandomNumberGenerator::Instance()->randMod(end+1);
00191             boost::shared_ptr<T> temp = rValues[end];
00192             rValues[end] = rValues[k];
00193             rValues[k] = temp;
00194         }
00195     }
00205     void Shuffle(unsigned num, std::vector<unsigned>& rValues);
00206 
00211     static RandomNumberGenerator* Instance();
00212 
00219     static void Destroy();
00220 
00226     void Reseed(int seed);
00227 };
00228 
00229 #endif /*RANDOMNUMBERGENERATORS_HPP_*/