Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r65157 - in trunk: boost boost/random libs/random/test
From: steven_at_[hidden]
Date: 2010-08-31 16:08:00


Author: steven_watanabe
Date: 2010-08-31 16:07:59 EDT (Tue, 31 Aug 2010)
New Revision: 65157
URL: http://svn.boost.org/trac/boost/changeset/65157

Log:
Implement negative_binomial_distribution.
Added:
   trunk/boost/random/negative_binomial_distribution.hpp (contents, props changed)
   trunk/libs/random/test/test_negative_binomial.cpp
      - copied, changed from r65152, /trunk/libs/random/test/test_binomial.cpp
   trunk/libs/random/test/test_negative_binomial_distribution.cpp
      - copied, changed from r65152, /trunk/libs/random/test/test_binomial_distribution.cpp
Text files modified:
   trunk/boost/random.hpp | 1 +
   trunk/libs/random/test/Jamfile.v2 | 2 ++
   trunk/libs/random/test/test_negative_binomial.cpp | 24 +++++++++++++-----------
   trunk/libs/random/test/test_negative_binomial_distribution.cpp | 22 +++++++++++-----------
   4 files changed, 27 insertions(+), 22 deletions(-)

Modified: trunk/boost/random.hpp
==============================================================================
--- trunk/boost/random.hpp (original)
+++ trunk/boost/random.hpp 2010-08-31 16:07:59 EDT (Tue, 31 Aug 2010)
@@ -79,6 +79,7 @@
 #include <boost/random/poisson_distribution.hpp>
 #include <boost/random/gamma_distribution.hpp>
 #include <boost/random/binomial_distribution.hpp>
+#include <boost/random/negative_binomial_distribution.hpp>
 #include <boost/random/uniform_on_sphere.hpp>
 
 #endif // BOOST_RANDOM_HPP

Added: trunk/boost/random/negative_binomial_distribution.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/random/negative_binomial_distribution.hpp 2010-08-31 16:07:59 EDT (Tue, 31 Aug 2010)
@@ -0,0 +1,220 @@
+/* boost random/negative_binomial_distribution.hpp header file
+ *
+ * Copyright Steven Watanabe 2010
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * See http://www.boost.org for most recent version including documentation.
+ *
+ * $Id$
+ */
+
+#ifndef BOOST_RANDOM_BINOMIAL_DISTRIBUTION_HPP_INCLUDED
+#define BOOST_RANDOM_BINOMIAL_DISTRIBUTION_HPP_INCLUDED
+
+#include <iosfwd>
+
+#include <boost/limits.hpp>
+#include <boost/random/detail/config.hpp>
+#include <boost/random/gamma_distribution.hpp>
+#include <boost/random/poisson_distribution.hpp>
+
+namespace boost {
+namespace random {
+
+/**
+ * The negative binomial distribution is an integer valued
+ * distribution with two parameters, @c k and @c p. The
+ * distribution produces non-negative values.
+ *
+ * The distribution function is
+ * \f$\displaystyle P(i) = {k+i-1\choose i}p^k(1-p)^i\f$.
+ *
+ * This implementation uses a gamma-poisson mixture.
+ */
+template<class IntType = int, class RealType = double>
+class negative_binomial_distribution {
+public:
+ typedef IntType result_type;
+ typedef RealType input_type;
+
+ class param_type {
+ public:
+ typedef negative_binomial_distribution distribution_type;
+ /**
+ * Construct a param_type object. @c k and @c p
+ * are the parameters of the distribution.
+ *
+ * Requires: k >=0 && 0 <= p <= 1
+ */
+ explicit param_type(IntType k_arg = 1, RealType p_arg = RealType (0.5))
+ : _k(k_arg), _p(p_arg)
+ {}
+ /** Returns the @c k parameter of the distribution. */
+ IntType k() const { return _k; }
+ /** Returns the @c p parameter of the distribution. */
+ RealType p() const { return _p; }
+#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
+ /** Writes the parameters of the distribution to a @c std::ostream. */
+ template<class CharT, class Traits>
+ friend std::basic_ostream<CharT,Traits>&
+ operator<<(std::basic_ostream<CharT,Traits>& os,
+ const param_type& parm)
+ {
+ os << parm._p << " " << parm._k;
+ return os;
+ }
+
+ /** Reads the parameters of the distribution from a @c std::istream. */
+ template<class CharT, class Traits>
+ friend std::basic_istream<CharT,Traits>&
+ operator>>(std::basic_istream<CharT,Traits>& is, param_type& parm)
+ {
+ is >> parm._p >> std::ws >> parm._k;
+ return is;
+ }
+#endif
+ /** Returns true if the parameters have the same values. */
+ friend bool operator==(const param_type& lhs, const param_type& rhs)
+ {
+ return lhs._k == rhs._k && lhs._p == rhs._p;
+ }
+ /** Returns true if the parameters have different values. */
+ friend bool operator!=(const param_type& lhs, const param_type& rhs)
+ {
+ return !(lhs == rhs);
+ }
+ private:
+ IntType _k;
+ RealType _p;
+ };
+
+ /**
+ * Construct a @c negative_binomial_distribution object. @c k and @c p
+ * are the parameters of the distribution.
+ *
+ * Requires: k >=0 && 0 <= p <= 1
+ */
+ explicit negative_binomial_distribution(IntType k_arg = 1,
+ RealType p_arg = RealType(0.5))
+ : _k(k_arg), _p(p_arg)
+ {}
+
+ /**
+ * Construct an @c negative_binomial_distribution object from the
+ * parameters.
+ */
+ explicit negative_binomial_distribution(const param_type& parm)
+ : _k(parm.k()), _p(parm.p())
+ {}
+
+ /**
+ * Returns a random variate distributed according to the
+ * negative binomial distribution.
+ */
+ template<class URNG>
+ IntType operator()(URNG& urng) const
+ {
+ gamma_distribution<RealType> gamma(_k, (1-_p)/_p);
+ poisson_distribution<IntType, RealType> poisson(gamma(urng));
+ return poisson(urng);
+ }
+
+ /**
+ * Returns a random variate distributed according to the negative
+ * binomial distribution with parameters specified by @c param.
+ */
+ template<class URNG>
+ IntType operator()(URNG& urng, const param_type& parm) const
+ {
+ return negative_binomial_distribution(parm)(urng);
+ }
+
+ /** Returns the @c k parameter of the distribution. */
+ IntType k() const { return _k; }
+ /** Returns the @c p parameter of the distribution. */
+ RealType p() const { return _p; }
+
+ /** Returns the smallest value that the distribution can produce. */
+ IntType min BOOST_PREVENT_MACRO_SUBSTITUTION() const { return 0; }
+ /** Returns the largest value that the distribution can produce. */
+ IntType max BOOST_PREVENT_MACRO_SUBSTITUTION() const
+ { return (std::numeric_limits<IntType>::max)(); }
+
+ /** Returns the parameters of the distribution. */
+ param_type param() const { return param_type(_k, _p); }
+ /** Sets parameters of the distribution. */
+ void param(const param_type& parm)
+ {
+ _k = parm.k();
+ _p = parm.p();
+ }
+
+ /**
+ * Effects: Subsequent uses of the distribution do not depend
+ * on values produced by any engine prior to invoking reset.
+ */
+ void reset() { }
+
+#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
+ /** Writes the parameters of the distribution to a @c std::ostream. */
+ template<class CharT, class Traits>
+ friend std::basic_ostream<CharT,Traits>&
+ operator<<(std::basic_ostream<CharT,Traits>& os,
+ const negative_binomial_distribution& bd)
+ {
+ os << bd.param();
+ return os;
+ }
+
+ /** Reads the parameters of the distribution from a @c std::istream. */
+ template<class CharT, class Traits>
+ friend std::basic_istream<CharT,Traits>&
+ operator>>(std::basic_istream<CharT,Traits>& is,
+ negative_binomial_distribution& bd)
+ {
+ bd.read(is);
+ return is;
+ }
+#endif
+
+ /** Returns true if the two distributions will produce the same
+ sequence of values, given equal generators. */
+ friend bool operator==(const negative_binomial_distribution& lhs,
+ const negative_binomial_distribution& rhs)
+ {
+ return lhs._k == rhs._k && lhs._p == rhs._p;
+ }
+ /** Returns true if the two distributions could produce different
+ sequences of values, given equal generators. */
+ friend bool operator!=(const negative_binomial_distribution& lhs,
+ const negative_binomial_distribution& rhs)
+ {
+ return !(lhs == rhs);
+ }
+
+private:
+
+ /// @cond
+
+ template<class CharT, class Traits>
+ void read(std::basic_istream<CharT, Traits>& is) {
+ param_type parm;
+ if(is >> parm) {
+ param(parm);
+ }
+ }
+
+ // parameters
+ IntType _k;
+ RealType _p;
+
+ /// @endcond
+};
+
+}
+
+}
+
+#endif

Modified: trunk/libs/random/test/Jamfile.v2
==============================================================================
--- trunk/libs/random/test/Jamfile.v2 (original)
+++ trunk/libs/random/test/Jamfile.v2 2010-08-31 16:07:59 EDT (Tue, 31 Aug 2010)
@@ -58,6 +58,8 @@
 run test_weibull_distribution.cpp /boost//unit_test_framework ;
 run test_extreme_value.cpp ;
 run test_extreme_value_distribution.cpp /boost//unit_test_framework ;
+run test_negative_binomial.cpp ;
+run test_negative_binomial_distribution.cpp /boost//unit_test_framework ;
 
 # run nondet_random_speed.cpp ;
 # run random_device.cpp ;

Copied: trunk/libs/random/test/test_negative_binomial.cpp (from r65152, /trunk/libs/random/test/test_binomial.cpp)
==============================================================================
--- /trunk/libs/random/test/test_binomial.cpp (original)
+++ trunk/libs/random/test/test_negative_binomial.cpp 2010-08-31 16:07:59 EDT (Tue, 31 Aug 2010)
@@ -1,4 +1,4 @@
-/* test_binomial.cpp
+/* test_negative_binomial.cpp
  *
  * Copyright Steven Watanabe 2010
  * Distributed under the Boost Software License, Version 1.0. (See
@@ -9,11 +9,11 @@
  *
  */
 
-#include <boost/random/binomial_distribution.hpp>
+#include <boost/random/negative_binomial_distribution.hpp>
 #include <boost/random/uniform_int.hpp>
 #include <boost/random/uniform_01.hpp>
 #include <boost/random/mersenne_twister.hpp>
-#include <boost/math/distributions/binomial.hpp>
+#include <boost/math/distributions/negative_binomial.hpp>
 #include <boost/lexical_cast.hpp>
 #include <boost/exception/diagnostic_information.hpp>
 #include <vector>
@@ -23,21 +23,23 @@
 #include "chi_squared_test.hpp"
 
 bool do_test(int n, double p, long long max) {
- std::cout << "running binomial(" << n << ", " << p << ")" << " " << max << " times: " << std::flush;
+ std::cout << "running negative_binomial(" << n << ", " << p << ")" << " " << max << " times: " << std::flush;
 
- std::vector<double> expected(n+1);
+ int max_value = static_cast<int>(4*n*std::ceil((1-p)/p));
+ std::vector<double> expected(max_value+1);
     {
- boost::math::binomial dist(n, p);
- for(int i = 0; i <= n; ++i) {
+ boost::math::negative_binomial dist(n, p);
+ for(int i = 0; i <= max_value; ++i) {
             expected[i] = pdf(dist, i);
         }
+ expected.back() += 1-cdf(dist,max_value);
     }
     
- boost::random::binomial_distribution<int, double> dist(n, p);
+ boost::random::negative_binomial_distribution<int, double> dist(n, p);
     boost::mt19937 gen;
- std::vector<long long> results(n + 1);
+ std::vector<long long> results(max_value + 1);
     for(long long i = 0; i < max; ++i) {
- ++results[dist(gen)];
+ ++results[std::min(dist(gen), max_value)];
     }
 
     long long sum = std::accumulate(results.begin(), results.end(), 0ll);
@@ -73,7 +75,7 @@
 }
 
 int usage() {
- std::cerr << "Usage: test_binomial_distribution -r <repeat> -n <max n> -t <trials>" << std::endl;
+ std::cerr << "Usage: test_negative_binomial_distribution -r <repeat> -n <max n> -t <trials>" << std::endl;
     return 2;
 }
 

Copied: trunk/libs/random/test/test_negative_binomial_distribution.cpp (from r65152, /trunk/libs/random/test/test_binomial_distribution.cpp)
==============================================================================
--- /trunk/libs/random/test/test_binomial_distribution.cpp (original)
+++ trunk/libs/random/test/test_negative_binomial_distribution.cpp 2010-08-31 16:07:59 EDT (Tue, 31 Aug 2010)
@@ -1,4 +1,4 @@
-/* test_binomial_distribution.cpp
+/* test_negative_binomial_distribution.cpp
  *
  * Copyright Steven Watanabe 2010
  * Distributed under the Boost Software License, Version 1.0. (See
@@ -9,10 +9,11 @@
  *
  */
 
-#include <boost/random/binomial_distribution.hpp>
+#include <boost/random/negative_binomial_distribution.hpp>
+#include <limits>
 
-#define BOOST_RANDOM_DISTRIBUTION boost::random::binomial_distribution<>
-#define BOOST_RANDOM_ARG1 t
+#define BOOST_RANDOM_DISTRIBUTION boost::random::negative_binomial_distribution<>
+#define BOOST_RANDOM_ARG1 k
 #define BOOST_RANDOM_ARG2 p
 #define BOOST_RANDOM_ARG1_DEFAULT 1
 #define BOOST_RANDOM_ARG2_DEFAULT 0.5
@@ -20,18 +21,17 @@
 #define BOOST_RANDOM_ARG2_VALUE 0.25
 
 #define BOOST_RANDOM_DIST0_MIN 0
-#define BOOST_RANDOM_DIST0_MAX 1
+#define BOOST_RANDOM_DIST0_MAX (std::numeric_limits<int>::max)()
 #define BOOST_RANDOM_DIST1_MIN 0
-#define BOOST_RANDOM_DIST1_MAX 10
+#define BOOST_RANDOM_DIST1_MAX (std::numeric_limits<int>::max)()
 #define BOOST_RANDOM_DIST2_MIN 0
-#define BOOST_RANDOM_DIST2_MAX 10
+#define BOOST_RANDOM_DIST2_MAX (std::numeric_limits<int>::max)()
 
 #define BOOST_RANDOM_TEST1_PARAMS
 #define BOOST_RANDOM_TEST1_MIN 0
-#define BOOST_RANDOM_TEST1_MAX 1
+#define BOOST_RANDOM_TEST1_MAX 10
 
-#define BOOST_RANDOM_TEST2_PARAMS (10, 0.25)
-#define BOOST_RANDOM_TEST2_MIN 0
-#define BOOST_RANDOM_TEST2_MAX 10
+#define BOOST_RANDOM_TEST2_PARAMS (100, 0.5)
+#define BOOST_RANDOM_TEST2_MIN 50
 
 #include "test_distribution.ipp"


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk