/* acosh.c * * Inverse hyperbolic cosine * * * * SYNOPSIS: * * double x, y, acosh(); * * y = acosh( x ); * * * * DESCRIPTION: * * Returns inverse hyperbolic cosine of argument. * * If 1 <= x < 1.5, a rational approximation * * sqrt(z) * P(z)/Q(z) * * where z = x-1, is used. Otherwise, * * acosh(x) = log( x + sqrt( (x-1)(x+1) ). * * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * DEC 1,3 30000 4.2e-17 1.1e-17 * IEEE 1,3 30000 4.6e-16 8.7e-17 * * * ERROR MESSAGES: * * message condition value returned * acosh domain |x| < 1 NAN * */ /* acosh.c */ /* Cephes Math Library Release 2.3: March, 1995 Copyright 1984, 1995 by Stephen L. Moshier */ /* acosh(z) = sqrt(x) * R(x), z = x + 1, interval 0 < x < 0.5 */ #include "mconf.h" static double P[] = { 1.18801130533544501356E2, 3.94726656571334401102E3, 3.43989375926195455866E4, 1.08102874834699867335E5, 1.10855947270161294369E5 }; static double Q[] = { /* 1.00000000000000000000E0,*/ 1.86145380837903397292E2, 4.15352677227719831579E3, 2.97683430363289370382E4, 8.29725251988426222434E4, 7.83869920495893927727E4 }; #ifndef ANSIPROT double log(), sqrt(), polevl(), p1evl(); #endif extern double LOGE2; double acosh(x) double x; { double a, z; if( x < 1.0 ) { mtherr( "acosh", DOMAIN ); return(quiet_nan()); } if( x > 1.0e8 ) { if( !finite(x) ) return(x); return( log(x) + LOGE2 ); } z = x - 1.0; if( z < 0.5 ) { a = sqrt(z) * (polevl(z, P, 4) / p1evl(z, Q, 5) ); return( a ); } a = sqrt( z*(x+1.0) ); return( log(x + a) ); }