Esempio n. 1
0
         T non_central_t2_q(T v, T delta, T x, T y, const Policy& pol, T init_val)
         {
            BOOST_MATH_STD_USING
            //
            // Variables come first:
            //
            boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
            T errtol = boost::math::policies::get_epsilon<T, Policy>();
            T d2 = delta * delta / 2;
            //
            // k is the starting point for iteration, and is the
            // maximum of the poisson weighting term, we don't allow
            // k == 0 as this can cause catastrophic cancellation errors
            // (test case is v = 561908036470413.25, delta = 0.056190803647041321,
            // x = 1.6155232703966216):
            //
            int k = itrunc(d2);
            if(k == 0) k = 1;
            // Starting Poisson weight:
            T pois;
            if((k < (int)(max_factorial<T>::value)) && (d2 < tools::log_max_value<T>()) && (log(d2) * k < tools::log_max_value<T>()))
            {
               //
               // For small k we can optimise this calculation by using
               // a simpler reduced formula:
               //
               pois = exp(-d2);
               pois *= pow(d2, static_cast<T>(k));
               pois /= boost::math::tgamma(T(k + 1 + 0.5), pol);
               pois *= delta / constants::root_two<T>();
            }
            else
            {
               pois = gamma_p_derivative(T(k+1), d2, pol) 
                  * tgamma_delta_ratio(T(k + 1), T(0.5f))
                  * delta / constants::root_two<T>();
            }
            if(pois == 0)
               return init_val;
            // Recurance term:
            T xterm;
            T beta;
            // Starting beta term:
            if(k != 0)
            {
               beta = x < y 
                  ? detail::ibeta_imp(T(k + 1), T(v / 2), x, pol, true, true, &xterm) 
                  : detail::ibeta_imp(T(v / 2), T(k + 1), y, pol, false, true, &xterm);

               xterm *= y / (v / 2 + k);
            }
            else
            {
               beta = pow(y, v / 2);
               xterm = beta;
            }
            T poisf(pois), betaf(beta), xtermf(xterm);
            T sum = init_val;
            if((xterm == 0) && (beta == 0))
               return init_val;

            //
            // Fused forward and backwards recursion:
            //
            boost::uintmax_t count = 0;
            T last_term = 0;
            for(int i = k + 1, j = k; ; ++i, --j)
            {
               poisf *= d2 / (i + 0.5f);
               xtermf *= (x * (v / 2 + i - 1)) / (i);
               betaf += xtermf;
               T term = poisf * betaf;

               if(j >= 0)
               {
                  term += beta * pois;
                  pois *= (j + 0.5f) / d2;
                  beta -= xterm;
                  xterm *= (j) / (x * (v / 2 + j - 1));
               }

               sum += term;
               // Don't terminate on first term in case we "fixed" the value of k above:
               if((fabs(last_term) > fabs(term)) && fabs(term/sum) < errtol)
                  break;
               last_term = term;
               if(count > max_iter)
               {
                  return policies::raise_evaluation_error(
                     "cdf(non_central_t_distribution<%1%>, %1%)", 
                     "Series did not converge, closest value was %1%", sum, pol);
               }
               ++count;
            }
            return sum;
         }
Esempio n. 2
0
         T non_central_t2_p(T v, T delta, T x, T y, const Policy& pol, T init_val)
         {
            BOOST_MATH_STD_USING
            //
            // Variables come first:
            //
            boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
            T errtol = policies::get_epsilon<T, Policy>();
            T d2 = delta * delta / 2;
            //
            // k is the starting point for iteration, and is the
            // maximum of the poisson weighting term, we don't
            // ever allow k == 0 as this can lead to catastrophic
            // cancellation errors later (test case is v = 1621286869049072.3
            // delta = 0.16212868690490723, x = 0.86987415482475994).
            //
            int k = itrunc(d2);
            T pois;
            if(k == 0) k = 1;
            // Starting Poisson weight:
            pois = gamma_p_derivative(T(k+1), d2, pol) 
               * tgamma_delta_ratio(T(k + 1), T(0.5f))
               * delta / constants::root_two<T>();
            if(pois == 0)
               return init_val;
            T xterm, beta;
            // Recurrance & starting beta terms:
            beta = x < y
               ? detail::ibeta_imp(T(k + 1), T(v / 2), x, pol, false, true, &xterm)
               : detail::ibeta_imp(T(v / 2), T(k + 1), y, pol, true, true, &xterm);
            xterm *= y / (v / 2 + k);
            T poisf(pois), betaf(beta), xtermf(xterm);
            T sum = init_val;
            if((xterm == 0) && (beta == 0))
               return init_val;

            //
            // Backwards recursion first, this is the stable
            // direction for recursion:
            //
            boost::uintmax_t count = 0;
            T last_term = 0;
            for(int i = k; i >= 0; --i)
            {
               T term = beta * pois;
               sum += term;
               // Don't terminate on first term in case we "fixed" k above:
               if((fabs(last_term) > fabs(term)) && fabs(term/sum) < errtol)
                  break;
               last_term = term;
               pois *= (i + 0.5f) / d2;
               beta += xterm;
               xterm *= (i) / (x * (v / 2 + i - 1));
               ++count;
            }
            last_term = 0;
            for(int i = k + 1; ; ++i)
            {
               poisf *= d2 / (i + 0.5f);
               xtermf *= (x * (v / 2 + i - 1)) / (i);
               betaf -= xtermf;
               T term = poisf * betaf;
               sum += term;
               if((fabs(last_term) > fabs(term)) && (fabs(term/sum) < errtol))
                  break;
               last_term = term;
               ++count;
               if(count > max_iter)
               {
                  return policies::raise_evaluation_error(
                     "cdf(non_central_t_distribution<%1%>, %1%)", 
                     "Series did not converge, closest value was %1%", sum, pol);
               }
            }
            return sum;
         }
Esempio n. 3
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;
}