|
|
|
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 |
|
|
|
|
|