Skip to content
Snippets Groups Projects
Commit 24dc0968 authored by Christophe Geuzaine's avatar Christophe Geuzaine
Browse files

TINY has to be smaller than the initial interval!!
parent 1c7965a7
No related branches found
No related tags found
No related merge requests found
// $Id: gsl_brent.cpp,v 1.3 2003-02-21 09:39:01 remacle Exp $ // $Id: gsl_brent.cpp,v 1.4 2003-03-01 22:22:27 geuzaine Exp $
// //
// Copyright (C) 1997 - 2003 C. Geuzaine, J.-F. Remacle // Copyright (C) 1997 - 2003 C. Geuzaine, J.-F. Remacle
// //
...@@ -19,10 +19,6 @@ ...@@ -19,10 +19,6 @@
// //
// Please report all bugs and problems to "gmsh@geuz.org". // Please report all bugs and problems to "gmsh@geuz.org".
// This implements a Newton method using the GSL.
//
// Author: Nicolas Tardiey <nicolas.tardieu@der.edf.fr>
#if defined(HAVE_GSL) #if defined(HAVE_GSL)
#include "Gmsh.h" #include "Gmsh.h"
...@@ -87,89 +83,89 @@ double brent(double ax, double bx, double cx, ...@@ -87,89 +83,89 @@ double brent(double ax, double bx, double cx,
b = gsl_min_fminimizer_x_minimum(s); b = gsl_min_fminimizer_x_minimum(s);
a = gsl_min_fminimizer_x_lower(s); a = gsl_min_fminimizer_x_lower(s);
c = gsl_min_fminimizer_x_upper(s); c = gsl_min_fminimizer_x_upper(s);
status = gsl_min_test_interval(a, c, tol, 0.0); status = gsl_min_test_interval(a, c, tol, 0.0);
//if(status == GSL_SUCCESS) printf ("Converged\n");
} }
while(status == GSL_CONTINUE && iter < MAXITER); while(status == GSL_CONTINUE && iter < MAXITER);
if(status != GSL_SUCCESS)Msg(GERROR, "MIN1D NOT CONVERGED : f(%lf) = %lf \n",b,fn1(b,NULL));
if(status != GSL_SUCCESS)
Msg(GERROR, "MIN1D not converged: f(%g) = %g",b,fn1(b,NULL));
*xmin = b; *xmin = b;
gsl_min_fminimizer_free (s); gsl_min_fminimizer_free (s);
return fn1(b, NULL); return fn1(b, NULL);
} }
// mnbrak finds an initial bracketting of the minimum of funct. You // Find an initial bracketting of the minimum of func. Given 2 initial
// give 2 initial points, ax and xx. The algo checks in which // points ax and bx, mnbrak checks in which direction func decreases,
// direction func decreases, and takes some steps in that direction, // and takes some steps in that direction, until the function
// until the function increases. It then returns ax, xx (possibibly // increases--at cx. mnbrak returns ax and cx (possibly switched),
// switched) and bx, and we know that there is a minimum between ax // bracketting a minimum.
// and bx.
#define MYGOLD__ 1.618034 #define MYGOLD_ 1.618034
#define GLIMIT 100.0 #define MYLIMIT_ 100.0
#define TINY 1.0e-12 #define MYTINY_ 1.0e-20
#define SHFT(a,b,c,d) (a)=(b);(b)=(c);(c)=(d);
void mnbrak(double *ax, double *bx, double *cx, double *fa, double *fb, double *fc, void mnbrak(double *ax, double *bx, double *cx, double *fa, double *fb, double *fc,
double (*func)(double)) double (*func)(double))
{ {
double ulim,u,r,q,fu,dum; double ulim,u,r,q,fu;
// Msg(INFO, "--MNBRAK1 : ax %12.5E bx = %12.5E\n",*ax,*bx);
//Msg(INFO, "--MNBRAK1 : ax %12.5E bx = %12.5E",*ax,*bx);
*fa=(*func)(*ax); *fa=(*func)(*ax);
*fb=(*func)(*bx); *fb=(*func)(*bx);
if (*fb > *fa) { if (*fb > *fa) {
SHFT(dum,*ax,*bx,dum); double tmp;
SHFT(dum,*fb,*fa,dum); tmp = *ax; *ax = *bx; *bx = tmp;
tmp = *fb; *fb = *fa; *fa = tmp;
} }
// Msg(INFO, "--MNBRAK2 : ax %12.5E bx = %12.5E\n",*ax,*bx);
*cx=(*bx)+MYGOLD__*(*bx-*ax); //Msg(INFO, "--MNBRAK2 : ax %12.5E bx = %12.5E",*ax,*bx);
*fc=(*func)(*cx);
*cx = *bx + MYGOLD_*(*bx-*ax);
*fc = (*func)(*cx);
while (*fb > *fc) { while (*fb > *fc) {
r=(*bx-*ax)*(*fb-*fc); r=(*bx-*ax)*(*fb-*fc);
q=(*bx-*cx)*(*fb-*fa); q=(*bx-*cx)*(*fb-*fa);
u=(*bx)-((*bx-*cx)*q-(*bx-*ax)*r)/ u=(*bx)-((*bx-*cx)*q-(*bx-*ax)*r)/(2.0*SIGN(MAX(fabs(q-r),MYTINY_),q-r));
(2.0*SIGN(FMAX(fabs(q-r),TINY),q-r));
// Msg(INFO, "--MNBRAK : %12.5E %12.5E %12.5E %12.5E %12.5E\n",*ax,*fa,*fb,*fc,u); //Msg(INFO, "--MNBRAK : %12.5E %12.5E %12.5E %12.5E %12.5E",*ax,*fa,*fb,*fc,u);
ulim=(*bx)+GLIMIT*(*cx-*bx);
ulim = *bx + MYLIMIT_*(*cx-*bx);
if ((*bx-u)*(u-*cx) > 0.0) { if ((*bx-u)*(u-*cx) > 0.0) {
fu=(*func)(u); fu=(*func)(u);
if (fu < *fc) { if (fu < *fc) {
*ax=(*bx); *ax = *bx;
*bx=u; *bx = u;
*fa=(*fb); *fa = *fb;
*fb=fu; *fb = fu;
return; return;
} else if (fu > *fb) { } else if (fu > *fb) {
*cx=u; *cx = u;
*fc=fu; *fc = fu;
return; return;
} }
u=(*cx)+MYGOLD__*(*cx-*bx); u = *cx + MYGOLD_*(*cx-*bx);
fu=(*func)(u); fu = (*func)(u);
} else if ((*cx-u)*(u-ulim) > 0.0) { } else if ((*cx-u)*(u-ulim) > 0.0) {
fu=(*func)(u); fu=(*func)(u);
if (fu < *fc) { if (fu < *fc) {
SHFT(*bx,*cx,u,*cx+MYGOLD__*(*cx-*bx)) *bx = *cx; *cx = u; u = *cx + MYGOLD_*(*cx-*bx);
SHFT(*fb,*fc,fu,(*func)(u)) *fb = *fc; *fc = fu; fu = (*func)(u);
} }
} else if ((u-ulim)*(ulim-*cx) >= 0.0) { } else if ((u-ulim)*(ulim-*cx) >= 0.0) {
u=ulim; u = ulim;
fu=(*func)(u); fu = (*func)(u);
} else { } else {
u=(*cx)+MYGOLD__*(*cx-*bx); u = *cx + MYGOLD_*(*cx-*bx);
fu=(*func)(u); fu = (*func)(u);
} }
SHFT(*ax,*bx,*cx,u) *ax = *bx; *bx = *cx; *cx = u;
SHFT(*fa,*fb,*fc,fu) *fa = *fb; *fb = *fc; *fc = fu;
// Msg(INFO, "MNBRAK : %12.5E %12.5E %12.5E \n",*ax,*bx,*cx);
//Msg(INFO, "MNBRAK : %12.5E %12.5E %12.5E",*ax,*bx,*cx);
} }
} }
#undef MYGOLD__
#undef GLIMIT
#undef TINY
#undef SHFT
#endif #endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment