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_DISCRETE 00013 #define _H_SST_CORE_RNG_DISCRETE 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 SSTDiscreteDistribution discrete.h "sst/core/rng/discrete.h" 00027 00028 Creates a discrete distribution for use within SST. This distribution is the same across 00029 platforms and compilers. 00030 */ 00031 class SSTDiscreteDistribution : public SSTRandomDistribution { 00032 00033 public: 00034 /** 00035 Creates an exponential distribution with a specific lambda 00036 \param lambda The lambda of the exponential distribution 00037 */ 00038 SSTDiscreteDistribution(const double* probs, const uint32_t probsCount) : 00039 SSTRandomDistribution(), 00040 probCount(probsCount) { 00041 00042 probabilities = (double*) malloc(sizeof(double) * probsCount); 00043 double prob_sum = 0; 00044 00045 for(uint32_t i = 0; i < probsCount; i++) { 00046 probabilities[i] = prob_sum; 00047 prob_sum += probs[i]; 00048 } 00049 00050 baseDistrib = new MersenneRNG(); 00051 deleteDistrib = true; 00052 } 00053 00054 /** 00055 Creates an exponential distribution with a specific lambda and a base random number generator 00056 \param lambda The lambda of the exponential distribution 00057 \param baseDist The base random number generator to take the distribution from. 00058 */ 00059 SSTDiscreteDistribution(const double* probs, const uint32_t probsCount, SSTRandom* baseDist) : 00060 probCount(probsCount) { 00061 00062 probabilities = (double*) malloc(sizeof(double) * probsCount); 00063 double prob_sum = 0; 00064 00065 for(uint32_t i = 0; i < probsCount; i++) { 00066 probabilities[i] = prob_sum; 00067 prob_sum += probs[i]; 00068 } 00069 00070 baseDistrib = baseDist; 00071 deleteDistrib = false; 00072 } 00073 00074 /** 00075 Destroys the exponential distribution 00076 */ 00077 ~SSTDiscreteDistribution() { 00078 free(probabilities); 00079 00080 if(deleteDistrib) { 00081 delete baseDistrib; 00082 } 00083 } 00084 00085 /** 00086 Gets the next (random) double value in the distribution 00087 \return The next random double from the discrete distribution, this is the double converted of the index where the probability is located 00088 */ 00089 double getNextDouble() { 00090 const double nextD = baseDistrib->nextUniform(); 00091 00092 uint32_t index = 0; 00093 00094 for(; index < probCount; index++) { 00095 if(probabilities[index] >= nextD) { 00096 break; 00097 } 00098 } 00099 00100 return (double) index; 00101 } 00102 00103 protected: 00104 /** 00105 Sets the base random number generator for the distribution. 00106 */ 00107 SSTRandom* baseDistrib; 00108 00109 /** 00110 Controls whether the base distribution should be deleted when this class is destructed. 00111 */ 00112 bool deleteDistrib; 00113 00114 /** 00115 The discrete probability list 00116 */ 00117 double* probabilities; 00118 00119 /** 00120 Count of discrete probabilities 00121 */ 00122 uint32_t probCount; 00123 00124 }; 00125 00126 } 00127 } 00128 00129 #endif