Commit 9aa53350 by Paolo Carlini Committed by Paolo Carlini

random (class subtract_with_carry_01): Add.

2006-08-22  Paolo Carlini  <pcarlini@suse.de>

	* include/tr1/random (class subtract_with_carry_01): Add.
	* include/tr1/random.tcc (subtract_with_carry_01<>::
	seed(unsigned long), subtract_with_carry_01<>::
	seed(_Gen&, false_type), subtract_with_carry_01<>::
	operator(), operator<<(std::basic_ostream<>&, const
	subtract_with_carry_01<>&), operator>>(std::basic_istream<>&,
	subtract_with_carry_01<>&)): Define.
	* testsuite/tr1/5_numerical_facilities/random/ranlux3_01.cc:
	New.
	* testsuite/tr1/5_numerical_facilities/random/ranlux4_01.cc:
	Likewise.
	* testsuite/tr1/5_numerical_facilities/random/
	subtract_with_carry_01/cons/seed1.cc: Likewise.
	* testsuite/tr1/5_numerical_facilities/random/
	subtract_with_carry_01/cons/seed2.cc: Likewise.
	* testsuite/tr1/5_numerical_facilities/random/
	subtract_with_carry_01/cons/default.cc: Likewise.
	* testsuite/tr1/5_numerical_facilities/random/
	subtract_with_carry_01/cons/gen1.cc: Likewise.
	* testsuite/tr1/5_numerical_facilities/random/
	subtract_with_carry_01/requirements/typedefs.cc: Likewise.
	* testsuite/tr1/5_numerical_facilities/random/
	subtract_with_carry_01/operators/equal.cc: Likewise.
	* testsuite/tr1/5_numerical_facilities/random/
	subtract_with_carry_01/operators/not_equal.cc: Likewise.
	* testsuite/tr1/5_numerical_facilities/random/
	subtract_with_carry_01/operators/serialize.cc: Likewise.

	* docs/html/ext/howto.html: Add two implemented TR1 issues.

	* include/tr1/random.tcc (struct _To_Unsigned_Type): Move...
	* include/tr1/random: ... here.
	(class subtract_with_carry): Use it everywhere.

	* testsuite/tr1/5_numerical_facilities/random/
	subtract_with_carry/cons/seed1.cc: Qualify 1 as 1UL.
	* testsuite/tr1/5_numerical_facilities/random/
	subtract_with_carry/cons/seed2.cc: Likewise.
	* testsuite/tr1/5_numerical_facilities/random/
	subtract_with_carry/cons/default.cc: Likewise.
	* testsuite/tr1/5_numerical_facilities/random/
	subtract_with_carry/cons/gen1.cc: Likewise.
	* testsuite/tr1/5_numerical_facilities/random/
	subtract_with_carry/requirements/typedefs.cc: Likewise.
	* testsuite/tr1/5_numerical_facilities/random/
	subtract_with_carry/operators/equal.cc: Likewise.
	* testsuite/tr1/5_numerical_facilities/random/
	subtract_with_carry/operators/not_equal.cc: Likewise.
	* testsuite/tr1/5_numerical_facilities/random/
	subtract_with_carry/operators/serialize.cc: Likewise.

From-SVN: r116327
parent 8a613cae
2006-08-22 Paolo Carlini <pcarlini@suse.de>
* include/tr1/random (class subtract_with_carry_01): Add.
* include/tr1/random.tcc (subtract_with_carry_01<>::
seed(unsigned long), subtract_with_carry_01<>::
seed(_Gen&, false_type), subtract_with_carry_01<>::
operator(), operator<<(std::basic_ostream<>&, const
subtract_with_carry_01<>&), operator>>(std::basic_istream<>&,
subtract_with_carry_01<>&)): Define.
* testsuite/tr1/5_numerical_facilities/random/ranlux3_01.cc:
New.
* testsuite/tr1/5_numerical_facilities/random/ranlux4_01.cc:
Likewise.
* testsuite/tr1/5_numerical_facilities/random/
subtract_with_carry_01/cons/seed1.cc: Likewise.
* testsuite/tr1/5_numerical_facilities/random/
subtract_with_carry_01/cons/seed2.cc: Likewise.
* testsuite/tr1/5_numerical_facilities/random/
subtract_with_carry_01/cons/default.cc: Likewise.
* testsuite/tr1/5_numerical_facilities/random/
subtract_with_carry_01/cons/gen1.cc: Likewise.
* testsuite/tr1/5_numerical_facilities/random/
subtract_with_carry_01/requirements/typedefs.cc: Likewise.
* testsuite/tr1/5_numerical_facilities/random/
subtract_with_carry_01/operators/equal.cc: Likewise.
* testsuite/tr1/5_numerical_facilities/random/
subtract_with_carry_01/operators/not_equal.cc: Likewise.
* testsuite/tr1/5_numerical_facilities/random/
subtract_with_carry_01/operators/serialize.cc: Likewise.
* docs/html/ext/howto.html: Add two implemented TR1 issues.
* include/tr1/random.tcc (struct _To_Unsigned_Type): Move...
* include/tr1/random: ... here.
(class subtract_with_carry): Use it everywhere.
* testsuite/tr1/5_numerical_facilities/random/
subtract_with_carry/cons/seed1.cc: Qualify 1 as 1UL.
* testsuite/tr1/5_numerical_facilities/random/
subtract_with_carry/cons/seed2.cc: Likewise.
* testsuite/tr1/5_numerical_facilities/random/
subtract_with_carry/cons/default.cc: Likewise.
* testsuite/tr1/5_numerical_facilities/random/
subtract_with_carry/cons/gen1.cc: Likewise.
* testsuite/tr1/5_numerical_facilities/random/
subtract_with_carry/requirements/typedefs.cc: Likewise.
* testsuite/tr1/5_numerical_facilities/random/
subtract_with_carry/operators/equal.cc: Likewise.
* testsuite/tr1/5_numerical_facilities/random/
subtract_with_carry/operators/not_equal.cc: Likewise.
* testsuite/tr1/5_numerical_facilities/random/
subtract_with_carry/operators/serialize.cc: Likewise.
2006-08-20 Paolo Carlini <pcarlini@suse.de> 2006-08-20 Paolo Carlini <pcarlini@suse.de>
* include/tr1/random (gamma_distribution<>::_M_initialize, * include/tr1/random (gamma_distribution<>::_M_initialize,
......
...@@ -574,6 +574,18 @@ ...@@ -574,6 +574,18 @@
<code>at(const key_type&amp;)</code> to <code>std::map</code>. <code>at(const key_type&amp;)</code> to <code>std::map</code>.
</dd> </dd>
<dt><a href="lwg-defects.html#508">508</a>:
<em>Bad parameters for ranlux64_base_01</em>
</dt>
<dd>Fix the parameters.
</dd>
<dt><a href="lwg-active.html#512">512</a>:
<em>Seeding subtract_with_carry_01 from a single unsigned long</em>
</dt>
<dd>Construct a <code>linear_congruential</code> engine and seed with it.
</dd>
<dt><a href="lwg-active.html#538">538</a>: <dt><a href="lwg-active.html#538">538</a>:
<em>DR 538. 241 again: Does unique_copy() require CopyConstructible <em>DR 538. 241 again: Does unique_copy() require CopyConstructible
and Assignable?</em> and Assignable?</em>
......
...@@ -85,6 +85,31 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) ...@@ -85,6 +85,31 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
template<typename _UIntType, int __w> template<typename _UIntType, int __w>
struct _Shift<_UIntType, __w, true> struct _Shift<_UIntType, __w, true>
{ static const _UIntType __value = _UIntType(1) << __w; }; { static const _UIntType __value = _UIntType(1) << __w; };
template<typename _ValueT>
struct _To_Unsigned_Type
{ typedef _ValueT _Type; };
template<>
struct _To_Unsigned_Type<short>
{ typedef unsigned short _Type; };
template<>
struct _To_Unsigned_Type<int>
{ typedef unsigned int _Type; };
template<>
struct _To_Unsigned_Type<long>
{ typedef unsigned long _Type; };
#ifdef _GLIBCXX_USE_LONG_LONG
template<>
struct _To_Unsigned_Type<long long>
{ typedef unsigned long long _Type; };
#endif
typedef _Select<(sizeof(unsigned) == 4),
unsigned, unsigned long>::_Type _UInt32Type;
} // anonymous namespace } // anonymous namespace
/* /*
...@@ -673,7 +698,7 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) ...@@ -673,7 +698,7 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
* type large enough to store values up to m." * type large enough to store values up to m."
* *
* @if maint * @if maint
* @var _M_x The state of te generator. This is a ring buffer. * @var _M_x The state of the generator. This is a ring buffer.
* @var _M_carry The carry. * @var _M_carry The carry.
* @var _M_p Current index of x(i - r). * @var _M_p Current index of x(i - r).
* @endif * @endif
...@@ -724,8 +749,10 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) ...@@ -724,8 +749,10 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
{ this->seed(__value); } { this->seed(__value); }
/** /**
* Constructs a % subtract_with_carry random number generator seeded from * Constructs a %subtract_with_carry random number generator engine
* the PAD iterated by [__first, last). * seeded from the generator function @p __g.
*
* @param __g The seed generator function.
*/ */
template<class _Gen> template<class _Gen>
subtract_with_carry(_Gen& __g) subtract_with_carry(_Gen& __g)
...@@ -734,10 +761,6 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) ...@@ -734,10 +761,6 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
/** /**
* Seeds the initial state @f$ x_0 @f$ of the random number generator. * Seeds the initial state @f$ x_0 @f$ of the random number generator.
* *
* @note This implementation follows the tr1 specification but will
* obviously not work correctly on all platforms, since it has hardcoded
* values that may overflow ints on some platforms.
*
* N1688[4.19] modifies this as follows. * N1688[4.19] modifies this as follows.
* If @p __value == 0, sets value to 19780503. In any case, with a linear * If @p __value == 0, sets value to 19780503. In any case, with a linear
* congruential generator lcg(i) having parameters @f$ m_{lcg} = * congruential generator lcg(i) having parameters @f$ m_{lcg} =
...@@ -854,13 +877,210 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) ...@@ -854,13 +877,210 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
seed(_Gen& __g, false_type); seed(_Gen& __g, false_type);
private: private:
int _M_p; typedef typename _To_Unsigned_Type<_IntType>::_Type _UIntType;
result_type _M_x[long_lag];
result_type _M_carry; _UIntType _M_x[long_lag];
_UIntType _M_carry;
int _M_p;
}; };
/** /**
* @brief The Marsaglia-Zaman generator (floats version).
*
* @if maint
* @var _M_x The state of the generator. This is a ring buffer.
* @var _M_carry The carry.
* @var _M_p Current index of x(i - r).
* @var _M_npows Precomputed negative powers of 2.
* @endif
*/
template<typename _RealType, int __w, int __s, int __r>
class subtract_with_carry_01;
template<typename _RealType, int __w, int __s, int __r,
typename _CharT, typename _Traits>
std::basic_ostream<_CharT, _Traits>&
operator<<(std::basic_ostream<_CharT, _Traits>& __os,
const subtract_with_carry_01<_RealType, __w, __s, __r>& __x);
template<typename _RealType, int __w, int __s, int __r,
typename _CharT, typename _Traits>
std::basic_istream<_CharT, _Traits>&
operator>>(std::basic_istream<_CharT, _Traits>& __is,
subtract_with_carry_01<_RealType, __w, __s, __r>& __x);
template<typename _RealType, int __w, int __s, int __r>
class subtract_with_carry_01
{
public:
/** The type of the generated random value. */
typedef _RealType result_type;
// parameter values
static const int word_size = __w;
static const int long_lag = __r;
static const int short_lag = __s;
public:
/**
* Constructs a default-initialized % subtract_with_carry_01 random
* number generator.
*/
subtract_with_carry_01()
{ this->seed(); }
/**
* Constructs an explicitly seeded % subtract_with_carry_01 random number
* generator.
*/
explicit
subtract_with_carry_01(unsigned long __value)
{ this->seed(__value); }
/**
* Constructs a % subtract_with_carry_01 random number generator engine
* seeded from the generator function @p __g.
*
* @param __g The seed generator function.
*/
template<class _Gen>
subtract_with_carry_01(_Gen& __g)
{ this->seed(__g); }
/**
* Seeds the initial state @f$ x_0 @f$ of the random number generator.
*/
void
seed(unsigned long __value = 19780503);
/**
* Seeds the initial state @f$ x_0 @f$ of the % subtract_with_carry_01
* random number generator.
*/
template<class _Gen>
void
seed(_Gen& __g)
{ seed(__g, typename is_fundamental<_Gen>::type()); }
/**
* Gets the minimum value of the range of random floats
* returned by this generator.
*/
result_type
min() const
{ return 0.0; }
/**
* Gets the maximum value of the range of random floats
* returned by this generator.
*/
result_type
max() const
{ return 1.0; }
/**
* Gets the next random number in the sequence.
*/
result_type
operator()();
/**
* Compares two % subtract_with_carry_01 random number generator objects
* of the same type for equality.
*
* @param __lhs A % subtract_with_carry_01 random number generator object.
* @param __rhs Another % subtract_with_carry_01 random number generator
* object.
*
* @returns true if the two objects are equal, false otherwise.
*/
friend bool
operator==(const subtract_with_carry_01& __lhs,
const subtract_with_carry_01& __rhs)
{
for (int __i = 0; __i < long_lag; ++__i)
if (!std::equal(__lhs._M_x[__i], __lhs._M_x[__i] + __n,
__rhs._M_x[__i]))
return false;
return true;
}
/**
* Compares two % subtract_with_carry_01 random number generator objects
* of the same type for inequality.
*
* @param __lhs A % subtract_with_carry_01 random number generator object.
* @param __rhs Another % subtract_with_carry_01 random number generator
* object.
*
* @returns true if the two objects are not equal, false otherwise.
*/
friend bool
operator!=(const subtract_with_carry_01& __lhs,
const subtract_with_carry_01& __rhs)
{ return !(__lhs == __rhs); }
/**
* Inserts the current state of a % subtract_with_carry_01 random number
* generator engine @p __x into the output stream @p __os.
*
* @param __os An output stream.
* @param __x A % subtract_with_carry_01 random number generator engine.
*
* @returns The output stream with the state of @p __x inserted or in
* an error state.
*/
template<typename _RealType1, int __w1, int __s1, int __r1,
typename _CharT, typename _Traits>
friend std::basic_ostream<_CharT, _Traits>&
operator<<(std::basic_ostream<_CharT, _Traits>& __os,
const subtract_with_carry_01<_RealType1, __w1, __s1,
__r1>& __x);
/**
* Extracts the current state of a % subtract_with_carry_01 random number
* generator engine @p __x from the input stream @p __is.
*
* @param __is An input stream.
* @param __x A % subtract_with_carry_01 random number generator engine.
*
* @returns The input stream with the state of @p __x extracted or in
* an error state.
*/
template<typename _RealType1, int __w1, int __s1, int __r1,
typename _CharT, typename _Traits>
friend std::basic_istream<_CharT, _Traits>&
operator>>(std::basic_istream<_CharT, _Traits>& __is,
subtract_with_carry_01<_RealType1, __w1, __s1, __r1>& __x);
private:
template<class _Gen>
void
seed(_Gen& __g, true_type)
{ return seed(static_cast<unsigned long>(__g)); }
template<class _Gen>
void
seed(_Gen& __g, false_type);
private:
static const int __n = (__w + 31) / 32;
_UInt32Type _M_x[long_lag][__n];
_RealType _M_npows[__n];
_UInt32Type _M_carry;
int _M_p;
};
typedef subtract_with_carry_01<float, 24, 10, 24> ranlux_base_01;
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 508. Bad parameters for ranlux64_base_01.
typedef subtract_with_carry_01<double, 48, 5, 12> ranlux64_base_01;
/**
* Produces random numbers from some base engine by discarding blocks of * Produces random numbers from some base engine by discarding blocks of
* data. * data.
* *
...@@ -927,7 +1147,7 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) ...@@ -927,7 +1147,7 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
: _M_b(__s), _M_n(0) { } : _M_b(__s), _M_n(0) { }
/** /**
* Generator constructs a %discard_block engine. * Generator construct a %discard_block engine.
* *
* @param __g A seed generator function. * @param __g A seed generator function.
*/ */
...@@ -1056,7 +1276,7 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) ...@@ -1056,7 +1276,7 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
* James's luxury-level-3 integer adaptation of Luescher's generator. * James's luxury-level-3 integer adaptation of Luescher's generator.
*/ */
typedef discard_block< typedef discard_block<
subtract_with_carry<unsigned long, (1 << 24), 10, 24>, subtract_with_carry<unsigned long, (1UL << 24), 10, 24>,
223, 223,
24 24
> ranlux3; > ranlux3;
...@@ -1065,11 +1285,23 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) ...@@ -1065,11 +1285,23 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
* James's luxury-level-4 integer adaptation of Luescher's generator. * James's luxury-level-4 integer adaptation of Luescher's generator.
*/ */
typedef discard_block< typedef discard_block<
subtract_with_carry<unsigned long, (1 << 24), 10, 24>, subtract_with_carry<unsigned long, (1UL << 24), 10, 24>,
389, 389,
24 24
> ranlux4; > ranlux4;
typedef discard_block<
subtract_with_carry_01<float, 24, 10, 24>,
223,
24
> ranlux3_01;
typedef discard_block<
subtract_with_carry_01<float, 24, 10, 24>,
389,
24
> ranlux4_01;
/** /**
* A random number generator adaptor class that combines two random number * A random number generator adaptor class that combines two random number
...@@ -1863,14 +2095,14 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) ...@@ -1863,14 +2095,14 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
// NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined. // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
normal_distribution<_RealType> _M_nd; normal_distribution<_RealType> _M_nd;
_IntType _M_t;
_RealType _M_p;
_RealType _M_q; _RealType _M_q;
#if _GLIBCXX_USE_C99_MATH_TR1 #if _GLIBCXX_USE_C99_MATH_TR1
_RealType _M_d1, _M_d2, _M_s1, _M_s2, _M_c, _RealType _M_d1, _M_d2, _M_s1, _M_s2, _M_c,
_M_a1, _M_a123, _M_s, _M_lf, _M_lp1p; _M_a1, _M_a123, _M_s, _M_lf, _M_lp1p;
#endif #endif
_RealType _M_p;
_IntType _M_t;
bool _M_easy; bool _M_easy;
}; };
......
...@@ -32,7 +32,7 @@ namespace std ...@@ -32,7 +32,7 @@ namespace std
_GLIBCXX_BEGIN_NAMESPACE(tr1) _GLIBCXX_BEGIN_NAMESPACE(tr1)
/* /*
* Implementation-space details. * (Further) implementation-space details.
*/ */
namespace namespace
{ {
...@@ -101,29 +101,6 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) ...@@ -101,29 +101,6 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
static const std::streamsize __value = static const std::streamsize __value =
2 + std::numeric_limits<_RealType>::digits * 3010/10000; 2 + std::numeric_limits<_RealType>::digits * 3010/10000;
}; };
template<typename _ValueT>
struct _To_Unsigned_Type
{ typedef _ValueT _Type; };
template<>
struct _To_Unsigned_Type<short>
{ typedef unsigned short _Type; };
template<>
struct _To_Unsigned_Type<int>
{ typedef unsigned int _Type; };
template<>
struct _To_Unsigned_Type<long>
{ typedef unsigned long _Type; };
#ifdef _GLIBCXX_USE_LONG_LONG
template<>
struct _To_Unsigned_Type<long long>
{ typedef unsigned long long _Type; };
#endif
} // anonymous namespace } // anonymous namespace
...@@ -376,7 +353,7 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) ...@@ -376,7 +353,7 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
__lcg(__value); __lcg(__value);
for (int __i = 0; __i < long_lag; ++__i) for (int __i = 0; __i < long_lag; ++__i)
_M_x[__i] = __mod<_IntType, 1, 0, modulus>(__lcg()); _M_x[__i] = __mod<_UIntType, 1, 0, modulus>(__lcg());
_M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0; _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0;
_M_p = 0; _M_p = 0;
...@@ -388,13 +365,7 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) ...@@ -388,13 +365,7 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
subtract_with_carry<_IntType, __m, __s, __r>:: subtract_with_carry<_IntType, __m, __s, __r>::
seed(_Gen& __gen, false_type) seed(_Gen& __gen, false_type)
{ {
const int __n = (std::numeric_limits<_IntType>::digits + 31) / 32; const int __n = (std::numeric_limits<_UIntType>::digits + 31) / 32;
typedef typename _Select<(sizeof(unsigned) == 4),
unsigned, unsigned long>::_Type _UInt32Type;
typedef typename _To_Unsigned_Type<_IntType>::_Type
_UIntType;
for (int __i = 0; __i < long_lag; ++__i) for (int __i = 0; __i < long_lag; ++__i)
{ {
...@@ -402,8 +373,7 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) ...@@ -402,8 +373,7 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
_UIntType __factor = 1; _UIntType __factor = 1;
for (int __j = 0; __j < __n; ++__j) for (int __j = 0; __j < __n; ++__j)
{ {
__tmp += (__mod<_UInt32Type, 1, 0, 0>(__gen()) __tmp += __mod<_UInt32Type, 1, 0, 0>(__gen()) * __factor;
* __factor);
__factor *= _Shift<_UIntType, 32>::__value; __factor *= _Shift<_UIntType, 32>::__value;
} }
_M_x[__i] = __mod<_UIntType, 1, 0, modulus>(__tmp); _M_x[__i] = __mod<_UIntType, 1, 0, modulus>(__tmp);
...@@ -423,7 +393,9 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) ...@@ -423,7 +393,9 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
__ps += long_lag; __ps += long_lag;
// Calculate new x(i) without overflow or division. // Calculate new x(i) without overflow or division.
_IntType __xi; // NB: Thanks to the requirements for _IntType, _M_x[_M_p] + _M_carry
// cannot overflow.
_UIntType __xi;
if (_M_x[__ps] >= _M_x[_M_p] + _M_carry) if (_M_x[__ps] >= _M_x[_M_p] + _M_carry)
{ {
__xi = _M_x[__ps] - _M_x[_M_p] - _M_carry; __xi = _M_x[__ps] - _M_x[_M_p] - _M_carry;
...@@ -434,10 +406,10 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) ...@@ -434,10 +406,10 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
__xi = modulus - _M_x[_M_p] - _M_carry + _M_x[__ps]; __xi = modulus - _M_x[_M_p] - _M_carry + _M_x[__ps];
_M_carry = 1; _M_carry = 1;
} }
_M_x[_M_p++] = __xi; _M_x[_M_p] = __xi;
// Adjust current index to loop around in ring buffer. // Adjust current index to loop around in ring buffer.
if (_M_p >= long_lag) if (++_M_p >= long_lag)
_M_p = 0; _M_p = 0;
return __xi; return __xi;
...@@ -483,6 +455,134 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) ...@@ -483,6 +455,134 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
} }
template<typename _RealType, int __w, int __s, int __r>
void
subtract_with_carry_01<_RealType, __w, __s, __r>::
seed(unsigned long __value)
{
if (__value == 0)
__value = 19780503;
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 512. Seeding subtract_with_carry_01 from a single unsigned long.
std::tr1::linear_congruential<unsigned long, 40014, 0, 2147483563>
__lcg(__value);
this->seed(__lcg);
}
template<typename _RealType, int __w, int __s, int __r>
template<class _Gen>
void
subtract_with_carry_01<_RealType, __w, __s, __r>::
seed(_Gen& __gen, false_type)
{
for (int __i = 0; __i < long_lag; ++__i)
{
for (int __j = 0; __j < __n - 1; ++__j)
_M_x[__i][__j] = __mod<_UInt32Type, 1, 0, 0>(__gen());
_M_x[__i][__n - 1] = __mod<_UInt32Type, 1, 0,
_Shift<_UInt32Type, __w % 32>::__value>(__gen());
}
_M_carry = (_M_x[long_lag - 1][0] == 0) ? 1 : 0;
_M_p = 0;
// Initialize the array holding the negative powers of 2.
for (int __j = 0; __j < __n; ++__j)
#if _GLIBCXX_USE_C99_MATH_TR1
_M_npows[__j] = std::tr1::ldexp(_RealType(1), -__w + __j * 32);
#else
_M_npows[__j] = std::pow(_RealType(2), -__w + __j * 32);
#endif
}
template<typename _RealType, int __w, int __s, int __r>
typename subtract_with_carry_01<_RealType, __w, __s, __r>::result_type
subtract_with_carry_01<_RealType, __w, __s, __r>::
operator()()
{
// Derive short lag index from current index.
int __ps = _M_p - short_lag;
if (__ps < 0)
__ps += long_lag;
_UInt32Type __new_carry;
for (int __j = 0; __j < __n - 1; ++__j)
{
if (_M_x[__ps][__j] > _M_x[_M_p][__j]
|| (_M_x[__ps][__j] == _M_x[_M_p][__j] && _M_carry == 0))
__new_carry = 0;
else
__new_carry = 1;
_M_x[_M_p][__j] = _M_x[__ps][__j] - _M_x[_M_p][__j] - _M_carry;
_M_carry = __new_carry;
}
if (_M_x[__ps][__n - 1] > _M_x[_M_p][__n - 1]
|| (_M_x[__ps][__n - 1] == _M_x[_M_p][__n - 1] && _M_carry == 0))
__new_carry = 0;
else
__new_carry = 1;
_M_x[_M_p][__n - 1] = __mod<_UInt32Type, 1, 0,
_Shift<_UInt32Type, __w % 32>::__value>
(_M_x[__ps][__n - 1] - _M_x[_M_p][__n - 1] - _M_carry);
_M_carry = __new_carry;
result_type __ret = 0.0;
for (int __j = 0; __j < __n; ++__j)
__ret += _M_x[_M_p][__j] * _M_npows[__j];
// Adjust current index to loop around in ring buffer.
if (++_M_p >= long_lag)
_M_p = 0;
return __ret;
}
template<typename _RealType, int __w, int __s, int __r,
typename _CharT, typename _Traits>
std::basic_ostream<_CharT, _Traits>&
operator<<(std::basic_ostream<_CharT, _Traits>& __os,
const subtract_with_carry_01<_RealType, __w, __s, __r>& __x)
{
const std::ios_base::fmtflags __flags = __os.flags();
const _CharT __fill = __os.fill();
const _CharT __space = __os.widen(' ');
__os.flags(std::ios_base::dec | std::ios_base::fixed
| std::ios_base::left);
__os.fill(__space);
for (int __i = 0; __i < __r; ++__i)
for (int __j = 0; __j < __x.__n; ++__j)
__os << __x._M_x[__i][__j] << __space;
__os << __x._M_carry;
__os.flags(__flags);
__os.fill(__fill);
return __os;
}
template<typename _RealType, int __w, int __s, int __r,
typename _CharT, typename _Traits>
std::basic_istream<_CharT, _Traits>&
operator>>(std::basic_istream<_CharT, _Traits>& __is,
subtract_with_carry_01<_RealType, __w, __s, __r>& __x)
{
const std::ios_base::fmtflags __flags = __is.flags();
__is.flags(std::ios_base::dec | std::ios_base::skipws);
for (int __i = 0; __i < __r; ++__i)
for (int __j = 0; __j < __x.__n; ++__j)
__is >> __x._M_x[__i][__j];
__is >> __x._M_carry;
__is.flags(__flags);
return __is;
}
template<class _UniformRandomNumberGenerator, int __p, int __r> template<class _UniformRandomNumberGenerator, int __p, int __r>
typename discard_block<_UniformRandomNumberGenerator, typename discard_block<_UniformRandomNumberGenerator,
__p, __r>::result_type __p, __r>::result_type
......
// 2006-08-22 Paolo Carlini <pcarlini@suse.de>
//
// Copyright (C) 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 5.1.5 Engines with predefined parameters
// 5.1.5 [3]
#include <iostream>
#include <tr1/random>
#include <testsuite_hooks.h>
void
test01()
{
bool test __attribute__((unused)) = true;
std::tr1::ranlux3_01 a;
for (int i = 0; i < 9999; ++i)
a();
#if _GLIBCXX_USE_C99_MATH_TR1
VERIFY( a() == 5957620 * std::tr1::ldexp(float(1), -24) );
#else
VERIFY( a() == 5957620 * std::pow(float(2), -24) );
#endif
}
int main()
{
test01();
return 0;
}
// 2006-08-22 Paolo Carlini <pcarlini@suse.de>
//
// Copyright (C) 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 5.1.5 Engines with predefined parameters
// 5.1.5 [3]
#include <tr1/random>
#include <testsuite_hooks.h>
void
test01()
{
bool test __attribute__((unused)) = true;
std::tr1::ranlux4_01 a;
for (int i = 0; i < 9999; ++i)
a();
#if _GLIBCXX_USE_C99_MATH_TR1
VERIFY( a() == 8587295 * std::tr1::ldexp(float(1), -24) );
#else
VERIFY( a() == 8587295 * std::pow(float(2), -24) );
#endif
}
int main()
{
test01();
return 0;
}
...@@ -30,7 +30,7 @@ test01() ...@@ -30,7 +30,7 @@ test01()
bool test __attribute__((unused)) = true; bool test __attribute__((unused)) = true;
using namespace std::tr1; using namespace std::tr1;
subtract_with_carry<unsigned long, (1 << 24), 10, 24> x; subtract_with_carry<unsigned long, (1UL << 24), 10, 24> x;
VERIFY( x.min() == 0 ); VERIFY( x.min() == 0 );
VERIFY( x.max() == ((1<<24)-1) ); VERIFY( x.max() == ((1<<24)-1) );
VERIFY( x() == 15039276 ); VERIFY( x() == 15039276 );
......
...@@ -38,7 +38,7 @@ test01() ...@@ -38,7 +38,7 @@ test01()
bool test __attribute__((unused)) = true; bool test __attribute__((unused)) = true;
using namespace std::tr1; using namespace std::tr1;
subtract_with_carry<unsigned long, (1 << 24), 10, 24> x(gen); subtract_with_carry<unsigned long, (1UL << 24), 10, 24> x(gen);
VERIFY( x.min() == 0 ); VERIFY( x.min() == 0 );
VERIFY( x.max() == ((1 << 24) - 1) ); VERIFY( x.max() == ((1 << 24) - 1) );
} }
......
...@@ -30,7 +30,7 @@ test01() ...@@ -30,7 +30,7 @@ test01()
using namespace std::tr1; using namespace std::tr1;
unsigned long seed = 2; unsigned long seed = 2;
subtract_with_carry<unsigned long, (1 << 24), 10, 24> x(seed); subtract_with_carry<unsigned long, (1UL << 24), 10, 24> x(seed);
} }
int main() int main()
......
...@@ -31,7 +31,7 @@ test01() ...@@ -31,7 +31,7 @@ test01()
using namespace std::tr1; using namespace std::tr1;
double seed = 2.0; double seed = 2.0;
subtract_with_carry<unsigned long, (1 << 24), 10, 24> x(seed); subtract_with_carry<unsigned long, (1UL << 24), 10, 24> x(seed);
} }
int main() int main()
......
...@@ -30,8 +30,8 @@ test01() ...@@ -30,8 +30,8 @@ test01()
bool test __attribute__((unused)) = true; bool test __attribute__((unused)) = true;
using namespace std::tr1; using namespace std::tr1;
subtract_with_carry<unsigned long, (1 << 24), 10, 24> u; subtract_with_carry<unsigned long, (1UL << 24), 10, 24> u;
subtract_with_carry<unsigned long, (1 << 24), 10, 24> v; subtract_with_carry<unsigned long, (1UL << 24), 10, 24> v;
VERIFY( u == v ); VERIFY( u == v );
......
...@@ -30,8 +30,8 @@ test01() ...@@ -30,8 +30,8 @@ test01()
bool test __attribute__((unused)) = true; bool test __attribute__((unused)) = true;
using namespace std::tr1; using namespace std::tr1;
subtract_with_carry<unsigned long, (1 << 24), 10, 24> u(1); subtract_with_carry<unsigned long, (1UL << 24), 10, 24> u(1);
subtract_with_carry<unsigned long, (1 << 24), 10, 24> v(2); subtract_with_carry<unsigned long, (1UL << 24), 10, 24> v(2);
VERIFY( u != v ); VERIFY( u != v );
} }
......
...@@ -32,8 +32,8 @@ test01() ...@@ -32,8 +32,8 @@ test01()
using std::tr1::subtract_with_carry; using std::tr1::subtract_with_carry;
std::stringstream str; std::stringstream str;
subtract_with_carry<unsigned long, (1 << 24), 10, 24> u; subtract_with_carry<unsigned long, (1UL << 24), 10, 24> u;
subtract_with_carry<unsigned long, (1 << 24), 10, 24> v; subtract_with_carry<unsigned long, (1UL << 24), 10, 24> v;
u(); // advance u(); // advance
str << u; str << u;
......
...@@ -28,7 +28,8 @@ ...@@ -28,7 +28,8 @@
void void
test01() test01()
{ {
typedef std::tr1::subtract_with_carry<long, 8, 2, 4> test_type; typedef std::tr1::subtract_with_carry<unsigned long, (1UL << 24), 10, 24>
test_type;
typedef test_type::result_type result_type; typedef test_type::result_type result_type;
} }
// 2006-08-22 Paolo Carlini <pcarlini@suse.de>
//
// Copyright (C) 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 5.1.4.4 class template subtract_with_carry_01 [tr.rand.eng.sub1]
// 5.1.1 Table 16 line 1 default ctor
#include <tr1/random>
#include <testsuite_hooks.h>
void
test01()
{
bool test __attribute__((unused)) = true;
using namespace std::tr1;
subtract_with_carry_01<float, 24, 10, 24> x;
VERIFY( x.min() == 0.0 );
VERIFY( x.max() == 1.0 );
#if _GLIBCXX_USE_C99_MATH_TR1
VERIFY( x() == 15039276 * std::tr1::ldexp(float(1), -24) );
#else
VERIFY( x() == 15039276 * std::pow(float(2), -24) );
#endif
}
int main()
{
test01();
return 0;
}
// 2006-08-22 Paolo Carlini <pcarlini@suse.de>
//
// Copyright (C) 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 5.1.4.4 class template subtract_with_carry_01 [tr.rand.eng.sub1]
// 5.1.1 Table 16 line 3 Gen ctor
#include <ctime>
#include <tr1/random>
#include <testsuite_hooks.h>
// a not untypical initialization function
unsigned long
gen()
{
return std::time(0);
}
void
test01()
{
bool test __attribute__((unused)) = true;
using namespace std::tr1;
subtract_with_carry_01<float, 24, 10, 24> x(gen);
VERIFY( x.min() == 0.0 );
VERIFY( x.max() == 1.0 );
}
int main()
{
test01();
return 0;
}
// 2006-08-22 Paolo Carlini <pcarlini@suse.de>
//
// Copyright (C) 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 5.1.4.4 class template subtract_with_carry_01 [tr.rand.eng.sub1]
// 5.1.1 Table 16 line 2 seed ctor
#include <tr1/random>
#include <testsuite_hooks.h>
void
test01()
{
using namespace std::tr1;
unsigned long seed = 2;
subtract_with_carry_01<float, 24, 10, 24> x(seed);
}
int main()
{
test01();
return 0;
}
// 2006-08-22 Paolo Carlini <pcarlini@suse.de>
//
// Copyright (C) 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 5.1.4.4 class template subtract_with_carry_01 [tr.rand.eng.sub1]
// 5.1.1 Table 16 line 2 seed ctor
// 5.1.1 (4) point 2: Gen is a fundamental type.
#include <tr1/random>
#include <testsuite_hooks.h>
void
test01()
{
using namespace std::tr1;
double seed = 2.0;
subtract_with_carry_01<float, 24, 10, 24> x(seed);
}
int main()
{
test01();
return 0;
}
// 2006-08-22 Paolo Carlini <pcarlini@suse.de>
//
// Copyright (C) 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 5.1.4.4 class template subtract_with_carry_01 [tr.rand.eng.sub1]
// 5.1.1 Table 16
#include <tr1/random>
#include <testsuite_hooks.h>
void
test01()
{
bool test __attribute__((unused)) = true;
using namespace std::tr1;
subtract_with_carry_01<float, 24, 10, 24> u;
subtract_with_carry_01<float, 24, 10, 24> v;
VERIFY( u == v );
for (int i = 0; i < 100; ++i)
{
u();
v();
}
VERIFY( u == v );
}
int main()
{
test01();
return 0;
}
// 2006-08-22 Paolo Carlini <pcarlini@suse.de>
//
// Copyright (C) 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 5.1.4.4 class template subtract_with_carry_01 [tr.rand.eng.sub1]
// 5.1.1 Table 16
#include <tr1/random>
#include <testsuite_hooks.h>
void
test01()
{
bool test __attribute__((unused)) = true;
using namespace std::tr1;
subtract_with_carry_01<float, 24, 10, 24> u(1);
subtract_with_carry_01<float, 24, 10, 24> v(2);
VERIFY( u != v );
}
int main()
{
test01();
return 0;
}
// 2006-08-22 Paolo Carlini <pcarlini@suse.de>
//
// Copyright (C) 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 5.1.4.4 class template subtract_with_carry_01 [tr.rand.eng.sub1]
// 5.1.1 Table 16
#include <sstream>
#include <tr1/random>
#include <testsuite_hooks.h>
void
test01()
{
bool test __attribute__((unused)) = true;
using std::tr1::subtract_with_carry_01;
std::stringstream str;
subtract_with_carry_01<float, 24, 10, 24> u;
subtract_with_carry_01<float, 24, 10, 24> v;
u(); // advance
str << u;
VERIFY( u != v );
str >> v;
VERIFY( u == v );
}
int main()
{
test01();
return 0;
}
// { dg-do compile }
//
// 2006-08-22 Paolo Carlini <pcarlini@suse.de>
//
// Copyright (C) 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 5.1.4.4 Class template subtract_with_carry_01
// 5.1.1 [1] Table 15
#include <tr1/random>
void
test01()
{
typedef std::tr1::subtract_with_carry_01<float, 24, 10, 24> test_type;
typedef test_type::result_type result_type;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment