Implement __gnu_cxx::hypergeometric_distribution.

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.

From-SVN: r205212
This commit is contained in:
Edward Smith-Rowland 2013-11-21 12:27:02 +00:00 committed by Edward Smith-Rowland
parent ca1babb8e8
commit d2ae7b11b5
12 changed files with 762 additions and 1 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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>;

View File

@ -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;
}

View File

@ -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