00001 // Copyright 2009-2015 Sandia Corporation. Under the terms 00002 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. 00003 // Government retains certain rights in this software. 00004 // 00005 // Copyright (c) 2009-2015, Sandia Corporation 00006 // All rights reserved. 00007 // 00008 // This file is part of the SST software package. For license 00009 // information, see the LICENSE file in the top level directory of the 00010 // distribution. 00011 00012 #ifndef _H_SST_CORE_RNG_GAUSSIAN 00013 #define _H_SST_CORE_RNG_GAUSSIAN 00014 00015 #include "math.h" 00016 00017 #include "distrib.h" 00018 #include "mersenne.h" 00019 00020 using namespace SST::RNG; 00021 00022 namespace SST { 00023 namespace RNG { 00024 00025 /** 00026 \class SSTGaussianDistribution gaussian.h "sst/core/rng/gaussian.h" 00027 00028 Creates a Gaussian (normal) distribution for which to sample 00029 */ 00030 class SSTGaussianDistribution : public SSTRandomDistribution { 00031 00032 public: 00033 /** 00034 Creates a new distribution with a predefined random number generator with a specified mean and standard deviation. 00035 \param mn The mean of the Gaussian distribution 00036 \param sd The standard deviation of the Gaussian distribution 00037 */ 00038 SSTGaussianDistribution(double mn, double sd) : 00039 SSTRandomDistribution() { 00040 00041 mean = mn; 00042 stddev = sd; 00043 00044 baseDistrib = new MersenneRNG(); 00045 unusedPair = 0; 00046 usePair = false; 00047 deleteDistrib = true; 00048 } 00049 00050 /** 00051 Creates a new distribution with a predefined random number generator with a specified mean and standard deviation. 00052 \param mn The mean of the Gaussian distribution 00053 \param sd The standard deviation of the Gaussian distribution 00054 \param baseRNG The random number generator as the base of the distribution 00055 */ 00056 SSTGaussianDistribution(double mn, double sd, SSTRandom* baseRNG) : 00057 SSTRandomDistribution() { 00058 00059 mean = mn; 00060 stddev = sd; 00061 00062 baseDistrib = baseRNG; 00063 unusedPair = 0; 00064 usePair = false; 00065 deleteDistrib = false; 00066 } 00067 00068 /** 00069 Destroys the Gaussian distribution. 00070 */ 00071 ~SSTGaussianDistribution() { 00072 if(deleteDistrib) { 00073 delete baseDistrib; 00074 } 00075 } 00076 00077 /** 00078 Gets the next double value in the distributon 00079 \return The next double value of the distribution (in this case a Gaussian distribution) 00080 */ 00081 double getNextDouble() { 00082 if(usePair) { 00083 usePair = false; 00084 return unusedPair; 00085 } else { 00086 double gauss_u, gauss_v, sq_sum; 00087 00088 do { 00089 gauss_u = baseDistrib->nextUniform(); 00090 gauss_v = baseDistrib->nextUniform(); 00091 sq_sum = (gauss_u * gauss_u) + (gauss_v * gauss_v); 00092 } while(sq_sum >= 1 || sq_sum == 0); 00093 00094 if(baseDistrib->nextUniform() < 0.5) { 00095 gauss_u *= -1.0; 00096 } 00097 00098 if(baseDistrib->nextUniform() < 0.5) { 00099 gauss_v *= -1.0; 00100 } 00101 00102 double multipler = sqrt(-2.0 * log(sq_sum) / sq_sum); 00103 unusedPair = mean + stddev * gauss_v * multipler; 00104 usePair = true; 00105 00106 return mean + stddev * gauss_u * multipler; 00107 } 00108 } 00109 00110 /** 00111 Gets the mean of the distribution 00112 \return The mean of the Guassian distribution 00113 */ 00114 double getMean() { 00115 return mean; 00116 } 00117 00118 /** 00119 Gets the standard deviation of the distribution 00120 \return The standard deviation of the Gaussian distribution 00121 */ 00122 double getStandardDev() { 00123 return stddev; 00124 } 00125 00126 protected: 00127 /** 00128 The mean of the Gaussian distribution 00129 */ 00130 double mean; 00131 /** 00132 The standard deviation of the Gaussian distribution 00133 */ 00134 double stddev; 00135 /** 00136 The base random number generator for the distribution 00137 */ 00138 SSTRandom* baseDistrib; 00139 /** 00140 Random numbers for the distribution are read in pairs, this stores the second of the pair 00141 */ 00142 double unusedPair; 00143 /** 00144 Random numbers for the distribution are read in pairs, this tells the code to use the second of the pair 00145 */ 00146 bool usePair; 00147 00148 /** 00149 Controls whether the destructor deletes the distribution (we need to ensure we do this IF we created the distribution) 00150 */ 00151 bool deleteDistrib; 00152 }; 00153 00154 } 00155 } 00156 00157 #endif