Пример #1
0
inline T falling_factorial_imp(T x, unsigned n, const Policy& pol)
{
   BOOST_STATIC_ASSERT(!boost::is_integral<T>::value);
   BOOST_MATH_STD_USING // ADL of std names
   if((x == 0) && (n >= 0))
      return 0;
   if(x < 0)
   {
      //
      // For x < 0 we really have a rising factorial
      // modulo a possible change of sign:
      //
      return (n&1 ? -1 : 1) * rising_factorial(-x, n, pol);
   }
   if(n == 0)
      return 1;
   if(x < 0.5f)
   {
      //
      // 1 + x below will throw away digits, so split up calculation:
      //
      if(n > max_factorial<T>::value - 2)
      {
         // If the two end of the range are far apart we have a ratio of two very large
         // numbers, split the calculation up into two blocks:
         T t1 = x * boost::math::falling_factorial(x - 1, max_factorial<T>::value - 2);
         T t2 = boost::math::falling_factorial(x - max_factorial<T>::value + 1, n - max_factorial<T>::value + 1);
         if(tools::max_value<T>() / fabs(t1) < fabs(t2))
            return boost::math::sign(t1) * boost::math::sign(t2) * policies::raise_overflow_error<T>("boost::math::falling_factorial<%1%>", 0, pol);
         return t1 * t2;
      }
      return x * boost::math::falling_factorial(x - 1, n - 1);
   }
   if(x <= n - 1)
   {
      //
      // x+1-n will be negative and tgamma_delta_ratio won't
      // handle it, split the product up into three parts:
      //
      T xp1 = x + 1;
      unsigned n2 = itrunc((T)floor(xp1), pol);
      if(n2 == xp1)
         return 0;
      T result = boost::math::tgamma_delta_ratio(xp1, -static_cast<T>(n2), pol);
      x -= n2;
      result *= x;
      ++n2;
      if(n2 < n)
         result *= falling_factorial(x - 1, n - n2, pol);
      return result;
   }
   //
   // Simple case: just the ratio of two
   // (positive argument) gamma functions.
   // Note that we don't optimise this for small n,
   // because tgamma_delta_ratio is alreay optimised
   // for that use case:
   //
   return boost::math::tgamma_delta_ratio(x + 1, -static_cast<T>(n), pol);
}
Пример #2
0
T rising_factorial_imp(T x, int n, const Policy& pol)
{
   BOOST_STATIC_ASSERT(!lslboost::is_integral<T>::value);
   if(x < 0)
   {
      //
      // For x less than zero, we really have a falling
      // factorial, modulo a possible change of sign.
      //
      // Note that the falling factorial isn't defined
      // for negative n, so we'll get rid of that case
      // first:
      //
      bool inv = false;
      if(n < 0)
      {
         x += n;
         n = -n;
         inv = true;
      }
      T result = ((n&1) ? -1 : 1) * falling_factorial(-x, n, pol);
      if(inv)
         result = 1 / result;
      return result;
   }
   if(n == 0)
      return 1;
   //
   // We don't optimise this for small n, because
   // tgamma_delta_ratio is alreay optimised for that
   // use case:
   //
   return 1 / lslboost::math::tgamma_delta_ratio(x, static_cast<T>(n), pol);
}
Пример #3
0
inline T falling_factorial_imp(T x, unsigned n, const Policy& pol)
{
   BOOST_STATIC_ASSERT(!lslboost::is_integral<T>::value);
   BOOST_MATH_STD_USING // ADL of std names
   if(x == 0)
      return 0;
   if(x < 0)
   {
      //
      // For x < 0 we really have a rising factorial
      // modulo a possible change of sign:
      //
      return (n&1 ? -1 : 1) * rising_factorial(-x, n, pol);
   }
   if(n == 0)
      return 1;
   if(x < n-1)
   {
      //
      // x+1-n will be negative and tgamma_delta_ratio won't
      // handle it, split the product up into three parts:
      //
      T xp1 = x + 1;
      unsigned n2 = itrunc((T)floor(xp1), pol);
      if(n2 == xp1)
         return 0;
      T result = lslboost::math::tgamma_delta_ratio(xp1, -static_cast<T>(n2), pol);
      x -= n2;
      result *= x;
      ++n2;
      if(n2 < n)
         result *= falling_factorial(x - 1, n - n2, pol);
      return result;
   }
   //
   // Simple case: just the ratio of two
   // (positive argument) gamma functions.
   // Note that we don't optimise this for small n,
   // because tgamma_delta_ratio is alreay optimised
   // for that use case:
   //
   return lslboost::math::tgamma_delta_ratio(x + 1, -static_cast<T>(n), pol);
}
Пример #4
0
int test_main(int, char* [])
{
   int i;
   TEST_POLICY_SF(tgamma(3.0));
   TEST_POLICY_SF(tgamma1pm1(0.25));
   TEST_POLICY_SF(lgamma(50.0));
   TEST_POLICY_SF(lgamma(50.0, &i));
   TEST_POLICY_SF(digamma(12.0));
   TEST_POLICY_SF(tgamma_ratio(12.0, 13.5));
   TEST_POLICY_SF(tgamma_delta_ratio(100.0, 0.25));
   TEST_POLICY_SF(factorial<double>(8));
   TEST_POLICY_SF(unchecked_factorial<double>(3));
   TEST_POLICY_SF(double_factorial<double>(5));
   TEST_POLICY_SF(rising_factorial(20.5, 5));
   TEST_POLICY_SF(falling_factorial(10.2, 7));
   TEST_POLICY_SF(tgamma(12.0, 13.0));
   TEST_POLICY_SF(tgamma_lower(12.0, 13.0));
   TEST_POLICY_SF(gamma_p(12.0, 13.0));
   TEST_POLICY_SF(gamma_q(12.0, 15.0));
   TEST_POLICY_SF(gamma_p_inv(12.0, 0.25));
   TEST_POLICY_SF(gamma_q_inv(15.0, 0.25));
   TEST_POLICY_SF(gamma_p_inva(12.0, 0.25));
   TEST_POLICY_SF(gamma_q_inva(12.0, 0.25));
   TEST_POLICY_SF(erf(2.5));
   TEST_POLICY_SF(erfc(2.5));
   TEST_POLICY_SF(erf_inv(0.25));
   TEST_POLICY_SF(erfc_inv(0.25));
   TEST_POLICY_SF(beta(12.0, 15.0));
   TEST_POLICY_SF(beta(12.0, 15.0, 0.25));
   TEST_POLICY_SF(betac(12.0, 15.0, 0.25));
   TEST_POLICY_SF(ibeta(12.0, 15.0, 0.25));
   TEST_POLICY_SF(ibetac(12.0, 15.0, 0.25));
   TEST_POLICY_SF(ibeta_inv(12.0, 15.0, 0.25));
   TEST_POLICY_SF(ibetac_inv(12.0, 15.0, 0.25));
   TEST_POLICY_SF(ibeta_inva(12.0, 0.75, 0.25));
   TEST_POLICY_SF(ibetac_inva(12.0, 0.75, 0.25));
   TEST_POLICY_SF(ibeta_invb(12.0, 0.75, 0.25));
   TEST_POLICY_SF(ibetac_invb(12.0, 0.75, 0.25));
   TEST_POLICY_SF(gamma_p_derivative(12.0, 15.0));
   TEST_POLICY_SF(ibeta_derivative(12.0, 15.75, 0.25));
   TEST_POLICY_SF(fpclassify(12.0));
   TEST_POLICY_SF(isfinite(12.0));
   TEST_POLICY_SF(isnormal(12.0));
   TEST_POLICY_SF(isnan(12.0));
   TEST_POLICY_SF(isinf(12.0));
   TEST_POLICY_SF(log1p(0.0025));
   TEST_POLICY_SF(expm1(0.0025));
   TEST_POLICY_SF(cbrt(30.0));
   TEST_POLICY_SF(sqrt1pm1(0.0025));
   TEST_POLICY_SF(powm1(1.0025, 12.0));
   TEST_POLICY_SF(legendre_p(5, 0.75));
   TEST_POLICY_SF(legendre_p(7, 3, 0.75));
   TEST_POLICY_SF(legendre_q(5, 0.75));
   TEST_POLICY_SF(legendre_next(2, 0.25, 12.0, 5.0));
   TEST_POLICY_SF(legendre_next(2, 2, 0.25, 12.0, 5.0));
   TEST_POLICY_SF(laguerre(5, 12.2));
   TEST_POLICY_SF(laguerre(7, 3, 5.0));
   TEST_POLICY_SF(laguerre_next(2, 5.0, 12.0, 5.0));
   TEST_POLICY_SF(laguerre_next(5, 3, 5.0, 20.0, 10.0));
   TEST_POLICY_SF(hermite(1, 2.0));
   TEST_POLICY_SF(hermite_next(2, 2.0, 3.0, 2.0));
   TEST_POLICY_SF(spherical_harmonic_r(5, 4, 0.75, 0.25));
   TEST_POLICY_SF(spherical_harmonic_i(5, 4, 0.75, 0.25));
   TEST_POLICY_SF(ellint_1(0.25));
   TEST_POLICY_SF(ellint_1(0.25, 0.75));
   TEST_POLICY_SF(ellint_2(0.25));
   TEST_POLICY_SF(ellint_2(0.25, 0.75));
   TEST_POLICY_SF(ellint_3(0.25, 0.75));
   TEST_POLICY_SF(ellint_3(0.25, 0.125, 0.75));
   TEST_POLICY_SF(ellint_rc(3.0, 5.0));
   TEST_POLICY_SF(ellint_rd(2.0, 3.0, 4.0));
   TEST_POLICY_SF(ellint_rf(2.0, 3.0, 4.0));
   TEST_POLICY_SF(ellint_rj(2.0, 3.0, 5.0, 0.25));
   TEST_POLICY_SF(hypot(5.0, 3.0));
   TEST_POLICY_SF(sinc_pi(3.0));
   TEST_POLICY_SF(sinhc_pi(2.0));
   TEST_POLICY_SF(asinh(12.0));
   TEST_POLICY_SF(acosh(5.0));
   TEST_POLICY_SF(atanh(0.75));
   TEST_POLICY_SF(sin_pi(5.0));
   TEST_POLICY_SF(cos_pi(6.0));
   TEST_POLICY_SF(cyl_neumann(2.0, 5.0));
   TEST_POLICY_SF(cyl_neumann(2, 5.0));
   TEST_POLICY_SF(cyl_bessel_j(2.0, 5.0));
   TEST_POLICY_SF(cyl_bessel_j(2, 5.0));
   TEST_POLICY_SF(cyl_bessel_i(3.0, 5.0));
   TEST_POLICY_SF(cyl_bessel_i(3, 5.0));
   TEST_POLICY_SF(cyl_bessel_k(3.0, 5.0));
   TEST_POLICY_SF(cyl_bessel_k(3, 5.0));
   TEST_POLICY_SF(sph_bessel(3, 5.0));
   TEST_POLICY_SF(sph_bessel(3, 5));
   TEST_POLICY_SF(sph_neumann(3, 5.0));
   TEST_POLICY_SF(sph_neumann(3, 5));
   return 0;
}
Пример #5
0
 inline 
 typename stan::return_type<T0,T1>::type
 operator()(const T0& arg1,
            const T1& arg2) const {
   return falling_factorial(arg1,arg2);
 }