26 static double maxarg1, maxarg2;
27 #define FMAX(a,b) (maxarg1=(a),maxarg2=(b),(maxarg1) > (maxarg2) ?\
28 (maxarg1) : (maxarg2))
32 static double *vector(
int n) {
35 b = (
double *) malloc(
sizeof(
double) *
n);
43 static double **matrix(
int n1,
int n2)
50 m = (
double **) malloc(
sizeof(
double *) * (n1 + 1));
56 for(i = 0; i < n1; i++) {
57 m[i] = (
double *) malloc(
sizeof(
double) * n2);
67 static void free_matrix(
double **m)
88 static void rkSetBuffer(
int nvar) {
97 if(yp) free_matrix(yp);
98 yp = matrix(nvar, kmax);
123 void (*derivs)(
double,
double [],
double [])) {
125 static double a2 = 0.2, a3 = 0.3, a4 = 0.6, a5 = 1.0, a6 = 0.875, b21 = 0.2,
126 b31 = 3.0 / 40.0, b32 = 9.0 / 40.0, b41 = 0.3, b42 = -0.9, b43 = 1.2,
127 b51 = -11.0 / 54.0, b52 = 2.5, b53 = -70.0 / 27.0, b54 = 35.0 / 27.0,
128 b61 = 1631.0 / 55296.0, b62 = 175.0 / 512.0, b63 = 575.0 / 13824.0,
129 b64 = 44275.0 / 110592.0, b65 = 253.0 / 4096.0, c1 = 37.0 / 378.0,
130 c3 = 250.0 / 621.0, c4 = 125.0 / 594.0, c6 = 512.0 / 1771.0,
131 dc5 = -277.0 / 14336.0;
132 double dc1 = c1 - 2825.0 / 27648.0, dc3 = c3 - 18575.0 / 48384.0,
133 dc4 = c4 - 13525.0 / 55296.0, dc6 = c6 - 0.25;
134 double *ak2, *ak3, *ak4, *ak5, *ak6, *ytemp;
143 for(i = 0; i <
n; i++)
144 ytemp[i] = y[i] + b21 * h * dydx[i];
145 (*derivs)(x + a2 * h, ytemp, ak2);
146 for(i = 0; i <
n; i++)
147 ytemp[i] = y[i] + h * (b31 * dydx[i] + b32 * ak2[i]);
148 (*derivs)(x + a3 * h, ytemp, ak3);
149 for(i = 0; i <
n; i++)
150 ytemp[i] = y[i] + h * (b41 * dydx[i] + b42 * ak2[i] + b43 * ak3[i]);
151 (*derivs)(x + a4 * h, ytemp, ak4);
152 for(i = 0; i <
n; i++)
153 ytemp[i] = y[i] + h * (b51 * dydx[i] + b52 * ak2[i] + b53 * ak3[i] + b54 * ak4[i]);
154 (*derivs)(x + a5 * h, ytemp, ak5);
155 for(i = 0; i <
n; i++)
156 ytemp[i] = y[i] + h * (b61 * dydx[i] + b62 * ak2[i] + b63 * ak3[i] + b64 * ak4[i] + b65 * ak5[i]);
157 (*derivs)(x + a6 * h, ytemp, ak6);
158 for(i = 0; i <
n; i++)
159 yout[i] = y[i] + h * (c1 * dydx[i] + c3 * ak3[i] + c4 * ak4[i] + c6 * ak6[i]);
160 for(i = 0; i <
n; i++)
161 yerr[i] = h * (dc1 * dydx[i] + dc3 * ak3[i] + dc4 * ak4[i] + dc5 * ak5[i] + dc6 * ak6[i]);
175 #define ERRCON 1.89e-4
203 double y[],
double dydx[],
int n,
double *x,
double htry,
double eps,
204 double yscal[],
double *hdid,
double *hnext,
205 void (*derivs)(
double,
double [],
double [])) {
207 double errmax, h, xnew, *yerr, *ytemp;
215 rkck(y, dydx, n, *x, h, ytemp, yerr, derivs);
217 for(i = 0; i <
n; i++) errmax =
FMAX(errmax,
fabs(yerr[i] / yscal[i]));
221 if(h < 0.1 * h) h *= 0.1;
235 else *hnext = 5.0 * h;
237 for(i = 0; i <
n; i++) y[i] = ytemp[i];
263 void rk4(
double y[],
int n,
double x,
double h,
264 void (*derivs)(
double,
double [],
double [])) {
266 double xh, hh, h6, *dydx, *dym, *dyt, *yt;
273 (*derivs)(x, y, dydx);
277 for(i = 0; i <
n; i++) yt[i] = y[i] + hh * dydx[i];
278 (*derivs)(xh, yt, dyt);
279 for(i = 0; i <
n; i++) yt[i] = y[i] + hh * dyt[i];
280 (*derivs)(xh, yt, dym);
281 for(i = 0; i <
n; i++) {
282 yt[i] = y[i] + h * dym[i];
285 (*derivs)(x + h, yt, dyt);
286 for(i = 0; i <
n; i++)
287 y[i] += h6 * (dydx[i] + dyt[i] + 2.0 * dym[i]);
298 #define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a))
333 void (*derivs)(
double,
double [],
double [])) {
335 double xsav = 0.0, x, hnext, hdid, h;
336 double *yscal, *y, *dydx;
342 yscal = vector(nvar);
346 h =
SIGN(h1, x2 - x1);
347 *nok = (*nbad) = kount = 0;
348 for(i = 0; i < nvar; i++) y[i] = ystart[i];
349 if(kmax > 0) xsav = x - dxsav * 2.0;
350 for(nstp = 0; nstp <
MAXSTP; nstp++) {
351 (*derivs)(x, y, dydx);
352 for(i = 0; i < nvar; i++) {
355 if(kmax > 0 && kount < kmax - 1 &&
fabs(x - xsav) >
fabs(dxsav)) {
357 for(i = 0; i < nvar; i++) yp[i][kount] = y[i];
360 if((x + h - x2) * (x + h - x1) > 0.0) h = x2 - x;
361 if(rkqs(y, dydx, nvar, &x, h, eps, yscal, &hdid, &hnext, derivs) == 1) {
368 if(hdid == h) ++(*nok);
370 if((x - x2) * (x2 - x1) >= 0.0) {
371 for(i = 0; i < nvar; i++) ystart[i] = y[i];
374 for(i = 0; i < nvar; i++) yp[i][kount] = y[i];
381 if(
fabs(hnext) <= hmin) {
399 if(yp) free_matrix(yp);
411 fprintf(f,
"odeint output buffer, kmax = %d/%d\n", kount, kmax);
413 fprintf(f,
"%-4s %-10s",
"k",
"xp");
415 while(yp[j]) fprintf(f,
" [%2d] ", j++);
418 for(i = 0; i < kount; i++) {
419 fprintf(f,
"%4d %10.4f", i, xp[i]);
421 while(yp[j]) fprintf(f,
" %10.4f", yp[j++][i]);
void writeBetError(std::string err)
PETE_TUTree< FnFabs, typename T::PETE_Expr_t > fabs(const PETE_Expr< T > &l)
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
void rkck(double y[], double dydx[], int n, double x, double h, double yout[], double yerr[], void(*derivs)(double, double[], double[]))
void rk4(double y[], int n, double x, double h, void(*derivs)(double, double[], double[]))
void rkActivateBuffer(int max)
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
void rkPrintBuffer(FILE *f)
int odeint(double ystart[], int nvar, double x1, double x2, double eps, double h1, double hmin, int *nok, int *nbad, void(*derivs)(double, double[], double[]))