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; } }
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 ); }