예제 #1
0
/**
 * Here GOLD is the default ratio by which successive intervals are magnified; GLIMIT is the
 * maximum magnification allowed for a parabolic-fit step.
 *
 * Given a function func, and given distinct initial points ax and bx, this routine searches in
 * the downhill direction (defined by the function as evaluated at the initial points) and returns
 * new points ax, bx, cx that bracket a minimum of the function. Also returned are the function
 * values at the three points, fa, fb, and fc.
 */
void mnbrak(float *ax, float *bx, float *cx, float *fa, float *fb, float *fc,
            float (*func)(float))
{
   float ulim,u,r,q,fu,dum;
   *fa=(*func)(*ax);
   *fb=(*func)(*bx);
   if (*fb > *fa) { /*Switch roles of a and b so that we can go*/
                    /*  downhill in the direction from a to b.*/
      SHFT(dum,*ax,*bx,dum)
      SHFT(dum,*fb,*fa,dum)
   }
   *cx=(*bx)+GOLD*(*bx-*ax); /*First guess for c.*/
   *fc=(*func)(*cx);
   while (*fb > *fc) { /*Keep returning here until we bracket.*/
      r=(*bx-*ax)*(*fb-*fc); /*Compute u by parabolic extrapolation from*/
                             /*a, b, c. TINY is used to prevent any possible*/
                             /*division by zero.*/
      q=(*bx-*cx)*(*fb-*fa);
      u=(*bx)-((*bx-*cx)*q-(*bx-*ax)*r)/
         (2.0*SIGN(FMAX(fabs(q-r),TINY),q-r));
      ulim=(*bx)+GLIMIT*(*cx-*bx);
      /*We won’t go farther than this. Test various possibilities:*/
      if ((*bx-u)*(u-*cx) > 0.0) { /*Parabolic u is between b and c: try it.*/
         fu=(*func)(u);
         if (fu < *fc) { /*Got a minimum between b and c.*/
            *ax=(*bx);
            *bx=u;
            *fa=(*fb);
            *fb=fu;
            return;
         } else if (fu > *fb) { /*Got a minimum between between a and u.*/
            *cx=u;
            *fc=fu;
            return;
         }
         u=(*cx)+GOLD*(*cx-*bx); /*Parabolic fit was no use. Use default magnification.*/
         fu=(*func)(u);
      } else if ((*cx-u)*(u-ulim) > 0.0) { /*Parabolic fit is between c and its*/
                                           /* allowed limit.*/
         fu=(*func)(u);
         if (fu < *fc) {
            SHFT(*bx,*cx,u,*cx+GOLD*(*cx-*bx))
            SHFT(*fb,*fc,fu,(*func)(u))
         }
      } else if ((u-ulim)*(ulim-*cx) >= 0.0) { /*Limit parabolic u to maximum*/
예제 #2
0
void NROptF1vND::mnbrack
     ( 
           REAL *ax,REAL *bx,REAL *cx,
           REAL *fa,REAL * fb,REAL *fc
     )        
{
        REAL ulim,u,r,q,fu,dum;

        *fa=NRF1v(*ax);
        *fb=NRF1v(*bx);
        if (*fb > *fa) {
                SHFT(dum,*ax,*bx,dum)
                SHFT(dum,*fb,*fa,dum)
        }
        *cx=(*bx)+GOLD*(*bx-*ax);
        *fc=NRF1v(*cx);
        while (*fb > *fc) {
                r=(*bx-*ax)*(*fb-*fc);
                q=(*bx-*cx)*(*fb-*fa);
                u=(*bx)-((*bx-*cx)*q-(*bx-*ax)*r)/
                        (2.0*SIGN(NRMAX(fabs(q-r),TINY),q-r));
                ulim=(*bx)+GLIMIT*(*cx-*bx);
                if ((*bx-u)*(u-*cx) > 0.0) {
                        fu=NRF1v(u);
                        if (fu < *fc) {
                                *ax=(*bx);
                                *bx=u;
                                *fa=(*fb);
                                *fb=fu;
                                return;
                        } else if (fu > *fb) {
                                *cx=u;
                                *fc=fu;
                                return;
                        }
                        u=(*cx)+GOLD*(*cx-*bx);
                        fu=NRF1v(u);                       
                } else if ((*cx-u)*(u-ulim) > 0.0) {
                        fu=NRF1v(u);
                        if (fu < *fc) {
                                SHFT(*bx,*cx,u,*cx+GOLD*(*cx-*bx))
                                SHFT(*fb,*fc,fu,NRF1v(u))
                        }
                } else if ((u-ulim)*(ulim-*cx) >= 0.0) {
예제 #3
0
파일: opt_mnbrak.c 프로젝트: berndf/avg_q
GLOBAL void
opt_mnbrak(optimize_struct *ostructp, OPT_DTYPE *ax, OPT_DTYPE *bx,
 OPT_DTYPE *cx, OPT_DTYPE *fa, OPT_DTYPE *fb, OPT_DTYPE *fc) {
 OPT_DTYPE ulim,u,r,q,fu,dum;

 *fa=EVAL_AT(*ax);
 *fb=EVAL_AT(*bx);
 if (*fb > *fa) {
  SHFT(dum,*ax,*bx,dum)
  SHFT(dum,*fb,*fa,dum)
 }
 *cx=(*bx)+GOLD*(*bx-*ax);
 *fc=EVAL_AT(*cx);
 while (*fb > *fc) {
  r=(*bx-*ax)*(*fb-*fc);
  q=(*bx-*cx)*(*fb-*fa);
  u=fabs(q-r);
  u=(*bx)-((*bx-*cx)*q-(*bx-*ax)*r)/
   (2.0*SIGN(FMAX(u,TINY),q-r));
  ulim=(*bx)+GLIMIT*(*cx-*bx);
  if ((*bx-u)*(u-*cx) > 0.0) {
   fu=EVAL_AT(u);
   if (fu < *fc) {
    *ax=(*bx);
    *bx=u;
    *fa=(*fb);
    *fb=fu;
    return;
   } else if (fu > *fb) {
    *cx=u;
    *fc=fu;
    return;
   }
   u=(*cx)+GOLD*(*cx-*bx);
   fu=EVAL_AT(u);
  } else if ((*cx-u)*(u-ulim) > 0.0) {
   fu=EVAL_AT(u);
   if (fu < *fc) {
    SHFT(*bx,*cx,u,*cx+GOLD*(*cx-*bx))
    SHFT(*fb,*fc,fu,EVAL_AT(u))
   }
  } else if ((u-ulim)*(ulim-*cx) >= 0.0) {
예제 #4
0
void j_mnbrak(double *ax,double *bx,double *cx,double *fa,double *fb,double *fc,
	      double (*func)(double a, void *localdata),void *localdata)
{
	double ulim,u,r,q,fu,dum;

	*fa=(*func)(*ax,localdata);
	*fb=(*func)(*bx,localdata);
	if (*fb > *fa) {
		SHFT(dum,*ax,*bx,dum)
		SHFT(dum,*fb,*fa,dum)
	}
	*cx=(*bx)+GOLD*(*bx-*ax);
	*fc=(*func)(*cx,localdata);
	while (*fb > *fc) {
		r=(*bx-*ax)*(*fb-*fc);
		q=(*bx-*cx)*(*fb-*fa);
		u=(*bx)-((*bx-*cx)*q-(*bx-*ax)*r)/
			(2.0*SIGN(MAX(fabs(q-r),TINY),q-r));
		ulim=(*bx)+GLIMIT*(*cx-*bx);
		if ((*bx-u)*(u-*cx) > 0.0) {
			fu=(*func)(u,localdata);
			if (fu < *fc) {
				*ax=(*bx);
				*bx=u;
				*fa=(*fb);
				*fb=fu;
				return;
			} else if (fu > *fb) {
				*cx=u;
				*fc=fu;
				return;
			}
			u=(*cx)+GOLD*(*cx-*bx);
			fu=(*func)(u,localdata);
		} else if ((*cx-u)*(u-ulim) > 0.0) {
			fu=(*func)(u,localdata);
			if (fu < *fc) {
				SHFT(*bx,*cx,u,*cx+GOLD*(*cx-*bx))
				SHFT(*fb,*fc,fu,(*func)(u,localdata))
			}
		} else if ((u-ulim)*(ulim-*cx) >= 0.0) {
예제 #5
0
/*
Given a function func, and given distinct initial points ax and bx, this routine searches in
the downhill direction (defined by the function as evaluated at the initial points) and returns
new points ax, bx, cx that bracket a minimum of the function. Also returned are the function
values at the three points, fa, fb, and fc.
*/
void BracketMin(Real &ax, Real &bx, Real &cx, Real& fa, Real& fb, Real& fc, RealFunction& func)
{
  Real ulim,u,fu;
  fa=func(ax);
  fb=func(bx);
  if (fb > fa) { //Switch roles of a and b so that we can go downhill in the direction from a to b.
    std::swap(ax,bx);
    std::swap(fa,fb);
  }
  cx=bx+GOLD*(bx-ax); //First guess for c.
  fc=func(cx);
  while (fb > fc) { //Keep returning here until we bracket.
    u=ParabolicExtremum(ax,bx,cx,fa,fb,fc);
    ulim=bx+GLIMIT*(cx-bx);  //We won't go farther than this. Test various possibilities:
    if ((bx-u)*(u-cx) > 0.0) { //Parabolic u is between b and c: try it.
      fu=func(u);
      if (fu < fc) { //Got a minimum between b and c.
        ax=bx;  bx=u;
        fa=fb;  fb=fu;
        return;
      }
      else if (fu > fb) { //Got a minimum between between a and u.
        cx=u;
        fc=fu;
        return;
      }
      u=cx+GOLD*(cx-bx); //Parabolic fit was no use. Use default magnification.
      fu=func(u);
    }
    else if ((cx-u)*(u-ulim) > 0.0) { //Parabolic fit is between c and its allowed limit.
      fu=func(u);
      if (fu < fc) {
        SHFT(bx,cx,u,cx+GOLD*(cx-bx))
        SHFT(fb,fc,fu,func(u))
      }
    }
    else if ((u-ulim)*(ulim-cx) >= 0.0) { //Limit parabolic u to maximum allowed value.
예제 #6
0
void BracketMin (TSIL_REAL *ax, TSIL_REAL *bx, TSIL_REAL *cx, 
		 TSIL_REAL *fa, TSIL_REAL *fb, TSIL_REAL *fc, 
		 TSIL_REAL (*func)(TSIL_REAL))
{
  TSIL_REAL ulim, u, r, q, fu, dum;

  *fa = (*func)(*ax);
  *fb = (*func)(*bx);
  if (*fb > *fa) {
    SHFT(dum,*ax,*bx,dum) ;
    SHFT(dum,*fb,*fa,dum) ;
  }
  *cx = (*bx) + GOLD*(*bx - *ax);
  *fc = (*func)(*cx);
  while (*fb > *fc) {
    r = (*bx - *ax)*(*fb - *fc);
    q = (*bx - *cx)*(*fb - *fa);
    u = (*bx) - ((*bx - *cx)*q - (*bx - *ax)*r)/
      (2.0L*SIGN(FMAX(TSIL_FABS(q-r),TINY), q-r));
    ulim = (*bx) + GLIMIT*(*cx - *bx);

    if ((*bx - u)*(u - *cx) > 0.0) {
      fu = (*func)(u);
      if (fu < *fc) {
	*ax = *bx;
	*bx = u;
	*fa = *fb;
	*fb = fu;
	return;
      }
      else if (fu > *fb) {
	*cx = u;
	*fc = fu;
	return;
      }
      u = (*cx) + GOLD*(*cx - *bx);
      fu = (*func)(u);
    }
    else if ((*cx - u)*(u - ulim) > 0.0) {
      fu = (*func)(u);
      if (fu < *fc) {
	SHFT(*bx,*cx,u,*cx + GOLD*(*cx - *bx)) ;
	SHFT(*fb,*fc,fu,(*func)(u)) ;
      }
    }
    else if ((u-ulim)*(ulim-*cx) >= 0.0) {
      u = ulim;
      fu = (*func)(u);
    }
    else {
      u = *cx + GOLD*(*cx - *bx);
      fu = (*func)(u);
    }
    SHFT(*ax,*bx,*cx,u) ;
    SHFT(*fa,*fb,*fc,fu) ;
  }
}
예제 #7
0
static void bracket (double s[], double f[], Geometry *g, Point a, Vector ap)
{
  double ulim, u, r, q, fu;

  fa = getAngle (xa, g, a, ap);
  fb = getAngle (xb, g, a, ap);

  if (fb > fa) { SHFT (u, xa, xb, u); SHFT (fu, fb, fa, fu); }

  xc = xb + GOLD*(xb - xa);
  fc = getAngle (xc, g, a, ap);

  while (fb > fc) {
    r = (xb - xa) * (fb - fc);
    q = (xb - xc) * (fb - fa);
    u =  xb - ((xb - xc) * q - (xb - xa) * r) /
              (2.*SIGN(max(fabs(q-r),TINY),q-r));
    ulim = xb * GLIMIT * (xc - xb);

    if ((xb - u)*(u - xc) > 0.) {      /* Parabolic u is bewteen b and c */
      fu = getAngle (u, g, a, ap);
      if (fu < fc) {                    /* Got a minimum between b and c */
  SHFT2 (xa,xb, u);
  SHFT2 (fa,fb,fu);
  return;
      } else if (fu > fb) {             /* Got a minimum between a and u */
  xc = u;
  fc = fu;
  return;
      }
      u  = xc + GOLD*(xc - xb);    /* Parabolic fit was no good. Use the */
      fu = getAngle (u, g, a, ap);             /* default magnification. */

    } else if ((xc-u)*(u-ulim) > 0.) {   /* Parabolic fit is bewteen c   */
      fu = getAngle (u, g, a, ap);                         /* and ulim   */
      if (fu < fc) {
  SHFT  (xb, xc, u, xc + GOLD*(xc - xb));
  SHFT  (fb, fc, fu, getAngle(u, g, a, ap));
      }
    } else if ((u-ulim)*(ulim-xc) >= 0.) {  /* Limit parabolic u to the  */
      u   = ulim;                           /* maximum allowed value     */
      fu  = getAngle (u, g, a, ap);
    } else {                                       /* Reject parabolic u */
      u   = xc + GOLD * (xc - xb);
      fu  = getAngle (u, g, a, ap);
    }
    SHFT  (xa, xb, xc, u);      /* Eliminate the oldest point & continue */
    SHFT  (fa, fb, fc, fu);
  }
  return;
}
예제 #8
0
static double brent (double s[], Geometry *g, Point ap, Vector app, double tol)
{
  int    iter;
  double a,b,d,etemp,fu,fv,fw,fx,p,q,r,tol1,tol2,u,v,w,x,xm;
  double e=0.0;

  a  = min (xa, xc);               /* a and b must be in decending order */
  b  = max (xa, xc);
  d  = 1.;
  x  = w  = v  = xb;
  fw = fv = fx = getAngle (x, g, ap, app);

  for (iter = 1; iter <= ITMAX; iter++) {    /* ....... Main Loop ...... */
    xm   = 0.5*(a+b);
    tol2 = 2.0*(tol1 = tol*fabs(x)+ZEPS);
    if (fabs(x-xm) <= (tol2-0.5*(b-a))) {             /* Completion test */
      xb = x;
      return fx;
    }
    if (fabs(e) > tol1) {             /* Construct a trial parabolic fit */
      r = (x-w) * (fx-fv);
      q = (x-v) * (fx-fw);
      p = (x-v) * q-(x-w) * r;
      q = (q-r) * 2.;
      if (q > 0.) p = -p;
      q = fabs(q);
      etemp=e;
      e = d;

      /* The following conditions determine the acceptability of the    */
      /* parabolic fit.  Following we take either the golden section    */
      /* step or the parabolic step.                                    */

      if (fabs(p) >= fabs(.5*q*etemp) || p <= q*(a-x) || p >= q*(b-x))
  d = CGOLD * (e = (x >= xm ? a-x : b-x));
      else {
  d = p / q;
  u = x + d;
  if (u-a < tol2 || b-u < tol2)
    d = SIGN(tol1,xm-x);
      }
    } else
      d = CGOLD * (e = (x >= xm ? a-x : b-x));

    u  = (fabs(d) >= tol1 ? x+d : x+SIGN(tol1,d));
    fu = getAngle(u,g,ap,app);

    /* That was the one function evaluation per step.  Housekeeping... */

    if (fu <= fx) {
      if (u >= x) a = x; else b = x;
      SHFT(v ,w ,x ,u );
      SHFT(fv,fw,fx,fu)
    } else {
      if (u < x) a=u; else b=u;
      if (fu <= fw || w == x) {
  v  = w;
  w  = u;
  fv = fw;
  fw = fu;
      } else if (fu <= fv || v == x || v == w) {
  v  = u;
  fv = fu;
      }
    }
  }                        /* .......... End of the Main Loop .......... */
예제 #9
0
TSIL_REAL BrentMin (TSIL_REAL ax,
		    TSIL_REAL bx,
		    TSIL_REAL cx,
		    TSIL_REAL (*f)(TSIL_REAL),
		    TSIL_REAL tol,
		    TSIL_REAL *xmin)
{
  int iter;
  TSIL_REAL a,b,d,etemp,fu,fv,fw,fx,p,q,r,tol1,tol2,u,v,w,x,xm;
  TSIL_REAL e = 0.0;

  a = (ax < cx ? ax : cx);
  b = (ax > cx ? ax : cx);

  x = w = v = bx;
  fw = fv = fx = (*f)(x);
  for (iter=1; iter<=ITMAX; iter++) {
    xm = 0.5L*(a + b);
    tol2 = 2.0L*(tol1 = tol*TSIL_FABS(x) + ZEPS);
    if (TSIL_FABS(x - xm) <= (tol2 - 0.5*(b-a))) {
      *xmin = x;
/*       printf("Brent: %d evaluations\n", iter); */
      return fx;
    }
    if (TSIL_FABS(e) > tol1) {
      r = (x - w)*(fx - fv);
      q = (x - v)*(fx - fw);
      p = (x - v)*q - (x - w)*r;
      q = 2.0L*(q - r);
      if (q > 0.0) p = -p;
      q = TSIL_FABS(q);
      etemp = e;
      e = d;
      if (TSIL_FABS(p) >= TSIL_FABS(0.5L*q*etemp) ||
	  p <= q*(a - x) ||
	  p >= q*(b - x))
	d = CGOLD*(e = (x >= xm ? a-x : b-x));
      else {
	d = p/q;
	u = x + d;
	if (u-a < tol2 || b-u < tol2)
	  d = SIGN(tol1, xm-x);
      }
    }
    else {
      d = CGOLD*(e = (x >= xm ? a-x: b-x));
    }
    u = (TSIL_FABS(d) >= tol1 ? x+d : x + SIGN(tol1,d));
    fu = (*f)(u);
    if (fu <= fx) {
      if (u >= x) a = x; else b = x;
      SHFT(v,w,x,u) ;
      SHFT(fv,fw,fx,fu) ;
    }
    else {
      if (u < x) a = u; else b = u;
      if (fu <= fw || w == x) {
	v = w;
	w = u;
	fv = fw;
	fw = fu;
      }
      else if (fu <= fv || v == x || v == w) {
	v = u;
	fv = fu;
      }
    }
  }
  TSIL_Error ("Brent", "Too many iterations", 42);
  *xmin = x;
  return fx;
}
예제 #10
0
void Grnn::Trainer::trainBrent(Grnn& grnn)
{
    double a = tolerance();
    double b = grnn.bandwidth();
    double x = 0.5*(a + b);
    bracket(grnn, a, b, x);
       
    if (a > b)
        SWP(a, b);
        
    double fx = error(grnn, x);
    double w = x, fw = fx;
    double v = x, fv = fx;
    
    double d = 0.0, u, e = 0.0;
    for(unsigned iter = 1; iter <= maxIter(); ++iter) 
    {
        double xm = 0.5*(a + b);
        double tol1 = tolerance()*fabs(x) + ZEPS;
        double tol2 = 2.0*(tol1);
        if (fabs(x - xm) <= (tol2 - 0.5*(b - a))) 
            break;
        if (fabs(e) > tol1)
        {
            double p = (x-v)*(x-v)*(fx-fw) - (x-w)*(x-w)*(fx-fv);
            double q = 2.0*((x-v)*(fx-fw) - (x-w)*(fx-fv));
            
            if (q > 0.0) 
                p = -p;
            q = fabs(q);
            
            double etemp = e;
            e = d;
            if (fabs(p) >= fabs(0.5*q*etemp) || 
                p <= q*(a - x) || 
                p >= q*(b - x))
            {
                if (x >= xm) 
                    e = a - x; 
                else 
                    e = b - x;
                d = CGOLD*(e);
            }   
            else
            {
                d = p/q;
                u = x + d;
                if (u - a < tol2 || b - u < tol2)
                    d = SIGN(tol1, xm - x);
            }
        } 
        else 
        {
            if (x >= xm) 
                    e = a - x; 
                else 
                    e = b - x;
            d = CGOLD *(e);
        }
        
        double u;
        if(fabs(d) >= tol1)
            u = x + d;
        else
            u = x + SIGN(tol1, d);
        double fu = error(grnn, u);
        if (fu <= fx) 
        {
            if (u >= x) 
                a = x; 
            else 
                b = x;
            SHFT(v, w, x, u);
            SHFT(fv, fw, fx, fu);
        } 
        else 
        {
            if (u < x) 
                a = u; 
            else
                b = u;
            if (fu <= fw || w == x)
            {
                v = w;
                w = u;
                fv = fw;
                fw = fu;
            } 
            else if (fu <= fv || v == x || v == w) 
            {
                v = u;
                fv = fu;
            }
        }
    }
    grnn.setBandwidth(x);
}
예제 #11
0
void Grnn::Trainer::bracket(Grnn& grnn, double& a, double& b, double& c)
{
    double fa = error(grnn, a);
    double fb = error(grnn, b);
    if (fb > fa)
    {
        SWP(a, b);
        SWP(fa, fb);
    }
    c = b + GOLD*(b - a);
    double fc = error(grnn, c);
    double fu;
    while (fb > fc)
    {
        double r = (b - a)*(fb - fc);
        double q = (b - c)*(fb - fa);
        double u = b - (q*(b - c) - r*(b - a))/
            (2.0*SIGN(FMAX(fabs(q - r), TINY), q - r));
        double ulim = b + GLIMIT*(c - b);
        if(a > 5.0 && b > 5.0 && c > 5.0)
        {
                a = b;
                b = u;
                fa = fb;
                fb = fu;
                return;
        }
        if ((b - u)*(u - c) > 0.0)
        {
            fu = error(grnn, u);
            if (fu < fc)
            {
                a = b;
                b = u;
                fa = fb;
                fb = fu;
                return;
            } 
            else if (fu > fb)
            {
                c = u;
                fc = fu;
                return;
            }
            u = c + GOLD*(c - b);
            fu = error(grnn, u);
        }
        else if ((c - u)*(u - ulim) > 0.0) 
        {
            fu = error(grnn, u);
            if (fu < fc)
            {
                double temp;
                temp = c + GOLD*(c - b);
                SHFT(b, c, u, temp);
                temp = error(grnn, u);
                SHFT(fb, fc, fu, temp);
            }
        }
        else if ((u - ulim)*(ulim - c) >= 0.0)
        {
            u = ulim;
            fu = error(grnn, u);
        } 
        else 
        {
            u = c + GOLD*(c - b);
            fu = error(grnn, u);
        }
        SHFT(a, b, c, u);
        SHFT(fa, fb, fc, fu);
    }
}