|
|
| 30 |
#include <fcntl.h> |
30 |
#include <fcntl.h> |
| 31 |
|
31 |
|
| 32 |
|
32 |
|
|
|
33 |
#include "assert.h" |
| 33 |
#include "random-variable.h" |
34 |
#include "random-variable.h" |
| 34 |
#include "rng-stream.h" |
35 |
#include "rng-stream.h" |
| 35 |
#include "fatal-error.h" |
36 |
#include "fatal-error.h" |
|
|
| 40 |
|
41 |
|
| 41 |
//----------------------------------------------------------------------------- |
42 |
//----------------------------------------------------------------------------- |
| 42 |
//----------------------------------------------------------------------------- |
43 |
//----------------------------------------------------------------------------- |
| 43 |
// RandomVariable methods |
44 |
// RandomVariableBase methods |
| 44 |
|
45 |
|
| 45 |
bool RandomVariable::initialized = false; // True if RngStream seed set |
46 |
|
| 46 |
bool RandomVariable::useDevRandom = false; // True if use /dev/random |
47 |
class RandomVariableBase |
| 47 |
bool RandomVariable::globalSeedSet = false; // True if GlobalSeed called |
48 |
{ |
| 48 |
int RandomVariable::devRandom = -1; |
49 |
public: |
| 49 |
uint32_t RandomVariable::globalSeed[6]; |
50 |
RandomVariableBase (); |
| 50 |
unsigned long RandomVariable::heuristic_sequence; |
51 |
RandomVariableBase (const RandomVariableBase &o); |
| 51 |
RngStream* RandomVariable::m_static_generator = 0; |
52 |
virtual ~RandomVariableBase(); |
| 52 |
uint32_t RandomVariable::runNumber = 0; |
53 |
virtual double GetValue() = 0; |
|
|
54 |
virtual uint32_t GetIntValue(); |
| 55 |
virtual RandomVariableBase* Copy(void) const = 0; |
| 56 |
virtual void GetSeed(uint32_t seed[6]); |
| 57 |
|
| 58 |
static void UseDevRandom(bool udr = true); |
| 59 |
static void UseGlobalSeed(uint32_t s0, uint32_t s1, uint32_t s2, |
| 60 |
uint32_t s3, uint32_t s4, uint32_t s5); |
| 61 |
static void SetRunNumber(uint32_t n); |
| 62 |
private: |
| 63 |
static void GetRandomSeeds(uint32_t seeds[6]); |
| 64 |
private: |
| 65 |
static bool useDevRandom; // True if using /dev/random desired |
| 66 |
static bool globalSeedSet; // True if global seed has been specified |
| 67 |
static int devRandom; // File handle for /dev/random |
| 68 |
static uint32_t globalSeed[6]; // The global seed to use |
| 69 |
friend class RandomVariableInitializer; |
| 70 |
protected: |
| 71 |
static unsigned long heuristic_sequence; |
| 72 |
static RngStream* m_static_generator; |
| 73 |
static uint32_t runNumber; |
| 74 |
static void Initialize(); // Initialize the RNG system |
| 75 |
static bool initialized; // True if package seed is set |
| 76 |
RngStream* m_generator; //underlying generator being wrapped |
| 77 |
}; |
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
bool RandomVariableBase::initialized = false; // True if RngStream seed set |
| 82 |
bool RandomVariableBase::useDevRandom = false; // True if use /dev/random |
| 83 |
bool RandomVariableBase::globalSeedSet = false; // True if GlobalSeed called |
| 84 |
int RandomVariableBase::devRandom = -1; |
| 85 |
uint32_t RandomVariableBase::globalSeed[6]; |
| 86 |
unsigned long RandomVariableBase::heuristic_sequence; |
| 87 |
RngStream* RandomVariableBase::m_static_generator = 0; |
| 88 |
uint32_t RandomVariableBase::runNumber = 0; |
| 53 |
|
89 |
|
| 54 |
//the static object random_variable_initializer initializes the static members |
90 |
//the static object random_variable_initializer initializes the static members |
| 55 |
//of RandomVariable |
91 |
//of RandomVariable |
|
Lines 58-82
static class RandomVariableInitializer
|
Link Here
|
|---|
|
| 58 |
public: |
94 |
public: |
| 59 |
RandomVariableInitializer() |
95 |
RandomVariableInitializer() |
| 60 |
{ |
96 |
{ |
| 61 |
// RandomVariable::Initialize(); // sets the static package seed |
97 |
// RandomVariableBase::Initialize(); // sets the static package seed |
| 62 |
// RandomVariable::m_static_generator = new RngStream(); |
98 |
// RandomVariableBase::m_static_generator = new RngStream(); |
| 63 |
// RandomVariable::m_static_generator->InitializeStream(); |
99 |
// RandomVariableBase::m_static_generator->InitializeStream(); |
| 64 |
} |
100 |
} |
| 65 |
~RandomVariableInitializer() |
101 |
~RandomVariableInitializer() |
| 66 |
{ |
102 |
{ |
| 67 |
delete RandomVariable::m_static_generator; |
103 |
delete RandomVariableBase::m_static_generator; |
| 68 |
} |
104 |
} |
| 69 |
} random_variable_initializer; |
105 |
} random_variable_initializer; |
| 70 |
|
106 |
|
| 71 |
RandomVariable::RandomVariable() |
107 |
RandomVariableBase::RandomVariableBase() |
| 72 |
: m_generator(NULL) |
108 |
: m_generator(NULL) |
| 73 |
{ |
109 |
{ |
| 74 |
// m_generator = new RngStream(); |
110 |
// m_generator = new RngStream(); |
| 75 |
// m_generator->InitializeStream(); |
111 |
// m_generator->InitializeStream(); |
| 76 |
// m_generator->ResetNthSubstream(RandomVariable::runNumber); |
112 |
// m_generator->ResetNthSubstream(RandomVariableBase::runNumber); |
| 77 |
} |
113 |
} |
| 78 |
|
114 |
|
| 79 |
RandomVariable::RandomVariable(const RandomVariable& r) |
115 |
RandomVariableBase::RandomVariableBase(const RandomVariableBase& r) |
| 80 |
:m_generator(0) |
116 |
:m_generator(0) |
| 81 |
{ |
117 |
{ |
| 82 |
if(r.m_generator) |
118 |
if(r.m_generator) |
|
Lines 85-145
RandomVariable::RandomVariable(const Ran
|
Link Here
|
|---|
|
| 85 |
} |
121 |
} |
| 86 |
} |
122 |
} |
| 87 |
|
123 |
|
| 88 |
RandomVariable::~RandomVariable() |
124 |
RandomVariableBase::~RandomVariableBase() |
| 89 |
{ |
125 |
{ |
| 90 |
delete m_generator; |
126 |
delete m_generator; |
| 91 |
} |
127 |
} |
| 92 |
|
128 |
|
| 93 |
uint32_t RandomVariable::GetIntValue() |
129 |
uint32_t RandomVariableBase::GetIntValue() |
| 94 |
{ |
130 |
{ |
| 95 |
return (uint32_t)GetValue(); |
131 |
return (uint32_t)GetValue(); |
| 96 |
} |
132 |
} |
| 97 |
|
133 |
|
| 98 |
void RandomVariable::UseDevRandom(bool udr) |
134 |
void RandomVariableBase::UseDevRandom(bool udr) |
| 99 |
{ |
135 |
{ |
| 100 |
RandomVariable::useDevRandom = udr; |
136 |
RandomVariableBase::useDevRandom = udr; |
| 101 |
} |
137 |
} |
| 102 |
|
138 |
|
| 103 |
void RandomVariable::GetSeed(uint32_t seed[6]) |
139 |
void RandomVariableBase::GetSeed(uint32_t seed[6]) |
| 104 |
{ |
140 |
{ |
| 105 |
if(!m_generator) |
141 |
if(!m_generator) |
| 106 |
{ |
142 |
{ |
| 107 |
m_generator = new RngStream(); |
143 |
m_generator = new RngStream(); |
| 108 |
m_generator->InitializeStream(); |
144 |
m_generator->InitializeStream(); |
| 109 |
m_generator->ResetNthSubstream(RandomVariable::runNumber); |
145 |
m_generator->ResetNthSubstream(RandomVariableBase::runNumber); |
| 110 |
} |
146 |
} |
| 111 |
m_generator->GetState(seed); |
147 |
m_generator->GetState(seed); |
| 112 |
} |
148 |
} |
| 113 |
|
149 |
|
| 114 |
//----------------------------------------------------------------------------- |
150 |
//----------------------------------------------------------------------------- |
| 115 |
//----------------------------------------------------------------------------- |
151 |
//----------------------------------------------------------------------------- |
| 116 |
// RandomVariable static methods |
152 |
// RandomVariableBase static methods |
| 117 |
void RandomVariable::UseGlobalSeed(uint32_t s0, uint32_t s1, uint32_t s2, |
153 |
void RandomVariableBase::UseGlobalSeed(uint32_t s0, uint32_t s1, uint32_t s2, |
| 118 |
uint32_t s3, uint32_t s4, uint32_t s5) |
154 |
uint32_t s3, uint32_t s4, uint32_t s5) |
| 119 |
{ |
155 |
{ |
| 120 |
if (RandomVariable::globalSeedSet) |
156 |
if (RandomVariableBase::globalSeedSet) |
| 121 |
{ |
157 |
{ |
| 122 |
cerr << "Random number generator already initialized!" << endl; |
158 |
cerr << "Random number generator already initialized!" << endl; |
| 123 |
cerr << "Call to RandomVariable::UseGlobalSeed() ignored" << endl; |
159 |
cerr << "Call to RandomVariableBase::UseGlobalSeed() ignored" << endl; |
| 124 |
return; |
160 |
return; |
| 125 |
} |
161 |
} |
| 126 |
RandomVariable::globalSeed[0] = s0; |
162 |
RandomVariableBase::globalSeed[0] = s0; |
| 127 |
RandomVariable::globalSeed[1] = s1; |
163 |
RandomVariableBase::globalSeed[1] = s1; |
| 128 |
RandomVariable::globalSeed[2] = s2; |
164 |
RandomVariableBase::globalSeed[2] = s2; |
| 129 |
RandomVariable::globalSeed[3] = s3; |
165 |
RandomVariableBase::globalSeed[3] = s3; |
| 130 |
RandomVariable::globalSeed[4] = s4; |
166 |
RandomVariableBase::globalSeed[4] = s4; |
| 131 |
RandomVariable::globalSeed[5] = s5; |
167 |
RandomVariableBase::globalSeed[5] = s5; |
| 132 |
if (!RngStream::CheckSeed(RandomVariable::globalSeed)) |
168 |
if (!RngStream::CheckSeed(RandomVariableBase::globalSeed)) |
| 133 |
NS_FATAL_ERROR("Invalid seed"); |
169 |
NS_FATAL_ERROR("Invalid seed"); |
| 134 |
|
170 |
|
| 135 |
RandomVariable::globalSeedSet = true; |
171 |
RandomVariableBase::globalSeedSet = true; |
| 136 |
} |
172 |
} |
| 137 |
|
173 |
|
| 138 |
void RandomVariable::Initialize() |
174 |
void RandomVariableBase::Initialize() |
| 139 |
{ |
175 |
{ |
| 140 |
if (RandomVariable::initialized) return; // Already initialized and seeded |
176 |
if (RandomVariableBase::initialized) return; // Already initialized and seeded |
| 141 |
RandomVariable::initialized = true; |
177 |
RandomVariableBase::initialized = true; |
| 142 |
if (!RandomVariable::globalSeedSet) |
178 |
if (!RandomVariableBase::globalSeedSet) |
| 143 |
{ // No global seed, try a random one |
179 |
{ // No global seed, try a random one |
| 144 |
GetRandomSeeds(globalSeed); |
180 |
GetRandomSeeds(globalSeed); |
| 145 |
} |
181 |
} |
|
Lines 147-166
void RandomVariable::Initialize()
|
Link Here
|
|---|
|
| 147 |
RngStream::SetPackageSeed(globalSeed); |
183 |
RngStream::SetPackageSeed(globalSeed); |
| 148 |
} |
184 |
} |
| 149 |
|
185 |
|
| 150 |
void RandomVariable::GetRandomSeeds(uint32_t seeds[6]) |
186 |
void RandomVariableBase::GetRandomSeeds(uint32_t seeds[6]) |
| 151 |
{ |
187 |
{ |
| 152 |
// Check if /dev/random exists |
188 |
// Check if /dev/random exists |
| 153 |
if (RandomVariable::useDevRandom && RandomVariable::devRandom < 0) |
189 |
if (RandomVariableBase::useDevRandom && RandomVariableBase::devRandom < 0) |
| 154 |
{ |
190 |
{ |
| 155 |
RandomVariable::devRandom = open("/dev/random", O_RDONLY); |
191 |
RandomVariableBase::devRandom = open("/dev/random", O_RDONLY); |
| 156 |
} |
192 |
} |
| 157 |
if (RandomVariable::devRandom > 0) |
193 |
if (RandomVariableBase::devRandom > 0) |
| 158 |
{ // Use /dev/random |
194 |
{ // Use /dev/random |
| 159 |
while(true) |
195 |
while(true) |
| 160 |
{ |
196 |
{ |
| 161 |
for (int i = 0; i < 6; ++i) |
197 |
for (int i = 0; i < 6; ++i) |
| 162 |
{ |
198 |
{ |
| 163 |
read(RandomVariable::devRandom, &seeds[i], sizeof(seeds[i])); |
199 |
read(RandomVariableBase::devRandom, &seeds[i], sizeof(seeds[i])); |
| 164 |
} |
200 |
} |
| 165 |
if (RngStream::CheckSeed(seeds)) break; // Got a valid one |
201 |
if (RngStream::CheckSeed(seeds)) break; // Got a valid one |
| 166 |
} |
202 |
} |
|
Lines 194-398
void RandomVariable::GetRandomSeeds(uint
|
Link Here
|
|---|
|
| 194 |
} |
230 |
} |
| 195 |
} |
231 |
} |
| 196 |
|
232 |
|
| 197 |
void RandomVariable::SetRunNumber(uint32_t n) |
233 |
void RandomVariableBase::SetRunNumber(uint32_t n) |
| 198 |
{ |
234 |
{ |
| 199 |
runNumber = n; |
235 |
runNumber = n; |
| 200 |
} |
236 |
} |
| 201 |
|
237 |
|
|
|
238 |
|
| 239 |
|
| 240 |
RandomVariable::RandomVariable() |
| 241 |
: m_variable (0) |
| 242 |
{} |
| 243 |
RandomVariable::RandomVariable(const RandomVariable&o) |
| 244 |
: m_variable (o.m_variable->Copy ()) |
| 245 |
{} |
| 246 |
RandomVariable::RandomVariable (const RandomVariableBase &variable) |
| 247 |
: m_variable (variable.Copy ()) |
| 248 |
{} |
| 249 |
RandomVariable & |
| 250 |
RandomVariable::operator = (const RandomVariable &o) |
| 251 |
{ |
| 252 |
delete m_variable; |
| 253 |
m_variable = o.m_variable->Copy (); |
| 254 |
return *this; |
| 255 |
} |
| 256 |
RandomVariable::~RandomVariable() |
| 257 |
{ |
| 258 |
delete m_variable; |
| 259 |
} |
| 260 |
double |
| 261 |
RandomVariable::GetValue (void) const |
| 262 |
{ |
| 263 |
return m_variable->GetValue (); |
| 264 |
} |
| 265 |
|
| 266 |
uint32_t |
| 267 |
RandomVariable::GetIntValue (void) const |
| 268 |
{ |
| 269 |
return m_variable->GetIntValue (); |
| 270 |
} |
| 271 |
void |
| 272 |
RandomVariable::GetSeed(uint32_t seed[6]) const |
| 273 |
{ |
| 274 |
return m_variable->GetSeed (seed); |
| 275 |
} |
| 276 |
void |
| 277 |
RandomVariable::UseDevRandom(bool udr) |
| 278 |
{ |
| 279 |
RandomVariableBase::UseDevRandom (udr); |
| 280 |
} |
| 281 |
void |
| 282 |
RandomVariable::UseGlobalSeed(uint32_t s0, uint32_t s1, uint32_t s2, |
| 283 |
uint32_t s3, uint32_t s4, uint32_t s5) |
| 284 |
{ |
| 285 |
RandomVariableBase::UseGlobalSeed (s0, s1, s2, s3, s4, s5); |
| 286 |
} |
| 287 |
void |
| 288 |
RandomVariable::SetRunNumber(uint32_t n) |
| 289 |
{ |
| 290 |
RandomVariableBase::SetRunNumber (n); |
| 291 |
} |
| 292 |
RandomVariableBase * |
| 293 |
RandomVariable::Peek (void) |
| 294 |
{ |
| 295 |
return m_variable; |
| 296 |
} |
| 297 |
|
| 298 |
|
| 202 |
//----------------------------------------------------------------------------- |
299 |
//----------------------------------------------------------------------------- |
| 203 |
//----------------------------------------------------------------------------- |
300 |
//----------------------------------------------------------------------------- |
| 204 |
// UniformVariable |
301 |
// UniformVariableImpl |
| 205 |
UniformVariable::UniformVariable() |
302 |
|
|
|
303 |
class UniformVariableImpl : public RandomVariableBase { |
| 304 |
public: |
| 305 |
/** |
| 306 |
* Creates a uniform random number generator in the |
| 307 |
* range [0.0 .. 1.0). |
| 308 |
*/ |
| 309 |
UniformVariableImpl(); |
| 310 |
|
| 311 |
/** |
| 312 |
* Creates a uniform random number generator with the specified range |
| 313 |
* \param s Low end of the range |
| 314 |
* \param l High end of the range |
| 315 |
*/ |
| 316 |
UniformVariableImpl(double s, double l); |
| 317 |
|
| 318 |
UniformVariableImpl(const UniformVariableImpl& c); |
| 319 |
|
| 320 |
/** |
| 321 |
* \return A value between low and high values specified by the constructor |
| 322 |
*/ |
| 323 |
virtual double GetValue(); |
| 324 |
virtual RandomVariableBase* Copy(void) const; |
| 325 |
|
| 326 |
public: |
| 327 |
/** |
| 328 |
* \param s Low end of the range |
| 329 |
* \param l High end of the range |
| 330 |
* \return A uniformly distributed random number between s and l |
| 331 |
*/ |
| 332 |
static double GetSingleValue(double s, double l); |
| 333 |
private: |
| 334 |
double m_min; |
| 335 |
double m_max; |
| 336 |
}; |
| 337 |
|
| 338 |
UniformVariableImpl::UniformVariableImpl() |
| 206 |
: m_min(0), m_max(1.0) { } |
339 |
: m_min(0), m_max(1.0) { } |
| 207 |
|
340 |
|
| 208 |
UniformVariable::UniformVariable(double s, double l) |
341 |
UniformVariableImpl::UniformVariableImpl(double s, double l) |
| 209 |
: m_min(s), m_max(l) { } |
342 |
: m_min(s), m_max(l) { } |
| 210 |
|
343 |
|
| 211 |
UniformVariable::UniformVariable(const UniformVariable& c) |
344 |
UniformVariableImpl::UniformVariableImpl(const UniformVariableImpl& c) |
| 212 |
: RandomVariable(c), m_min(c.m_min), m_max(c.m_max) { } |
345 |
: RandomVariableBase(c), m_min(c.m_min), m_max(c.m_max) { } |
| 213 |
|
346 |
|
| 214 |
double UniformVariable::GetValue() |
347 |
double UniformVariableImpl::GetValue() |
| 215 |
{ |
348 |
{ |
| 216 |
if(!RandomVariable::initialized) |
349 |
if(!RandomVariableBase::initialized) |
| 217 |
{ |
350 |
{ |
| 218 |
RandomVariable::Initialize(); |
351 |
RandomVariableBase::Initialize(); |
| 219 |
} |
352 |
} |
| 220 |
if(!m_generator) |
353 |
if(!m_generator) |
| 221 |
{ |
354 |
{ |
| 222 |
m_generator = new RngStream(); |
355 |
m_generator = new RngStream(); |
| 223 |
m_generator->InitializeStream(); |
356 |
m_generator->InitializeStream(); |
| 224 |
m_generator->ResetNthSubstream(RandomVariable::runNumber); |
357 |
m_generator->ResetNthSubstream(RandomVariableBase::runNumber); |
| 225 |
} |
358 |
} |
| 226 |
return m_min + m_generator->RandU01() * (m_max - m_min); |
359 |
return m_min + m_generator->RandU01() * (m_max - m_min); |
| 227 |
} |
360 |
} |
| 228 |
|
361 |
|
| 229 |
RandomVariable* UniformVariable::Copy() const |
362 |
RandomVariableBase* UniformVariableImpl::Copy() const |
| 230 |
{ |
363 |
{ |
| 231 |
return new UniformVariable(*this); |
364 |
return new UniformVariableImpl(*this); |
| 232 |
} |
365 |
} |
| 233 |
|
366 |
|
| 234 |
double UniformVariable::GetSingleValue(double s, double l) |
367 |
double UniformVariableImpl::GetSingleValue(double s, double l) |
| 235 |
{ |
368 |
{ |
| 236 |
if(!RandomVariable::m_static_generator) |
369 |
if(!RandomVariableBase::m_static_generator) |
| 237 |
{ |
370 |
{ |
| 238 |
RandomVariable::Initialize(); // sets the static package seed |
371 |
RandomVariableBase::Initialize(); // sets the static package seed |
| 239 |
RandomVariable::m_static_generator = new RngStream(); |
372 |
RandomVariableBase::m_static_generator = new RngStream(); |
| 240 |
RandomVariable::m_static_generator->InitializeStream(); |
373 |
RandomVariableBase::m_static_generator->InitializeStream(); |
| 241 |
} |
374 |
} |
| 242 |
return s + m_static_generator->RandU01() * (l - s);; |
375 |
return s + m_static_generator->RandU01() * (l - s);; |
| 243 |
} |
376 |
} |
| 244 |
|
377 |
|
|
|
378 |
UniformVariable::UniformVariable() |
| 379 |
: RandomVariable (UniformVariableImpl ()) |
| 380 |
{} |
| 381 |
UniformVariable::UniformVariable(double s, double l) |
| 382 |
: RandomVariable (UniformVariableImpl (s, l)) |
| 383 |
{} |
| 384 |
double |
| 385 |
UniformVariable::GetSingleValue(double s, double l) |
| 386 |
{ |
| 387 |
return UniformVariableImpl::GetSingleValue (s, l); |
| 388 |
} |
| 389 |
|
| 390 |
|
| 245 |
//----------------------------------------------------------------------------- |
391 |
//----------------------------------------------------------------------------- |
| 246 |
//----------------------------------------------------------------------------- |
392 |
//----------------------------------------------------------------------------- |
| 247 |
// ConstantVariable methods |
393 |
// ConstantVariableImpl methods |
| 248 |
ConstantVariable::ConstantVariable() |
394 |
|
|
|
395 |
class ConstantVariableImpl : public RandomVariableBase { |
| 396 |
|
| 397 |
public: |
| 398 |
/** |
| 399 |
* Construct a ConstantVariableImpl RNG that returns zero every sample |
| 400 |
*/ |
| 401 |
ConstantVariableImpl(); |
| 402 |
|
| 403 |
/** |
| 404 |
* Construct a ConstantVariableImpl RNG that returns the specified value |
| 405 |
* every sample. |
| 406 |
* \param c Unchanging value for this RNG. |
| 407 |
*/ |
| 408 |
ConstantVariableImpl(double c); |
| 409 |
|
| 410 |
|
| 411 |
ConstantVariableImpl(const ConstantVariableImpl& c) ; |
| 412 |
|
| 413 |
/** |
| 414 |
* \brief Specify a new constant RNG for this generator. |
| 415 |
* \param c New constant value for this RNG. |
| 416 |
*/ |
| 417 |
void NewConstant(double c); |
| 418 |
|
| 419 |
/** |
| 420 |
* \return The constant value specified |
| 421 |
*/ |
| 422 |
virtual double GetValue(); |
| 423 |
virtual uint32_t GetIntValue(); |
| 424 |
virtual RandomVariableBase* Copy(void) const; |
| 425 |
private: |
| 426 |
double m_const; |
| 427 |
}; |
| 428 |
|
| 429 |
ConstantVariableImpl::ConstantVariableImpl() |
| 249 |
: m_const(0) { } |
430 |
: m_const(0) { } |
| 250 |
|
431 |
|
| 251 |
ConstantVariable::ConstantVariable(double c) |
432 |
ConstantVariableImpl::ConstantVariableImpl(double c) |
| 252 |
: m_const(c) { }; |
433 |
: m_const(c) { }; |
| 253 |
|
434 |
|
| 254 |
ConstantVariable::ConstantVariable(const ConstantVariable& c) |
435 |
ConstantVariableImpl::ConstantVariableImpl(const ConstantVariableImpl& c) |
| 255 |
: RandomVariable(c), m_const(c.m_const) { } |
436 |
: RandomVariableBase(c), m_const(c.m_const) { } |
| 256 |
|
437 |
|
| 257 |
void ConstantVariable::NewConstant(double c) |
438 |
void ConstantVariableImpl::NewConstant(double c) |
| 258 |
{ m_const = c;} |
439 |
{ m_const = c;} |
| 259 |
|
440 |
|
| 260 |
double ConstantVariable::GetValue() |
441 |
double ConstantVariableImpl::GetValue() |
| 261 |
{ |
442 |
{ |
| 262 |
return m_const; |
443 |
return m_const; |
| 263 |
} |
444 |
} |
| 264 |
|
445 |
|
| 265 |
uint32_t ConstantVariable::GetIntValue() |
446 |
uint32_t ConstantVariableImpl::GetIntValue() |
| 266 |
{ |
447 |
{ |
| 267 |
return (uint32_t)m_const; |
448 |
return (uint32_t)m_const; |
| 268 |
} |
449 |
} |
| 269 |
|
450 |
|
| 270 |
RandomVariable* ConstantVariable::Copy() const |
451 |
RandomVariableBase* ConstantVariableImpl::Copy() const |
| 271 |
{ |
452 |
{ |
| 272 |
return new ConstantVariable(*this); |
453 |
return new ConstantVariableImpl(*this); |
| 273 |
} |
|
|
| 274 |
//----------------------------------------------------------------------------- |
| 275 |
//----------------------------------------------------------------------------- |
| 276 |
// SequentialVariable methods |
| 277 |
SequentialVariable::SequentialVariable(double f, double l, double i, uint32_t c) |
| 278 |
: m_min(f), m_max(l), m_increment(ConstantVariable(i).Copy()), m_consecutive(c), |
| 279 |
m_current(f), m_currentConsecutive(0) |
| 280 |
{ |
| 281 |
} |
454 |
} |
| 282 |
|
455 |
|
| 283 |
SequentialVariable::SequentialVariable(double f, double l, const RandomVariable& i, uint32_t c) |
456 |
ConstantVariable::ConstantVariable() |
| 284 |
: m_min(f), m_max(l), m_increment(i.Copy()), m_consecutive(c), |
457 |
: RandomVariable (ConstantVariableImpl ()) |
| 285 |
m_current(f), m_currentConsecutive(0) |
458 |
{} |
|
|
459 |
ConstantVariable::ConstantVariable(double c) |
| 460 |
: RandomVariable (ConstantVariableImpl (c)) |
| 461 |
{} |
| 462 |
void |
| 463 |
ConstantVariable::SetConstant(double c) |
| 286 |
{ |
464 |
{ |
|
|
465 |
*this = ConstantVariable (c); |
| 287 |
} |
466 |
} |
| 288 |
|
467 |
|
| 289 |
SequentialVariable::SequentialVariable(const SequentialVariable& c) |
468 |
//----------------------------------------------------------------------------- |
| 290 |
: RandomVariable(c), m_min(c.m_min), m_max(c.m_max), |
469 |
//----------------------------------------------------------------------------- |
| 291 |
m_increment(c.m_increment->Copy()), m_consecutive(c.m_consecutive), |
470 |
// SequentialVariableImpl methods |
|
|
471 |
|
| 472 |
|
| 473 |
class SequentialVariableImpl : public RandomVariableBase { |
| 474 |
|
| 475 |
public: |
| 476 |
/** |
| 477 |
* \brief Constructor for the SequentialVariableImpl RNG. |
| 478 |
* |
| 479 |
* The four parameters define the sequence. For example |
| 480 |
* SequentialVariableImpl(0,5,1,2) creates a RNG that has the sequence |
| 481 |
* 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 0, 0 ... |
| 482 |
* \param f First value of the sequence. |
| 483 |
* \param l One more than the last value of the sequence. |
| 484 |
* \param i Increment between sequence values |
| 485 |
* \param c Number of times each member of the sequence is repeated |
| 486 |
*/ |
| 487 |
SequentialVariableImpl(double f, double l, double i = 1, uint32_t c = 1); |
| 488 |
|
| 489 |
/** |
| 490 |
* \brief Constructor for the SequentialVariableImpl RNG. |
| 491 |
* |
| 492 |
* Differs from the first only in that the increment parameter is a |
| 493 |
* random variable |
| 494 |
* \param f First value of the sequence. |
| 495 |
* \param l One more than the last value of the sequence. |
| 496 |
* \param i Reference to a RandomVariableBase for the sequence increment |
| 497 |
* \param c Number of times each member of the sequence is repeated |
| 498 |
*/ |
| 499 |
SequentialVariableImpl(double f, double l, const RandomVariable& i, uint32_t c = 1); |
| 500 |
|
| 501 |
SequentialVariableImpl(const SequentialVariableImpl& c); |
| 502 |
|
| 503 |
~SequentialVariableImpl(); |
| 504 |
/** |
| 505 |
* \return The next value in the Sequence |
| 506 |
*/ |
| 507 |
virtual double GetValue(); |
| 508 |
virtual RandomVariableBase* Copy(void) const; |
| 509 |
private: |
| 510 |
double m_min; |
| 511 |
double m_max; |
| 512 |
RandomVariable m_increment; |
| 513 |
uint32_t m_consecutive; |
| 514 |
double m_current; |
| 515 |
uint32_t m_currentConsecutive; |
| 516 |
}; |
| 517 |
|
| 518 |
SequentialVariableImpl::SequentialVariableImpl(double f, double l, double i, uint32_t c) |
| 519 |
: m_min(f), m_max(l), m_increment(ConstantVariable(i)), m_consecutive(c), |
| 520 |
m_current(f), m_currentConsecutive(0) |
| 521 |
{} |
| 522 |
|
| 523 |
SequentialVariableImpl::SequentialVariableImpl(double f, double l, const RandomVariable& i, uint32_t c) |
| 524 |
: m_min(f), m_max(l), m_increment(i), m_consecutive(c), |
| 525 |
m_current(f), m_currentConsecutive(0) |
| 526 |
{} |
| 527 |
|
| 528 |
SequentialVariableImpl::SequentialVariableImpl(const SequentialVariableImpl& c) |
| 529 |
: RandomVariableBase(c), m_min(c.m_min), m_max(c.m_max), |
| 530 |
m_increment(c.m_increment), m_consecutive(c.m_consecutive), |
| 292 |
m_current(c.m_current), m_currentConsecutive(c.m_currentConsecutive) |
531 |
m_current(c.m_current), m_currentConsecutive(c.m_currentConsecutive) |
| 293 |
{ |
532 |
{} |
| 294 |
} |
|
|
| 295 |
|
533 |
|
| 296 |
SequentialVariable::~SequentialVariable() |
534 |
SequentialVariableImpl::~SequentialVariableImpl() |
| 297 |
{ |
535 |
{} |
| 298 |
delete m_increment; |
|
|
| 299 |
} |
| 300 |
|
536 |
|
| 301 |
double SequentialVariable::GetValue() |
537 |
double SequentialVariableImpl::GetValue() |
| 302 |
{ // Return a sequential series of values |
538 |
{ // Return a sequential series of values |
| 303 |
double r = m_current; |
539 |
double r = m_current; |
| 304 |
if (++m_currentConsecutive == m_consecutive) |
540 |
if (++m_currentConsecutive == m_consecutive) |
| 305 |
{ // Time to advance to next |
541 |
{ // Time to advance to next |
| 306 |
m_currentConsecutive = 0; |
542 |
m_currentConsecutive = 0; |
| 307 |
m_current += m_increment->GetValue(); |
543 |
m_current += m_increment.GetValue(); |
| 308 |
if (m_current >= m_max) |
544 |
if (m_current >= m_max) |
| 309 |
m_current = m_min + (m_current - m_max); |
545 |
m_current = m_min + (m_current - m_max); |
| 310 |
} |
546 |
} |
| 311 |
return r; |
547 |
return r; |
| 312 |
} |
548 |
} |
| 313 |
|
549 |
|
| 314 |
RandomVariable* SequentialVariable::Copy() const |
550 |
RandomVariableBase* SequentialVariableImpl::Copy() const |
| 315 |
{ |
551 |
{ |
| 316 |
return new SequentialVariable(*this); |
552 |
return new SequentialVariableImpl(*this); |
| 317 |
} |
553 |
} |
|
|
554 |
|
| 555 |
SequentialVariable::SequentialVariable(double f, double l, double i, uint32_t c) |
| 556 |
: RandomVariable (SequentialVariableImpl (f, l, i, c)) |
| 557 |
{} |
| 558 |
SequentialVariable::SequentialVariable(double f, double l, const RandomVariable& i, uint32_t c) |
| 559 |
: RandomVariable (SequentialVariableImpl (f, l, i, c)) |
| 560 |
{} |
| 561 |
|
| 318 |
//----------------------------------------------------------------------------- |
562 |
//----------------------------------------------------------------------------- |
| 319 |
//----------------------------------------------------------------------------- |
563 |
//----------------------------------------------------------------------------- |
| 320 |
// ExponentialVariable methods |
564 |
// ExponentialVariableImpl methods |
| 321 |
ExponentialVariable::ExponentialVariable() |
565 |
|
|
|
566 |
class ExponentialVariableImpl : public RandomVariableBase { |
| 567 |
public: |
| 568 |
/** |
| 569 |
* Constructs an exponential random variable with a mean |
| 570 |
* value of 1.0. |
| 571 |
*/ |
| 572 |
ExponentialVariableImpl(); |
| 573 |
|
| 574 |
/** |
| 575 |
* \brief Constructs an exponential random variable with a specified mean |
| 576 |
* \param m Mean value for the random variable |
| 577 |
*/ |
| 578 |
explicit ExponentialVariableImpl(double m); |
| 579 |
|
| 580 |
/** |
| 581 |
* \brief Constructs an exponential random variable with spefified |
| 582 |
* \brief mean and upper limit. |
| 583 |
* |
| 584 |
* Since exponential distributions can theoretically return unbounded values, |
| 585 |
* it is sometimes useful to specify a fixed upper limit. Note however when |
| 586 |
* the upper limit is specified, the true mean of the distribution is |
| 587 |
* slightly smaller than the mean value specified. |
| 588 |
* \param m Mean value of the random variable |
| 589 |
* \param b Upper bound on returned values |
| 590 |
*/ |
| 591 |
ExponentialVariableImpl(double m, double b); |
| 592 |
|
| 593 |
ExponentialVariableImpl(const ExponentialVariableImpl& c); |
| 594 |
|
| 595 |
/** |
| 596 |
* \return A random value from this exponential distribution |
| 597 |
*/ |
| 598 |
virtual double GetValue(); |
| 599 |
virtual RandomVariableBase* Copy(void) const; |
| 600 |
public: |
| 601 |
/** |
| 602 |
* \param m The mean of the distribution from which the return value is drawn |
| 603 |
* \param b The upper bound value desired, beyond which values get clipped |
| 604 |
* \return A random number from an exponential distribution with mean m |
| 605 |
*/ |
| 606 |
static double GetSingleValue(double m, double b=0); |
| 607 |
private: |
| 608 |
double m_mean; // Mean value of RV |
| 609 |
double m_bound; // Upper bound on value (if non-zero) |
| 610 |
}; |
| 611 |
|
| 612 |
ExponentialVariableImpl::ExponentialVariableImpl() |
| 322 |
: m_mean(1.0), m_bound(0) { } |
613 |
: m_mean(1.0), m_bound(0) { } |
| 323 |
|
614 |
|
| 324 |
ExponentialVariable::ExponentialVariable(double m) |
615 |
ExponentialVariableImpl::ExponentialVariableImpl(double m) |
| 325 |
: m_mean(m), m_bound(0) { } |
616 |
: m_mean(m), m_bound(0) { } |
| 326 |
|
617 |
|
| 327 |
ExponentialVariable::ExponentialVariable(double m, double b) |
618 |
ExponentialVariableImpl::ExponentialVariableImpl(double m, double b) |
| 328 |
: m_mean(m), m_bound(b) { } |
619 |
: m_mean(m), m_bound(b) { } |
| 329 |
|
620 |
|
| 330 |
ExponentialVariable::ExponentialVariable(const ExponentialVariable& c) |
621 |
ExponentialVariableImpl::ExponentialVariableImpl(const ExponentialVariableImpl& c) |
| 331 |
: RandomVariable(c), m_mean(c.m_mean), m_bound(c.m_bound) { } |
622 |
: RandomVariableBase(c), m_mean(c.m_mean), m_bound(c.m_bound) { } |
| 332 |
|
623 |
|
| 333 |
double ExponentialVariable::GetValue() |
624 |
double ExponentialVariableImpl::GetValue() |
| 334 |
{ |
625 |
{ |
| 335 |
if(!RandomVariable::initialized) |
626 |
if(!RandomVariableBase::initialized) |
| 336 |
{ |
627 |
{ |
| 337 |
RandomVariable::Initialize(); |
628 |
RandomVariableBase::Initialize(); |
| 338 |
} |
629 |
} |
| 339 |
if(!m_generator) |
630 |
if(!m_generator) |
| 340 |
{ |
631 |
{ |
| 341 |
m_generator = new RngStream(); |
632 |
m_generator = new RngStream(); |
| 342 |
m_generator->InitializeStream(); |
633 |
m_generator->InitializeStream(); |
| 343 |
m_generator->ResetNthSubstream(RandomVariable::runNumber); |
634 |
m_generator->ResetNthSubstream(RandomVariableBase::runNumber); |
| 344 |
} |
635 |
} |
| 345 |
double r = -m_mean*log(m_generator->RandU01()); |
636 |
double r = -m_mean*log(m_generator->RandU01()); |
| 346 |
if (m_bound != 0 && r > m_bound) return m_bound; |
637 |
if (m_bound != 0 && r > m_bound) return m_bound; |
| 347 |
return r; |
638 |
return r; |
| 348 |
} |
639 |
} |
| 349 |
|
640 |
|
| 350 |
RandomVariable* ExponentialVariable::Copy() const |
641 |
RandomVariableBase* ExponentialVariableImpl::Copy() const |
| 351 |
{ |
642 |
{ |
| 352 |
return new ExponentialVariable(*this); |
643 |
return new ExponentialVariableImpl(*this); |
| 353 |
} |
644 |
} |
| 354 |
double ExponentialVariable::GetSingleValue(double m, double b/*=0*/) |
645 |
double ExponentialVariableImpl::GetSingleValue(double m, double b/*=0*/) |
| 355 |
{ |
646 |
{ |
| 356 |
if(!RandomVariable::m_static_generator) |
647 |
if(!RandomVariableBase::m_static_generator) |
| 357 |
{ |
648 |
{ |
| 358 |
RandomVariable::Initialize(); // sets the static package seed |
649 |
RandomVariableBase::Initialize(); // sets the static package seed |
| 359 |
RandomVariable::m_static_generator = new RngStream(); |
650 |
RandomVariableBase::m_static_generator = new RngStream(); |
| 360 |
RandomVariable::m_static_generator->InitializeStream(); |
651 |
RandomVariableBase::m_static_generator->InitializeStream(); |
| 361 |
} |
652 |
} |
| 362 |
double r = -m*log(m_static_generator->RandU01()); |
653 |
double r = -m*log(m_static_generator->RandU01()); |
| 363 |
if (b != 0 && r > b) return b; |
654 |
if (b != 0 && r > b) return b; |
| 364 |
return r; |
655 |
return r; |
| 365 |
} |
656 |
} |
|
|
657 |
|
| 658 |
ExponentialVariable::ExponentialVariable() |
| 659 |
: RandomVariable (ExponentialVariableImpl ()) |
| 660 |
{} |
| 661 |
ExponentialVariable::ExponentialVariable(double m) |
| 662 |
: RandomVariable (ExponentialVariableImpl (m)) |
| 663 |
{} |
| 664 |
ExponentialVariable::ExponentialVariable(double m, double b) |
| 665 |
: RandomVariable (ExponentialVariableImpl (m, b)) |
| 666 |
{} |
| 667 |
double |
| 668 |
ExponentialVariable::GetSingleValue(double m, double b) |
| 669 |
{ |
| 670 |
return ExponentialVariableImpl::GetSingleValue (m, b); |
| 671 |
} |
| 672 |
|
| 366 |
//----------------------------------------------------------------------------- |
673 |
//----------------------------------------------------------------------------- |
| 367 |
//----------------------------------------------------------------------------- |
674 |
//----------------------------------------------------------------------------- |
| 368 |
// ParetoVariable methods |
675 |
// ParetoVariableImpl methods |
| 369 |
ParetoVariable::ParetoVariable() |
676 |
class ParetoVariableImpl : public RandomVariableBase { |
|
|
677 |
public: |
| 678 |
/** |
| 679 |
* Constructs a pareto random variable with a mean of 1 and a shape |
| 680 |
* parameter of 1.5 |
| 681 |
*/ |
| 682 |
ParetoVariableImpl(); |
| 683 |
|
| 684 |
/** |
| 685 |
* Constructs a pareto random variable with specified mean and shape |
| 686 |
* parameter of 1.5 |
| 687 |
* \param m Mean value of the distribution |
| 688 |
*/ |
| 689 |
explicit ParetoVariableImpl(double m); |
| 690 |
|
| 691 |
/** |
| 692 |
* Constructs a pareto random variable with the specified mean value and |
| 693 |
* shape parameter. |
| 694 |
* \param m Mean value of the distribution |
| 695 |
* \param s Shape parameter for the distribution |
| 696 |
*/ |
| 697 |
ParetoVariableImpl(double m, double s); |
| 698 |
|
| 699 |
/** |
| 700 |
* \brief Constructs a pareto random variable with the specified mean |
| 701 |
* \brief value, shape (alpha), and upper bound. |
| 702 |
* |
| 703 |
* Since pareto distributions can theoretically return unbounded values, |
| 704 |
* it is sometimes useful to specify a fixed upper limit. Note however |
| 705 |
* when the upper limit is specified, the true mean of the distribution |
| 706 |
* is slightly smaller than the mean value specified. |
| 707 |
* \param m Mean value |
| 708 |
* \param s Shape parameter |
| 709 |
* \param b Upper limit on returned values |
| 710 |
*/ |
| 711 |
ParetoVariableImpl(double m, double s, double b); |
| 712 |
|
| 713 |
ParetoVariableImpl(const ParetoVariableImpl& c); |
| 714 |
|
| 715 |
/** |
| 716 |
* \return A random value from this Pareto distribution |
| 717 |
*/ |
| 718 |
virtual double GetValue(); |
| 719 |
virtual RandomVariableBase* Copy() const; |
| 720 |
public: |
| 721 |
/** |
| 722 |
* \param m The mean value of the distribution from which the return value |
| 723 |
* is drawn. |
| 724 |
* \param s The shape parameter of the distribution from which the return |
| 725 |
* value is drawn. |
| 726 |
* \param b The upper bound to which to restrict return values |
| 727 |
* \return A random number from a Pareto distribution with mean m and shape |
| 728 |
* parameter s. |
| 729 |
*/ |
| 730 |
static double GetSingleValue(double m, double s, double b=0); |
| 731 |
private: |
| 732 |
double m_mean; // Mean value of RV |
| 733 |
double m_shape; // Shape parameter |
| 734 |
double m_bound; // Upper bound on value (if non-zero) |
| 735 |
}; |
| 736 |
|
| 737 |
ParetoVariableImpl::ParetoVariableImpl() |
| 370 |
: m_mean(1.0), m_shape(1.5), m_bound(0) { } |
738 |
: m_mean(1.0), m_shape(1.5), m_bound(0) { } |
| 371 |
|
739 |
|
| 372 |
ParetoVariable::ParetoVariable(double m) |
740 |
ParetoVariableImpl::ParetoVariableImpl(double m) |
| 373 |
: m_mean(m), m_shape(1.5), m_bound(0) { } |
741 |
: m_mean(m), m_shape(1.5), m_bound(0) { } |
| 374 |
|
742 |
|
| 375 |
ParetoVariable::ParetoVariable(double m, double s) |
743 |
ParetoVariableImpl::ParetoVariableImpl(double m, double s) |
| 376 |
: m_mean(m), m_shape(s), m_bound(0) { } |
744 |
: m_mean(m), m_shape(s), m_bound(0) { } |
| 377 |
|
745 |
|
| 378 |
ParetoVariable::ParetoVariable(double m, double s, double b) |
746 |
ParetoVariableImpl::ParetoVariableImpl(double m, double s, double b) |
| 379 |
: m_mean(m), m_shape(s), m_bound(b) { } |
747 |
: m_mean(m), m_shape(s), m_bound(b) { } |
| 380 |
|
748 |
|
| 381 |
ParetoVariable::ParetoVariable(const ParetoVariable& c) |
749 |
ParetoVariableImpl::ParetoVariableImpl(const ParetoVariableImpl& c) |
| 382 |
: RandomVariable(c), m_mean(c.m_mean), m_shape(c.m_shape), |
750 |
: RandomVariableBase(c), m_mean(c.m_mean), m_shape(c.m_shape), |
| 383 |
m_bound(c.m_bound) { } |
751 |
m_bound(c.m_bound) { } |
| 384 |
|
752 |
|
| 385 |
double ParetoVariable::GetValue() |
753 |
double ParetoVariableImpl::GetValue() |
| 386 |
{ |
754 |
{ |
| 387 |
if(!RandomVariable::initialized) |
755 |
if(!RandomVariableBase::initialized) |
| 388 |
{ |
756 |
{ |
| 389 |
RandomVariable::Initialize(); |
757 |
RandomVariableBase::Initialize(); |
| 390 |
} |
758 |
} |
| 391 |
if(!m_generator) |
759 |
if(!m_generator) |
| 392 |
{ |
760 |
{ |
| 393 |
m_generator = new RngStream(); |
761 |
m_generator = new RngStream(); |
| 394 |
m_generator->InitializeStream(); |
762 |
m_generator->InitializeStream(); |
| 395 |
m_generator->ResetNthSubstream(RandomVariable::runNumber); |
763 |
m_generator->ResetNthSubstream(RandomVariableBase::runNumber); |
| 396 |
} |
764 |
} |
| 397 |
double scale = m_mean * ( m_shape - 1.0) / m_shape; |
765 |
double scale = m_mean * ( m_shape - 1.0) / m_shape; |
| 398 |
double r = (scale * ( 1.0 / pow(m_generator->RandU01(), 1.0 / m_shape))); |
766 |
double r = (scale * ( 1.0 / pow(m_generator->RandU01(), 1.0 / m_shape))); |
|
Lines 400-448
double ParetoVariable::GetValue()
|
Link Here
|
|---|
|
| 400 |
return r; |
768 |
return r; |
| 401 |
} |
769 |
} |
| 402 |
|
770 |
|
| 403 |
RandomVariable* ParetoVariable::Copy() const |
771 |
RandomVariableBase* ParetoVariableImpl::Copy() const |
| 404 |
{ |
772 |
{ |
| 405 |
return new ParetoVariable(*this); |
773 |
return new ParetoVariableImpl(*this); |
| 406 |
} |
774 |
} |
| 407 |
|
775 |
|
| 408 |
double ParetoVariable::GetSingleValue(double m, double s, double b/*=0*/) |
776 |
double ParetoVariableImpl::GetSingleValue(double m, double s, double b/*=0*/) |
| 409 |
{ |
777 |
{ |
| 410 |
if(!RandomVariable::m_static_generator) |
778 |
if(!RandomVariableBase::m_static_generator) |
| 411 |
{ |
779 |
{ |
| 412 |
RandomVariable::Initialize(); // sets the static package seed |
780 |
RandomVariableBase::Initialize(); // sets the static package seed |
| 413 |
RandomVariable::m_static_generator = new RngStream(); |
781 |
RandomVariableBase::m_static_generator = new RngStream(); |
| 414 |
RandomVariable::m_static_generator->InitializeStream(); |
782 |
RandomVariableBase::m_static_generator->InitializeStream(); |
| 415 |
} |
783 |
} |
| 416 |
double scale = m * ( s - 1.0) / s; |
784 |
double scale = m * ( s - 1.0) / s; |
| 417 |
double r = (scale * ( 1.0 / pow(m_static_generator->RandU01(), 1.0 / s))); |
785 |
double r = (scale * ( 1.0 / pow(m_static_generator->RandU01(), 1.0 / s))); |
| 418 |
if (b != 0 && r > b) return b; |
786 |
if (b != 0 && r > b) return b; |
| 419 |
return r; |
787 |
return r; |
| 420 |
} |
788 |
} |
|
|
789 |
|
| 790 |
ParetoVariable::ParetoVariable () |
| 791 |
: RandomVariable (ParetoVariableImpl ()) |
| 792 |
{} |
| 793 |
ParetoVariable::ParetoVariable(double m) |
| 794 |
: RandomVariable (ParetoVariableImpl (m)) |
| 795 |
{} |
| 796 |
ParetoVariable::ParetoVariable(double m, double s) |
| 797 |
: RandomVariable (ParetoVariableImpl (m, s)) |
| 798 |
{} |
| 799 |
ParetoVariable::ParetoVariable(double m, double s, double b) |
| 800 |
: RandomVariable (ParetoVariableImpl (m, s, b)) |
| 801 |
{} |
| 802 |
double |
| 803 |
ParetoVariable::GetSingleValue(double m, double s, double b) |
| 804 |
{ |
| 805 |
return ParetoVariableImpl::GetSingleValue (m, s, b); |
| 806 |
} |
| 807 |
|
| 421 |
//----------------------------------------------------------------------------- |
808 |
//----------------------------------------------------------------------------- |
| 422 |
//----------------------------------------------------------------------------- |
809 |
//----------------------------------------------------------------------------- |
| 423 |
// WeibullVariable methods |
810 |
// WeibullVariableImpl methods |
| 424 |
WeibullVariable::WeibullVariable() : m_mean(1.0), m_alpha(1), m_bound(0) { } |
811 |
|
| 425 |
WeibullVariable::WeibullVariable(double m) |
812 |
class WeibullVariableImpl : public RandomVariableBase { |
|
|
813 |
public: |
| 814 |
/** |
| 815 |
* Constructs a weibull random variable with a mean |
| 816 |
* value of 1.0 and a shape (alpha) parameter of 1 |
| 817 |
*/ |
| 818 |
WeibullVariableImpl(); |
| 819 |
|
| 820 |
|
| 821 |
/** |
| 822 |
* Constructs a weibull random variable with the specified mean |
| 823 |
* value and a shape (alpha) parameter of 1.5. |
| 824 |
* \param m mean value of the distribution |
| 825 |
*/ |
| 826 |
WeibullVariableImpl(double m) ; |
| 827 |
|
| 828 |
/** |
| 829 |
* Constructs a weibull random variable with the specified mean |
| 830 |
* value and a shape (alpha). |
| 831 |
* \param m Mean value for the distribution. |
| 832 |
* \param s Shape (alpha) parameter for the distribution. |
| 833 |
*/ |
| 834 |
WeibullVariableImpl(double m, double s); |
| 835 |
|
| 836 |
/** |
| 837 |
* \brief Constructs a weibull random variable with the specified mean |
| 838 |
* \brief value, shape (alpha), and upper bound. |
| 839 |
* Since WeibullVariableImpl distributions can theoretically return unbounded values, |
| 840 |
* it is sometimes usefull to specify a fixed upper limit. Note however |
| 841 |
* that when the upper limit is specified, the true mean of the distribution |
| 842 |
* is slightly smaller than the mean value specified. |
| 843 |
* \param m Mean value for the distribution. |
| 844 |
* \param s Shape (alpha) parameter for the distribution. |
| 845 |
* \param b Upper limit on returned values |
| 846 |
*/ |
| 847 |
WeibullVariableImpl(double m, double s, double b); |
| 848 |
|
| 849 |
WeibullVariableImpl(const WeibullVariableImpl& c); |
| 850 |
|
| 851 |
/** |
| 852 |
* \return A random value from this Weibull distribution |
| 853 |
*/ |
| 854 |
virtual double GetValue(); |
| 855 |
virtual RandomVariableBase* Copy(void) const; |
| 856 |
public: |
| 857 |
/** |
| 858 |
* \param m Mean value for the distribution. |
| 859 |
* \param s Shape (alpha) parameter for the distribution. |
| 860 |
* \param b Upper limit on returned values |
| 861 |
* \return Random number from a distribution specified by m,s, and b |
| 862 |
*/ |
| 863 |
static double GetSingleValue(double m, double s, double b=0); |
| 864 |
private: |
| 865 |
double m_mean; // Mean value of RV |
| 866 |
double m_alpha; // Shape parameter |
| 867 |
double m_bound; // Upper bound on value (if non-zero) |
| 868 |
}; |
| 869 |
|
| 870 |
WeibullVariableImpl::WeibullVariableImpl() : m_mean(1.0), m_alpha(1), m_bound(0) { } |
| 871 |
WeibullVariableImpl::WeibullVariableImpl(double m) |
| 426 |
: m_mean(m), m_alpha(1), m_bound(0) { } |
872 |
: m_mean(m), m_alpha(1), m_bound(0) { } |
| 427 |
WeibullVariable::WeibullVariable(double m, double s) |
873 |
WeibullVariableImpl::WeibullVariableImpl(double m, double s) |
| 428 |
: m_mean(m), m_alpha(s), m_bound(0) { } |
874 |
: m_mean(m), m_alpha(s), m_bound(0) { } |
| 429 |
WeibullVariable::WeibullVariable(double m, double s, double b) |
875 |
WeibullVariableImpl::WeibullVariableImpl(double m, double s, double b) |
| 430 |
: m_mean(m), m_alpha(s), m_bound(b) { }; |
876 |
: m_mean(m), m_alpha(s), m_bound(b) { }; |
| 431 |
WeibullVariable::WeibullVariable(const WeibullVariable& c) |
877 |
WeibullVariableImpl::WeibullVariableImpl(const WeibullVariableImpl& c) |
| 432 |
: RandomVariable(c), m_mean(c.m_mean), m_alpha(c.m_alpha), |
878 |
: RandomVariableBase(c), m_mean(c.m_mean), m_alpha(c.m_alpha), |
| 433 |
m_bound(c.m_bound) { } |
879 |
m_bound(c.m_bound) { } |
| 434 |
|
880 |
|
| 435 |
double WeibullVariable::GetValue() |
881 |
double WeibullVariableImpl::GetValue() |
| 436 |
{ |
882 |
{ |
| 437 |
if(!RandomVariable::initialized) |
883 |
if(!RandomVariableBase::initialized) |
| 438 |
{ |
884 |
{ |
| 439 |
RandomVariable::Initialize(); |
885 |
RandomVariableBase::Initialize(); |
| 440 |
} |
886 |
} |
| 441 |
if(!m_generator) |
887 |
if(!m_generator) |
| 442 |
{ |
888 |
{ |
| 443 |
m_generator = new RngStream(); |
889 |
m_generator = new RngStream(); |
| 444 |
m_generator->InitializeStream(); |
890 |
m_generator->InitializeStream(); |
| 445 |
m_generator->ResetNthSubstream(RandomVariable::runNumber); |
891 |
m_generator->ResetNthSubstream(RandomVariableBase::runNumber); |
| 446 |
} |
892 |
} |
| 447 |
double exponent = 1.0 / m_alpha; |
893 |
double exponent = 1.0 / m_alpha; |
| 448 |
double r = m_mean * pow( -log(m_generator->RandU01()), exponent); |
894 |
double r = m_mean * pow( -log(m_generator->RandU01()), exponent); |
|
Lines 450-501
double WeibullVariable::GetValue()
|
Link Here
|
|---|
|
| 450 |
return r; |
896 |
return r; |
| 451 |
} |
897 |
} |
| 452 |
|
898 |
|
| 453 |
RandomVariable* WeibullVariable::Copy() const |
899 |
RandomVariableBase* WeibullVariableImpl::Copy() const |
| 454 |
{ |
900 |
{ |
| 455 |
return new WeibullVariable(*this); |
901 |
return new WeibullVariableImpl(*this); |
| 456 |
} |
902 |
} |
| 457 |
|
903 |
|
| 458 |
double WeibullVariable::GetSingleValue(double m, double s, double b/*=0*/) |
904 |
double WeibullVariableImpl::GetSingleValue(double m, double s, double b/*=0*/) |
| 459 |
{ |
905 |
{ |
| 460 |
if(!RandomVariable::m_static_generator) |
906 |
if(!RandomVariableBase::m_static_generator) |
| 461 |
{ |
907 |
{ |
| 462 |
RandomVariable::Initialize(); // sets the static package seed |
908 |
RandomVariableBase::Initialize(); // sets the static package seed |
| 463 |
RandomVariable::m_static_generator = new RngStream(); |
909 |
RandomVariableBase::m_static_generator = new RngStream(); |
| 464 |
RandomVariable::m_static_generator->InitializeStream(); |
910 |
RandomVariableBase::m_static_generator->InitializeStream(); |
| 465 |
} |
911 |
} |
| 466 |
double exponent = 1.0 / s; |
912 |
double exponent = 1.0 / s; |
| 467 |
double r = m * pow( -log(m_static_generator->RandU01()), exponent); |
913 |
double r = m * pow( -log(m_static_generator->RandU01()), exponent); |
| 468 |
if (b != 0 && r > b) return b; |
914 |
if (b != 0 && r > b) return b; |
| 469 |
return r; |
915 |
return r; |
| 470 |
} |
916 |
} |
|
|
917 |
|
| 918 |
WeibullVariable::WeibullVariable() |
| 919 |
: RandomVariable (WeibullVariableImpl ()) |
| 920 |
{} |
| 921 |
WeibullVariable::WeibullVariable(double m) |
| 922 |
: RandomVariable (WeibullVariableImpl (m)) |
| 923 |
{} |
| 924 |
WeibullVariable::WeibullVariable(double m, double s) |
| 925 |
: RandomVariable (WeibullVariableImpl (m, s)) |
| 926 |
{} |
| 927 |
WeibullVariable::WeibullVariable(double m, double s, double b) |
| 928 |
: RandomVariable (WeibullVariableImpl (m, s, b)) |
| 929 |
{} |
| 930 |
double |
| 931 |
WeibullVariable::GetSingleValue(double m, double s, double b) |
| 932 |
{ |
| 933 |
return WeibullVariableImpl::GetSingleValue (m, s, b); |
| 934 |
} |
| 471 |
//----------------------------------------------------------------------------- |
935 |
//----------------------------------------------------------------------------- |
| 472 |
//----------------------------------------------------------------------------- |
936 |
//----------------------------------------------------------------------------- |
| 473 |
// NormalVariable methods |
937 |
// NormalVariableImpl methods |
| 474 |
bool NormalVariable::m_static_nextValid = false; |
|
|
| 475 |
double NormalVariable::m_static_next; |
| 476 |
const double NormalVariable::INFINITE_VALUE = 1e307; |
| 477 |
|
938 |
|
| 478 |
NormalVariable::NormalVariable() |
939 |
class NormalVariableImpl : public RandomVariableBase { // Normally Distributed random var |
|
|
940 |
|
| 941 |
public: |
| 942 |
static const double INFINITE_VALUE; |
| 943 |
/** |
| 944 |
* Constructs an normal random variable with a mean |
| 945 |
* value of 0 and variance of 1. |
| 946 |
*/ |
| 947 |
NormalVariableImpl(); |
| 948 |
|
| 949 |
/** |
| 950 |
* \brief Construct a normal random variable with specified mean and variance |
| 951 |
* \param m Mean value |
| 952 |
* \param v Variance |
| 953 |
* \param b Bound. The NormalVariableImpl is bounded within +-bound. |
| 954 |
*/ |
| 955 |
NormalVariableImpl(double m, double v, double b = INFINITE_VALUE); |
| 956 |
|
| 957 |
NormalVariableImpl(const NormalVariableImpl& c); |
| 958 |
|
| 959 |
/** |
| 960 |
* \return A value from this normal distribution |
| 961 |
*/ |
| 962 |
virtual double GetValue(); |
| 963 |
virtual RandomVariableBase* Copy(void) const; |
| 964 |
public: |
| 965 |
/** |
| 966 |
* \param m Mean value |
| 967 |
* \param v Variance |
| 968 |
* \param b Bound. The NormalVariableImpl is bounded within +-bound. |
| 969 |
* \return A random number from a distribution specified by m,v, and b. |
| 970 |
*/ |
| 971 |
static double GetSingleValue(double m, double v, double b = INFINITE_VALUE); |
| 972 |
private: |
| 973 |
double m_mean; // Mean value of RV |
| 974 |
double m_variance; // Mean value of RV |
| 975 |
double m_bound; // Bound on value (absolute value) |
| 976 |
bool m_nextValid; // True if next valid |
| 977 |
double m_next; // The algorithm produces two values at a time |
| 978 |
static bool m_static_nextValid; |
| 979 |
static double m_static_next; |
| 980 |
}; |
| 981 |
|
| 982 |
bool NormalVariableImpl::m_static_nextValid = false; |
| 983 |
double NormalVariableImpl::m_static_next; |
| 984 |
const double NormalVariableImpl::INFINITE_VALUE = 1e307; |
| 985 |
|
| 986 |
NormalVariableImpl::NormalVariableImpl() |
| 479 |
: m_mean(0.0), m_variance(1.0), m_bound(INFINITE_VALUE), m_nextValid(false){} |
987 |
: m_mean(0.0), m_variance(1.0), m_bound(INFINITE_VALUE), m_nextValid(false){} |
| 480 |
|
988 |
|
| 481 |
NormalVariable::NormalVariable(double m, double v, double b/*=INFINITE_VALUE*/) |
989 |
NormalVariableImpl::NormalVariableImpl(double m, double v, double b/*=INFINITE_VALUE*/) |
| 482 |
: m_mean(m), m_variance(v), m_bound(b), m_nextValid(false) { } |
990 |
: m_mean(m), m_variance(v), m_bound(b), m_nextValid(false) { } |
| 483 |
|
991 |
|
| 484 |
NormalVariable::NormalVariable(const NormalVariable& c) |
992 |
NormalVariableImpl::NormalVariableImpl(const NormalVariableImpl& c) |
| 485 |
: RandomVariable(c), m_mean(c.m_mean), m_variance(c.m_variance), |
993 |
: RandomVariableBase(c), m_mean(c.m_mean), m_variance(c.m_variance), |
| 486 |
m_bound(c.m_bound) { } |
994 |
m_bound(c.m_bound) { } |
| 487 |
|
995 |
|
| 488 |
double NormalVariable::GetValue() |
996 |
double NormalVariableImpl::GetValue() |
| 489 |
{ |
997 |
{ |
| 490 |
if(!RandomVariable::initialized) |
998 |
if(!RandomVariableBase::initialized) |
| 491 |
{ |
999 |
{ |
| 492 |
RandomVariable::Initialize(); |
1000 |
RandomVariableBase::Initialize(); |
| 493 |
} |
1001 |
} |
| 494 |
if(!m_generator) |
1002 |
if(!m_generator) |
| 495 |
{ |
1003 |
{ |
| 496 |
m_generator = new RngStream(); |
1004 |
m_generator = new RngStream(); |
| 497 |
m_generator->InitializeStream(); |
1005 |
m_generator->InitializeStream(); |
| 498 |
m_generator->ResetNthSubstream(RandomVariable::runNumber); |
1006 |
m_generator->ResetNthSubstream(RandomVariableBase::runNumber); |
| 499 |
} |
1007 |
} |
| 500 |
if (m_nextValid) |
1008 |
if (m_nextValid) |
| 501 |
{ // use previously generated |
1009 |
{ // use previously generated |
|
Lines 523-540
double NormalVariable::GetValue()
|
Link Here
|
|---|
|
| 523 |
} |
1031 |
} |
| 524 |
} |
1032 |
} |
| 525 |
|
1033 |
|
| 526 |
RandomVariable* NormalVariable::Copy() const |
1034 |
RandomVariableBase* NormalVariableImpl::Copy() const |
| 527 |
{ |
1035 |
{ |
| 528 |
return new NormalVariable(*this); |
1036 |
return new NormalVariableImpl(*this); |
| 529 |
} |
1037 |
} |
| 530 |
|
1038 |
|
| 531 |
double NormalVariable::GetSingleValue(double m, double v, double b) |
1039 |
double NormalVariableImpl::GetSingleValue(double m, double v, double b) |
| 532 |
{ |
1040 |
{ |
| 533 |
if(!RandomVariable::m_static_generator) |
1041 |
if(!RandomVariableBase::m_static_generator) |
| 534 |
{ |
1042 |
{ |
| 535 |
RandomVariable::Initialize(); // sets the static package seed |
1043 |
RandomVariableBase::Initialize(); // sets the static package seed |
| 536 |
RandomVariable::m_static_generator = new RngStream(); |
1044 |
RandomVariableBase::m_static_generator = new RngStream(); |
| 537 |
RandomVariable::m_static_generator->InitializeStream(); |
1045 |
RandomVariableBase::m_static_generator->InitializeStream(); |
| 538 |
} |
1046 |
} |
| 539 |
if (m_static_nextValid) |
1047 |
if (m_static_nextValid) |
| 540 |
{ // use previously generated |
1048 |
{ // use previously generated |
|
Lines 562-600
double NormalVariable::GetSingleValue(do
|
Link Here
|
|---|
|
| 562 |
} |
1070 |
} |
| 563 |
} |
1071 |
} |
| 564 |
|
1072 |
|
|
|
1073 |
NormalVariable::NormalVariable() |
| 1074 |
: RandomVariable (NormalVariableImpl ()) |
| 1075 |
{} |
| 1076 |
NormalVariable::NormalVariable(double m, double v, double b) |
| 1077 |
: RandomVariable (NormalVariableImpl (m, v, b)) |
| 1078 |
{} |
| 1079 |
double |
| 1080 |
NormalVariable::GetSingleValue(double m, double v, double b) |
| 1081 |
{ |
| 1082 |
return NormalVariableImpl::GetSingleValue (m, v, b); |
| 1083 |
} |
| 1084 |
|
| 1085 |
|
| 565 |
//----------------------------------------------------------------------------- |
1086 |
//----------------------------------------------------------------------------- |
| 566 |
//----------------------------------------------------------------------------- |
1087 |
//----------------------------------------------------------------------------- |
|
|
1088 |
class EmpiricalVariableImpl : public RandomVariableBase { |
| 1089 |
public: |
| 1090 |
/** |
| 1091 |
* Constructor for the EmpiricalVariableImpl random variables. |
| 1092 |
*/ |
| 1093 |
explicit EmpiricalVariableImpl(); |
| 1094 |
|
| 1095 |
virtual ~EmpiricalVariableImpl(); |
| 1096 |
EmpiricalVariableImpl(const EmpiricalVariableImpl& c); |
| 1097 |
/** |
| 1098 |
* \return A value from this empirical distribution |
| 1099 |
*/ |
| 1100 |
virtual double GetValue(); |
| 1101 |
virtual RandomVariableBase* Copy(void) const; |
| 1102 |
/** |
| 1103 |
* \brief Specifies a point in the empirical distribution |
| 1104 |
* \param v The function value for this point |
| 1105 |
* \param c Probability that the function is less than or equal to v |
| 1106 |
*/ |
| 1107 |
virtual void CDF(double v, double c); // Value, prob <= Value |
| 1108 |
|
| 1109 |
private: |
| 1110 |
class ValueCDF { |
| 1111 |
public: |
| 1112 |
ValueCDF(); |
| 1113 |
ValueCDF(double v, double c); |
| 1114 |
ValueCDF(const ValueCDF& c); |
| 1115 |
double value; |
| 1116 |
double cdf; |
| 1117 |
}; |
| 1118 |
virtual void Validate(); // Insure non-decreasing emiprical values |
| 1119 |
virtual double Interpolate(double, double, double, double, double); |
| 1120 |
bool validated; // True if non-decreasing validated |
| 1121 |
std::vector<ValueCDF> emp; // Empicical CDF |
| 1122 |
}; |
| 1123 |
|
| 1124 |
|
| 567 |
// ValueCDF methods |
1125 |
// ValueCDF methods |
| 568 |
EmpiricalVariable::ValueCDF::ValueCDF() |
1126 |
EmpiricalVariableImpl::ValueCDF::ValueCDF() |
| 569 |
: value(0.0), cdf(0.0){ } |
1127 |
: value(0.0), cdf(0.0){ } |
| 570 |
EmpiricalVariable::ValueCDF::ValueCDF(double v, double c) |
1128 |
EmpiricalVariableImpl::ValueCDF::ValueCDF(double v, double c) |
| 571 |
: value(v), cdf(c) { } |
1129 |
: value(v), cdf(c) { } |
| 572 |
EmpiricalVariable::ValueCDF::ValueCDF(const ValueCDF& c) |
1130 |
EmpiricalVariableImpl::ValueCDF::ValueCDF(const ValueCDF& c) |
| 573 |
: value(c.value), cdf(c.cdf) { } |
1131 |
: value(c.value), cdf(c.cdf) { } |
| 574 |
|
1132 |
|
| 575 |
//----------------------------------------------------------------------------- |
1133 |
//----------------------------------------------------------------------------- |
| 576 |
//----------------------------------------------------------------------------- |
1134 |
//----------------------------------------------------------------------------- |
| 577 |
// EmpiricalVariable methods |
1135 |
// EmpiricalVariableImpl methods |
| 578 |
EmpiricalVariable::EmpiricalVariable() |
1136 |
EmpiricalVariableImpl::EmpiricalVariableImpl() |
| 579 |
: validated(false) { } |
1137 |
: validated(false) { } |
| 580 |
|
1138 |
|
| 581 |
EmpiricalVariable::EmpiricalVariable(const EmpiricalVariable& c) |
1139 |
EmpiricalVariableImpl::EmpiricalVariableImpl(const EmpiricalVariableImpl& c) |
| 582 |
: RandomVariable(c), validated(c.validated), emp(c.emp) { } |
1140 |
: RandomVariableBase(c), validated(c.validated), emp(c.emp) { } |
| 583 |
|
1141 |
|
| 584 |
EmpiricalVariable::~EmpiricalVariable() { } |
1142 |
EmpiricalVariableImpl::~EmpiricalVariableImpl() { } |
| 585 |
|
1143 |
|
| 586 |
double EmpiricalVariable::GetValue() |
1144 |
double EmpiricalVariableImpl::GetValue() |
| 587 |
{ // Return a value from the empirical distribution |
1145 |
{ // Return a value from the empirical distribution |
| 588 |
// This code based (loosely) on code by Bruce Mah (Thanks Bruce!) |
1146 |
// This code based (loosely) on code by Bruce Mah (Thanks Bruce!) |
| 589 |
if(!RandomVariable::initialized) |
1147 |
if(!RandomVariableBase::initialized) |
| 590 |
{ |
1148 |
{ |
| 591 |
RandomVariable::Initialize(); |
1149 |
RandomVariableBase::Initialize(); |
| 592 |
} |
1150 |
} |
| 593 |
if(!m_generator) |
1151 |
if(!m_generator) |
| 594 |
{ |
1152 |
{ |
| 595 |
m_generator = new RngStream(); |
1153 |
m_generator = new RngStream(); |
| 596 |
m_generator->InitializeStream(); |
1154 |
m_generator->InitializeStream(); |
| 597 |
m_generator->ResetNthSubstream(RandomVariable::runNumber); |
1155 |
m_generator->ResetNthSubstream(RandomVariableBase::runNumber); |
| 598 |
} |
1156 |
} |
| 599 |
if (emp.size() == 0) return 0.0; // HuH? No empirical data |
1157 |
if (emp.size() == 0) return 0.0; // HuH? No empirical data |
| 600 |
if (!validated) Validate(); // Insure in non-decreasing |
1158 |
if (!validated) Validate(); // Insure in non-decreasing |
|
Lines 619-636
double EmpiricalVariable::GetValue()
|
Link Here
|
|---|
|
| 619 |
} |
1177 |
} |
| 620 |
} |
1178 |
} |
| 621 |
|
1179 |
|
| 622 |
RandomVariable* EmpiricalVariable::Copy() const |
1180 |
RandomVariableBase* EmpiricalVariableImpl::Copy() const |
| 623 |
{ |
1181 |
{ |
| 624 |
return new EmpiricalVariable(*this); |
1182 |
return new EmpiricalVariableImpl(*this); |
| 625 |
} |
1183 |
} |
| 626 |
|
1184 |
|
| 627 |
void EmpiricalVariable::CDF(double v, double c) |
1185 |
void EmpiricalVariableImpl::CDF(double v, double c) |
| 628 |
{ // Add a new empirical datapoint to the empirical cdf |
1186 |
{ // Add a new empirical datapoint to the empirical cdf |
| 629 |
// NOTE. These MUST be inserted in non-decreasing order |
1187 |
// NOTE. These MUST be inserted in non-decreasing order |
| 630 |
emp.push_back(ValueCDF(v, c)); |
1188 |
emp.push_back(ValueCDF(v, c)); |
| 631 |
} |
1189 |
} |
| 632 |
|
1190 |
|
| 633 |
void EmpiricalVariable::Validate() |
1191 |
void EmpiricalVariableImpl::Validate() |
| 634 |
{ |
1192 |
{ |
| 635 |
ValueCDF prior; |
1193 |
ValueCDF prior; |
| 636 |
for (std::vector<ValueCDF>::size_type i = 0; i < emp.size(); ++i) |
1194 |
for (std::vector<ValueCDF>::size_type i = 0; i < emp.size(); ++i) |
|
Lines 650-715
void EmpiricalVariable::Validate()
|
Link Here
|
|---|
|
| 650 |
validated = true; |
1208 |
validated = true; |
| 651 |
} |
1209 |
} |
| 652 |
|
1210 |
|
| 653 |
double EmpiricalVariable::Interpolate(double c1, double c2, |
1211 |
double EmpiricalVariableImpl::Interpolate(double c1, double c2, |
| 654 |
double v1, double v2, double r) |
1212 |
double v1, double v2, double r) |
| 655 |
{ // Interpolate random value in range [v1..v2) based on [c1 .. r .. c2) |
1213 |
{ // Interpolate random value in range [v1..v2) based on [c1 .. r .. c2) |
| 656 |
return (v1 + ((v2 - v1) / (c2 - c1)) * (r - c1)); |
1214 |
return (v1 + ((v2 - v1) / (c2 - c1)) * (r - c1)); |
| 657 |
} |
1215 |
} |
| 658 |
|
1216 |
|
|
|
1217 |
EmpiricalVariable::EmpiricalVariable() |
| 1218 |
: RandomVariable (EmpiricalVariableImpl ()) |
| 1219 |
{} |
| 1220 |
EmpiricalVariable::EmpiricalVariable (const RandomVariableBase &variable) |
| 1221 |
: RandomVariable (variable) |
| 1222 |
{} |
| 1223 |
void |
| 1224 |
EmpiricalVariable::CDF(double v, double c) |
| 1225 |
{ |
| 1226 |
EmpiricalVariableImpl *impl = dynamic_cast<EmpiricalVariableImpl *> (Peek ()); |
| 1227 |
NS_ASSERT (impl); |
| 1228 |
impl->CDF (v, c); |
| 1229 |
} |
| 1230 |
|
| 1231 |
|
| 659 |
//----------------------------------------------------------------------------- |
1232 |
//----------------------------------------------------------------------------- |
| 660 |
//----------------------------------------------------------------------------- |
1233 |
//----------------------------------------------------------------------------- |
| 661 |
// Integer EmpiricalVariable methods |
1234 |
// Integer EmpiricalVariableImpl methods |
| 662 |
IntEmpiricalVariable::IntEmpiricalVariable() { } |
1235 |
class IntEmpiricalVariableImpl : public EmpiricalVariableImpl { |
|
|
1236 |
public: |
| 663 |
|
1237 |
|
| 664 |
uint32_t IntEmpiricalVariable::GetIntValue() |
1238 |
IntEmpiricalVariableImpl(); |
|
|
1239 |
|
| 1240 |
virtual RandomVariableBase* Copy(void) const; |
| 1241 |
/** |
| 1242 |
* \return An integer value from this empirical distribution |
| 1243 |
*/ |
| 1244 |
virtual uint32_t GetIntValue(); |
| 1245 |
private: |
| 1246 |
virtual double Interpolate(double, double, double, double, double); |
| 1247 |
}; |
| 1248 |
|
| 1249 |
|
| 1250 |
IntEmpiricalVariableImpl::IntEmpiricalVariableImpl() { } |
| 1251 |
|
| 1252 |
uint32_t IntEmpiricalVariableImpl::GetIntValue() |
| 665 |
{ |
1253 |
{ |
| 666 |
return (uint32_t)GetValue(); |
1254 |
return (uint32_t)GetValue(); |
| 667 |
} |
1255 |
} |
| 668 |
|
1256 |
|
| 669 |
RandomVariable* IntEmpiricalVariable::Copy() const |
1257 |
RandomVariableBase* IntEmpiricalVariableImpl::Copy() const |
| 670 |
{ |
1258 |
{ |
| 671 |
return new IntEmpiricalVariable(*this); |
1259 |
return new IntEmpiricalVariableImpl(*this); |
| 672 |
} |
1260 |
} |
| 673 |
|
1261 |
|
| 674 |
double IntEmpiricalVariable::Interpolate(double c1, double c2, |
1262 |
double IntEmpiricalVariableImpl::Interpolate(double c1, double c2, |
| 675 |
double v1, double v2, double r) |
1263 |
double v1, double v2, double r) |
| 676 |
{ // Interpolate random value in range [v1..v2) based on [c1 .. r .. c2) |
1264 |
{ // Interpolate random value in range [v1..v2) based on [c1 .. r .. c2) |
| 677 |
return ceil(v1 + ((v2 - v1) / (c2 - c1)) * (r - c1)); |
1265 |
return ceil(v1 + ((v2 - v1) / (c2 - c1)) * (r - c1)); |
| 678 |
} |
1266 |
} |
| 679 |
|
1267 |
|
|
|
1268 |
IntEmpiricalVariable::IntEmpiricalVariable() |
| 1269 |
: EmpiricalVariable (IntEmpiricalVariableImpl ()) |
| 1270 |
{} |
| 680 |
|
1271 |
|
| 681 |
//----------------------------------------------------------------------------- |
1272 |
//----------------------------------------------------------------------------- |
| 682 |
//----------------------------------------------------------------------------- |
1273 |
//----------------------------------------------------------------------------- |
| 683 |
// DeterministicVariable |
1274 |
// DeterministicVariableImpl |
| 684 |
DeterministicVariable::DeterministicVariable(double* d, uint32_t c) |
1275 |
class DeterministicVariableImpl : public RandomVariableBase |
|
|
1276 |
{ |
| 1277 |
|
| 1278 |
public: |
| 1279 |
/** |
| 1280 |
* \brief Constructor |
| 1281 |
* |
| 1282 |
* Creates a generator that returns successive elements of the d array |
| 1283 |
* on successive calls to ::Value(). Note that the d pointer is copied |
| 1284 |
* for use by the generator (shallow-copy), not its contents, so the |
| 1285 |
* contents of the array d points to have to remain unchanged for the use |
| 1286 |
* of DeterministicVariableImpl to be meaningful. |
| 1287 |
* \param d Pointer to array of random values to return in sequence |
| 1288 |
* \param c Number of values in the array |
| 1289 |
*/ |
| 1290 |
explicit DeterministicVariableImpl(double* d, uint32_t c); |
| 1291 |
|
| 1292 |
virtual ~DeterministicVariableImpl(); |
| 1293 |
/** |
| 1294 |
* \return The next value in the deterministic sequence |
| 1295 |
*/ |
| 1296 |
virtual double GetValue(); |
| 1297 |
virtual RandomVariableBase* Copy(void) const; |
| 1298 |
private: |
| 1299 |
uint32_t count; |
| 1300 |
uint32_t next; |
| 1301 |
double* data; |
| 1302 |
}; |
| 1303 |
|
| 1304 |
DeterministicVariableImpl::DeterministicVariableImpl(double* d, uint32_t c) |
| 685 |
: count(c), next(c), data(d) |
1305 |
: count(c), next(c), data(d) |
| 686 |
{ // Nothing else needed |
1306 |
{ // Nothing else needed |
| 687 |
} |
1307 |
} |
| 688 |
|
1308 |
|
| 689 |
DeterministicVariable::~DeterministicVariable() { } |
1309 |
DeterministicVariableImpl::~DeterministicVariableImpl() { } |
| 690 |
|
1310 |
|
| 691 |
double DeterministicVariable::GetValue() |
1311 |
double DeterministicVariableImpl::GetValue() |
| 692 |
{ |
1312 |
{ |
| 693 |
if (next == count) next = 0; |
1313 |
if (next == count) next = 0; |
| 694 |
return data[next++]; |
1314 |
return data[next++]; |
| 695 |
} |
1315 |
} |
| 696 |
|
1316 |
|
| 697 |
RandomVariable* DeterministicVariable::Copy() const |
1317 |
RandomVariableBase* DeterministicVariableImpl::Copy() const |
| 698 |
{ |
1318 |
{ |
| 699 |
return new DeterministicVariable(*this); |
1319 |
return new DeterministicVariableImpl(*this); |
| 700 |
} |
1320 |
} |
| 701 |
|
1321 |
|
|
|
1322 |
DeterministicVariable::DeterministicVariable(double* d, uint32_t c) |
| 1323 |
: RandomVariable (DeterministicVariableImpl (d, c)) |
| 1324 |
{} |
| 702 |
|
1325 |
|
| 703 |
//----------------------------------------------------------------------------- |
1326 |
//----------------------------------------------------------------------------- |
| 704 |
//----------------------------------------------------------------------------- |
1327 |
//----------------------------------------------------------------------------- |
| 705 |
// LogNormalVariable |
1328 |
// LogNormalVariableImpl |
|
|
1329 |
class LogNormalVariableImpl : public RandomVariableBase { |
| 1330 |
public: |
| 1331 |
/** |
| 1332 |
* \param mu mu parameter of the lognormal distribution |
| 1333 |
* \param sigma sigma parameter of the lognormal distribution |
| 1334 |
*/ |
| 1335 |
LogNormalVariableImpl (double mu, double sigma); |
| 706 |
|
1336 |
|
| 707 |
RandomVariable* LogNormalVariable::Copy () const |
1337 |
/** |
|
|
1338 |
* \return A random value from this distribution |
| 1339 |
*/ |
| 1340 |
virtual double GetValue (); |
| 1341 |
virtual RandomVariableBase* Copy(void) const; |
| 1342 |
public: |
| 1343 |
/** |
| 1344 |
* \param mu mu parameter of the underlying normal distribution |
| 1345 |
* \param sigma sigma parameter of the underlying normal distribution |
| 1346 |
* \return A random number from the distribution specified by mu and sigma |
| 1347 |
*/ |
| 1348 |
static double GetSingleValue(double mu, double sigma); |
| 1349 |
private: |
| 1350 |
double m_mu; |
| 1351 |
double m_sigma; |
| 1352 |
}; |
| 1353 |
|
| 1354 |
|
| 1355 |
RandomVariableBase* LogNormalVariableImpl::Copy () const |
| 708 |
{ |
1356 |
{ |
| 709 |
return new LogNormalVariable (m_mu, m_sigma); |
1357 |
return new LogNormalVariableImpl (m_mu, m_sigma); |
| 710 |
} |
1358 |
} |
| 711 |
|
1359 |
|
| 712 |
LogNormalVariable::LogNormalVariable (double mu, double sigma) |
1360 |
LogNormalVariableImpl::LogNormalVariableImpl (double mu, double sigma) |
| 713 |
:m_mu(mu), m_sigma(sigma) |
1361 |
:m_mu(mu), m_sigma(sigma) |
| 714 |
{ |
1362 |
{ |
| 715 |
} |
1363 |
} |
|
Lines 741-757
LogNormalVariable::LogNormalVariable (do
|
Link Here
|
|---|
|
| 741 |
for x > 0. Lognormal random numbers are the exponentials of |
1389 |
for x > 0. Lognormal random numbers are the exponentials of |
| 742 |
gaussian random numbers */ |
1390 |
gaussian random numbers */ |
| 743 |
double |
1391 |
double |
| 744 |
LogNormalVariable::GetValue () |
1392 |
LogNormalVariableImpl::GetValue () |
| 745 |
{ |
1393 |
{ |
| 746 |
if(!RandomVariable::initialized) |
1394 |
if(!RandomVariableBase::initialized) |
| 747 |
{ |
1395 |
{ |
| 748 |
RandomVariable::Initialize(); |
1396 |
RandomVariableBase::Initialize(); |
| 749 |
} |
1397 |
} |
| 750 |
if(!m_generator) |
1398 |
if(!m_generator) |
| 751 |
{ |
1399 |
{ |
| 752 |
m_generator = new RngStream(); |
1400 |
m_generator = new RngStream(); |
| 753 |
m_generator->InitializeStream(); |
1401 |
m_generator->InitializeStream(); |
| 754 |
m_generator->ResetNthSubstream(RandomVariable::runNumber); |
1402 |
m_generator->ResetNthSubstream(RandomVariableBase::runNumber); |
| 755 |
} |
1403 |
} |
| 756 |
double u, v, r2, normal, z; |
1404 |
double u, v, r2, normal, z; |
| 757 |
|
1405 |
|
|
Lines 774-786
LogNormalVariable::GetValue ()
|
Link Here
|
|---|
|
| 774 |
return z; |
1422 |
return z; |
| 775 |
} |
1423 |
} |
| 776 |
|
1424 |
|
| 777 |
double LogNormalVariable::GetSingleValue (double mu, double sigma) |
1425 |
double LogNormalVariableImpl::GetSingleValue (double mu, double sigma) |
| 778 |
{ |
1426 |
{ |
| 779 |
if(!RandomVariable::m_static_generator) |
1427 |
if(!RandomVariableBase::m_static_generator) |
| 780 |
{ |
1428 |
{ |
| 781 |
RandomVariable::Initialize(); // sets the static package seed |
1429 |
RandomVariableBase::Initialize(); // sets the static package seed |
| 782 |
RandomVariable::m_static_generator = new RngStream(); |
1430 |
RandomVariableBase::m_static_generator = new RngStream(); |
| 783 |
RandomVariable::m_static_generator->InitializeStream(); |
1431 |
RandomVariableBase::m_static_generator->InitializeStream(); |
| 784 |
} |
1432 |
} |
| 785 |
double u, v, r2, normal, z; |
1433 |
double u, v, r2, normal, z; |
| 786 |
do |
1434 |
do |
|
Lines 801-829
double LogNormalVariable::GetSingleValue
|
Link Here
|
|---|
|
| 801 |
return z; |
1449 |
return z; |
| 802 |
} |
1450 |
} |
| 803 |
|
1451 |
|
|
|
1452 |
LogNormalVariable::LogNormalVariable (double mu, double sigma) |
| 1453 |
: RandomVariable (LogNormalVariableImpl (mu, sigma)) |
| 1454 |
{} |
| 1455 |
double |
| 1456 |
LogNormalVariable::GetSingleValue(double mu, double sigma) |
| 1457 |
{ |
| 1458 |
return LogNormalVariableImpl::GetSingleValue (mu, sigma); |
| 1459 |
} |
| 1460 |
|
| 1461 |
|
| 804 |
//----------------------------------------------------------------------------- |
1462 |
//----------------------------------------------------------------------------- |
| 805 |
//----------------------------------------------------------------------------- |
1463 |
//----------------------------------------------------------------------------- |
| 806 |
// TriangularVariable methods |
1464 |
// TriangularVariableImpl methods |
| 807 |
TriangularVariable::TriangularVariable() |
1465 |
class TriangularVariableImpl : public RandomVariableBase { |
|
|
1466 |
public: |
| 1467 |
/** |
| 1468 |
* Creates a triangle distribution random number generator in the |
| 1469 |
* range [0.0 .. 1.0), with mean of 0.5 |
| 1470 |
*/ |
| 1471 |
TriangularVariableImpl(); |
| 1472 |
|
| 1473 |
/** |
| 1474 |
* Creates a triangle distribution random number generator with the specified |
| 1475 |
* range |
| 1476 |
* \param s Low end of the range |
| 1477 |
* \param l High end of the range |
| 1478 |
* \param mean mean of the distribution |
| 1479 |
*/ |
| 1480 |
TriangularVariableImpl(double s, double l, double mean); |
| 1481 |
|
| 1482 |
TriangularVariableImpl(const TriangularVariableImpl& c); |
| 1483 |
|
| 1484 |
/** |
| 1485 |
* \return A value from this distribution |
| 1486 |
*/ |
| 1487 |
virtual double GetValue(); |
| 1488 |
virtual RandomVariableBase* Copy(void) const; |
| 1489 |
public: |
| 1490 |
/** |
| 1491 |
* \param s Low end of the range |
| 1492 |
* \param l High end of the range |
| 1493 |
* \param mean mean of the distribution |
| 1494 |
* \return A triangularly distributed random number between s and l |
| 1495 |
*/ |
| 1496 |
static double GetSingleValue(double s, double l, double mean); |
| 1497 |
private: |
| 1498 |
double m_min; |
| 1499 |
double m_max; |
| 1500 |
double m_mode; //easier to work with the mode internally instead of the mean |
| 1501 |
//they are related by the simple: mean = (min+max+mode)/3 |
| 1502 |
}; |
| 1503 |
|
| 1504 |
TriangularVariableImpl::TriangularVariableImpl() |
| 808 |
: m_min(0), m_max(1), m_mode(0.5) { } |
1505 |
: m_min(0), m_max(1), m_mode(0.5) { } |
| 809 |
|
1506 |
|
| 810 |
TriangularVariable::TriangularVariable(double s, double l, double mean) |
1507 |
TriangularVariableImpl::TriangularVariableImpl(double s, double l, double mean) |
| 811 |
: m_min(s), m_max(l), m_mode(3.0*mean-s-l) { } |
1508 |
: m_min(s), m_max(l), m_mode(3.0*mean-s-l) { } |
| 812 |
|
1509 |
|
| 813 |
TriangularVariable::TriangularVariable(const TriangularVariable& c) |
1510 |
TriangularVariableImpl::TriangularVariableImpl(const TriangularVariableImpl& c) |
| 814 |
: RandomVariable(c), m_min(c.m_min), m_max(c.m_max), m_mode(c.m_mode) { } |
1511 |
: RandomVariableBase(c), m_min(c.m_min), m_max(c.m_max), m_mode(c.m_mode) { } |
| 815 |
|
1512 |
|
| 816 |
double TriangularVariable::GetValue() |
1513 |
double TriangularVariableImpl::GetValue() |
| 817 |
{ |
1514 |
{ |
| 818 |
if(!RandomVariable::initialized) |
1515 |
if(!RandomVariableBase::initialized) |
| 819 |
{ |
1516 |
{ |
| 820 |
RandomVariable::Initialize(); |
1517 |
RandomVariableBase::Initialize(); |
| 821 |
} |
1518 |
} |
| 822 |
if(!m_generator) |
1519 |
if(!m_generator) |
| 823 |
{ |
1520 |
{ |
| 824 |
m_generator = new RngStream(); |
1521 |
m_generator = new RngStream(); |
| 825 |
m_generator->InitializeStream(); |
1522 |
m_generator->InitializeStream(); |
| 826 |
m_generator->ResetNthSubstream(RandomVariable::runNumber); |
1523 |
m_generator->ResetNthSubstream(RandomVariableBase::runNumber); |
| 827 |
} |
1524 |
} |
| 828 |
double u = m_generator->RandU01(); |
1525 |
double u = m_generator->RandU01(); |
| 829 |
if(u <= (m_mode - m_min) / (m_max - m_min) ) |
1526 |
if(u <= (m_mode - m_min) / (m_max - m_min) ) |
|
Lines 832-849
double TriangularVariable::GetValue()
|
Link Here
|
|---|
|
| 832 |
return m_max - sqrt( (1-u) * (m_max - m_min) * (m_max - m_mode) ); |
1529 |
return m_max - sqrt( (1-u) * (m_max - m_min) * (m_max - m_mode) ); |
| 833 |
} |
1530 |
} |
| 834 |
|
1531 |
|
| 835 |
RandomVariable* TriangularVariable::Copy() const |
1532 |
RandomVariableBase* TriangularVariableImpl::Copy() const |
| 836 |
{ |
1533 |
{ |
| 837 |
return new TriangularVariable(*this); |
1534 |
return new TriangularVariableImpl(*this); |
| 838 |
} |
1535 |
} |
| 839 |
|
1536 |
|
| 840 |
double TriangularVariable::GetSingleValue(double s, double l, double mean) |
1537 |
double TriangularVariableImpl::GetSingleValue(double s, double l, double mean) |
| 841 |
{ |
1538 |
{ |
| 842 |
if(!RandomVariable::m_static_generator) |
1539 |
if(!RandomVariableBase::m_static_generator) |
| 843 |
{ |
1540 |
{ |
| 844 |
RandomVariable::Initialize(); // sets the static package seed |
1541 |
RandomVariableBase::Initialize(); // sets the static package seed |
| 845 |
RandomVariable::m_static_generator = new RngStream(); |
1542 |
RandomVariableBase::m_static_generator = new RngStream(); |
| 846 |
RandomVariable::m_static_generator->InitializeStream(); |
1543 |
RandomVariableBase::m_static_generator->InitializeStream(); |
| 847 |
} |
1544 |
} |
| 848 |
double mode = 3.0*mean-s-l; |
1545 |
double mode = 3.0*mean-s-l; |
| 849 |
double u = m_static_generator->RandU01(); |
1546 |
double u = m_static_generator->RandU01(); |
|
Lines 852-857
double TriangularVariable::GetSingleValu
|
Link Here
|
|---|
|
| 852 |
else |
1549 |
else |
| 853 |
return l - sqrt( (1-u) * (l - s) * (l - mode) ); |
1550 |
return l - sqrt( (1-u) * (l - s) * (l - mode) ); |
| 854 |
} |
1551 |
} |
|
|
1552 |
|
| 1553 |
TriangularVariable::TriangularVariable() |
| 1554 |
: RandomVariable (TriangularVariableImpl ()) |
| 1555 |
{} |
| 1556 |
TriangularVariable::TriangularVariable(double s, double l, double mean) |
| 1557 |
: RandomVariable (TriangularVariableImpl (s,l,mean)) |
| 1558 |
{} |
| 1559 |
double |
| 1560 |
TriangularVariable::GetSingleValue(double s, double l, double mean) |
| 1561 |
{ |
| 1562 |
return TriangularVariableImpl::GetSingleValue (s,l,mean); |
| 1563 |
} |
| 1564 |
|
| 855 |
|
1565 |
|
| 856 |
|
1566 |
|
| 857 |
}//namespace ns3 |
1567 |
}//namespace ns3 |