aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/bits/sf_distributions.tcc
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++-v3/include/bits/sf_distributions.tcc')
-rw-r--r--libstdc++-v3/include/bits/sf_distributions.tcc588
1 files changed, 588 insertions, 0 deletions
diff --git a/libstdc++-v3/include/bits/sf_distributions.tcc b/libstdc++-v3/include/bits/sf_distributions.tcc
new file mode 100644
index 00000000000..7e45b03d8b8
--- /dev/null
+++ b/libstdc++-v3/include/bits/sf_distributions.tcc
@@ -0,0 +1,588 @@
+// Special functions -*- C++ -*-
+
+// Copyright (C) 2006-2016 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.
+//
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/sf_distributions.tcc
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{cmath}
+ */
+
+//
+// ISO C++ 14882 TR29124: Mathematical Special Functions
+//
+
+// Written by Edward Smith-Rowland.
+//
+// References:
+// (1) Handbook of Mathematical Functions,
+// ed. Milton Abramowitz and Irene A. Stegun,
+// Dover Publications,
+// Section 6, pp. 253-266
+// (2) The Gnu Scientific Library, http://www.gnu.org/software/gsl
+// (3) Numerical Recipes in C, by W. H. Press, S. A. Teukolsky,
+// W. T. Vetterling, B. P. Flannery, Cambridge University Press (1992),
+// 2nd ed, pp. 213-216
+// (4) Gamma, Exploring Euler's Constant, Julian Havil,
+// Princeton, 2003.
+
+#ifndef _GLIBCXX_BITS_SF_DISTRIBUTIONS_TCC
+#define _GLIBCXX_BITS_SF_DISTRIBUTIONS_TCC 1
+
+#pragma GCC system_header
+
+#include <ext/math_const.h>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+// Implementation-space details.
+namespace __detail
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ /**
+ * @brief Return the chi-squared propability function.
+ * This returns the probability that the observed chi-squared for a correct model
+ * is less than the value @f$ \chi^2 @f$.
+ *
+ * The chi-squared propability function is related
+ * to the normalized lower incomplete gamma function:
+ * @f[
+ * P(\chi^2|\nu) = \Gamma_P(\frac{\nu}{2}, \frac{\chi^2}{2})
+ * @f]
+ */
+ template<typename _Tp>
+ _Tp
+ __chi_squared_pdf(_Tp __chi2, unsigned int __nu)
+ {
+ if (__isnan(__chi2))
+ return std::numeric_limits<_Tp>::quiet_NaN();
+ else if (__chi2 < _Tp{0})
+ std::__throw_domain_error(__N("__chi_squared_cdf: "
+ "chi-squared is negative"));
+ else
+ return __pgamma(_Tp(__nu) / _Tp{2}, __chi2 / _Tp{2});
+ }
+
+ /**
+ * @brief Return the complementary chi-squared propability function.
+ * This returns the probability that the observed chi-squared for a correct model
+ * is greater than the value @f$ \chi^2 @f$.
+ *
+ * The complementary chi-squared propability function is related
+ * to the normalized upper incomplete gamma function:
+ * @f[
+ * Q(\chi^2|\nu) = \Gamma_Q(\frac{\nu}{2}, \frac{\chi^2}{2})
+ * @f]
+ */
+ template<typename _Tp>
+ _Tp
+ __chi_squared_pdfc(_Tp __chi2, unsigned int __nu)
+ {
+ if (__isnan(__chi2) || __isnan(__nu))
+ return std::numeric_limits<_Tp>::quiet_NaN();
+ else if (__chi2 < _Tp{0})
+ std::__throw_domain_error(__N("__chi_square_pdfc: "
+ "chi-squared is negative"));
+ else
+ return __qgamma(_Tp(__nu) / _Tp{2}, __chi2 / _Tp{2});
+ }
+
+ /**
+ * @brief Return the gamma propability distribution function.
+ *
+ * The formula for the gamma probability density function is:
+ * @f[
+ * \Gamma(x|\alpha,\beta) = \frac{1}{\beta\Gamma(\alpha)}
+ * (x/\beta)^{\alpha - 1} e^{-x/\beta}
+ * @f]
+ */
+ template<typename _Tp>
+ _Tp
+ __gamma_pdf(_Tp __alpha, _Tp __beta, _Tp __x)
+ {
+ if (__isnan(__alpha) || __isnan(__beta) || __isnan(__x))
+ return std::numeric_limits<_Tp>::quiet_NaN();
+ else
+ return std::pow(__beta, __alpha) * std::pow(__x, __alpha - _Tp{1})
+ * std::exp(__beta * __x) / __gamma(__alpha);
+ }
+
+ /**
+ * @brief Return the gamma cumulative propability distribution function.
+ *
+ * The formula for the gamma probability density function is:
+ * @f[
+ * \Gamma(x|\alpha,\beta) = \frac{1}{\beta\Gamma(\alpha)}
+ * (x/\beta)^{\alpha - 1} e^{-x/\beta}
+ * @f]
+ */
+ template<typename _Tp>
+ _Tp
+ __gamma_cdf(_Tp __alpha, _Tp __beta, _Tp __x)
+ {
+ if (__isnan(__alpha) || __isnan(__beta) || __isnan(__x))
+ return std::numeric_limits<_Tp>::quiet_NaN();
+ else
+ return __tgamma_lower(__alpha, __beta * __x)
+ / __gamma(__alpha);
+ }
+
+ /**
+ * @brief Return the gamma complementary cumulative propability
+ * distribution function.
+ *
+ * The formula for the gamma probability density function is:
+ * @f[
+ * \Gamma(x|\alpha,\beta) = \frac{1}{\beta\Gamma(\alpha)}
+ * (x/\beta)^{\alpha - 1} e^{-x/\beta}
+ * @f]
+ */
+ template<typename _Tp>
+ _Tp
+ __gamma_cdfc(_Tp __alpha, _Tp __beta, _Tp __x)
+ {
+ if (__isnan(__alpha) || __isnan(__beta) || __isnan(__x))
+ return std::numeric_limits<_Tp>::quiet_NaN();
+ else
+ return __tgamma(__alpha, __beta * __x)
+ / __gamma(__alpha);
+ }
+
+
+ /**
+ * @brief Return the Rice probability density function.
+ *
+ * The formula for the Rice probability density function is
+ * @f[
+ * p(x|\nu,\sigma) = \frac{x}{\sigma^2}
+ * \exp\left(-\frac{x^2+\nu^2}{2\sigma^2}\right)
+ * I_0\left(\frac{x \nu}{\sigma^2}\right)
+ * @f]
+ * where @f$I_0(x)@f$ is the modified Bessel function of the first kind
+ * of order 0 and @f$\nu >= 0@f$ and @f$\sigma > 0@f$.
+ */
+ template<typename _Tp>
+ _Tp
+ __rice_pdf(_Tp __nu, _Tp __sigma, _Tp __x)
+ {
+ if (__isnan(__nu) || __isnan(__sigma))
+ return std::numeric_limits<_Tp>::quiet_NaN();
+ else
+ {
+ auto __sigma2 = __sigma * __sigma;
+ return (__x / __sigma2)
+ * std::exp(-(__x * __x + __nu * __nu) / (_Tp{2} * __sigma2))
+ * __cyl_bessel_i(_Tp{0}, (__x * __nu) / (__sigma2));
+ }
+ }
+
+
+ /**
+ * @brief Return the normal probability density function.
+ *
+ * The formula for the normal probability density function is
+ * @f[
+ * f(x|\mu,\sigma) = \frac{e^{(x-\mu)^2/2\sigma^2}}{\sigma\sqrt{2\pi}}
+ * @f]
+ */
+ template<typename _Tp>
+ _Tp
+ __normal_pdf(_Tp __nu, _Tp __sigma, _Tp __x)
+ {
+ constexpr auto _S_sqrt_2 = __gnu_cxx::__math_constants<_Tp>::__root_2;
+ constexpr auto _S_sqrt_pi = __gnu_cxx::__math_constants<_Tp>::__root_pi;
+ constexpr auto _S_sqrt_2pi = _S_sqrt_2 * _S_sqrt_pi;
+ if (__isnan(__nu) || __isnan(__sigma))
+ return std::numeric_limits<_Tp>::quiet_NaN();
+ else
+ {
+ __x -= __nu;
+ __x /= __sigma;
+ __x *= __x;
+ __x /= _Tp{2};
+ return std::exp(-(__x)) / (__sigma * _S_sqrt_2pi);
+ }
+ }
+
+ /**
+ * @brief Return the normal cumulative probability density function.
+ *
+ * The formula for the normal cumulative probability density function is
+ * @f[
+ * F(x|\mu,\sigma)
+ * = \frac{1}{2}\left[ 1-erf(\frac{x-\mu}{\sqrt{2}\sigma}) \right]
+ * @f]
+ */
+ template<typename _Tp>
+ _Tp
+ __normal_cdf(_Tp __mu, _Tp __sigma, _Tp __x)
+ {
+ constexpr auto _S_sqrt_2 = __gnu_cxx::__math_constants<_Tp>::__root_2;
+ if (__isnan(__mu) || __isnan(__sigma) || __isnan(__x))
+ return std::numeric_limits<_Tp>::quiet_NaN();
+ else
+ return _Tp{0.5L}
+ * (_Tp{1} + std::erf((__x - __mu) / (__sigma * _S_sqrt_2)));
+ }
+
+
+ /**
+ * @brief Return the lognormal probability density function.
+ *
+ * The formula for the lognormal probability density function is
+ * @f[
+ * f(x|\mu,\sigma) = \frac{e^{(\ln{x}-\mu)^2/2\sigma^2}}{\sigma\sqrt{2\pi}}
+ * @f]
+ */
+ template<typename _Tp>
+ _Tp
+ __lognormal_pdf(_Tp __nu, _Tp __sigma, _Tp __x)
+ {
+ constexpr auto _S_sqrt_2 = __gnu_cxx::__math_constants<_Tp>::__root_2;
+ constexpr auto _S_sqrt_pi = __gnu_cxx::__math_constants<_Tp>::__root_pi;
+ constexpr auto _S_sqrt_2pi = _S_sqrt_2 * _S_sqrt_pi;
+ if (__isnan(__nu) || __isnan(__sigma))
+ return std::numeric_limits<_Tp>::quiet_NaN();
+ else
+ {
+ __x -= __nu;
+ __x /= __sigma;
+ __x *= __x;
+ __x /= _Tp{2};
+ return std::exp(-(std::log(__x))) / (__sigma * _S_sqrt_2pi);
+ }
+ }
+
+ /**
+ * @brief Return the lognormal cumulative probability density function.
+ *
+ * The formula for the lognormal cumulative probability density function is
+ * @f[
+ * F(x|\mu,\sigma)
+ * = \frac{1}{2}\left[ 1-erf(\frac{\ln{x}-\mu}{\sqrt{2}\sigma}) \right]
+ * @f]
+ */
+ template<typename _Tp>
+ _Tp
+ __lognormal_cdf(_Tp __mu, _Tp __sigma, _Tp __x)
+ {
+ constexpr auto _S_sqrt_2 = __gnu_cxx::__math_constants<_Tp>::__root_2;
+ if (__isnan(__mu) || __isnan(__sigma) || __isnan(__x))
+ return std::numeric_limits<_Tp>::quiet_NaN();
+ else
+ return _Tp{0.5L} * (_Tp{1} + std::erf((std::log(__x) - __mu)
+ / (__sigma * _S_sqrt_2)));
+ }
+
+
+ /**
+ * @brief Return the exponential probability density function.
+ *
+ * The formula for the exponential probability density function is
+ * @f[
+ * f(x|\lambda) = \lambda e^{-\lambda x} \mbox{ for } x >= 0
+ * @f]
+ */
+ template<typename _Tp>
+ _Tp
+ __exponential_pdf(_Tp __lambda, _Tp __x)
+ {
+ if (__isnan(__lambda) || __isnan(__x))
+ return std::numeric_limits<_Tp>::quiet_NaN();
+ else if (__x < _Tp{0})
+ return _Tp{0};
+ else
+ return __lambda * std::exp(-__lambda * __x);
+ }
+
+ /**
+ * @brief Return the exponential cumulative probability density function.
+ *
+ * The formula for the exponential cumulative probability density function is
+ * @f[
+ * F(x|\lambda) = 1 - e^{-\lambda x} \mbox{ for } x >= 0
+ * @f]
+ */
+ template<typename _Tp>
+ _Tp
+ __exponential_cdf(_Tp __lambda, _Tp __x)
+ {
+ if (__isnan(__lambda) || __isnan(__x))
+ return std::numeric_limits<_Tp>::quiet_NaN();
+ else if (__x < _Tp{0})
+ return _Tp{0};
+ else
+ return _Tp{1} - std::exp(-__lambda * __x);
+ }
+
+
+ /**
+ * @brief Return the Weibull probability density function.
+ *
+ * The formula for the Weibull probability density function is
+ * @f[
+ * f(x | a, b) = \frac{a}{b}
+ * \left(\frac{x}{b} \right)^{a-1}
+ * \exp{-\left(\frac{x}{b}\right)^a}
+ * \mbox{ for } x >= 0
+ * @f]
+ */
+ template<typename _Tp>
+ _Tp
+ __weibull_pdf(_Tp __a, _Tp __b, _Tp __x)
+ {
+ if (__isnan(__a) || __isnan(__b) || __isnan(__x))
+ return std::numeric_limits<_Tp>::quiet_NaN();
+ else if (__x < _Tp{0})
+ return _Tp{0};
+ else
+ return (__a / __b) * std::pow(__x / __b, __a - _Tp{1})
+ * std::exp(-std::pow(__x / __b, __a));
+ }
+
+ /**
+ * @brief Return the Weibull cumulative probability density function.
+ *
+ * The formula for the Weibull cumulative probability density function is
+ * @f[
+ * F(x|\lambda) = 1 - e^{-(x / b)^a} \mbox{ for } x >= 0
+ * @f]
+ */
+ template<typename _Tp>
+ _Tp
+ __weibull_cdf(_Tp __a, _Tp __b, _Tp __x)
+ {
+ if (__isnan(__a) || __isnan(__b) || __isnan(__x))
+ return std::numeric_limits<_Tp>::quiet_NaN();
+ else if (__x < _Tp{0})
+ return _Tp{0};
+ else
+ return _Tp{1} - std::exp(-std::pow(__x / __b, __a));
+ }
+
+ /**
+ * @brief Return the Students T probability function.
+ *
+ * The students T propability function is related to the incomplete beta function:
+ * @f[
+ * A(t|\nu) = 1 - I_{\frac{\nu}{\nu + t^2}}(\frac{\nu}{2}, \frac{1}{2})
+ * A(t|\nu) =
+ * @f]
+ *
+ * @param __t
+ * @param __nu
+ */
+ template<typename _Tp>
+ _Tp
+ __student_t_cdf(_Tp __t, unsigned int __nu)
+ {
+ if (__isnan(__t))
+ return std::numeric_limits<_Tp>::quiet_NaN();
+ else
+ return __beta_inc(_Tp{0.5L}, _Tp(__nu) / _Tp{2},
+ __t * __t / (_Tp(__nu) + __t * __t));
+ }
+
+ /**
+ * @brief Return the complement of the Students T probability function.
+ *
+ * The complement of the students T propability function is:
+ * @f[
+ * A_c(t|\nu) = I_{\frac{\nu}{\nu + t^2}}(\frac{\nu}{2}, \frac{1}{2})
+ * = 1 - A(t|\nu)
+ * @f]
+ *
+ * @param __t
+ * @param __nu
+ */
+ template<typename _Tp>
+ _Tp
+ __student_t_cdfc(_Tp __t, unsigned int __nu)
+ {
+ if (__isnan(__t))
+ return std::numeric_limits<_Tp>::quiet_NaN();
+ else
+ return __beta_inc(_Tp(__nu) / _Tp{2}, _Tp{0.5L},
+ _Tp(__nu) / (_Tp(__nu) + __t * __t));
+ }
+
+ /**
+ * @brief Return the F-distribution propability function.
+ * This returns the probability that the observed chi-square for a correct model
+ * exceeds the value @f$ \chi^2 @f$.
+ *
+ * The f-distribution propability function is related to the incomplete beta function:
+ * @f[
+ * Q(F|\nu_1, \nu_2) = I_{\frac{\nu_2}{\nu_2 + \nu_1 F}}
+ * (\frac{\nu_2}{2}, \frac{\nu_1}{2})
+ * @f]
+ *
+ * @param __nu1 The number of degrees of freedom of sample 1
+ * @param __nu2 The number of degrees of freedom of sample 2
+ * @param __F The F statistic
+ */
+ template<typename _Tp>
+ _Tp
+ __fisher_f_cdf(_Tp __F, unsigned int __nu1, unsigned int __nu2)
+ {
+ if (__isnan(__F))
+ return std::numeric_limits<_Tp>::quiet_NaN();
+ else if (__F < _Tp{0})
+ std::__throw_domain_error(__N("__f_cdf: F is negative"));
+ else
+ return __beta_inc(_Tp(__nu2) / _Tp{2}, _Tp(__nu1) / _Tp{2},
+ _Tp(__nu2) / (_Tp(__nu2) + __nu1 * __F));
+ }
+
+ /**
+ * @brief Return the F-distribution propability function.
+ * This returns the probability that the observed chi-square for a correct model
+ * exceeds the value @f$ \chi^2 @f$.
+ *
+ * The f-distribution propability function is related to the incomplete beta function:
+ * @f[
+ * P(F|\nu_1, \nu_2) = 1 - I_{\frac{\nu_2}{\nu_2 + \nu_1 F}}
+ * (\frac{\nu_2}{2}, \frac{\nu_1}{2})
+ * = 1 - Q(F|\nu_1, \nu_2)
+ * @f]
+ *
+ * @param __F
+ * @param __nu1
+ * @param __nu2
+ */
+ template<typename _Tp>
+ _Tp
+ __fisher_f_cdfc(_Tp __F, unsigned int __nu1, unsigned int __nu2)
+ {
+ if (__isnan(__F))
+ return std::numeric_limits<_Tp>::quiet_NaN();
+ else if (__F < _Tp{0})
+ std::__throw_domain_error(__N("__f_cdfc: F is negative"));
+ else
+ return __beta_inc(_Tp(__nu1) / _Tp{2}, _Tp(__nu2) / _Tp{2},
+ __nu1 * __F / (_Tp(__nu2) + __nu1 * __F));
+ }
+
+ /**
+ * @brief Return the binomial probability mass function.
+ *
+ * The binomial cumulative distribution function is related
+ * to the incomplete beta function:
+ * @f[
+ * f(k|n,p) = \binom{n}{k}p^k(1-p)^{n-k}
+ * @f]
+ *
+ * @param __p
+ * @param __n
+ * @param __k
+ */
+ template<typename _Tp>
+ _Tp
+ __binomial_pdf(_Tp __p, unsigned int __n, unsigned int __k)
+ {
+ if (__isnan(__p))
+ return std::numeric_limits<_Tp>::quiet_NaN();
+ else if (__p < _Tp{0} || __p > _Tp{1})
+ std::__throw_domain_error(__N("__binomial_cdf: "
+ "probability is out of range"));
+ else if (__k > __n)
+ return _Tp{0};
+ else if (__n == 0)
+ return _Tp{1};
+ else if (__k == 0)
+ return std::pow(_Tp{1} - __p, __n);
+ else if (__k == __n)
+ return std::pow(__p, __n);
+ else
+ return __bincoef<_Tp>(__n, __k)
+ * std::pow(__p, __k)
+ * std::pow(_Tp{1} - __p, __n - __k);
+ }
+
+
+ /**
+ * @brief Return the binomial cumulative distribution function.
+ *
+ * The binomial cumulative distribution function is related
+ * to the incomplete beta function:
+ * @f[
+ * P(k|n,p) = I_p(k, n-k+1)
+ * @f]
+ *
+ * @param __p
+ * @param __n
+ * @param __k
+ */
+ template<typename _Tp>
+ _Tp
+ __binomial_cdf(_Tp __p, unsigned int __n, unsigned int __k)
+ {
+ if (__isnan(__p))
+ return std::numeric_limits<_Tp>::quiet_NaN();
+ else if (__p < _Tp{0} || __p > _Tp{1})
+ std::__throw_domain_error(__N("__binomial_cdf: "
+ "probability is out of range"));
+ else if (__k == 0)
+ return _Tp{1};
+ else if (__k > __n)
+ return _Tp{0};
+ else
+ return __beta_inc(_Tp(__k), _Tp(__n - __k - 1), __p);
+ }
+
+ /**
+ * @brief Return the complementary binomial cumulative distribution function.
+ *
+ * The binomial cumulative distribution function is related
+ * to the incomplete beta function:
+ * @f[
+ * Q(k|n,p) = I_{1-p}(n-k+1, k)
+ * @f]
+ *
+ * @param __p
+ * @param __n
+ * @param __k
+ */
+ template<typename _Tp>
+ _Tp
+ __binomial_cdfc(_Tp __p, unsigned int __n, unsigned int __k)
+ {
+ if (__isnan(__p))
+ return std::numeric_limits<_Tp>::quiet_NaN();
+ else if (__p < _Tp{0} || __p > _Tp{1})
+ std::__throw_domain_error(__N("__binomial_cdfc: "
+ "probability is out of range"));
+ else if (__k == 0)
+ return _Tp{1};
+ else if (__k > __n)
+ return _Tp{0};
+ else
+ return __beta_inc(_Tp(__n - __k - 1), _Tp(__k), _Tp{1} - __p);
+ }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace std
+
+#endif // _GLIBCXX_BITS_SF_DISTRIBUTIONS_TCC
+