コード例 #1
0
ファイル: rk2imp.c プロジェクト: naorbrown/EpiFire
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;
}
コード例 #2
0
ファイル: eulerplus.c プロジェクト: BrianGladman/gsl
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;
}
コード例 #3
0
ファイル: euler.c プロジェクト: BrianGladman/gsl
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;
}
コード例 #4
0
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;
}