/* atan.c */

#define _LIBM_SOURCE

#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define EPSLN 1.0E-8 	/* convergence test value */

#ifdef __STDC__
static double confrac (double);
#else
static double confrac();
#endif


/* double uses Abramowitz & Stegun continued fraction formula 4.4.43 
* and matrix recurrence A&S 3.10.1 for evaluation starting with second
* term to cope with a1 = x whereas higher terms involve x*x  
*  S E Peterson  3/92    */

static double confrac(x)
double x;
{
double  n, x2, res, old;
double	   an, An, bn, Bn;
double	   a1,a2,b1,b2;
	   a1=x;
	   a2=0.0;
	   b1=1.0;
	   b2=1.0;

	n=1.0;  
	old=x;			 		
	x2 = x*x;
	while (n<100.0){  /* control for no. of iterations */
		an = n * n * x2;
		bn = (2.0*n)+1.0;
		An = (a1*bn)+(a2*an);
		Bn = (b1*bn)+(b2*an);
		res = An/Bn;
		if (fabs(old-res)<= EPSLN ){
			return (res);
		}
		else{
			old=res;
			a2=a1;
			a1=An;
			b2=b1;
			b1=Bn;
			n +=1.0;	
		}
	}
	(void)printf("atan: No convergence - increase no. of iterations or value of epsilon\n");
	return (HUGE_VAL);
}	

double	atan(x)
double x; 

{
	double ans;

	if (x>1.0)
		ans = PID2 - confrac(1.0/x);
	else if (x<-1.0)
		ans = confrac(1.0/x) - PID2;
	else
		ans = confrac(x);
	return (ans);	
}

