/* atanh.c * * Inverse hyperbolic tangent * * * * SYNOPSIS: * * double x, y, atanh(); * * y = atanh( x ); * * * * DESCRIPTION: * * Returns inverse hyperbolic tangent of argument in the range * MINLOG to MAXLOG. * * If |x| < 0.5, the rational form x + x**3 P(x)/Q(x) is * employed. Otherwise, * atanh(x) = 0.5 * log( (1+x)/(1-x) ). * * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * DEC -1,1 50000 2.4e-17 6.4e-18 * IEEE -1,1 30000 1.9e-16 5.2e-17 * */ /* atanh.c */ /* Cephes Math Library Release 2.3: March, 1995 Copyright (C) 1987, 1995 by Stephen L. Moshier */ #include "mconf.h" static double P[] = { -8.54074331929669305196E-1, 1.20426861384072379242E1, -4.61252884198732692637E1, 6.54566728676544377376E1, -3.09092539379866942570E1 }; static double Q[] = { /* 1.00000000000000000000E0,*/ -1.95638849376911654834E1, 1.08938092147140262656E2, -2.49839401325893582852E2, 2.52006675691344555838E2, -9.27277618139601130017E1 }; #ifndef ANSIPROT double fabs(), log(), polevl(), p1evl(); #endif double atanh(x) double x; { double s, z; #ifdef MINUSZERO if( x == 0.0 ) return(x); #endif z = fabs(x); if( z >= 1.0 ) { if( x == 1.0 ) return( infinity() ); if( x == -1.0 ) return( -infinity() ); mtherr( "atanh", DOMAIN ); return( quiet_nan() ); } if( z < 1.0e-7 ) return(x); if( z < 0.5 ) { z = x * x; s = x + x * z * (polevl(z, P, 4) / p1evl(z, Q, 5)); return(s); } return( 0.5 * log((1.0+x)/(1.0-x)) ); }