[cfe-commits] [libcxx] r104478 - /libcxx/trunk/include/random

Howard Hinnant hhinnant at apple.com
Sun May 23 17:35:40 PDT 2010


Author: hhinnant
Date: Sun May 23 19:35:40 2010
New Revision: 104478

URL: http://llvm.org/viewvc/llvm-project?rev=104478&view=rev
Log:
Optimized [rand.dist.samp.pconst] and several bug fixes in other distributions

Modified:
    libcxx/trunk/include/random

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





More information about the cfe-commits mailing list