Re: [PATCH, libstdc++] Add the logistic distribution as an extension

2014-07-11 Thread Ed Smith-Rowland

On 07/11/2014 11:42 AM, Paolo Carlini wrote:

Hi,

On 07/11/2014 05:38 PM, Ed Smith-Rowland wrote:

OK?
Ok, thanks, but please adjust the dates you have on the testcases to 
the date of the actual commit (I suppose today or tomorrow)


Thanks again!
Paolo.



As committed.
Thanks all for looking at this.
Ed

Index: include/ext/random
===
--- include/ext/random  (revision 212475)
+++ include/ext/random  (working copy)
@@ -2728,42 +2728,8 @@
   template
result_type
operator()(_UniformRandomNumberGenerator& __urng,
-  const param_type& __p)
-   {
- const result_type __pi
-   = __gnu_cxx::__math_constants::__pi;
- std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
-   __aurng(__urng);
+  const param_type& __p);
 
- result_type __f;
- while (1)
-   {
- result_type __rnd = std::cos(__pi * __aurng());
- __f = (result_type(1) + __p._M_r * __rnd) / (__p._M_r + __rnd);
- result_type __c = __p._M_kappa * (__p._M_r - __f);
-
- result_type __rnd2 = __aurng();
- if (__c * (result_type(2) - __c) > __rnd2)
-   break;
- if (std::log(__c / __rnd2) >= __c - result_type(1))
-   break;
-   }
-
- result_type __res = std::acos(__f);
-#if _GLIBCXX_USE_C99_MATH_TR1
- __res = std::copysign(__res, __aurng() - result_type(0.5));
-#else
- if (__aurng() < result_type(0.5))
-   __res = -__res;
-#endif
- __res += __p._M_mu;
- if (__res > __pi)
-   __res -= result_type(2) * __pi;
- else if (__res < -__pi)
-   __res += result_type(2) * __pi;
- return __res;
-   }
-
   template
void
@@ -3106,6 +3072,227 @@
   const __gnu_cxx::hypergeometric_distribution<_UIntType>& __d2)
 { return !(__d1 == __d2); }
 
+  /**
+   * @brief A logistic continuous distribution for random numbers.
+   *
+   * The formula for the logistic probability density function is
+   * @f[
+   * p(x|\a,\b) = \frac{e^{(x - a)/b}}{b[1 + e^{(x - a)/b}]^2}
+   * @f]
+   * where @f$b > 0@f$.
+   *
+   * The formula for the logistic probability function is
+   * @f[
+   * cdf(x|\a,\b) = \frac{e^{(x - a)/b}}{1 + e^{(x - a)/b}}
+   * @f]
+   * where @f$b > 0@f$.
+   *
+   * 
+   * Distribution Statistics
+   * Mean@f$a@f$
+   * Variance@f$b^2\pi^2/3@f$
+   * Range@f$[0, \infty)@f$
+   * 
+   */
+  template
+class
+logistic_distribution
+{
+  static_assert(std::is_floating_point<_RealType>::value,
+   "template argument not a floating point type");
+
+public:
+  /** The type of the range of the distribution. */
+  typedef _RealType result_type;
+  /** Parameter type. */
+  struct param_type
+  {
+   typedef logistic_distribution distribution_type;
+
+   param_type(result_type __a = result_type(0),
+  result_type __b = result_type(1))
+   : _M_a(__a), _M_b(__b)
+   {
+ _GLIBCXX_DEBUG_ASSERT(_M_b > result_type(0));
+   }
+
+   result_type
+   a() const
+   { return _M_a; }
+
+   result_type
+   b() const
+   { return _M_b; }
+
+   friend bool
+   operator==(const param_type& __p1, const param_type& __p2)
+   { return __p1._M_a == __p2._M_a
+  && __p1._M_b == __p2._M_b; }
+
+  private:
+   void _M_initialize();
+
+   result_type _M_a;
+   result_type _M_b;
+  };
+
+  /**
+   * @brief Constructors.
+   */
+  explicit
+  logistic_distribution(result_type __a = result_type(0),
+   result_type __b = result_type(1))
+  : _M_param(__a, __b)
+  { }
+
+  explicit
+  logistic_distribution(const param_type& __p)
+  : _M_param(__p)
+  { }
+
+  /**
+   * @brief Resets the distribution state.
+   */
+  void
+  reset()
+  { }
+
+  /**
+   * @brief Return the parameters of the distribution.
+   */
+  result_type
+  a() const
+  { return _M_param.a(); }
+
+  result_type
+  b() const
+  { return _M_param.b(); }
+
+  /**
+   * @brief Returns the parameter set of the distribution.
+   */
+  param_type
+  param() const
+  { return _M_param; }
+
+  /**
+   * @brief Sets the parameter set of the distribution.
+   * @param __param The new parameter set of the distribution.
+   */
+  void
+  param(const param_type& __param)
+  { _M_param = __param; }
+
+  /**
+   * @brief Returns the greatest lower bound value of the distribution.
+   */
+  result_type
+  min() const
+  { return -std::numeric_limits::max(); }
+
+  /**
+   * @brief Returns the least upper bound value of the distribution.
+   */
+  result_type
+  max

Re: [PATCH, libstdc++] Add the logistic distribution as an extension

2014-07-11 Thread Paolo Carlini

Hi,

On 07/11/2014 05:38 PM, Ed Smith-Rowland wrote:

OK?
Ok, thanks, but please adjust the dates you have on the testcases to the 
date of the actual commit (I suppose today or tomorrow)


Thanks again!
Paolo.



Re: [PATCH, libstdc++] Add the logistic distribution as an extension

2014-07-11 Thread Ed Smith-Rowland

On 07/10/2014 06:16 AM, Paolo Carlini wrote:

.. I have another comment: are we sure the usual strategy:

  template
result_type
operator()(_UniformRandomNumberGenerator& __urng)
{ return this->operator()(__urng, this->_M_param); }

doesn't make sense here too?

Paolo.


>> Look OK to me too, but I would move both operator() out of line

>> and definitely operator()(_UniformRandomNumberGenerator&, const 
param_type&) of von_mises_distribution.

Ouch - that on was huge huge!

So moved.  The logistic operator() bodies were small looking to me but 
they aren't one or two lines either.  And DRY.


Rebuilt and retested on x86_64-linux.
OK?


2014-07-11  Edward Smith-Rowland  <3dw...@verizon.net>

Add the logistic_distribution as an extension.
* include/ext/random: Add the logistic_distribution.
* include/ext/random.tcc: Add the logistic_distribution.
* testsuite/ext/random/logistic_distribution/cons/parms.cc: New.
* testsuite/ext/random/logistic_distribution/cons/default.cc: New.
* testsuite/ext/random/logistic_distribution/requirements/typedefs.cc:
New.
* testsuite/ext/random/logistic_distribution/operators/inequal.cc: New.
* testsuite/ext/random/logistic_distribution/operators/equal.cc: New.
* testsuite/ext/random/logistic_distribution/operators/serialize.cc:
New.

Index: include/ext/random
===
--- include/ext/random  (revision 212442)
+++ include/ext/random  (working copy)
@@ -2728,42 +2728,8 @@
   template
result_type
operator()(_UniformRandomNumberGenerator& __urng,
-  const param_type& __p)
-   {
- const result_type __pi
-   = __gnu_cxx::__math_constants::__pi;
- std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
-   __aurng(__urng);
+  const param_type& __p);
 
- result_type __f;
- while (1)
-   {
- result_type __rnd = std::cos(__pi * __aurng());
- __f = (result_type(1) + __p._M_r * __rnd) / (__p._M_r + __rnd);
- result_type __c = __p._M_kappa * (__p._M_r - __f);
-
- result_type __rnd2 = __aurng();
- if (__c * (result_type(2) - __c) > __rnd2)
-   break;
- if (std::log(__c / __rnd2) >= __c - result_type(1))
-   break;
-   }
-
- result_type __res = std::acos(__f);
-#if _GLIBCXX_USE_C99_MATH_TR1
- __res = std::copysign(__res, __aurng() - result_type(0.5));
-#else
- if (__aurng() < result_type(0.5))
-   __res = -__res;
-#endif
- __res += __p._M_mu;
- if (__res > __pi)
-   __res -= result_type(2) * __pi;
- else if (__res < -__pi)
-   __res += result_type(2) * __pi;
- return __res;
-   }
-
   template
void
@@ -3106,6 +3072,227 @@
   const __gnu_cxx::hypergeometric_distribution<_UIntType>& __d2)
 { return !(__d1 == __d2); }
 
+  /**
+   * @brief A logistic continuous distribution for random numbers.
+   *
+   * The formula for the logistic probability density function is
+   * @f[
+   * p(x|\a,\b) = \frac{e^{(x - a)/b}}{b[1 + e^{(x - a)/b}]^2}
+   * @f]
+   * where @f$b > 0@f$.
+   *
+   * The formula for the logistic probability function is
+   * @f[
+   * cdf(x|\a,\b) = \frac{e^{(x - a)/b}}{1 + e^{(x - a)/b}}
+   * @f]
+   * where @f$b > 0@f$.
+   *
+   * 
+   * Distribution Statistics
+   * Mean@f$a@f$
+   * Variance@f$b^2\pi^2/3@f$
+   * Range@f$[0, \infty)@f$
+   * 
+   */
+  template
+class
+logistic_distribution
+{
+  static_assert(std::is_floating_point<_RealType>::value,
+   "template argument not a floating point type");
+
+public:
+  /** The type of the range of the distribution. */
+  typedef _RealType result_type;
+  /** Parameter type. */
+  struct param_type
+  {
+   typedef logistic_distribution distribution_type;
+
+   param_type(result_type __a = result_type(0),
+  result_type __b = result_type(1))
+   : _M_a(__a), _M_b(__b)
+   {
+ _GLIBCXX_DEBUG_ASSERT(_M_b > result_type(0));
+   }
+
+   result_type
+   a() const
+   { return _M_a; }
+
+   result_type
+   b() const
+   { return _M_b; }
+
+   friend bool
+   operator==(const param_type& __p1, const param_type& __p2)
+   { return __p1._M_a == __p2._M_a
+  && __p1._M_b == __p2._M_b; }
+
+  private:
+   void _M_initialize();
+
+   result_type _M_a;
+   result_type _M_b;
+  };
+
+  /**
+   * @brief Constructors.
+   */
+  explicit
+  logistic_distribution(result_type __a = result_type(0),
+   result_type __b = result_type(1))
+  : _M_param(__a, __b)
+  { }
+
+  explicit
+  logistic_distribution(const param_type

Re: [PATCH, libstdc++] Add the logistic distribution as an extension

2014-07-10 Thread Paolo Carlini

.. I have another comment: are we sure the usual strategy:

  template
result_type
operator()(_UniformRandomNumberGenerator& __urng)
{ return this->operator()(__urng, this->_M_param); }

doesn't make sense here too?

Paolo.


Re: [PATCH, libstdc++] Add the logistic distribution as an extension

2014-07-10 Thread Paolo Carlini

Hi,

On 07/10/2014 10:07 AM, Ed Smith-Rowland wrote:

The title says it all.

I've been bootstrapping and testing with this on x86_64-linux for a 
month.


OK?
Look OK to me too, but I would move both operator() out of line, and 
definitely operator()(_UniformRandomNumberGenerator&, const param_type&) 
of von_mises_distribution.


Thanks!
Paolo.


Re: [PATCH, libstdc++] Add the logistic distribution as an extension

2014-07-10 Thread Ulrich Drepper
On Thu, Jul 10, 2014 at 4:07 AM, Ed Smith-Rowland <3dw...@verizon.net> wrote:
> The title says it all.
>
> I've been bootstrapping and testing with this on x86_64-linux for a month.
>
> OK?

Looks good to me.


[PATCH, libstdc++] Add the logistic distribution as an extension

2014-07-10 Thread Ed Smith-Rowland

The title says it all.

I've been bootstrapping and testing with this on x86_64-linux for a month.

OK?

Ed


2014-07-10  Edward Smith-Rowland  <3dw...@verizon.net>

Add the logistic_distribution as an extension.
* include/ext/random: Add the logistic_distribution.
* include/ext/random.tcc: Add the logistic_distribution.
* testsuite/ext/random/logistic_distribution/cons/parms.cc: New.
* testsuite/ext/random/logistic_distribution/cons/default.cc: New.
* testsuite/ext/random/logistic_distribution/requirements/typedefs.cc:
New.
* testsuite/ext/random/logistic_distribution/operators/inequal.cc: New.
* testsuite/ext/random/logistic_distribution/operators/equal.cc: New.
* testsuite/ext/random/logistic_distribution/operators/serialize.cc:
New.

Index: include/ext/random
===
--- include/ext/random  (revision 212391)
+++ include/ext/random  (working copy)
@@ -3106,6 +3106,246 @@
   const __gnu_cxx::hypergeometric_distribution<_UIntType>& __d2)
 { return !(__d1 == __d2); }
 
+  /**
+   * @brief A logistic continuous distribution for random numbers.
+   *
+   * The formula for the logistic probability density function is
+   * @f[
+   * p(x|\a,\b) = \frac{e^{(x - a)/b}}{b[1 + e^{(x - a)/b}]^2}
+   * @f]
+   * where @f$b > 0@f$.
+   *
+   * The formula for the logistic probability function is
+   * @f[
+   * cdf(x|\a,\b) = \frac{e^{(x - a)/b}}{1 + e^{(x - a)/b}}
+   * @f]
+   * where @f$b > 0@f$.
+   *
+   * 
+   * Distribution Statistics
+   * Mean@f$a@f$
+   * Variance@f$b^2\pi^2/3@f$
+   * Range@f$[0, \infty)@f$
+   * 
+   */
+  template
+class
+logistic_distribution
+{
+  static_assert(std::is_floating_point<_RealType>::value,
+   "template argument not a floating point type");
+
+public:
+  /** The type of the range of the distribution. */
+  typedef _RealType result_type;
+  /** Parameter type. */
+  struct param_type
+  {
+   typedef logistic_distribution distribution_type;
+
+   param_type(result_type __a = result_type(0),
+  result_type __b = result_type(1))
+   : _M_a(__a), _M_b(__b)
+   {
+ _GLIBCXX_DEBUG_ASSERT(_M_b > result_type(0));
+   }
+
+   result_type
+   a() const
+   { return _M_a; }
+
+   result_type
+   b() const
+   { return _M_b; }
+
+   friend bool
+   operator==(const param_type& __p1, const param_type& __p2)
+   { return __p1._M_a == __p2._M_a
+  && __p1._M_b == __p2._M_b; }
+
+  private:
+   void _M_initialize();
+
+   result_type _M_a;
+   result_type _M_b;
+  };
+
+  /**
+   * @brief Constructors.
+   */
+  explicit
+  logistic_distribution(result_type __a = result_type(0),
+   result_type __b = result_type(1))
+  : _M_param(__a, __b)
+  { }
+
+  explicit
+  logistic_distribution(const param_type& __p)
+  : _M_param(__p)
+  { }
+
+  /**
+   * @brief Resets the distribution state.
+   */
+  void
+  reset()
+  { }
+
+  /**
+   * @brief Return the parameters of the distribution.
+   */
+  result_type
+  a() const
+  { return _M_param.a(); }
+
+  result_type
+  b() const
+  { return _M_param.b(); }
+
+  /**
+   * @brief Returns the parameter set of the distribution.
+   */
+  param_type
+  param() const
+  { return _M_param; }
+
+  /**
+   * @brief Sets the parameter set of the distribution.
+   * @param __param The new parameter set of the distribution.
+   */
+  void
+  param(const param_type& __param)
+  { _M_param = __param; }
+
+  /**
+   * @brief Returns the greatest lower bound value of the distribution.
+   */
+  result_type
+  min() const
+  { return -std::numeric_limits::max(); }
+
+  /**
+   * @brief Returns the least upper bound value of the distribution.
+   */
+  result_type
+  max() const
+  { return std::numeric_limits::max(); }
+
+  /**
+   * @brief Generating functions.
+   */
+  template
+   result_type
+   operator()(_UniformRandomNumberGenerator& __urng)
+   {
+ std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
+   __aurng(__urng);
+
+ result_type __arg = result_type(1);
+ while (__arg == result_type(1) || __arg == result_type(0))
+   __arg = __aurng();
+ return this->param().a()
+  + this->param().b() * std::log(__arg / (result_type(1) - __arg));
+   }
+
+  template
+   result_type
+   operator()(_UniformRandomNumberGenerator& __urng,
+  const param_type& __p)
+{
+ std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
+   __aurng(__urn