Exemple #1
0
double rk_main(double alpha,double epsilon,double h_init){
  double x=0,y=1,y4,y5,h=h_init;
  double a[6][6],b5[6],b4[6],c[6];
  set_a(a);
  set_b4(b4);
  set_b5(b5);
  set_c(c);
  printf("#\t%s\t%s\t%s\t%s\n","x","y","h","dy/dx");
  while(x<10.0){
    rk_step(x,y,h,a,b4,c,&y4);
    rk_step(x,y,h,a,b5,c,&y5);
    if(y4-y5<epsilon){
      printf("\t%f\t%f\t%e\t%f\n",x,y,h,f(x));
      x+=h;
      y=y5;
      h=alpha*h*pow(epsilon/fabs(y4-y5),0.2);
    }else{
      h=h/2;
    }
  }
  return y;
}
int
gsl_sf_bessel_sequence_Jnu_e(double nu, gsl_mode_t mode, size_t size, double * v)
{
  /* CHECK_POINTER(v) */

  if(nu < 0.0) {
    GSL_ERROR ("domain error", GSL_EDOM);
  }
  else if(size == 0) {
    GSL_ERROR ("error", GSL_EINVAL);
  }
  else {
    const gsl_prec_t goal   = GSL_MODE_PREC(mode);
    const double dx_array[] = { 0.001, 0.03, 0.1 }; /* double, single, approx */
    const double dx_nominal = dx_array[goal];

    const int cnu = (int) ceil(nu);
    const double nu13 = pow(nu,1.0/3.0);
    const double smalls[] = { 0.01, 0.02, 0.4, 0.7, 1.3, 2.0, 2.5, 3.2, 3.5, 4.5, 6.0 };
    const double x_small = ( nu >= 10.0 ? nu - nu13 : smalls[cnu] );

    gsl_sf_result J0, J1;
    double Jp, J;
    double x;
    size_t i = 0;

    /* Calculate the first point. */
    x = v[0];
    gsl_sf_bessel_Jnu_e(nu, x, &J0);
    v[0] = J0.val;
    ++i;

    /* Step over the idiot case where the
     * first point was actually zero.
     */
    if(x == 0.0) {
      if(v[1] <= x) {
        /* Strict ordering failure. */
        GSL_ERROR ("error", GSL_EFAILED);
      }
      x = v[1];
      gsl_sf_bessel_Jnu_e(nu, x, &J0);
      v[1] = J0.val;
      ++i;
    }

    /* Calculate directly as long as the argument
     * is small. This is necessary because the
     * integration is not very good there.
     */
    while(v[i] < x_small && i < size) {
      if(v[i] <= x) {
        /* Strict ordering failure. */
        GSL_ERROR ("error", GSL_EFAILED);
      }
      x = v[i];
      gsl_sf_bessel_Jnu_e(nu, x, &J0);
      v[i] = J0.val;
      ++i;
    }

    /* At this point we are ready to integrate.
     * The value of x is the last calculated
     * point, which has the value J0; v[i] is
     * the next point we need to calculate. We
     * calculate nu+1 at x as well to get
     * the derivative, then we go forward.
     */
    gsl_sf_bessel_Jnu_e(nu+1.0, x, &J1);
    J  = J0.val;
    Jp = -J1.val + nu/x * J0.val;

    while(i < size) {
      const double dv = v[i] - x;
      const int Nd    = (int) ceil(dv/dx_nominal);
      const double dx = dv / Nd;
      double xj;
      int j;

      if(v[i] <= x) {
        /* Strict ordering failure. */
        GSL_ERROR ("error", GSL_EFAILED);
      }

      /* Integrate over interval up to next sample point.
       */
      for(j=0, xj=x; j<Nd; j++, xj += dx) {
        rk_step(nu, xj, dx, &Jp, &J);
      }

      /* Go to next interval. */
      x = v[i];
      v[i] = J;
      ++i;
    }

    return GSL_SUCCESS;
  }
}