예제 #1
0
complex_t *polynomial_eval(polynomial_t *p, complex_t *coef, monomial_t *m, complex_t *eval)
{
	complex_t *result = NULL, *tmp = NULL;
	unsigned long diff = 0;

	if (p == NULL || coef == NULL || eval == NULL)
		return NULL;

	if (p->first->degree == 0)
		return complex_init(coef->re, coef->im);
	else
	{
		diff = (m == NULL) ? p->last->degree : m->previous->degree - m->degree;
		while (diff > 0)
		{
			if (result == NULL)
			{
				result = complex_prod(coef, eval);
				if (result == NULL)
					return NULL;
			}
			else
			{
				tmp = complex_prod(result, eval);
				if (tmp == NULL)
				{
					complex_free(result);

					return NULL;
				}

				complex_free(result);
				result = tmp;
			}

			diff--;
		}

		if (m != NULL)
		{
			tmp = complex_sum(result, m->coef);
			if (tmp == NULL)
			{
				complex_free(result);

				return NULL;
			}

			complex_free(result);
			result = tmp;

			if (m->next != NULL || m->degree > 0)
			{
				result = polynomial_eval(p, tmp, m->next, eval);
				complex_free(tmp);
			}
		}

		return result;
	}
}
예제 #2
0
double
log_gamma(double x)
{
    double p, q, u, w, z;
    int i;

    int sgngam = 1;

    if (x >= MY_kDBL_MAX)
        return(MY_kDBL_MAX);

    if( x < -34.0 )
    {
        q = -x;
        w = log_gamma(q);
        p = floor(q);
        if( p==q )//_unur_FP_same(p,q)
            return(MY_kDBL_MAX);
        i = (int) p;
        if( (i & 1) == 0 )
            sgngam = -1;
        else
            sgngam = 1;
        z = q - p;
        if( z > 0.5 )
        {
            p += 1.0;
            z = p - q;
        }
        z = q * sin( M_PI * z );
        if( z == 0 )
            return(MY_kDBL_MAX);
        z = log(M_PI) - log( z ) - w;
        return( z );
    }

    if( x < 13.0 )
    {
        z = 1.0;
        p = 0.0;
        u = x;
        while( u >= 3.0 )
        {
            p -= 1.0;
            u = x + p;
            z *= u;
        }
        while( u < 2.0 )
        {
            if( u == 0 )
                return (MY_kDBL_MAX);
            z /= u;
            p += 1.0;
            u = x + p;
        }
        if( z < 0.0 )
        {
            sgngam = -1;
            z = -z;
        }
        else
            sgngam = 1;
        if( u == 2.0 )
            return( log(z) );
        p -= 2.0;
        x = x + p;
        p = x * polynomial_eval(x, B, 5 ) / polynomial_1eval( x, C, 6);
        return( log(z) + p );
    }

    if( x > MY_kMAXLGM )
        return( sgngam * MY_kDBL_MAX );

    q = ( x - 0.5 ) * log(x) - x + MY_kLS2PI;
    if( x > 1.0e8 )
        return( q );

    p = 1.0/(x*x);
    if( x >= 1000.0 )
        q += ((   7.9365079365079365079365e-4 * p
                  - 2.7777777777777777777778e-3) *p
              + 0.0833333333333333333333) / x;
    else
        q += polynomial_eval( p, A, 4 ) / x;
    return( q );
}