#include <gpk_std.h>
#include "runge6.h"
#include "doublestore.h"


/**\brief Euler step for numerical integration.
The dependent variable y, and its derivitive dydx0
are input at the start. Nvar is the size of y and dydx0.
Htot is the length to be integrated over, and nstep is the number of substeps
to be used.  The output is returned in yout which need not be a distinct
array from y; if it is distinct, however, then y and dydx0 are
unchanged when the function returns.
*/
int euler(C double *y, C double *dydx0, int nvar, double htot, int nstep,
				double *yout,
				BOOL (*derivs)(double *ydot, C double *y, int ny,
								void *c, int nc),
				void *c, int nc)
{
 C double h = htot/nstep;
 int n;
 int i;
 static doublestore ym;

 ym.alloc(nvar);
 if(!ym)
	return R_NOMEM;

 for(i=0;i<nvar;i++)
	yout[i] = y[i] + h*dydx0[i];
 for(n=1;n<nstep;n++) {
	if(! (*derivs)(ym, yout, nvar, c, nc)) {
		return R_NOSTEP;
		}
	for(i=0;i<nvar;i++)
		yout[i] += h*ym[i];
	}
 return R_NOERR;
}
