vcglib/vcg/math/random_generator.h

76 lines
3.2 KiB
C++

/*#***************************************************************************
* RandomGenerator.h o o *
* o o *
* Visual Computing Group _ O _ *
* IEI Institute, CNUCE Institute, CNR Pisa \/)\/ *
* /\/| *
* Copyright(C) 1999 by Paolo Cignoni, Paolo Pingi, Claudio Rocchini | *
* All rights reserved. \ *
* *
* Permission to use, copy, modify, distribute and sell this software and *
* its documentation for any purpose is hereby granted without fee, provided *
* that the above copyright notice appear in all copies and that both that *
* copyright notice and this permission notice appear in supporting *
* documentation. the author makes no representations about the suitability *
* of this software for any purpose. It is provided "as is" without express *
* or implied warranty. *
* *
*****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
*****************************************************************************/
// RandomGenerator is derived from a STL extension of sgi:
// it is based on the Subtractive Ring method.
// See section 3.6 of Knuth for an implementation of the subtractive method in FORTRAN.
// Section 3.2.2 of Knuth analyzes this class of algorithms.
// (D. E. Knuth, The Art of Computer Programming. Volume 2: Seminumerical Algorithms, second edition. Addison-Wesley, 1981.) .
// Note: this code assumes that int is 32 bits.
#ifndef __VCG_RandomGenerator
#define __VCG_RandomGenerator
namespace vcg {
namespace math {
class RandomGenerator : public std::unary_function<unsigned int, unsigned int> {
private:
unsigned int _M_table[55];
size_t _M_index1;
size_t _M_index2;
public:
unsigned int operator()(unsigned int __limit) {
_M_index1 = (_M_index1 + 1) % 55;
_M_index2 = (_M_index2 + 1) % 55;
_M_table[_M_index1] = _M_table[_M_index1] - _M_table[_M_index2];
return _M_table[_M_index1] % __limit;
}
void _M_initialize(unsigned int __seed)
{
unsigned int __k = 1;
_M_table[54] = __seed;
size_t __i;
for (__i = 0; __i < 54; __i++) {
size_t __ii = (21 * (__i + 1) % 55) - 1;
_M_table[__ii] = __k;
__k = __seed - __k;
__seed = _M_table[__ii];
}
for (int __loop = 0; __loop < 4; __loop++) {
for (__i = 0; __i < 55; __i++)
_M_table[__i] = _M_table[__i] - _M_table[(1 + __i + 30) % 55];
}
_M_index1 = 0;
_M_index2 = 31;
}
RandomGenerator(unsigned int __seed) { _M_initialize(__seed); }
RandomGenerator() { _M_initialize(161803398u); }
};
} // end namespace math
} // end namespace vcg
#endif