#include <gpk_std.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>
# include "runge6.h"
# include "bulsto.h"

#define ADDRESS char *

int xdotval = 0;

BOOL out(double *xo, C double *x, int nx, void *c, int nc, int nout)
{

 printf("\tout((%g,%g),%d,xxx,0,%d)\n", x[0], x[1], nx, nout);

 if(nout != 2)
	return FALSE;
 xo[0] = x[1];
 xo[1] = x[1] - 1/(1+100*x[0]*x[0]);
 return TRUE;
}

BOOL xdot(double *xd, C double *x, int nx, void *c, int nc)
{
 extern int xdotval;

/*
 printf("\txdot((%g,%g),%d,xxxx,0)=", x[0], x[1], nx);
*/
 xd[0] = 1.0;
 xd[1] = -200.0*x[0]*x[1]*x[1];
/*
 printf("(%g,%g)\n", xd[0], xd[1]);
*/
 if(x[1]<=0.0)
	printf("xdot:x[1]=%7.3g<0.0\n", x[1]);
 xdotval ++;
 return x[1]>0.0;
}



main(int argc, char **argv)
{
 double x[2], tv[100], eps, ntv[100];
 int i;
 extern int xdotval;
 struct runge_s  p, q;
 LOCAL double limits[] = {0.0, 0.0};

 eps = argc>1 ? atof(argv[1]) : 1e-12;
 for(i=0;i<9;i++)
	tv[i] = -3.0 + 2.9*i/8.0;
 tv[9] = 0.0;
 x[0] = -3.0;
 x[1] = 1.0/901.;
 p = bulsto(x, (void *)0, 2, 0, xdot, eps, tv, 10, out, 2, limits);
 if(!p.xx)      {
	printf("p==NULL\n");
	exit(-1);
	}
 if(!p.isgood)  printf("error %d in bulsto\n", p.errtype);

 for(i=0;i<10;i++)
	ntv[i] = tv[9-i];
 q = bulsto(x, (void *)0, 2, 0, xdot, eps, ntv, 10, out, 2, limits);
 if(!q.xx)      {
	printf("q==NULL\n");
	exit(-1);
	}
 if(!q.isgood)  printf("error %d in bulsto\n", q.errtype);
 for(i=0;i<q.stepcount;i++)
	printf("y[%g]=%g or %g, err=%g\n", tv[i], q.xx[2*(9-i)], p.xx[2*i],
			q.xx[2*i+1]);

 free((ADDRESS) p.xx);
 free((ADDRESS) q.xx);
 printf("Total of %d calls to xdot\n", xdotval);
 exit(0);
}
