|
|
|
| 1 |
|
// random TR1 header |
| 2 |
|
#pragma once |
| 3 |
|
#ifndef _RANDOM_ |
| 4 |
|
#define _RANDOM_ |
| 5 |
|
#ifndef RC_INVOKED |
| 6 |
|
#include <istream> |
| 7 |
|
#include <limits> |
| 8 |
|
#include <vector> |
| 9 |
|
#include <xtr1common> |
| 10 |
|
|
| 11 |
|
#pragma pack(push,_CRT_PACKING) |
| 12 |
|
#pragma warning(push,3) |
| 13 |
|
#pragma warning(disable: 4127 4244 4521 6294) |
| 14 |
|
|
| 15 |
|
#ifndef _BITS_BYTE |
| 16 |
|
#define _BITS_BYTE 8 |
| 17 |
|
#endif /* _BITS_BYTE */ |
| 18 |
|
|
| 19 |
|
#if defined(_DEBUG) || defined(_RNG_CHECK) |
| 20 |
|
#define _RNG_QUOTX(x) #x |
| 21 |
|
#define _RNG_QUOT(x) _RNG_QUOTX(x) |
| 22 |
|
#define _RNG_ASSERT(ex, msg) \ |
| 23 |
|
((ex) ? (void)0 : _Rng_abort(__FILE__ "(" _RNG_QUOT(__LINE__) "): " msg)) |
| 24 |
|
|
| 25 |
|
#else /* defined(_DEBUG) || defined(_RNG_CHECK) */ |
| 26 |
|
#define _RNG_ASSERT(ex, msg) ((void)0) |
| 27 |
|
#endif /* defined(_DEBUG) || defined(_RNG_CHECK) */ |
| 28 |
|
|
| 29 |
|
_STD_BEGIN |
| 30 |
|
namespace tr1 { // TR1 additions |
| 31 |
|
|
| 32 |
|
// CONSTANTS |
| 33 |
|
static const long double _Pi = 3.14159265358979323846264338327950288; |
| 34 |
|
static const long double _Exp1 = 2.71828182845904523536028747135266250; |
| 35 |
|
static const long double _Two32 = 4294967296.0; |
| 36 |
|
static const long double _Two31 = 2147483648.0; |
| 37 |
|
|
| 38 |
|
// HELPER FUNCTIONS |
| 39 |
|
_CRTIMP2_PURE __declspec(noreturn) void __CLRCALL_PURE_OR_CDECL |
| 40 |
|
_Xinvalid(_In_z_ const char *_Msg = ""); |
| 41 |
|
_CRTIMP2_PURE __declspec(noreturn) void __CLRCALL_PURE_OR_CDECL |
| 42 |
|
_Rng_abort(_In_z_ const char *_Msg); |
| 43 |
|
_CRTIMP2_PURE float __CLRCALL_PURE_OR_CDECL _XLgamma(float); |
| 44 |
|
_CRTIMP2_PURE double __CLRCALL_PURE_OR_CDECL _XLgamma(double); |
| 45 |
|
_CRTIMP2_PURE long double __CLRCALL_PURE_OR_CDECL _XLgamma(long double); |
| 46 |
|
|
| 47 |
|
// TEMPLATE FUNCTION _Nrand |
| 48 |
|
#define _NRAND(eng, resty) _Nrand(eng, (eng.min)(), (resty)1) |
| 49 |
|
|
| 50 |
|
template<class _Engine, |
| 51 |
|
class _Ety, |
| 52 |
|
class _Rty> |
| 53 |
|
_Rty _Nrand(_Engine& _Eng, _Ety _Emin, _Rty _Inc) |
| 54 |
|
{ // scale random value to [0, 1), integer engine |
| 55 |
|
return ((_Eng() - _Emin) |
| 56 |
|
/ ((_Rty)(_Eng.max)() - (_Rty)_Emin + _Inc)); |
| 57 |
|
} |
| 58 |
|
|
| 59 |
|
template<class _Engine, |
| 60 |
|
class _Rty> |
| 61 |
|
_Rty _Nrand(_Engine& _Eng, float _Emin, _Rty) |
| 62 |
|
{ // scale random value to [0, 1), float engine |
| 63 |
|
return ((_Eng() - _Emin) / ((_Eng.max)() - _Emin)); |
| 64 |
|
} |
| 65 |
|
|
| 66 |
|
template<class _Engine, |
| 67 |
|
class _Rty> |
| 68 |
|
_Rty _Nrand(_Engine& _Eng, double _Emin, _Rty) |
| 69 |
|
{ // scale random value to [0, 1), double engine |
| 342 |
|
|
| 343 |
|
result_type operator()() |
| 344 |
|
{ // return next value |
| 345 |
|
return (_Dist(_Eng)); |
| 346 |
|
} |
| 347 |
|
|
| 348 |
|
template<class _Ty> |
| 349 |
|
result_type operator()(_Ty _Value) |
| 350 |
|
{ // return next value that doesn't exceed _Value |
| 351 |
|
return (_Dist(_Eng, _Value)); |
| 352 |
|
} |
| 353 |
|
|
| 354 |
|
engine_value_type& engine() |
| 355 |
|
{ // return reference to engine object |
| 356 |
|
return (_Eng._Get()); |
| 357 |
|
} |
| 358 |
|
|
| 359 |
|
const engine_value_type& engine() const |
| 360 |
|
{ // return const reference to engine object |
| 361 |
|
return (_Eng._Get()); |
| 362 |
|
} |
| 363 |
|
|
| 364 |
|
distribution_type& distribution() |
| 365 |
|
{ // return reference to distribution object |
| 366 |
|
return (_Dist); |
| 367 |
|
} |
| 368 |
|
|
| 369 |
|
const distribution_type& distribution() const |
| 370 |
|
{ // return const reference to distribution object |
| 371 |
|
return (_Dist); |
| 372 |
|
} |
| 373 |
|
|
| 374 |
|
result_type (min)() const |
| 375 |
|
{ // return minimum value in distribution's range |
| 376 |
|
return ((_Dist.min)()); |
| 377 |
|
} |
| 378 |
|
|
| 379 |
|
result_type (max)() const |
| 380 |
|
{ // return maximum value in distribution's range |
| 381 |
|
return ((_Dist.max)()); |
| 382 |
|
} |
| 383 |
|
|
| 384 |
|
private: |
| 385 |
|
_Eng_wrapper _Eng; |
| 386 |
|
distribution_type _Dist; |
| 387 |
|
}; |
| 388 |
|
|
| 389 |
|
// MULTIPLE PRECISION MATH FUNCTIONS |
| 390 |
|
|
| 391 |
|
#ifdef _ULONGLONG |
| 392 |
|
typedef _ULONGLONG _Max_type; |
| 393 |
|
|
| 394 |
|
#else /* _ULONGLONG */ |
| 395 |
|
typedef unsigned long _Max_type; |
| 396 |
|
#endif /* _ULONGLONG */ |
| 397 |
|
|
| 398 |
|
static const int _MP_len = 5; |
| 399 |
|
typedef _Max_type _MP_arr[_MP_len]; |
| 400 |
|
|
| 401 |
|
_CRTIMP2_PURE _Max_type __CLRCALL_PURE_OR_CDECL _MP_Get(_MP_arr); |
| 402 |
|
_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL _MP_Add(_MP_arr, _Max_type); |
| 403 |
|
_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL _MP_Mul(_MP_arr, _Max_type, _Max_type); |
| 404 |
|
_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL _MP_Rem(_MP_arr, _Max_type); |
| 405 |
|
|
| 406 |
|
// TEMPLATE CLASS linear_congruential |
| 407 |
|
template<class _Ity, |
| 408 |
|
class _Ty, |
| 409 |
|
_Max_type _Ax, |
| 410 |
|
_Max_type _Cx, |
| 411 |
|
_Max_type _Mx> |
| 412 |
|
struct _Mul_mod |
| 413 |
|
{ // template class for linear congruential generator where |
| 414 |
|
// _Ty is large enough to hold intermediate result without overflow |
| 415 |
|
_Mul_mod(_Ty _Val = 0) |
| 416 |
|
: _Prev(_Val) |
| 417 |
|
{ // construct |
| 418 |
|
} |
| 419 |
|
|
| 420 |
|
_Ty operator()() |
| 421 |
|
{ // return next value |
| 422 |
|
static _Ty _Zero = 0; // to quiet diagnostics |
| 423 |
|
_Ty _Divisor = (_Ty)_Mx; |
| 424 |
|
|
| 425 |
|
_Prev = _Mx ? ((_Ity)_Ax * _Prev + (_Ty)_Cx) % _Divisor |
| 426 |
|
: ((_Ity)_Ax * _Prev + (_Ty)_Cx); |
| 427 |
|
if (_Prev < _Zero) |
| 428 |
|
_Prev += (_Ty)_Mx; |
| 429 |
|
return (_Prev); |
| 430 |
|
} |
| 431 |
|
|
| 432 |
|
_Ty _Prev; |
| 433 |
|
}; |
| 434 |
|
|
| 435 |
|
template<class _Ty, |
| 436 |
|
_Max_type _Ax, |
| 437 |
|
_Max_type _Cx, |
| 438 |
|
_Max_type _Mx> |
| 439 |
|
class _Mult_prec |
| 440 |
|
{ // template class for linear congruential generator using |
| 441 |
|
// multiple precision arithmetic to avoid overflows |
| 442 |
|
public: |
| 443 |
|
_Mult_prec(_Ty _Val = 0) |
| 444 |
|
: _Prev(_Val) |
| 445 |
|
{ // construct |
| 446 |
|
} |
| 447 |
|
|
| 448 |
|
_Ty operator()() |
| 449 |
|
{ // return next value |
| 450 |
|
_MP_arr _Wx; |
| 451 |
|
_MP_Mul(_Wx, _Prev, _Ax); |
| 452 |
|
_MP_Add(_Wx, _Cx); |
| 453 |
|
_MP_Rem(_Wx, _Mx); |
| 454 |
|
_Prev = _MP_Get(_Wx); |
| 455 |
|
return (_Prev); |
| 456 |
|
} |
| 457 |
|
|
| 458 |
|
_Ty _Prev; |
| 459 |
|
}; |
| 460 |
|
|
| 461 |
|
#ifdef _ULONGLONG |
| 462 |
|
template<class _Ty, |
| 463 |
|
_Max_type _Ax, |
| 464 |
|
_Max_type _Cx, |
| 465 |
|
_Max_type _Mx, |
| 466 |
|
bool> |
| 467 |
|
struct _Select_ulonglong |
| 468 |
|
{ // unsigned long long too small, use multiple precision |
| 469 |
|
typedef _Mult_prec<_Ty, _Ax, _Cx, _Mx> _Type; |
| 470 |
|
}; |
| 471 |
|
|
| 472 |
|
template<class _Ty, |
| 473 |
|
_Max_type _Ax, |
| 474 |
|
_Max_type _Cx, |
| 475 |
|
_Max_type _Mx> |
| 476 |
|
struct _Select_ulonglong<_Ty, _Ax, _Cx, _Mx, true> |
| 477 |
|
{ // unsigned long long can hold intermediate result |
| 478 |
|
typedef _Mul_mod<_ULONGLONG, _Ty, _Ax, _Cx, _Mx> _Type; |
| 479 |
|
}; |
| 480 |
|
|
| 481 |
|
template<class _Ty, |
| 482 |
|
_Max_type _Ax, |
| 483 |
|
_Max_type _Cx, |
| 484 |
|
_Max_type _Mx, |
| 485 |
|
bool> |
| 486 |
|
struct _Select_ulong |
| 487 |
|
{ // unsigned long too small, try unsigned long long |
| 488 |
|
typedef typename _Select_ulonglong<_Ty, _Ax, _Cx, _Mx, |
| 489 |
|
_Cx < _ULLONG_MAX && _Mx <= (_ULLONG_MAX - _Cx) / _Ax>::_Type _Type; |
| 490 |
|
}; |
| 491 |
|
|
| 492 |
|
#else /* _ULONGLONG */ |
| 493 |
|
template<class _Ty, |
| 494 |
|
_Max_type _Ax, |
| 495 |
|
_Max_type _Cx, |
| 496 |
|
_Max_type _Mx, |
| 497 |
|
bool> |
| 498 |
|
struct _Select_ulong |
| 499 |
|
{ // unsigned long too small, use multiple precision |
| 500 |
|
typedef _Mult_prec<_Ty, _Ax, _Cx, _Mx> _Type; |
| 501 |
|
}; |
| 502 |
|
#endif /* _ULONGLONG */ |
| 503 |
|
|
| 504 |
|
template<class _Ty, |
| 505 |
|
_Max_type _Ax, |
| 506 |
|
_Max_type _Cx, |
| 507 |
|
_Max_type _Mx> |
| 508 |
|
struct _Select_ulong<_Ty, _Ax, _Cx, _Mx, true> |
| 509 |
|
{ // unsigned long can hold intermediate result |
| 510 |
|
typedef _Mul_mod<unsigned long, _Ty, _Ax, _Cx, _Mx> _Type; |
| 511 |
|
}; |
| 3409 |
|
{ // class to generate random numbers (from hardware where available) |
| 3410 |
|
public: |
| 3411 |
|
typedef unsigned int result_type; |
| 3412 |
|
|
| 3413 |
|
explicit random_device(const std::string& = "") |
| 3414 |
|
{ // construct |
| 3415 |
|
(*this)(); // force early failure if bad engine |
| 3416 |
|
} |
| 3417 |
|
|
| 3418 |
|
result_type (min)() const |
| 3419 |
|
{ // return minimum possible generated value |
| 3420 |
|
return (0); |
| 3421 |
|
} |
| 3422 |
|
|
| 3423 |
|
result_type (max)() const |
| 3424 |
|
{ // return maximum possible generated value |
| 3425 |
|
return ((result_type)-1); |
| 3426 |
|
} |
| 3427 |
|
|
| 3428 |
|
double entropy() |
| 3429 |
|
{ // return entropy of random number source |
| 3430 |
|
return (32.0); |
| 3431 |
|
} |
| 3432 |
|
|
| 3433 |
|
result_type operator()() |
| 3434 |
|
{ // return next value |
| 3435 |
|
return (_Random_device()); |
| 3436 |
|
} |
| 3437 |
|
|
| 3438 |
|
private: |
| 3439 |
|
random_device(const random_device&); |
| 3440 |
|
random_device& operator=(const random_device&); |
| 3441 |
|
}; |
| 3442 |
|
|
| 3443 |
|
} // namespace tr1 |
| 3444 |
|
|
| 3445 |
|
_STD_END |
| 3446 |
|
#pragma warning(default: 4127 4244 4521 6294) |
| 3447 |
|
#pragma warning(pop) |
| 3448 |
|
#pragma pack(pop) |
| 3449 |
|
|
| 3450 |
|
#endif /* RC_INVOKED */ |
| 3451 |
|
#endif /* _RANDOM_ */ |
| 3452 |
|
|
| 3453 |
|
/* |
| 3454 |
|
* Copyright (c) 1992-2008 by P.J. Plauger. ALL RIGHTS RESERVED. |
| 3455 |
|
* Consult your license regarding permissions and restrictions. |
| 3456 |
|
V5.05:0009 */ |
| 3457 |
|
|
|
|
|