Пример #1
0
float8 studentT_cdf(int64 nu, float8 t) {
    float8		z,
                t_by_sqrt_nu;
    float8		A, /* contains A(t|nu) */
                prod = 1.,
                sum = 1.;

    /* Handle extreme cases. See above. */

    if (nu <= 0)
        return NAN;
    else if (nu >= 1000000)
        return normal_cdf(t);
    else if (nu >= 200)
        return studentT_cdf_approx(nu, t);

    /* Handle main case (nu < 200) in the rest of the function. */

    z = 1. + t * t / nu;
    t_by_sqrt_nu = fabs(t) / sqrt(nu);

    if (nu == 1)
    {
        A = 2. / M_PI * atan(t_by_sqrt_nu);
    }
    else if (nu & 1) /* odd nu > 1 */
    {
        for (int j = 2; j <= nu - 3; j += 2)
        {
            prod = prod * j / ((j + 1) * z);
            sum = sum + prod;
        }
        A = 2 / M_PI * ( atan(t_by_sqrt_nu) + t_by_sqrt_nu / z * sum );
    }
    else /* even nu */
    {
        for (int j = 2; j <= nu - 2; j += 2)
        {
            prod = prod * (j - 1) / (j * z);
            sum = sum + prod;
        }
        A = t_by_sqrt_nu / sqrt(z) * sum;
    }

    /* A should obviously lie withing the interval [0,1] plus minus (hopefully
     * small) rounding errors. */
    if (A > 1.)
        A = 1.;
    else if (A < 0.)
        A = 0.;

    /* The Student-T distribution is obviously symmetric around t=0... */
    if (t < 0)
        return .5 * (1. - A);
    else
        return 1. - .5 * (1. - A);
}
Пример #2
0
double studentT_CDF(int64_t nu, double t) {
	double		z,
				t_by_sqrt_nu;
	double		A, /* contains A(t|nu) */
				prod = 1.,
				sum = 1.;

	/* Handle extreme cases. See above. */
	 
	if (nu <= 0)
		return std::numeric_limits<double>::quiet_NaN();
    else if (t == std::numeric_limits<double>::infinity())
        return 1;
    else if (t == -std::numeric_limits<double>::infinity())
        return 0;
	else if (nu >= 1000000)
		return normal_cdf(t);
	else if (nu >= 200)
		return studentT_cdf_approx(nu, t);

	/* Handle main case (nu < 200) in the rest of the function. */

	z = 1. + t * t / nu;
	t_by_sqrt_nu = std::fabs(t) / std::sqrt(static_cast<double>(nu));
	
	if (nu == 1)
	{
		A = 2. / M_PI * std::atan(t_by_sqrt_nu);
	}
	else if (nu & 1) /* odd nu > 1 */
	{
		for (int j = 2; j <= nu - 3; j += 2)
		{
			prod = prod * j / ((j + 1) * z);
			sum = sum + prod;
		}
		A = 2 / M_PI * ( std::atan(t_by_sqrt_nu) + t_by_sqrt_nu / z * sum );
	}
	else /* even nu */
	{
		for (int j = 2; j <= nu - 2; j += 2)
		{
			prod = prod * (j - 1) / (j * z);
			sum = sum + prod;
		}
		A = t_by_sqrt_nu / std::sqrt(z) * sum;
	}
	
	/* A should obviously be within the interval [0,1] plus minus (hopefully
	 * small) rounding errors. */
	if (A > 1.)
		A = 1.;
	else if (A < 0.)
		A = 0.;
	
	/* The Student-T distribution is obviously symmetric around t=0... */
	if (t < 0)
		return .5 * (1. - A);
	else
		return 1. - .5 * (1. - A);
}