Optimized [rand.dist.samp.pconst] and several bug fixes in other distributions

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@104478 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Howard Hinnant 2010-05-24 00:35:40 +00:00
parent daf0ff111f
commit 2a59254a44

View File

@ -3642,7 +3642,8 @@ operator<<(basic_ostream<_CharT, _Traits>& __os,
const uniform_real_distribution<_RT>& __x) const uniform_real_distribution<_RT>& __x)
{ {
__save_flags<_CharT, _Traits> _(__os); __save_flags<_CharT, _Traits> _(__os);
__os.flags(ios_base::dec | ios_base::left); __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
ios_base::scientific);
_CharT __sp = __os.widen(' '); _CharT __sp = __os.widen(' ');
__os.fill(__sp); __os.fill(__sp);
return __os << __x.a() << __sp << __x.b(); return __os << __x.a() << __sp << __x.b();
@ -3736,7 +3737,8 @@ basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, const bernoulli_distribution& __x) operator<<(basic_ostream<_CharT, _Traits>& __os, const bernoulli_distribution& __x)
{ {
__save_flags<_CharT, _Traits> _(__os); __save_flags<_CharT, _Traits> _(__os);
__os.flags(ios_base::dec | ios_base::left); __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
ios_base::scientific);
_CharT __sp = __os.widen(' '); _CharT __sp = __os.widen(' ');
__os.fill(__sp); __os.fill(__sp);
return __os << __x.p(); return __os << __x.p();
@ -3880,7 +3882,8 @@ operator<<(basic_ostream<_CharT, _Traits>& __os,
const binomial_distribution<_IntType>& __x) const binomial_distribution<_IntType>& __x)
{ {
__save_flags<_CharT, _Traits> _(__os); __save_flags<_CharT, _Traits> _(__os);
__os.flags(ios_base::dec | ios_base::left); __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
ios_base::scientific);
_CharT __sp = __os.widen(' '); _CharT __sp = __os.widen(' ');
__os.fill(__sp); __os.fill(__sp);
return __os << __x.t() << __sp << __x.p(); return __os << __x.t() << __sp << __x.p();
@ -3981,7 +3984,8 @@ operator<<(basic_ostream<_CharT, _Traits>& __os,
const exponential_distribution<_RealType>& __x) const exponential_distribution<_RealType>& __x)
{ {
__save_flags<_CharT, _Traits> _(__os); __save_flags<_CharT, _Traits> _(__os);
__os.flags(ios_base::dec | ios_base::left); __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
ios_base::scientific);
return __os << __x.lambda(); return __os << __x.lambda();
} }
@ -4116,7 +4120,8 @@ operator<<(basic_ostream<_CharT, _Traits>& __os,
const normal_distribution<_RT>& __x) const normal_distribution<_RT>& __x)
{ {
__save_flags<_CharT, _Traits> _(__os); __save_flags<_CharT, _Traits> _(__os);
__os.flags(ios_base::dec | ios_base::left); __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
ios_base::scientific);
_CharT __sp = __os.widen(' '); _CharT __sp = __os.widen(' ');
__os.fill(__sp); __os.fill(__sp);
__os << __x.mean() << __sp << __x.stddev() << __sp << __x._V_hot_; __os << __x.mean() << __sp << __x.stddev() << __sp << __x._V_hot_;
@ -4451,7 +4456,8 @@ operator<<(basic_ostream<_CharT, _Traits>& __os,
const poisson_distribution<_IntType>& __x) const poisson_distribution<_IntType>& __x)
{ {
__save_flags<_CharT, _Traits> _(__os); __save_flags<_CharT, _Traits> _(__os);
__os.flags(ios_base::dec | ios_base::left); __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
ios_base::scientific);
return __os << __x.mean(); return __os << __x.mean();
} }
@ -4542,7 +4548,8 @@ operator<<(basic_ostream<_CharT, _Traits>& __os,
const weibull_distribution<_RT>& __x) const weibull_distribution<_RT>& __x)
{ {
__save_flags<_CharT, _Traits> _(__os); __save_flags<_CharT, _Traits> _(__os);
__os.flags(ios_base::dec | ios_base::left); __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
ios_base::scientific);
_CharT __sp = __os.widen(' '); _CharT __sp = __os.widen(' ');
__os.fill(__sp); __os.fill(__sp);
__os << __x.a() << __sp << __x.b(); __os << __x.a() << __sp << __x.b();
@ -4642,7 +4649,8 @@ operator<<(basic_ostream<_CharT, _Traits>& __os,
const extreme_value_distribution<_RT>& __x) const extreme_value_distribution<_RT>& __x)
{ {
__save_flags<_CharT, _Traits> _(__os); __save_flags<_CharT, _Traits> _(__os);
__os.flags(ios_base::dec | ios_base::left); __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
ios_base::scientific);
_CharT __sp = __os.widen(' '); _CharT __sp = __os.widen(' ');
__os.fill(__sp); __os.fill(__sp);
__os << __x.a() << __sp << __x.b(); __os << __x.a() << __sp << __x.b();
@ -4795,7 +4803,8 @@ operator<<(basic_ostream<_CharT, _Traits>& __os,
const gamma_distribution<_RT>& __x) const gamma_distribution<_RT>& __x)
{ {
__save_flags<_CharT, _Traits> _(__os); __save_flags<_CharT, _Traits> _(__os);
__os.flags(ios_base::dec | ios_base::left); __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
ios_base::scientific);
_CharT __sp = __os.widen(' '); _CharT __sp = __os.widen(' ');
__os.fill(__sp); __os.fill(__sp);
__os << __x.alpha() << __sp << __x.beta(); __os << __x.alpha() << __sp << __x.beta();
@ -4912,7 +4921,8 @@ operator<<(basic_ostream<_CharT, _Traits>& __os,
const negative_binomial_distribution<_IntType>& __x) const negative_binomial_distribution<_IntType>& __x)
{ {
__save_flags<_CharT, _Traits> _(__os); __save_flags<_CharT, _Traits> _(__os);
__os.flags(ios_base::dec | ios_base::left); __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
ios_base::scientific);
_CharT __sp = __os.widen(' '); _CharT __sp = __os.widen(' ');
__os.fill(__sp); __os.fill(__sp);
return __os << __x.k() << __sp << __x.p(); return __os << __x.k() << __sp << __x.p();
@ -4999,7 +5009,8 @@ operator<<(basic_ostream<_CharT, _Traits>& __os,
const geometric_distribution<_IntType>& __x) const geometric_distribution<_IntType>& __x)
{ {
__save_flags<_CharT, _Traits> _(__os); __save_flags<_CharT, _Traits> _(__os);
__os.flags(ios_base::dec | ios_base::left); __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
ios_base::scientific);
return __os << __x.p(); return __os << __x.p();
} }
@ -5085,7 +5096,8 @@ operator<<(basic_ostream<_CharT, _Traits>& __os,
const chi_squared_distribution<_RT>& __x) const chi_squared_distribution<_RT>& __x)
{ {
__save_flags<_CharT, _Traits> _(__os); __save_flags<_CharT, _Traits> _(__os);
__os.flags(ios_base::dec | ios_base::left); __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
ios_base::scientific);
__os << __x.n(); __os << __x.n();
return __os; return __os;
} }
@ -5186,7 +5198,8 @@ operator<<(basic_ostream<_CharT, _Traits>& __os,
const cauchy_distribution<_RT>& __x) const cauchy_distribution<_RT>& __x)
{ {
__save_flags<_CharT, _Traits> _(__os); __save_flags<_CharT, _Traits> _(__os);
__os.flags(ios_base::dec | ios_base::left); __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
ios_base::scientific);
_CharT __sp = __os.widen(' '); _CharT __sp = __os.widen(' ');
__os.fill(__sp); __os.fill(__sp);
__os << __x.a() << __sp << __x.b(); __os << __x.a() << __sp << __x.b();
@ -5289,7 +5302,8 @@ operator<<(basic_ostream<_CharT, _Traits>& __os,
const fisher_f_distribution<_RT>& __x) const fisher_f_distribution<_RT>& __x)
{ {
__save_flags<_CharT, _Traits> _(__os); __save_flags<_CharT, _Traits> _(__os);
__os.flags(ios_base::dec | ios_base::left); __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
ios_base::scientific);
_CharT __sp = __os.widen(' '); _CharT __sp = __os.widen(' ');
__os.fill(__sp); __os.fill(__sp);
__os << __x.m() << __sp << __x.n(); __os << __x.m() << __sp << __x.n();
@ -5388,7 +5402,8 @@ operator<<(basic_ostream<_CharT, _Traits>& __os,
const student_t_distribution<_RT>& __x) const student_t_distribution<_RT>& __x)
{ {
__save_flags<_CharT, _Traits> _(__os); __save_flags<_CharT, _Traits> _(__os);
__os.flags(ios_base::dec | ios_base::left); __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
ios_base::scientific);
__os << __x.n(); __os << __x.n();
return __os; return __os;
} }
@ -5586,7 +5601,8 @@ operator<<(basic_ostream<_CharT, _Traits>& __os,
const discrete_distribution<_IT>& __x) const discrete_distribution<_IT>& __x)
{ {
__save_flags<_CharT, _Traits> _(__os); __save_flags<_CharT, _Traits> _(__os);
__os.flags(ios_base::dec | ios_base::left); __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
ios_base::scientific);
_CharT __sp = __os.widen(' '); _CharT __sp = __os.widen(' ');
__os.fill(__sp); __os.fill(__sp);
size_t __n = __x.__p_.__p_.size(); size_t __n = __x.__p_.__p_.size();
@ -5627,8 +5643,10 @@ public:
class param_type class param_type
{ {
vector<double> __p_; typedef typename common_type<double, result_type>::type __area_type;
vector<result_type> __b_; vector<result_type> __b_;
vector<double> __densities_;
vector<__area_type> __areas_;
public: public:
typedef piecewise_constant_distribution distribution_type; typedef piecewise_constant_distribution distribution_type;
@ -5643,10 +5661,10 @@ public:
_UnaryOperation __fw); _UnaryOperation __fw);
vector<result_type> intervals() const {return __b_;} vector<result_type> intervals() const {return __b_;}
vector<double> densities() const; vector<double> densities() const {return __densities_;}
friend bool operator==(const param_type& __x, const param_type& __y) friend bool operator==(const param_type& __x, const param_type& __y)
{return __x.__p_ == __y.__p_ && __x.__b_ == __y.__b_;} {return __x.__densities_ == __y.__densities_ && __x.__b_ == __y.__b_;}
friend bool operator!=(const param_type& __x, const param_type& __y) friend bool operator!=(const param_type& __x, const param_type& __y)
{return !(__x == __y);} {return !(__x == __y);}
@ -5734,29 +5752,27 @@ template<class _RealType>
void void
piecewise_constant_distribution<_RealType>::param_type::__init() piecewise_constant_distribution<_RealType>::param_type::__init()
{ {
if (!__p_.empty()) // __densities_ contains non-normalized areas
{ __area_type __total_area = _STD::accumulate(__densities_.begin(),
if (__p_.size() > 1) __densities_.end(),
{ __area_type());
double __s = _STD::accumulate(__p_.begin(), __p_.end(), 0.0); for (size_t __i = 0; __i < __densities_.size(); ++__i)
for (_STD::vector<double>::iterator __i = __p_.begin(), __e = __p_.end(); __densities_[__i] /= __total_area;
__i < __e; ++__i) // __densities_ contains normalized areas
*__i /= __s; __areas_.assign(__densities_.size(), __area_type());
vector<double> __t(__p_.size() - 1); _STD::partial_sum(__densities_.begin(), __densities_.end() - 1,
_STD::partial_sum(__p_.begin(), __p_.end() - 1, __t.begin()); __areas_.begin() + 1);
swap(__p_, __t); // __areas_ contains partial sums of normalized areas: [0, __densities_ - 1]
} __densities_.back() = 1 - __areas_.back(); // correct round off error
else for (size_t __i = 0; __i < __densities_.size(); ++__i)
{ __densities_[__i] /= (__b_[__i+1] - __b_[__i]);
__p_.clear(); // __densities_ now contains __densities_
__p_.shrink_to_fit();
}
}
} }
template<class _RealType> template<class _RealType>
piecewise_constant_distribution<_RealType>::param_type::param_type() piecewise_constant_distribution<_RealType>::param_type::param_type()
: __b_(2) : __b_(2),
__densities_(1, 1.0)
{ {
__b_[1] = 1; __b_[1] = 1;
} }
@ -5772,12 +5788,13 @@ piecewise_constant_distribution<_RealType>::param_type::param_type(
__b_.resize(2); __b_.resize(2);
__b_[0] = 0; __b_[0] = 0;
__b_[1] = 1; __b_[1] = 1;
__densities_.assign(1, 1.0);
} }
else else
{ {
__p_.reserve(__b_.size() - 1); __densities_.reserve(__b_.size() - 1);
for (size_t __i = 0; __i < __b_.size() - 1; ++__i, ++__fW) for (size_t __i = 0; __i < __b_.size() - 1; ++__i, ++__fW)
__p_.push_back(*__fW); __densities_.push_back(*__fW);
__init(); __init();
} }
} }
@ -5793,12 +5810,13 @@ piecewise_constant_distribution<_RealType>::param_type::param_type(
__b_.resize(2); __b_.resize(2);
__b_[0] = 0; __b_[0] = 0;
__b_[1] = 1; __b_[1] = 1;
__densities_.assign(1, 1.0);
} }
else else
{ {
__p_.reserve(__b_.size() - 1); __densities_.reserve(__b_.size() - 1);
for (size_t __i = 0; __i < __b_.size() - 1; ++__i) for (size_t __i = 0; __i < __b_.size() - 1; ++__i)
__p_.push_back(__fw((__b_[__i+1] + __b_[__i])*.5)); __densities_.push_back(__fw((__b_[__i+1] + __b_[__i])*.5));
__init(); __init();
} }
} }
@ -5811,56 +5829,27 @@ piecewise_constant_distribution<_RealType>::param_type::param_type(
{ {
size_t __n = __b_.size() - 1; size_t __n = __b_.size() - 1;
result_type __d = (__xmax - __xmin) / __n; result_type __d = (__xmax - __xmin) / __n;
__p_.reserve(__n); __densities_.reserve(__n);
for (size_t __i = 0; __i < __n; ++__i) for (size_t __i = 0; __i < __n; ++__i)
{ {
__b_[__i] = __xmin + __i * __d; __b_[__i] = __xmin + __i * __d;
__p_.push_back(__fw(__b_[__i] + __d*.5)); __densities_.push_back(__fw(__b_[__i] + __d*.5));
} }
__b_[__n] = __xmax; __b_[__n] = __xmax;
__init(); __init();
} }
template<class _RealType>
vector<double>
piecewise_constant_distribution<_RealType>::param_type::densities() const
{
const size_t __n = __b_.size() - 1;
vector<double> __d(__n);
if (__n == 1)
__d[0] = 1/(__b_[1] - __b_[0]);
else
{
__d[0] = __p_[0] / (__b_[1] - __b_[0]);
for (size_t __i = 1; __i < __n - 1; ++__i)
__d[__i] = (__p_[__i] - __p_[__i-1]) / (__b_[__i+1] - __b_[__i]);
__d[__n-1] = (1 - __p_[__n-2]) / (__b_[__n] - __b_[__n-1]);
}
return __d;
};
template<class _RealType> template<class _RealType>
template<class _URNG> template<class _URNG>
_RealType _RealType
piecewise_constant_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) piecewise_constant_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
{ {
typedef uniform_real_distribution<result_type> _Gen; typedef uniform_real_distribution<result_type> _Gen;
if (__p.__b_.size() == 2)
return _Gen(__p.__b_[0], __p.__b_[1])(__g);
result_type __u = _Gen()(__g); result_type __u = _Gen()(__g);
const vector<double>& __dd = __p.__p_; ptrdiff_t __k = _STD::upper_bound(__p.__areas_.begin(), __p.__areas_.end(),
size_t __k = static_cast<size_t>(_STD::upper_bound(__dd.begin(), static_cast<double>(__u)) - __p.__areas_.begin() - 1;
__dd.end(), static_cast<double>(__u)) - __dd.begin()); return static_cast<result_type>((__u - __p.__areas_[__k]) / __p.__densities_[__k]
if (__k == 0) + __p.__b_[__k]);
return static_cast<result_type>(__u * (__p.__b_[1] - __p.__b_[0]) /
__dd[0] + __p.__b_[0]);
__u -= __dd[__k-1];
if (__k == __dd.size())
return static_cast<result_type>(__u * (__p.__b_[__k+1] - __p.__b_[__k]) /
(1 - __dd[__k-1]) + __p.__b_[__k]);
return static_cast<result_type>(__u * (__p.__b_[__k+1] - __p.__b_[__k]) /
(__dd[__k] - __dd[__k-1]) + __p.__b_[__k]);
} }
template <class _CharT, class _Traits, class _RT> template <class _CharT, class _Traits, class _RT>
@ -5869,17 +5858,22 @@ operator<<(basic_ostream<_CharT, _Traits>& __os,
const piecewise_constant_distribution<_RT>& __x) const piecewise_constant_distribution<_RT>& __x)
{ {
__save_flags<_CharT, _Traits> _(__os); __save_flags<_CharT, _Traits> _(__os);
__os.flags(ios_base::dec | ios_base::left); __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
ios_base::scientific);
_CharT __sp = __os.widen(' '); _CharT __sp = __os.widen(' ');
__os.fill(__sp); __os.fill(__sp);
size_t __n = __x.__p_.__p_.size(); size_t __n = __x.__p_.__b_.size();
__os << __n; __os << __n;
for (size_t __i = 0; __i < __n; ++__i) for (size_t __i = 0; __i < __n; ++__i)
__os << __sp << __x.__p_.__p_[__i]; __os << __sp << __x.__p_.__b_[__i];
__n = __x.__p_.__b_.size(); __n = __x.__p_.__densities_.size();
__os << __sp << __n; __os << __sp << __n;
for (size_t __i = 0; __i < __n; ++__i) for (size_t __i = 0; __i < __n; ++__i)
__os << __sp << __x.__p_.__b_[__i]; __os << __sp << __x.__p_.__densities_[__i];
__n = __x.__p_.__areas_.size();
__os << __sp << __n;
for (size_t __i = 0; __i < __n; ++__i)
__os << __sp << __x.__p_.__areas_[__i];
return __os; return __os;
} }
@ -5891,21 +5885,27 @@ operator>>(basic_istream<_CharT, _Traits>& __is,
typedef piecewise_constant_distribution<_RT> _Eng; typedef piecewise_constant_distribution<_RT> _Eng;
typedef typename _Eng::result_type result_type; typedef typename _Eng::result_type result_type;
typedef typename _Eng::param_type param_type; typedef typename _Eng::param_type param_type;
typedef typename param_type::__area_type __area_type;
__save_flags<_CharT, _Traits> _(__is); __save_flags<_CharT, _Traits> _(__is);
__is.flags(ios_base::dec | ios_base::skipws); __is.flags(ios_base::dec | ios_base::skipws);
size_t __n; size_t __n;
__is >> __n; __is >> __n;
vector<double> __p(__n);
for (size_t __i = 0; __i < __n; ++__i)
__is >> __p[__i];
__is >> __n;
vector<result_type> __b(__n); vector<result_type> __b(__n);
for (size_t __i = 0; __i < __n; ++__i) for (size_t __i = 0; __i < __n; ++__i)
__is >> __b[__i]; __is >> __b[__i];
__is >> __n;
vector<double> __densities(__n);
for (size_t __i = 0; __i < __n; ++__i)
__is >> __densities[__i];
__is >> __n;
vector<__area_type> __areas(__n);
for (size_t __i = 0; __i < __n; ++__i)
__is >> __areas[__i];
if (!__is.fail()) if (!__is.fail())
{ {
swap(__x.__p_.__p_, __p);
swap(__x.__p_.__b_, __b); swap(__x.__p_.__b_, __b);
swap(__x.__p_.__densities_, __densities);
swap(__x.__p_.__areas_, __areas);
} }
return __is; return __is;
} }