示例#1
0
static int
brent_init (void * vstate, gsl_function * f, double * root, double x_lower, double x_upper)
{
    brent_state_t * state = (brent_state_t *) vstate;

    double f_lower, f_upper ;

    *root = 0.5 * (x_lower + x_upper) ;

    SAFE_FUNC_CALL (f, x_lower, &f_lower);
    SAFE_FUNC_CALL (f, x_upper, &f_upper);

    state->a = x_lower;
    state->fa = f_lower;

    state->b = x_upper;
    state->fb = f_upper;

    state->c = x_upper;
    state->fc = f_upper;

    state->d = x_upper - x_lower ;
    state->e = x_upper - x_lower ;

    if ((f_lower < 0.0 && f_upper < 0.0) || (f_lower > 0.0 && f_upper > 0.0))
    {
        GSL_ERROR ("endpoints do not straddle y=0", GSL_EINVAL);
    }

    return GSL_SUCCESS;

}
示例#2
0
static int 
compute_f_values (gsl_function * f, double x_minimum, double * f_minimum,
                  double x_lower, double * f_lower,
                  double x_upper, double * f_upper)
{
  SAFE_FUNC_CALL(f, x_lower, f_lower);
  SAFE_FUNC_CALL(f, x_upper, f_upper);
  SAFE_FUNC_CALL(f, x_minimum, f_minimum);

  return GSL_SUCCESS;
}
示例#3
0
static int
brent_init (void *vstate, gsl_function * f, double x_minimum, double f_minimum, double x_lower, double f_lower, double x_upper, double f_upper)
{
  brent_state_t *state = (brent_state_t *) vstate;

  const double golden = 0.3819660;      /* golden = (3 - sqrt(5))/2 */

  double v = x_lower + golden * (x_upper - x_lower);
  double w = v;

  double f_vw;

  x_minimum = 0 ;  /* avoid warnings about unused varibles */
  f_minimum = 0 ;
  f_lower = 0 ;
  f_upper = 0 ;

  state->v = v;
  state->w = w;

  state->d = 0;
  state->e = 0;

  SAFE_FUNC_CALL (f, v, &f_vw);

  state->f_v = f_vw;
  state->f_w = f_vw;

  return GSL_SUCCESS;
}
示例#4
0
int
test_bracket (const char * description,gsl_function *f,double lower_bound, 
              double upper_bound, unsigned int max)
{
  int status;
  double x_lower, x_upper;
  double f_upper,f_lower,f_minimum;
  double x_minimum;

  x_lower=lower_bound;
  x_upper=upper_bound;
  SAFE_FUNC_CALL (f,x_lower,&f_lower);
  SAFE_FUNC_CALL (f,x_upper,&f_upper);
  status=gsl_min_find_bracket(f,&x_minimum,&f_minimum,&x_lower,&f_lower,&x_upper,&f_upper,max);
  gsl_test (status,"%s, interval: [%g,%g], values: (%g,%g), minimum at: %g, value: %g",
            description,x_lower,x_upper,f_lower,f_upper,x_minimum,f_minimum);
  return status;
}
示例#5
0
static int
bisection_iterate (void * vstate, gsl_function * f, double * root, double * x_lower, double * x_upper)
{
  bisection_state_t * state = (bisection_state_t *) vstate;

  double x_bisect, f_bisect;

  const double x_left = *x_lower ;
  const double x_right = *x_upper ;

  const double f_lower = state->f_lower; 
  const double f_upper = state->f_upper;

  if (f_lower == 0.0)
    {
      *root = x_left ;
      *x_upper = x_left;
      return GSL_SUCCESS;
    }
  
  if (f_upper == 0.0)
    {
      *root = x_right ;
      *x_lower = x_right;
      return GSL_SUCCESS;
    }
  
  x_bisect = (x_left + x_right) / 2.0;
  
  SAFE_FUNC_CALL (f, x_bisect, &f_bisect);
      
  if (f_bisect == 0.0)
    {
      *root = x_bisect;
      *x_lower = x_bisect;
      *x_upper = x_bisect;
      return GSL_SUCCESS;
    }
      
  /* Discard the half of the interval which doesn't contain the root. */
  
  if ((f_lower > 0.0 && f_bisect < 0.0) || (f_lower < 0.0 && f_bisect > 0.0))
    {
      *root = 0.5 * (x_left + x_bisect) ;
      *x_upper = x_bisect;
      state->f_upper = f_bisect;
    }
  else
    {
      *root = 0.5 * (x_bisect + x_right) ;
      *x_lower = x_bisect;
      state->f_lower = f_bisect;
    }

  return GSL_SUCCESS;
}
static int
bisection_init (void * vstate, gsl_function * f, float * root, float x_lower, float x_upper)
{
  bisection_state_t * state = (bisection_state_t *) vstate;

  float f_lower, f_upper ;

  *root = 0.5 * (x_lower + x_upper) ;

  SAFE_FUNC_CALL (f, x_lower, &f_lower);
  SAFE_FUNC_CALL (f, x_upper, &f_upper);
  
  state->f_lower = f_lower;
  state->f_upper = f_upper;

  if ((f_lower < 0.0 && f_upper < 0.0) || (f_lower > 0.0 && f_upper > 0.0))
    {
      GSL_ERROR ("endpoints do not straddle y=0", GSL_EINVAL);
    }

  return GSL_SUCCESS;

}
示例#7
0
static int
falsepos_init (void * vstate, gsl_function * f, double * root, double x_lower, double x_upper)
{
  falsepos_state_t * state = (falsepos_state_t *) vstate;

  double f_lower, f_upper ;

  *root = 0.5 * (x_lower + x_upper);

  SAFE_FUNC_CALL (f, x_lower, &f_lower);
  SAFE_FUNC_CALL (f, x_upper, &f_upper);
  
  state->f_lower = f_lower;
  state->f_upper = f_upper;

  if ((f_lower < 0.0 && f_upper < 0.0) || (f_lower > 0.0 && f_upper > 0.0))
    {
      GSL_ERROR ("endpoints do not straddle y=0", GSL_EINVAL);
    }

  return GSL_SUCCESS;

}
示例#8
0
static int
goldensection_iterate (void * vstate, gsl_function * f, double * x_minimum, double * f_minimum, double * x_lower, double * f_lower, double * x_upper, double * f_upper)
{
  goldensection_state_t * state = (goldensection_state_t *) vstate;

  const double x_center = *x_minimum ;
  const double x_left = *x_lower ;
  const double x_right = *x_upper ;

  const double f_min = *f_minimum;

  const double golden = 0.3819660; /* golden = (3 - sqrt(5))/2 */
  
  const double w_lower = (x_center - x_left);
  const double w_upper = (x_right - x_center);

  double x_new, f_new;

  state = 0 ; /* avoid warning about unused parameters */
  
  x_new = x_center + golden * ((w_upper > w_lower) ? w_upper : -w_lower) ;

  SAFE_FUNC_CALL (f, x_new, &f_new);

  if (f_new < f_min)
    {
      *x_minimum = x_new ;
      *f_minimum = f_new ;
      return GSL_SUCCESS;
    }
  else if (x_new < x_center && f_new > f_min)
    {
      *x_lower = x_new ;
      *f_lower = f_new ;
      return GSL_SUCCESS;
    }
  else if (x_new > x_center && f_new > f_min)
    {
      *x_upper = x_new ;
      *f_upper = f_new ;
      return GSL_SUCCESS;
    }
  else
    {
      return GSL_FAILURE;
    }
}
示例#9
0
static int
brent_iterate (void *vstate, gsl_function * f, double *x_minimum, double * f_minimum, double * x_lower, double * f_lower, double * x_upper, double * f_upper)
{
  brent_state_t *state = (brent_state_t *) vstate;

  const double x_left = *x_lower;
  const double x_right = *x_upper;

  const double z = *x_minimum;
  double d = state->e;
  double e = state->d;
  double u, f_u;
  const double v = state->v;
  const double w = state->w;
  const double f_v = state->f_v;
  const double f_w = state->f_w;
  const double f_z = *f_minimum;

  const double golden = 0.3819660;      /* golden = (3 - sqrt(5))/2 */

  const double w_lower = (z - x_left);
  const double w_upper = (x_right - z);

  const double tolerance =  GSL_SQRT_DBL_EPSILON * fabs (z);

  double p = 0, q = 0, r = 0;

  const double midpoint = 0.5 * (x_left + x_right);

  if (fabs (e) > tolerance)
    {
      /* fit parabola */

      r = (z - w) * (f_z - f_v);
      q = (z - v) * (f_z - f_w);
      p = (z - v) * q - (z - w) * r;
      q = 2 * (q - r);

      if (q > 0)
        {
          p = -p;
        }
      else
        {
          q = -q;
        }

      r = e;
      e = d;
    }

  if (fabs (p) < fabs (0.5 * q * r) && p < q * w_lower && p < q * w_upper)
    {
      double t2 = 2 * tolerance ;

      d = p / q;
      u = z + d;

      if ((u - x_left) < t2 || (x_right - u) < t2)
        {
          d = (z < midpoint) ? tolerance : -tolerance ;
        }
    }
  else
    {
      e = (z < midpoint) ? x_right - z : -(z - x_left) ;
      d = golden * e;
    }


  if (fabs (d) >= tolerance)
    {
      u = z + d;
    }
  else
    {
      u = z + ((d > 0) ? tolerance : -tolerance) ;
    }

  state->e = e;
  state->d = d;

  SAFE_FUNC_CALL(f, u, &f_u);

  if (f_u > f_z)
    {
      if (u < z)
        {
          *x_lower = u;
          *f_lower = f_u;
          return GSL_SUCCESS;
        }
      else
        {
          *x_upper = u;
          *f_upper = f_u;
          return GSL_SUCCESS;
        }
    }
  else if (f_u < f_z)
    {
      if (u < z)
        {
          *x_upper = z;
          *f_upper = f_z;
        }
      else
        {
          *x_lower = z;
          *f_lower = f_z;
        }

      state->v = w;
      state->f_v = f_w;
      state->w = z;
      state->f_w = f_z;
      *x_minimum = u;
      *f_minimum = f_u;
      return GSL_SUCCESS;
    }
  else if (f_u <= f_w || w == z)
    {
      state->v = w;
      state->f_v = f_w;
      state->w = u;
      state->f_w = f_u;
      return GSL_SUCCESS;
    }
  else if (f_u <= f_v || v == z || v == w)
    {
      state->v = u;
      state->f_v = f_u;
      return GSL_SUCCESS;
    }
  else
    {
      return GSL_FAILURE;
    }
}
示例#10
0
int
gsl_min_find_bracket(gsl_function *f,double *x_minimum,double * f_minimum,
                     double * x_lower, double * f_lower,
                     double * x_upper, double * f_upper,
                     size_t eval_max)
{
    /* The three following variables must be declared volatile to avoid storage
       in extended precision registers available on some architecture. The code
       relies on the ability to compare double values. As the values will be
       store in regular memory, the extended precision will then be lost and
       values that are different in extended precision might have equal
       representation in double precision. This behavior might break the
       algorithm.
     */
    volatile double f_left = *f_lower;
    volatile double f_right = *f_upper;
    volatile double f_center;
    double x_left = *x_lower;
    double x_right= *x_upper;
    double x_center;
    const double golden = 0.3819660;      /* golden = (3 - sqrt(5))/2 */
    size_t nb_eval = 0;


    if (f_right >= f_left)
    {
        x_center = (x_right - x_left) * golden + x_left;
        nb_eval++;
        SAFE_FUNC_CALL (f, x_center, &f_center);
    }
    else
    {
        x_center = x_right ;
        f_center = f_right ;
        x_right = (x_center - x_left) / golden + x_left;
        nb_eval++;
        SAFE_FUNC_CALL (f, x_right, &f_right);
    }

    do
    {
        if (f_center < f_left )
        {
            if (f_center < f_right)
            {
                *x_lower = x_left;
                *x_upper = x_right;
                *x_minimum = x_center;
                *f_lower = f_left;
                *f_upper = f_right;
                *f_minimum = f_center;
                /*            gsl_ieee_printf_double (&f_left);
                              printf(" ");
                              gsl_ieee_printf_double (&f_center);
                              printf("\n");*/
                return GSL_SUCCESS;
            }
            else if (f_center > f_right)
            {
                x_left = x_center;
                f_left = f_center;
                x_center = x_right;
                f_center = f_right;
                x_right = (x_center - x_left) / golden + x_left;
                nb_eval++;
                SAFE_FUNC_CALL (f, x_right, &f_right);
            }
            else /* f_center == f_right */
            {
                x_right = x_center;
                f_right = f_center;
                x_center = (x_right - x_left) * golden + x_left;
                nb_eval++;
                SAFE_FUNC_CALL (f, x_center, &f_center);
            }
        }
        else /* f_center >= f_left */
        {
            x_right = x_center;
            f_right = f_center;
            x_center = (x_right - x_left) * golden + x_left;
            nb_eval++;
            SAFE_FUNC_CALL (f, x_center, &f_center);
        }
    }
    while (nb_eval < eval_max
            && (x_right - x_left) > GSL_SQRT_DBL_EPSILON * ( (x_right + x_left) * 0.5 ) + GSL_SQRT_DBL_EPSILON);
    *x_lower = x_left;
    *x_upper = x_right;
    *x_minimum = x_center;
    *f_lower = f_left;
    *f_upper = f_right;
    *f_minimum = f_center;
    return GSL_FAILURE;
}
示例#11
0
static int
brent_iterate (void * vstate, gsl_function * f, double * root, double * x_lower, double * x_upper)
{
    brent_state_t * state = (brent_state_t *) vstate;

    double tol, m;

    int ac_equal = 0;

    double a = state->a, b = state->b, c = state->c;
    double fa = state->fa, fb = state->fb, fc = state->fc;
    double d = state->d, e = state->e;

    if ((fb < 0 && fc < 0) || (fb > 0 && fc > 0))
    {
        ac_equal = 1;
        c = a;
        fc = fa;
        d = b - a;
        e = b - a;
    }

    if (fabs (fc) < fabs (fb))
    {
        ac_equal = 1;
        a = b;
        b = c;
        c = a;
        fa = fb;
        fb = fc;
        fc = fa;
    }

    tol = 0.5 * GSL_DBL_EPSILON * fabs (b);
    m = 0.5 * (c - b);

    if (fb == 0)
    {
        *root = b;
        *x_lower = b;
        *x_upper = b;

        return GSL_SUCCESS;
    }

    if (fabs (m) <= tol)
    {
        *root = b;

        if (b < c)
        {
            *x_lower = b;
            *x_upper = c;
        }
        else
        {
            *x_lower = c;
            *x_upper = b;
        }

        return GSL_SUCCESS;
    }

    if (fabs (e) < tol || fabs (fa) <= fabs (fb))
    {
        d = m;            /* use bisection */
        e = m;
    }
    else
    {
        double p, q, r;   /* use inverse cubic interpolation */
        double s = fb / fa;

        if (ac_equal)
        {
            p = 2 * m * s;
            q = 1 - s;
        }
        else
        {
            q = fa / fc;
            r = fb / fc;
            p = s * (2 * m * q * (q - r) - (b - a) * (r - 1));
            q = (q - 1) * (r - 1) * (s - 1);
        }

        if (p > 0)
        {
            q = -q;
        }
        else
        {
            p = -p;
        }

        if (2 * p < GSL_MIN (3 * m * q - fabs (tol * q), fabs (e * q)))
        {
            e = d;
            d = p / q;
        }
        else
        {
            /* interpolation failed, fall back to bisection */

            d = m;
            e = m;
        }
    }

    a = b;
    fa = fb;

    if (fabs (d) > tol)
    {
        b += d;
    }
    else
    {
        b += (m > 0 ? +tol : -tol);
    }

    SAFE_FUNC_CALL (f, b, &fb);

    state->a = a ;
    state->b = b ;
    state->c = c ;
    state->d = d ;
    state->e = e ;
    state->fa = fa ;
    state->fb = fb ;
    state->fc = fc ;

    /* Update the best estimate of the root and bounds on each
       iteration */

    *root = b;

    if ((fb < 0 && fc < 0) || (fb > 0 && fc > 0))
    {
        c = a;
    }

    if (b < c)
    {
        *x_lower = b;
        *x_upper = c;
    }
    else
    {
        *x_lower = c;
        *x_upper = b;
    }

    return GSL_SUCCESS ;
}
示例#12
0
static int
falsepos_iterate (void * vstate, gsl_function * f, double * root, double * x_lower, double * x_upper)
{
  falsepos_state_t * state = (falsepos_state_t *) vstate;

  double x_linear, f_linear;
  double x_bisect, f_bisect;

  double x_left = *x_lower ;
  double x_right = *x_upper ;

  double f_lower = state->f_lower; 
  double f_upper = state->f_upper;

  double w ;

  if (f_lower == 0.0)
    {
      *root = x_left ;
      *x_upper = x_left;
      return GSL_SUCCESS;
    }
  
  if (f_upper == 0.0)
    {
      *root = x_right ;
      *x_lower = x_right;
      return GSL_SUCCESS;
    }
      
  /* Draw a line between f(*lower_bound) and f(*upper_bound) and
     note where it crosses the X axis; that's where we will
     split the interval. */
  
  x_linear = x_right - (f_upper * (x_left - x_right) / (f_lower - f_upper));

  SAFE_FUNC_CALL (f, x_linear, &f_linear);
      
  if (f_linear == 0.0)
    {
      *root = x_linear;
      *x_lower = x_linear;
      *x_upper = x_linear;
      return GSL_SUCCESS;
    }
      
  /* Discard the half of the interval which doesn't contain the root. */
  
  if ((f_lower > 0.0 && f_linear < 0.0) || (f_lower < 0.0 && f_linear > 0.0))
    {
      *root = x_linear ;
      *x_upper = x_linear;
      state->f_upper = f_linear;
      w = x_linear - x_left ;
    }
  else
    {
      *root = x_linear ;
      *x_lower = x_linear;
      state->f_lower = f_linear;
      w = x_right - x_linear;
    }

  if (w < 0.5 * (x_right - x_left)) 
    {
      return GSL_SUCCESS ;
    }

  x_bisect = 0.5 * (x_left + x_right);

  SAFE_FUNC_CALL (f, x_bisect, &f_bisect);

  if ((f_lower > 0.0 && f_bisect < 0.0) || (f_lower < 0.0 && f_bisect > 0.0))
    {
      *x_upper = x_bisect;
      state->f_upper = f_bisect;
      if (*root > x_bisect)
        *root = 0.5 * (x_left + x_bisect) ;
    }
  else
    {
      *x_lower = x_bisect;
      state->f_lower = f_bisect;
      if (*root < x_bisect)
        *root = 0.5 * (x_bisect + x_right) ;
    }

  return GSL_SUCCESS;
}