static int rk2imp_apply (void *vstate, size_t dim, double t, double h, double y[], double yerr[], const double dydt_in[], double dydt_out[], const gsl_odeiv_system * sys) { rk2imp_state_t *state = (rk2imp_state_t *) vstate; const int iter_steps = 3; int status = 0; int nu; size_t i; double *const knu = state->knu; double *const ytmp = state->ytmp; /* initialization step */ if (dydt_in != NULL) { DBL_MEMCPY (knu, dydt_in, dim); } else { int s = GSL_ODEIV_FN_EVAL (sys, t, y, knu); GSL_STATUS_UPDATE (&status, s); } /* iterative solution */ for (nu = 0; nu < iter_steps; nu++) { for (i = 0; i < dim; i++) { ytmp[i] = y[i] + 0.5 * h * knu[i]; } { int s = GSL_ODEIV_FN_EVAL (sys, t + 0.5 * h, ytmp, knu); GSL_STATUS_UPDATE (&status, s); } } /* assignment */ for (i = 0; i < dim; i++) { y[i] += h * knu[i]; yerr[i] = h * h * knu[i]; if (dydt_out != NULL) dydt_out[i] = knu[i]; } return status; }
static int eulerplus_apply (void *vstate, size_t dim, double t, double h, double y[], double yerr[], const double dydt_in[], double dydt_out[], const gsl_odeiv_system * sys) { eulerplus_state_t *state = (eulerplus_state_t *) vstate; double temp; size_t i; int status = 0; double *const k1 = state->k1; double *const k2 = state->k2; double *const ytmp = state->ytmp; if (dydt_in != NULL) { DBL_MEMCPY (k1, dydt_in, dim); } else { int s = GSL_ODEIV_FN_EVAL (sys, t, y, k1); GSL_STATUS_UPDATE (&status, s); } /* aplicamos euler */ for (i = 0; i < dim; i++) { ytmp[i] = y[i] + h * k1[i] ; } { int s = GSL_ODEIV_FN_EVAL (sys, t+h, ytmp, k2); GSL_STATUS_UPDATE (&status, s); } for (i = 0; i < dim; i++) { temp = (k1[i]+k2[i]) / 2; /* la pendiente en x + h */ if (dydt_out != NULL) dydt_out[i] = temp; yerr[i] = h * temp; y[i] += h*temp; } return status; }
static int euler_apply (void *vstate, size_t dim, double t, double h, double y[], double yerr[], const double dydt_in[], double dydt_out[], const gsl_odeiv_system * sys) { euler_state_t *state = (euler_state_t *) vstate; double temp; size_t i; int status = 0; double *const k = state->k; if (dydt_in != NULL) { DBL_MEMCPY (k, dydt_in, dim); } else { int s = GSL_ODEIV_FN_EVAL (sys, t, y, k); GSL_STATUS_UPDATE (&status, s); } for (i = 0; i < dim; i++) { temp = y[i]; /* save y[i] */ y[i] = h * k[i]; yerr[i] = h * y[i]; y[i] += temp; if (dydt_out != NULL) dydt_out[i] = k[i]; } return status; }
static int rk8pd_apply (void *vstate, size_t dim, double t, double h, double y[], double yerr[], const double dydt_in[], double dydt_out[], const gsl_odeiv_system * sys) { rk8pd_state_t *state = (rk8pd_state_t *) vstate; size_t i; int status = 0; double *const ytmp = state->ytmp; /* Note that k1 is stored in state->k[0] due to zero-based indexing */ double *const k1 = state->k[0]; double *const k2 = state->k[1]; double *const k3 = state->k[2]; double *const k4 = state->k[3]; double *const k5 = state->k[4]; double *const k6 = state->k[5]; double *const k7 = state->k[6]; double *const k8 = state->k[7]; double *const k9 = state->k[8]; double *const k10 = state->k[9]; double *const k11 = state->k[10]; double *const k12 = state->k[11]; double *const k13 = state->k[12]; /* k1 step */ if (dydt_in != NULL) { DBL_MEMCPY (k1, dydt_in, dim); } else { int s = GSL_ODEIV_FN_EVAL (sys, t, y, k1); GSL_STATUS_UPDATE (&status, s); } for (i = 0; i < dim; i++) ytmp[i] = y[i] + b21 * h * k1[i]; /* k2 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + ah[0] * h, ytmp, k2); GSL_STATUS_UPDATE (&status, s); } for (i = 0; i < dim; i++) ytmp[i] = y[i] + h * (b3[0] * k1[i] + b3[1] * k2[i]); /* k3 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + ah[1] * h, ytmp, k3); GSL_STATUS_UPDATE (&status, s); } for (i = 0; i < dim; i++) ytmp[i] = y[i] + h * (b4[0] * k1[i] + b4[2] * k3[i]); /* k4 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + ah[2] * h, ytmp, k4); GSL_STATUS_UPDATE (&status, s); } for (i = 0; i < dim; i++) ytmp[i] = y[i] + h * (b5[0] * k1[i] + b5[2] * k3[i] + b5[3] * k4[i]); /* k5 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + ah[3] * h, ytmp, k5); GSL_STATUS_UPDATE (&status, s); } for (i = 0; i < dim; i++) ytmp[i] = y[i] + h * (b6[0] * k1[i] + b6[3] * k4[i] + b6[4] * k5[i]); /* k6 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + ah[4] * h, ytmp, k6); GSL_STATUS_UPDATE (&status, s); } for (i = 0; i < dim; i++) ytmp[i] = y[i] + h * (b7[0] * k1[i] + b7[3] * k4[i] + b7[4] * k5[i] + b7[5] * k6[i]); /* k7 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + ah[5] * h, ytmp, k7); GSL_STATUS_UPDATE (&status, s); } for (i = 0; i < dim; i++) ytmp[i] = y[i] + h * (b8[0] * k1[i] + b8[3] * k4[i] + b8[4] * k5[i] + b8[5] * k6[i] + b8[6] * k7[i]); /* k8 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + ah[6] * h, ytmp, k8); GSL_STATUS_UPDATE (&status, s); } for (i = 0; i < dim; i++) ytmp[i] = y[i] + h * (b9[0] * k1[i] + b9[3] * k4[i] + b9[4] * k5[i] + b9[5] * k6[i] + b9[6] * k7[i] + b9[7] * k8[i]); /* k9 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + ah[7] * h, ytmp, k9); GSL_STATUS_UPDATE (&status, s); } for (i = 0; i < dim; i++) ytmp[i] = y[i] + h * (b10[0] * k1[i] + b10[3] * k4[i] + b10[4] * k5[i] + b10[5] * k6[i] + b10[6] * k7[i] + b10[7] * k8[i] + b10[8] * k9[i]); /* k10 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + ah[8] * h, ytmp, k10); GSL_STATUS_UPDATE (&status, s); } for (i = 0; i < dim; i++) ytmp[i] = y[i] + h * (b11[0] * k1[i] + b11[3] * k4[i] + b11[4] * k5[i] + b11[5] * k6[i] + b11[6] * k7[i] + b11[7] * k8[i] + b11[8] * k9[i] + b11[9] * k10[i]); /* k11 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + ah[9] * h, ytmp, k11); GSL_STATUS_UPDATE (&status, s); } for (i = 0; i < dim; i++) ytmp[i] = y[i] + h * (b12[0] * k1[i] + b12[3] * k4[i] + b12[4] * k5[i] + b12[5] * k6[i] + b12[6] * k7[i] + b12[7] * k8[i] + b12[8] * k9[i] + b12[9] * k10[i] + b12[10] * k11[i]); /* k12 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + h, ytmp, k12); GSL_STATUS_UPDATE (&status, s); } for (i = 0; i < dim; i++) ytmp[i] = y[i] + h * (b13[0] * k1[i] + b13[3] * k4[i] + b13[4] * k5[i] + b13[5] * k6[i] + b13[6] * k7[i] + b13[7] * k8[i] + b13[8] * k9[i] + b13[9] * k10[i] + b13[10] * k11[i] + b13[11] * k12[i]); /* k13 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + h, ytmp, k13); GSL_STATUS_UPDATE (&status, s); } /* final sum and error estimate */ for (i = 0; i < dim; i++) { const double ksum8 = Abar[0] * k1[i] + Abar[5] * k6[i] + Abar[6] * k7[i] + Abar[7] * k8[i] + Abar[8] * k9[i] + Abar[9] * k10[i] + Abar[10] * k11[i] + Abar[11] * k12[i] + Abar[12] * k13[i]; const double ksum7 = A[0] * k1[i] + A[5] * k6[i] + A[6] * k7[i] + A[7] * k8[i] + A[8] * k9[i] + A[9] * k10[i] + A[10] * k11[i] + A[11] * k12[i]; y[i] += h * ksum8; yerr[i] = h * (ksum7 - ksum8); if (dydt_out != NULL) dydt_out[i] = ksum8; } return status; }