summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libstdc++-v3/ChangeLog23
-rw-r--r--libstdc++-v3/include/ext/random261
-rw-r--r--libstdc++-v3/include/ext/random.tcc108
-rw-r--r--libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/cons/default.cc47
-rw-r--r--libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/cons/parms.cc47
-rw-r--r--libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/operators/equal.cc44
-rw-r--r--libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/operators/inequal.cc44
-rw-r--r--libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/operators/serialize.cc50
-rw-r--r--libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/operators/values.cc57
-rw-r--r--libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/requirements/explicit_instantiation/1.cc27
-rw-r--r--libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/requirements/typedefs.cc36
-rw-r--r--libstdc++-v3/testsuite/util/testsuite_random.h19
12 files changed, 762 insertions, 1 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index c1e20c2c8e4..16a06fb12ec 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,26 @@
+2013-11-21 Edward Smith-Rowland <3dw4rd@verizon.net>
+
+ Implement __gnu_cxx::hypergeometric_distribution.
+ * include/ext/random: Add hypergeometric_distribution.
+ * include/ext/random.tcc: Add hypergeometric_distribution.
+ * testsuite/util/testsuite_random.h (hypergeometric_pdf): New pdf
+ for the hypergeometric discreet distribution;
+ (lbincoef): New supporting function for binomial coefficients.
+ * testsuite/ext/random/hypergeometric_distribution/operators/
+ serialize.cc: New.
+ * testsuite/ext/random/hypergeometric_distribution/operators/
+ equal.cc: New.
+ * testsuite/ext/random/hypergeometric_distribution/operators/
+ inequal.cc: New.
+ * testsuite/ext/random/hypergeometric_distribution/operators/
+ values.cc: New.
+ * testsuite/ext/random/hypergeometric_distribution/cons/parms.cc: New.
+ * testsuite/ext/random/hypergeometric_distribution/cons/default.cc: New.
+ * testsuite/ext/random/hypergeometric_distribution/requirements/
+ explicit_instantiation/1.cc: New.
+ * testsuite/ext/random/hypergeometric_distribution/requirements/
+ typedefs.cc: New.
+
2013-11-20 Jonathan Wakely <jwakely.gcc@gmail.com>
PR c++/59173
diff --git a/libstdc++-v3/include/ext/random b/libstdc++-v3/include/ext/random
index 347ebed449c..c82430e0746 100644
--- a/libstdc++-v3/include/ext/random
+++ b/libstdc++-v3/include/ext/random
@@ -2845,6 +2845,267 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
const __gnu_cxx::von_mises_distribution<_RealType>& __d2)
{ return !(__d1 == __d2); }
+
+ /**
+ * @brief A discrete hypergeometric random number distribution.
+ *
+ * The hypergeometric distribution is a discrete probability distribution
+ * that describes the probability of @p k successes in @p n draws @a without
+ * replacement from a finite population of size @p N containing exactly @p K
+ * successes.
+ *
+ * The formula for the hypergeometric probability density function is
+ * @f[
+ * p(k|N,K,n) = \frac{\binom{K}{k} \binom{N-K}{n-k}}{\binom{N}{n}}
+ * @f]
+ * where @f$N@f$ is the total population of the distribution,
+ * @f$K@f$ is the total population of the distribution.
+ *
+ * <table border=1 cellpadding=10 cellspacing=0>
+ * <caption align=top>Distribution Statistics</caption>
+ * <tr><td>Mean</td><td>@f$ n\frac{K}{N} @f$</td></tr>
+ * <tr><td>Variance</td><td>@f$ n\frac{K}{N}\frac{N-K}{N}\frac{N-n}{N-1}
+ * @f$</td></tr>
+ * <tr><td>Range</td><td>@f$[max(0, n+K-N), min(K, n)]@f$</td></tr>
+ * </table>
+ */
+ template<typename _UIntType = unsigned int>
+ class hypergeometric_distribution
+ {
+ static_assert(std::is_unsigned<_UIntType>::value, "template argument "
+ "substituting _UIntType not an unsigned integral type");
+
+ public:
+ /** The type of the range of the distribution. */
+ typedef _UIntType result_type;
+
+ /** Parameter type. */
+ struct param_type
+ {
+ typedef hypergeometric_distribution<_UIntType> distribution_type;
+ friend class hypergeometric_distribution<_UIntType>;
+
+ explicit
+ param_type(result_type __N = 10, result_type __K = 5,
+ result_type __n = 1)
+ : _M_N{__N}, _M_K{__K}, _M_n{__n}
+ {
+ _GLIBCXX_DEBUG_ASSERT(_M_N >= _M_K);
+ _GLIBCXX_DEBUG_ASSERT(_M_N >= _M_n);
+ }
+
+ result_type
+ total_size() const
+ { return _M_N; }
+
+ result_type
+ successful_size() const
+ { return _M_K; }
+
+ result_type
+ unsuccessful_size() const
+ { return _M_N - _M_K; }
+
+ result_type
+ total_draws() const
+ { return _M_n; }
+
+ friend bool
+ operator==(const param_type& __p1, const param_type& __p2)
+ { return (__p1._M_N == __p2._M_N)
+ && (__p1._M_K == __p2._M_K)
+ && (__p1._M_n == __p2._M_n); }
+
+ private:
+
+ result_type _M_N;
+ result_type _M_K;
+ result_type _M_n;
+ };
+
+ // constructors and member function
+ explicit
+ hypergeometric_distribution(result_type __N = 10, result_type __K = 5,
+ result_type __n = 1)
+ : _M_param{__N, __K, __n}
+ { }
+
+ explicit
+ hypergeometric_distribution(const param_type& __p)
+ : _M_param{__p}
+ { }
+
+ /**
+ * @brief Resets the distribution state.
+ */
+ void
+ reset()
+ { }
+
+ /**
+ * @brief Returns the distribution parameter @p N,
+ * the total number of items.
+ */
+ result_type
+ total_size() const
+ { return this->_M_param.total_size(); }
+
+ /**
+ * @brief Returns the distribution parameter @p K,
+ * the total number of successful items.
+ */
+ result_type
+ successful_size() const
+ { return this->_M_param.successful_size(); }
+
+ /**
+ * @brief Returns the total number of unsuccessful items @f$ N - K @f$.
+ */
+ result_type
+ unsuccessful_size() const
+ { return this->_M_param.unsuccessful_size(); }
+
+ /**
+ * @brief Returns the distribution parameter @p n,
+ * the total number of draws.
+ */
+ result_type
+ total_draws() const
+ { return this->_M_param.total_draws(); }
+
+ /**
+ * @brief Returns the parameter set of the distribution.
+ */
+ param_type
+ param() const
+ { return this->_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)
+ { this->_M_param = __param; }
+
+ /**
+ * @brief Returns the greatest lower bound value of the distribution.
+ */
+ result_type
+ min() const
+ {
+ using _IntType = typename std::make_signed<result_type>::type;
+ return static_cast<result_type>(std::max(static_cast<_IntType>(0),
+ static_cast<_IntType>(this->total_draws()
+ - this->unsuccessful_size())));
+ }
+
+ /**
+ * @brief Returns the least upper bound value of the distribution.
+ */
+ result_type
+ max() const
+ { return std::min(this->successful_size(), this->total_draws()); }
+
+ /**
+ * @brief Generating functions.
+ */
+ template<typename _UniformRandomNumberGenerator>
+ result_type
+ operator()(_UniformRandomNumberGenerator& __urng)
+ { return this->operator()(__urng, this->_M_param); }
+
+ template<typename _UniformRandomNumberGenerator>
+ result_type
+ operator()(_UniformRandomNumberGenerator& __urng,
+ const param_type& __p);
+
+ template<typename _ForwardIterator,
+ typename _UniformRandomNumberGenerator>
+ void
+ __generate(_ForwardIterator __f, _ForwardIterator __t,
+ _UniformRandomNumberGenerator& __urng)
+ { this->__generate(__f, __t, __urng, this->_M_param); }
+
+ template<typename _ForwardIterator,
+ typename _UniformRandomNumberGenerator>
+ void
+ __generate(_ForwardIterator __f, _ForwardIterator __t,
+ _UniformRandomNumberGenerator& __urng,
+ const param_type& __p)
+ { this->__generate_impl(__f, __t, __urng, __p); }
+
+ template<typename _UniformRandomNumberGenerator>
+ void
+ __generate(result_type* __f, result_type* __t,
+ _UniformRandomNumberGenerator& __urng,
+ const param_type& __p)
+ { this->__generate_impl(__f, __t, __urng, __p); }
+
+ /**
+ * @brief Return true if two hypergeometric distributions have the same
+ * parameters and the sequences that would be generated
+ * are equal.
+ */
+ friend bool
+ operator==(const hypergeometric_distribution& __d1,
+ const hypergeometric_distribution& __d2)
+ { return __d1._M_param == __d2._M_param; }
+
+ /**
+ * @brief Inserts a %hypergeometric_distribution random number
+ * distribution @p __x into the output stream @p __os.
+ *
+ * @param __os An output stream.
+ * @param __x A %hypergeometric_distribution random number
+ * distribution.
+ *
+ * @returns The output stream with the state of @p __x inserted or in
+ * an error state.
+ */
+ template<typename _UIntType1, typename _CharT, typename _Traits>
+ friend std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const __gnu_cxx::hypergeometric_distribution<_UIntType1>&
+ __x);
+
+ /**
+ * @brief Extracts a %hypergeometric_distribution random number
+ * distribution @p __x from the input stream @p __is.
+ *
+ * @param __is An input stream.
+ * @param __x A %hypergeometric_distribution random number generator
+ * distribution.
+ *
+ * @returns The input stream with @p __x extracted or in an error
+ * state.
+ */
+ template<typename _UIntType1, typename _CharT, typename _Traits>
+ friend std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ __gnu_cxx::hypergeometric_distribution<_UIntType1>& __x);
+
+ private:
+
+ template<typename _ForwardIterator,
+ typename _UniformRandomNumberGenerator>
+ void
+ __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
+ _UniformRandomNumberGenerator& __urng,
+ const param_type& __p);
+
+ param_type _M_param;
+ };
+
+ /**
+ * @brief Return true if two hypergeometric distributions are different.
+ */
+ template<typename _UIntType>
+ inline bool
+ operator!=(const __gnu_cxx::hypergeometric_distribution<_UIntType>& __d1,
+ const __gnu_cxx::hypergeometric_distribution<_UIntType>& __d2)
+ { return !(__d1 == __d2); }
+
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace __gnu_cxx
diff --git a/libstdc++-v3/include/ext/random.tcc b/libstdc++-v3/include/ext/random.tcc
index 009e0effba8..7d68958c093 100644
--- a/libstdc++-v3/include/ext/random.tcc
+++ b/libstdc++-v3/include/ext/random.tcc
@@ -32,7 +32,6 @@
#pragma GCC system_header
-
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -1307,6 +1306,113 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __is;
}
+
+ template<typename _UIntType>
+ template<typename _UniformRandomNumberGenerator>
+ typename hypergeometric_distribution<_UIntType>::result_type
+ hypergeometric_distribution<_UIntType>::
+ operator()(_UniformRandomNumberGenerator& __urng,
+ const param_type& __param)
+ {
+ std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
+ __aurng(__urng);
+
+ result_type __a = __param.successful_size();
+ result_type __b = __param.total_size();
+ result_type __k = 0;
+
+ if (__param.total_draws() < __param.total_size() / 2)
+ {
+ for (result_type __i = 0; __i < __param.total_draws(); ++__i)
+ {
+ if (__b * __aurng() < __a)
+ {
+ ++__k;
+ if (__k == __param.successful_size())
+ return __k;
+ --__a;
+ }
+ --__b;
+ }
+ return __k;
+ }
+ else
+ {
+ for (result_type __i = 0; __i < __param.unsuccessful_size(); ++__i)
+ {
+ if (__b * __aurng() < __a)
+ {
+ ++__k;
+ if (__k == __param.successful_size())
+ return __param.successful_size() - __k;
+ --__a;
+ }
+ --__b;
+ }
+ return __param.successful_size() - __k;
+ }
+ }
+
+ template<typename _UIntType>
+ template<typename _OutputIterator,
+ typename _UniformRandomNumberGenerator>
+ void
+ hypergeometric_distribution<_UIntType>::
+ __generate_impl(_OutputIterator __f, _OutputIterator __t,
+ _UniformRandomNumberGenerator& __urng,
+ const param_type& __param)
+ {
+ __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator>)
+
+ while (__f != __t)
+ *__f++ = this->operator()(__urng);
+ }
+
+ template<typename _UIntType, typename _CharT, typename _Traits>
+ std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+ const __gnu_cxx::hypergeometric_distribution<_UIntType>& __x)
+ {
+ typedef std::basic_ostream<_CharT, _Traits> __ostream_type;
+ typedef typename __ostream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __os.flags();
+ const _CharT __fill = __os.fill();
+ const std::streamsize __precision = __os.precision();
+ const _CharT __space = __os.widen(' ');
+ __os.flags(__ios_base::scientific | __ios_base::left);
+ __os.fill(__space);
+ __os.precision(std::numeric_limits<_UIntType>::max_digits10);
+
+ __os << __x.total_size() << __space << __x.successful_size() << __space
+ << __x.total_draws();
+
+ __os.flags(__flags);
+ __os.fill(__fill);
+ __os.precision(__precision);
+ return __os;
+ }
+
+ template<typename _UIntType, typename _CharT, typename _Traits>
+ std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ __gnu_cxx::hypergeometric_distribution<_UIntType>& __x)
+ {
+ typedef std::basic_istream<_CharT, _Traits> __istream_type;
+ typedef typename __istream_type::ios_base __ios_base;
+
+ const typename __ios_base::fmtflags __flags = __is.flags();
+ __is.flags(__ios_base::dec | __ios_base::skipws);
+
+ _UIntType __total_size, __successful_size, __total_draws;
+ __is >> __total_size >> __successful_size >> __total_draws;
+ __x.param(typename __gnu_cxx::hypergeometric_distribution<_UIntType>::
+ param_type(__total_size, __successful_size, __total_draws));
+
+ __is.flags(__flags);
+ return __is;
+ }
+
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
diff --git a/libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/cons/default.cc b/libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/cons/default.cc
new file mode 100644
index 00000000000..34978075d71
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/cons/default.cc
@@ -0,0 +1,47 @@
+// { dg-options "-std=gnu++11" }
+// { dg-require-cstdint "" }
+//
+// 2013-11-18 Edward M. Smith-Rowland <3dw4rd@verizon.net>
+//
+// Copyright (C) 2013 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 3, 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 COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 26.4.8.3.* Class template hypergeometric_distribution [rand.dist.ext.hypergeometric]
+// 26.4.2.4 Concept RandomNumberDistribution [rand.concept.dist]
+
+#include <ext/random>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test [[gnu::unused]] = true;
+
+ __gnu_cxx::hypergeometric_distribution<> u;
+ VERIFY( u.total_size() == 10 );
+ VERIFY( u.successful_size() == 5 );
+ VERIFY( u.total_draws() == 1 );
+ VERIFY( u.min() == 0 );
+ VERIFY( u.max() == 1 );
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/cons/parms.cc b/libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/cons/parms.cc
new file mode 100644
index 00000000000..09aec0f1451
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/cons/parms.cc
@@ -0,0 +1,47 @@
+// { dg-options "-std=gnu++11" }
+// { dg-require-cstdint "" }
+//
+// 2013-11-18 Edward M. Smith-Rowland <3dw4rd@verizon.net>
+//
+// Copyright (C) 2013 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 3, 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 COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 26.4.8.3.* Class template hypergeometric_distribution [rand.dist.ext.hypergeometric]
+// 26.4.2.4 Concept RandomNumberDistribution [rand.concept.dist]
+
+#include <ext/random>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test [[gnu::unused]] = true;
+
+ __gnu_cxx::hypergeometric_distribution<> u(15, 3, 2);
+ VERIFY( u.total_size() == 15 );
+ VERIFY( u.successful_size() == 3 );
+ VERIFY( u.total_draws() == 2 );
+ VERIFY( u.min() == 0 );
+ VERIFY( u.max() == 2 );
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/operators/equal.cc b/libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/operators/equal.cc
new file mode 100644
index 00000000000..1887457a727
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/operators/equal.cc
@@ -0,0 +1,44 @@
+// { dg-options "-std=gnu++11" }
+// { dg-require-cstdint "" }
+//
+// 2013-11-18 Edward M. Smith-Rowland <3dw4rd@verizon.net>
+//
+// Copyright (C) 2013 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 3, 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 COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 26.5.8.4.5 Class template rice_distribution [rand.dist.ext.hypergeometric]
+
+#include <ext/random>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test [[gnu::unused]] = true;
+
+ __gnu_cxx::hypergeometric_distribution<unsigned int> u(20, 3, 2), v, w;
+
+ VERIFY( v == w );
+ VERIFY( !(u == v) );
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/operators/inequal.cc b/libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/operators/inequal.cc
new file mode 100644
index 00000000000..4b56f4dc817
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/operators/inequal.cc
@@ -0,0 +1,44 @@
+// { dg-options "-std=gnu++11" }
+// { dg-require-cstdint "" }
+//
+// 2013-11-18 Edward M. Smith-Rowland <3dw4rd@verizon.net>
+//
+// Copyright (C) 2013 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 3, 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 COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 26.5.8.4.5 Class template rice_distribution [rand.dist.ext.hypergeometric]
+
+#include <ext/random>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test [[gnu::unused]] = true;
+
+ __gnu_cxx::hypergeometric_distribution<unsigned int> u(20, 3, 5), v, w;
+
+ VERIFY( u != v );
+ VERIFY( !(v != w) );
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/operators/serialize.cc b/libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/operators/serialize.cc
new file mode 100644
index 00000000000..583993a951c
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/operators/serialize.cc
@@ -0,0 +1,50 @@
+// { dg-options "-std=gnu++11" }
+// { dg-require-cstdint "" }
+//
+// 2013-11-18 Edward M. Smith-Rowland <3dw4rd@verizon.net>
+//
+// Copyright (C) 2013 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 3, 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 COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 26.4.8.3.* Class template hypergeometric_distribution [rand.dist.ext.hypergeometric]
+// 26.4.2.4 Concept RandomNumberDistribution [rand.concept.dist]
+
+#include <ext/random>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test [[gnu::unused]] = true;
+
+ std::stringstream str;
+ __gnu_cxx::hypergeometric_distribution<unsigned int> u(15, 3, 6), v;
+ std::minstd_rand0 rng;
+
+ u(rng); // advance
+ str << u;
+
+ str >> v;
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/operators/values.cc b/libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/operators/values.cc
new file mode 100644
index 00000000000..78c0475c935
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/operators/values.cc
@@ -0,0 +1,57 @@
+// { dg-options "-std=gnu++11" }
+// { dg-require-cstdint "" }
+//
+// 2013-11-18 Edward M. Smith-Rowland <3dw4rd@verizon.net>
+//
+// Copyright (C) 2013 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 3, 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 COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 26.4.8.3.* Class template hypergeometric_distribution [rand.dist.ext.hypergeometric]
+// 26.4.2.4 Concept RandomNumberDistribution [rand.concept.dist]
+
+#include <ext/random>
+#include <testsuite_random.h>
+
+void
+test01()
+{
+ using namespace __gnu_test;
+
+ std::mt19937 eng;
+
+ __gnu_cxx::hypergeometric_distribution hd1{15, 3, 2};
+ auto bhd1 = std::bind(hd1, eng);
+ testDiscreteDist(bhd1, [](int k)
+ { return hypergeometric_pdf(k, 15, 3, 2); });
+
+ __gnu_cxx::hypergeometric_distribution hd2{500, 50, 30};
+ auto bhd2 = std::bind(hd2, eng);
+ testDiscreteDist(bhd2, [](int k)
+ { return hypergeometric_pdf(k, 500, 50, 30); });
+
+ __gnu_cxx::hypergeometric_distribution hd3{100, 20, 5};
+ auto bhd3 = std::bind(hd3, eng);
+ testDiscreteDist(bhd3, [](int k)
+ { return hypergeometric_pdf(k, 100, 20, 5); });
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/requirements/explicit_instantiation/1.cc b/libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/requirements/explicit_instantiation/1.cc
new file mode 100644
index 00000000000..016adb0837f
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/requirements/explicit_instantiation/1.cc
@@ -0,0 +1,27 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++11" }
+// { dg-require-cstdint "" }
+//
+// Copyright (C) 2013 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 3, 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 COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <ext/random>
+
+template class __gnu_cxx::hypergeometric_distribution<unsigned short>;
+template class __gnu_cxx::hypergeometric_distribution<unsigned int>;
+template class __gnu_cxx::hypergeometric_distribution<unsigned long>;
+template class __gnu_cxx::hypergeometric_distribution<unsigned long long>;
diff --git a/libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/requirements/typedefs.cc b/libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/requirements/typedefs.cc
new file mode 100644
index 00000000000..779aad784e6
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/requirements/typedefs.cc
@@ -0,0 +1,36 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++11" }
+// { dg-require-cstdint "" }
+//
+// 2013-11-18 Edward M. Smith-Rowland <3dw4rd@verizon.net>
+//
+// Copyright (C) 2013 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 3, 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 COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 26.4.8.3.* Class template hypergeometric_distribution [rand.dist.ext.hypergeometric]
+// 26.4.2.4 Concept RandomNumberDistribution [rand.concept.dist]
+
+#include <ext/random>
+
+void
+test01()
+{
+ typedef __gnu_cxx::hypergeometric_distribution<unsigned int> test_type;
+
+ typedef test_type::result_type result_type;
+ typedef test_type::param_type param_type;
+}
diff --git a/libstdc++-v3/testsuite/util/testsuite_random.h b/libstdc++-v3/testsuite/util/testsuite_random.h
index bdac81ed006..84b6bc3ea36 100644
--- a/libstdc++-v3/testsuite/util/testsuite_random.h
+++ b/libstdc++-v3/testsuite/util/testsuite_random.h
@@ -176,6 +176,25 @@ namespace __gnu_test
return 1.0 / (b - a + 1.0);
}
+#ifdef _GLIBCXX_USE_C99_MATH_TR1
+ inline double
+ lbincoef(int n, int k)
+ {
+ return std::lgamma(double(1 + n))
+ - std::lgamma(double(1 + k))
+ - std::lgamma(double(1 + n - k));
+ }
+
+ inline double
+ hypergeometric_pdf(int k, int N, int K, int n)
+ {
+ if (k < 0 || k < std::max(0, n - (N - K)) || k > std::min(K, n))
+ return 0.0;
+ else
+ return lbincoef(K, k) + lbincoef(N - K, n - k) - lbincoef(N, n);
+ }
+#endif
+
} // namespace __gnu_test
#endif // #ifndef _GLIBCXX_TESTSUITE_RANDOM_H
OpenPOWER on IntegriCloud