X-Git-Url: https://git.donarmstrong.com/?p=rsem.git;a=blobdiff_plain;f=boost%2Fmath%2Fspecial_functions%2Fbinomial.hpp;fp=boost%2Fmath%2Fspecial_functions%2Fbinomial.hpp;h=16b4f3305d1cb8ccd0e1176c90fb0c72dc20f2a7;hp=0000000000000000000000000000000000000000;hb=2d71eb92104693ca9baa5a2e1c23eeca776d8fd3;hpb=da57529b92adbb7ae74a89861cb39fb35ac7c62d diff --git a/boost/math/special_functions/binomial.hpp b/boost/math/special_functions/binomial.hpp new file mode 100644 index 0000000..16b4f33 --- /dev/null +++ b/boost/math/special_functions/binomial.hpp @@ -0,0 +1,81 @@ +// Copyright John Maddock 2006. +// Use, modification and distribution are subject to 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) + +#ifndef BOOST_MATH_SF_BINOMIAL_HPP +#define BOOST_MATH_SF_BINOMIAL_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include + +namespace boost{ namespace math{ + +template +T binomial_coefficient(unsigned n, unsigned k, const Policy& pol) +{ + BOOST_STATIC_ASSERT(!boost::is_integral::value); + BOOST_MATH_STD_USING + static const char* function = "boost::math::binomial_coefficient<%1%>(unsigned, unsigned)"; + if(k > n) + return policies::raise_domain_error( + function, + "The binomial coefficient is undefined for k > n, but got k = %1%.", + k, pol); + T result; + if((k == 0) || (k == n)) + return 1; + if((k == 1) || (k == n-1)) + return n; + + if(n <= max_factorial::value) + { + // Use fast table lookup: + result = unchecked_factorial(n); + result /= unchecked_factorial(n-k); + result /= unchecked_factorial(k); + } + else + { + // Use the beta function: + if(k < n - k) + result = k * beta(static_cast(k), static_cast(n-k+1), pol); + else + result = (n - k) * beta(static_cast(k+1), static_cast(n-k), pol); + if(result == 0) + return policies::raise_overflow_error(function, 0, pol); + result = 1 / result; + } + // convert to nearest integer: + return ceil(result - 0.5f); +} +// +// Type float can only store the first 35 factorials, in order to +// increase the chance that we can use a table driven implementation +// we'll promote to double: +// +template <> +inline float binomial_coefficient >(unsigned n, unsigned k, const policies::policy<>& pol) +{ + return policies::checked_narrowing_cast >(binomial_coefficient(n, k, pol), "boost::math::binomial_coefficient<%1%>(unsigned,unsigned)"); +} + +template +inline T binomial_coefficient(unsigned n, unsigned k) +{ + return binomial_coefficient(n, k, policies::policy<>()); +} + +} // namespace math +} // namespace boost + + +#endif // BOOST_MATH_SF_BINOMIAL_HPP + + +