/* beta.c * * Beta function * * * * SYNOPSIS: * * double a, b, y, beta(); * * y = beta( a, b ); * * * * DESCRIPTION: * * - - * | (a) | (b) * beta( a, b ) = -----------. * - * | (a+b) * * For large arguments the logarithm of the function is * evaluated using lgam(), then exponentiated. * * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * DEC 0,30 1700 7.7e-15 1.5e-15 * IEEE 0,30 30000 8.1e-14 1.1e-14 * * ERROR MESSAGES: * * message condition value returned * beta overflow log(beta) > MAXLOG 0.0 * a or b <0 integer 0.0 * */ /* beta.c */ /* Cephes Math Library Release 2.0: April, 1987 Copyright 1984, 1987 by Stephen L. Moshier Direct inquiries to 30 Frost Street, Cambridge, MA 02140 */ #include "mconf.h" #ifdef UNK #define MAXGAM 34.84425627277176174 #endif #ifdef DEC #define MAXGAM 34.84425627277176174 #endif #ifdef IBMPC #define MAXGAM 171.624376956302725 #endif #ifdef MIEEE #define MAXGAM 171.624376956302725 #endif #ifdef ANSIPROT extern double fabs ( double ); extern double gamma ( double ); extern double lgam ( double ); extern double exp ( double ); extern double log ( double ); extern double floor ( double ); #else double fabs(), gamma(), lgam(), exp(), log(), floor(); #endif extern double MAXLOG, MAXNUM; extern int sgngam; double beta( a, b ) double a, b; { double y; int sign; sign = 1; if( a <= 0.0 ) { if( a == floor(a) ) goto over; } if( b <= 0.0 ) { if( b == floor(b) ) goto over; } y = a + b; if( fabs(y) > MAXGAM ) { y = lgam(y); sign *= sgngam; /* keep track of the sign */ y = lgam(b) - y; sign *= sgngam; y = lgam(a) + y; sign *= sgngam; if( y > MAXLOG ) { over: mtherr( "beta", OVERFLOW ); return( sign * MAXNUM ); } return( sign * exp(y) ); } y = gamma(y); if( y == 0.0 ) goto over; if( a > b ) { y = gamma(a)/y; y *= gamma(b); } else { y = gamma(b)/y; y *= gamma(a); } return(y); } /* Natural log of |beta|. Return the sign of beta in sgngam. */ double lbeta( a, b ) double a, b; { double y; int sign; sign = 1; if( a <= 0.0 ) { if( a == floor(a) ) goto over; } if( b <= 0.0 ) { if( b == floor(b) ) goto over; } y = a + b; if( fabs(y) > MAXGAM ) { y = lgam(y); sign *= sgngam; /* keep track of the sign */ y = lgam(b) - y; sign *= sgngam; y = lgam(a) + y; sign *= sgngam; sgngam = sign; return( y ); } y = gamma(y); if( y == 0.0 ) { over: mtherr( "lbeta", OVERFLOW ); return( sign * MAXNUM ); } if( a > b ) { y = gamma(a)/y; y *= gamma(b); } else { y = gamma(b)/y; y *= gamma(a); } if( y < 0 ) { sgngam = -1; y = -y; } else sgngam = 1; return( log(y) ); }