Пример #1
0
static int
steffenson_init (void * vstate, gsl_function_fdf * fdf, double * root)
{
  steffenson_state_t * state = (steffenson_state_t *) vstate;

  const double x = *root ;

  state->f = GSL_FN_FDF_EVAL_F (fdf, x);
  state->df = GSL_FN_FDF_EVAL_DF (fdf, x) ;

  state->x = x;
  state->x_1 = 0.0;
  state->x_2 = 0.0;

  state->count = 1;

  return GSL_SUCCESS;

}
Пример #2
0
static int
secant_iterate (void * vstate, gsl_function_fdf * fdf, double * root)
{
    secant_state_t * state = (secant_state_t *) vstate;

    const double x = *root ;
    const double f = state->f;
    const double df = state->df;

    double x_new, f_new, df_new;

    if (state->df == 0.0)
    {
        GSL_ERROR("derivative is zero", GSL_EZERODIV);
    }

    x_new = x - (f / df);

    f_new = GSL_FN_FDF_EVAL_F(fdf, x_new) ;
    df_new = (f_new - f) / (x_new - x) ;

    *root = x_new ;

    state->f = f_new ;
    state->df = df_new ;

    if (!gsl_finite (f_new))
    {
        GSL_ERROR ("function value is not finite", GSL_EBADFUNC);
    }

    if (!gsl_finite (df_new))
    {
        GSL_ERROR ("derivative value is not finite", GSL_EBADFUNC);
    }

    return GSL_SUCCESS;
}
Пример #3
0
static int minimize(gsl_function_fdf * fn, double rho, double sigma, double tau1, double tau2, double tau3, int order, double alpha1, double *alpha_new)
{
	double f0, fp0, falpha, falpha_prev, fpalpha, fpalpha_prev, delta, alpha_next;
	double alpha = alpha1, alpha_prev = 0.0;
	double a, b, fa, fb, fpa, fpb;
	const size_t bracket_iters = 100, section_iters = 100;
	size_t i = 0;

	if (debug)
		printf("...enter minimize() sigma = %.12g\n", sigma);

	GSL_FN_FDF_EVAL_F_DF(fn, 0.0, &f0, &fp0);
	if (debug)
		printf("..eval F_DF %g %g \n", f0, fp0);

	falpha_prev = f0;
	fpalpha_prev = fp0;

	/*
	 * Avoid uninitialized variables morning 
	 */
	a = 0.0;
	b = alpha;
	fa = f0;
	fb = 0.0;
	fpa = fp0;
	fpb = 0.0;

	/*
	 * Begin bracketing 
	 */

	while (i++ < bracket_iters) {
		if (debug)
			printf("...begin bracketing\n");

		falpha = GSL_FN_FDF_EVAL_F(fn, alpha);
		if (debug)
			printf("...begin bracketing: eval f %.12g\n", falpha);

		/*
		 * Fletcher's rho test 
		 */

		if (falpha > f0 + alpha * rho * fp0 || falpha >= falpha_prev || GMRFLib_request_optimiser_to_stop) {
			a = alpha_prev;
			fa = falpha_prev;
			fpa = fpalpha_prev;
			b = alpha;
			fb = falpha;
			fpb = GSL_NAN;
			break;				       /* goto sectioning */
		}

		fpalpha = GSL_FN_FDF_EVAL_DF(fn, alpha);
		if (debug)
			printf("...begin bracketing: eval df %.12g\n", falpha);

		/*
		 * Fletcher's sigma test 
		 */

		if (fabs(fpalpha) <= -sigma * fp0 || GMRFLib_request_optimiser_to_stop) {
			*alpha_new = alpha;
			return GSL_SUCCESS;
		}

		if (fpalpha >= 0 || GMRFLib_request_optimiser_to_stop) {
			a = alpha;
			fa = falpha;
			fpa = fpalpha;
			b = alpha_prev;
			fb = falpha_prev;
			fpb = fpalpha_prev;
			break;				       /* goto sectioning */
		}

		delta = alpha - alpha_prev;

		{
			double lower = alpha + delta;
			double upper = alpha + tau1 * delta;

			alpha_next = interpolate(alpha_prev, falpha_prev, fpalpha_prev, alpha, falpha, fpalpha, lower, upper, order);
		}

		alpha_prev = alpha;
		falpha_prev = falpha;
		fpalpha_prev = fpalpha;
		alpha = alpha_next;

		if (GMRFLib_request_optimiser_to_stop)
			break;
	}

	if (GMRFLib_request_optimiser_to_stop) {
		*alpha_new = alpha;
		return GSL_SUCCESS;			       /* terminate */
	}

	/*
	 * Sectioning of bracket [a,b] 
	 */

	while (i++ < section_iters) {

		if (debug)
			printf("...sectioning of bracket b %.12g a %.12g alpha %.12g\n", b, a, alpha);

		delta = b - a;

		{
			double lower = a + tau2 * delta;
			double upper = b - tau3 * delta;

			alpha = interpolate(a, fa, fpa, b, fb, fpb, lower, upper, order);
		}

		falpha = GSL_FN_FDF_EVAL_F(fn, alpha);
		if (debug)
			printf("...eval F %.12g\n", falpha);

		if (debug)
			printf("... roundoff check %.12g\n", (a - alpha) * fpa);

		if ((a - alpha) * fpa <= GMRFLib_eps(2.0/3.0)) {	       /* hrue */
			/*
			 * roundoff prevents progress 
			 */
			if (debug)
				printf("BFGS3: minimizer: abort search as we do not seem to get any longer...\n");

			*alpha_new = alpha;		       /* hrue */
			return GSL_ENOPROG;
		}

		if (debug)
			printf("...TEST %.12g > %.12g || %.12g >= %.12g\n", falpha, f0 + rho * alpha * fp0, falpha, fa);

		if (GMRFLib_request_optimiser_to_stop) {
			*alpha_new = alpha;
			return GSL_SUCCESS;		       /* terminate */
		}

		if (falpha > f0 + rho * alpha * fp0 || falpha >= fa) {
			/*
			 * a_next = a; 
			 */
			b = alpha;
			fb = falpha;
			fpb = GSL_NAN;
		} else {
			fpalpha = GSL_FN_FDF_EVAL_DF(fn, alpha);
			if (debug)
				printf("...eval DF %.12g\n", fpalpha);

			if (debug)
				printf("... TEST %.12g <= %.12g\n", fabs(fpalpha), -sigma * fp0);
			if (fabs(fpalpha) <= -sigma * fp0 || GMRFLib_request_optimiser_to_stop) {
				*alpha_new = alpha;
				return GSL_SUCCESS;	       /* terminate */
			}

			if (((b - a) >= 0 && fpalpha >= 0) || ((b - a) <= 0 && fpalpha <= 0)) {
				b = a;
				fb = fa;
				fpb = fpa;
				a = alpha;
				fa = falpha;
				fpa = fpalpha;
			} else {
				a = alpha;
				fa = falpha;
				fpa = fpalpha;
			}
		}
	}

	return GSL_SUCCESS;
}