Commit fe39596d86b7cd62b83e728160fcf84ac514f4cd
1 parent
7956c168
Updated code.
Showing
2 changed files
with
64 additions
and
74 deletions
include/GRan.hpp
| 1 | 1 | /*************************************************************************** |
| 2 | 2 | * GRan.hpp - Random number generator class * |
| 3 | 3 | * ----------------------------------------------------------------------- * |
| 4 | - * copyright (C) 2011-2013 by Juergen Knoedlseder * | |
| 4 | + * copyright (C) 2011-2014 by Juergen Knoedlseder * | |
| 5 | 5 | * ----------------------------------------------------------------------- * |
| 6 | 6 | * * |
| 7 | 7 | * This program is free software: you can redistribute it and/or modify * |
| ... | ... | @@ -71,16 +71,16 @@ protected: |
| 71 | 71 | void free_members(void); |
| 72 | 72 | |
| 73 | 73 | // Protected data members |
| 74 | - unsigned long long int m_seed; //!< Random number generator seed | |
| 75 | - unsigned long long int m_u; //!< u | |
| 76 | - unsigned long long int m_v; //!< v | |
| 77 | - unsigned long long int m_w; //!< w | |
| 74 | + unsigned long long int m_seed; //!< Random number generator seed | |
| 75 | + unsigned long long int m_value1; //!< Value 1 | |
| 76 | + unsigned long long int m_value2; //!< Value 2 | |
| 77 | + unsigned long long int m_value3; //!< Value 3 | |
| 78 | 78 | |
| 79 | 79 | // Poisson cache |
| 80 | - double m_oldm; | |
| 81 | - double m_sq; | |
| 82 | - double m_alxm; | |
| 83 | - double m_g; | |
| 80 | + double m_old_lambda; //!< Old lambda value | |
| 81 | + double m_sqrt_lambda; //!< sqrt(2*lambda) | |
| 82 | + double m_log_lambda; //!< log(lambda) | |
| 83 | + double m_exp_lambda; //!< exp(-lambda) | |
| 84 | 84 | }; |
| 85 | 85 | |
| 86 | 86 | ... | ... |
src/support/GRan.cpp
| 1 | 1 | /*************************************************************************** |
| 2 | 2 | * GRan.cpp - Random number generator class * |
| 3 | 3 | * ----------------------------------------------------------------------- * |
| 4 | - * copyright (C) 2011-2013 by Juergen Knoedlseder * | |
| 4 | + * copyright (C) 2011-2014 by Juergen Knoedlseder * | |
| 5 | 5 | * ----------------------------------------------------------------------- * |
| 6 | 6 | * * |
| 7 | 7 | * This program is free software: you can redistribute it and/or modify * |
| ... | ... | @@ -202,8 +202,6 @@ void GRan::seed(unsigned long long int seed) |
| 202 | 202 | |
| 203 | 203 | /***********************************************************************//** |
| 204 | 204 | * @brief Return 32-bit random unsigned integer |
| 205 | - * | |
| 206 | - * This method is inspired from Numerical Recipes Third Edition, page 343. | |
| 207 | 205 | ***************************************************************************/ |
| 208 | 206 | unsigned long int GRan::int32(void) |
| 209 | 207 | { |
| ... | ... | @@ -214,36 +212,32 @@ unsigned long int GRan::int32(void) |
| 214 | 212 | |
| 215 | 213 | /***********************************************************************//** |
| 216 | 214 | * @brief Return 64-bit random unsigned integer |
| 217 | - * | |
| 218 | - * This method is inspired from Numerical Recipes Third Edition, page 343. | |
| 219 | 215 | ***************************************************************************/ |
| 220 | 216 | unsigned long long int GRan::int64(void) |
| 221 | 217 | { |
| 222 | 218 | // Update u |
| 223 | - m_u = m_u * 2862933555777941757LL + 7046029254386353087LL; | |
| 219 | + m_value1 = m_value1 * 2862933555777941757LL + 7046029254386353087LL; | |
| 224 | 220 | |
| 225 | 221 | // Shuffle v |
| 226 | - m_v ^= m_v >> 17; | |
| 227 | - m_v ^= m_v << 31; | |
| 228 | - m_v ^= m_v >> 8; | |
| 222 | + m_value2 ^= m_value2 >> 17; | |
| 223 | + m_value2 ^= m_value2 << 31; | |
| 224 | + m_value2 ^= m_value2 >> 8; | |
| 229 | 225 | |
| 230 | 226 | // Update w |
| 231 | - m_w = 4294957665U * (m_w & 0xffffffff) + (m_w >> 32); | |
| 227 | + m_value3 = 4294957665U * (m_value3 & 0xffffffff) + (m_value3 >> 32); | |
| 232 | 228 | |
| 233 | 229 | // Compute x |
| 234 | - unsigned long long int x = m_u ^ (m_u << 21); | |
| 230 | + unsigned long long int x = m_value1 ^ (m_value1 << 21); | |
| 235 | 231 | x ^= x >> 35; |
| 236 | 232 | x ^= x << 4; |
| 237 | 233 | |
| 238 | 234 | // Return random value |
| 239 | - return ((x + m_v) ^ m_w); | |
| 235 | + return ((x + m_value2) ^ m_value3); | |
| 240 | 236 | } |
| 241 | 237 | |
| 242 | 238 | |
| 243 | 239 | /***********************************************************************//** |
| 244 | 240 | * @brief Returns random double precision floating value in range 0 to 1 |
| 245 | - * | |
| 246 | - * This method is inspired from Numerical Recipes Third Edition, page 343. | |
| 247 | 241 | ***************************************************************************/ |
| 248 | 242 | double GRan::uniform(void) |
| 249 | 243 | { |
| ... | ... | @@ -264,8 +258,6 @@ double GRan::uniform(void) |
| 264 | 258 | * This method may be used to simulate the occurence time of an event, where |
| 265 | 259 | * \f$\lambda\f$ is the mean event rate. Convsersely, \f$1/\lambda\f$ is the |
| 266 | 260 | * mean waiting time between events. |
| 267 | - * | |
| 268 | - * This method is inspired from Numerical Recipes Third Edition, page 362. | |
| 269 | 261 | * |
| 270 | 262 | * @todo Check that \f$\lambda>0\f$. |
| 271 | 263 | ***************************************************************************/ |
| ... | ... | @@ -293,51 +285,49 @@ double GRan::exp(const double& lambda) |
| 293 | 285 | * |
| 294 | 286 | * This method may be used to simulate the number of events in case that a |
| 295 | 287 | * given mean number of events is expected. |
| 296 | - * | |
| 297 | - * This method is inspired from Numerical Recipes Third Edition, page 362. | |
| 298 | 288 | ***************************************************************************/ |
| 299 | 289 | double GRan::poisson(const double& lambda) |
| 300 | 290 | { |
| 301 | 291 | // Declare result |
| 302 | - double em; | |
| 292 | + double value; | |
| 303 | 293 | |
| 304 | 294 | // Use direct method for small numbers ... |
| 305 | 295 | if (lambda < 12.0) { |
| 306 | - if (lambda != m_oldm) { | |
| 307 | - m_oldm = lambda; | |
| 308 | - m_g = std::exp(-lambda); | |
| 296 | + if (lambda != m_old_lambda) { | |
| 297 | + m_old_lambda = lambda; | |
| 298 | + m_exp_lambda = std::exp(-lambda); | |
| 309 | 299 | } |
| 310 | - em = -1.0; | |
| 311 | - double t = 1.0; | |
| 300 | + value = -1.0; | |
| 301 | + double tmp = 1.0; | |
| 312 | 302 | do { |
| 313 | - em += 1.0; | |
| 314 | - t *= uniform(); | |
| 315 | - } while (t > m_g); | |
| 303 | + value += 1.0; | |
| 304 | + tmp *= uniform(); | |
| 305 | + } while (tmp > m_exp_lambda); | |
| 316 | 306 | } // endif: direct method used |
| 317 | 307 | |
| 318 | 308 | // ... otherwise use rejection method |
| 319 | 309 | else { |
| 320 | - double t; | |
| 321 | - if (lambda != m_oldm) { | |
| 322 | - m_oldm = lambda; | |
| 323 | - m_sq = std::sqrt(2.0*lambda); | |
| 324 | - m_alxm = std::log(lambda); | |
| 325 | - m_g = lambda * m_alxm - gammalib::gammln(lambda+1.0); | |
| 310 | + double tmp; | |
| 311 | + if (lambda != m_old_lambda) { | |
| 312 | + m_old_lambda = lambda; | |
| 313 | + m_sqrt_lambda = std::sqrt(2.0*lambda); | |
| 314 | + m_log_lambda = std::log(lambda); | |
| 315 | + m_exp_lambda = lambda * m_log_lambda - gammalib::gammln(lambda+1.0); | |
| 326 | 316 | } |
| 327 | 317 | do { |
| 328 | - double y; | |
| 318 | + double factor; | |
| 329 | 319 | do { |
| 330 | - y = std::tan(gammalib::pi * uniform()); | |
| 331 | - em = m_sq * y + lambda; | |
| 332 | - } while (em < 0.0); | |
| 333 | - em = floor(em); | |
| 334 | - t = 0.9*(1.0+y*y) * | |
| 335 | - std::exp(em*m_alxm - gammalib::gammln(em+1.0)-m_g); | |
| 336 | - } while (uniform() > t); | |
| 320 | + factor = std::tan(gammalib::pi * uniform()); | |
| 321 | + value = m_sqrt_lambda * factor + lambda; | |
| 322 | + } while (value < 0.0); | |
| 323 | + value = floor(value); | |
| 324 | + tmp = 0.9*(1.0+factor*factor) * | |
| 325 | + std::exp(value*m_log_lambda - gammalib::gammln(value+1.0)-m_exp_lambda); | |
| 326 | + } while (uniform() > tmp); | |
| 337 | 327 | } |
| 338 | 328 | |
| 339 | 329 | // Return random deviate |
| 340 | - return em; | |
| 330 | + return value; | |
| 341 | 331 | } |
| 342 | 332 | |
| 343 | 333 | |
| ... | ... | @@ -384,9 +374,9 @@ std::string GRan::print(const GChatter& chatter) const |
| 384 | 374 | |
| 385 | 375 | // Append information |
| 386 | 376 | result.append("\n"+gammalib::parformat("Seed")+gammalib::str(m_seed)); |
| 387 | - result.append("\n"+gammalib::parformat("u")+gammalib::str(m_u)); | |
| 388 | - result.append("\n"+gammalib::parformat("v")+gammalib::str(m_v)); | |
| 389 | - result.append("\n"+gammalib::parformat("w")+gammalib::str(m_w)); | |
| 377 | + result.append("\n"+gammalib::parformat("Value 1")+gammalib::str(m_value1)); | |
| 378 | + result.append("\n"+gammalib::parformat("Value 2")+gammalib::str(m_value2)); | |
| 379 | + result.append("\n"+gammalib::parformat("Value 3")+gammalib::str(m_value3)); | |
| 390 | 380 | |
| 391 | 381 | } // endif: chatter was not silent |
| 392 | 382 | |
| ... | ... | @@ -407,20 +397,20 @@ std::string GRan::print(const GChatter& chatter) const |
| 407 | 397 | void GRan::init_members(unsigned long long int seed) |
| 408 | 398 | { |
| 409 | 399 | // Initialise members |
| 410 | - m_seed = seed; | |
| 411 | - m_v = 4101842887655102017LL; | |
| 412 | - m_w = 1; | |
| 413 | - m_oldm = -1.0; | |
| 414 | - m_sq = 0.0; | |
| 415 | - m_alxm = 0.0; | |
| 416 | - m_g = 0.0; | |
| 417 | - | |
| 418 | - // Initialise u, v, and w | |
| 419 | - m_u = m_seed ^ m_v; | |
| 400 | + m_seed = seed; | |
| 401 | + m_value2 = 4101842887655102017LL; | |
| 402 | + m_value3 = 1; | |
| 403 | + m_old_lambda = -1.0; | |
| 404 | + m_sqrt_lambda = 0.0; | |
| 405 | + m_log_lambda = 0.0; | |
| 406 | + m_exp_lambda = 0.0; | |
| 407 | + | |
| 408 | + // Initialise values | |
| 409 | + m_value1 = m_seed ^ m_value2; | |
| 420 | 410 | int64(); |
| 421 | - m_v = m_u; | |
| 411 | + m_value2 = m_value1; | |
| 422 | 412 | int64(); |
| 423 | - m_w = m_v; | |
| 413 | + m_value3 = m_value2; | |
| 424 | 414 | int64(); |
| 425 | 415 | |
| 426 | 416 | // Return |
| ... | ... | @@ -436,14 +426,14 @@ void GRan::init_members(unsigned long long int seed) |
| 436 | 426 | void GRan::copy_members(const GRan& ran) |
| 437 | 427 | { |
| 438 | 428 | // Copy members |
| 439 | - m_seed = ran.m_seed; | |
| 440 | - m_u = ran.m_u; | |
| 441 | - m_v = ran.m_v; | |
| 442 | - m_w = ran.m_w; | |
| 443 | - m_oldm = ran.m_oldm; | |
| 444 | - m_sq = ran.m_sq; | |
| 445 | - m_alxm = ran.m_alxm; | |
| 446 | - m_g = ran.m_g; | |
| 429 | + m_seed = ran.m_seed; | |
| 430 | + m_value1 = ran.m_value1; | |
| 431 | + m_value2 = ran.m_value2; | |
| 432 | + m_value3 = ran.m_value3; | |
| 433 | + m_old_lambda = ran.m_old_lambda; | |
| 434 | + m_sqrt_lambda = ran.m_sqrt_lambda; | |
| 435 | + m_log_lambda = ran.m_log_lambda; | |
| 436 | + m_exp_lambda = ran.m_exp_lambda; | |
| 447 | 437 | |
| 448 | 438 | // Return |
| 449 | 439 | return; | ... | ... |