#include<stdio.h>
#include<math.h>
#include<gsl/gsl_errno.h>
#include<gsl/gsl_odeiv2.h>

int tanprime(double t, const double y[], double dydt[], void* params){
	dydt[0]=1+y[0]*y[0];
	return GSL_SUCCESS;
	}

double my_tan(double x){
	if(x<0) return -my_tan(-x);
	int n=(int)(x/M_PI);
	x=x-n*M_PI;
	if(x>M_PI/2) x=x-M_PI;
	
	gsl_odeiv2_system sys;
	sys.function=tanprime;
	sys.jacobian=NULL;
	sys.dimension=1;
	sys.params=NULL;

	double hstart=copysign(1e-3,x), epsabs=1e-6, epsrel=1e-6;

	gsl_odeiv2_driver *driver = 
		gsl_odeiv2_driver_alloc_y_new
			(&sys, gsl_odeiv2_step_rk8pd, hstart, epsabs, epsrel);

	double t=0, y[1]={0};
	int status = gsl_odeiv2_driver_apply(driver,&t,x,y);
	if(status != GSL_SUCCESS) fprintf(stderr,"my_tan: status=%i",status);
	gsl_odeiv2_driver_free(driver);
	return y[0];
}
