예제 #1
0
파일: powell.c 프로젝트: acadien/BasinPave
void powell(float* p, float **xi, int n, float ftol, int *iter, float *fret,
            float (*func)(float [], void*),void* args)
{
    void linmin(float p[], float xi[], int n, float *fret,
                float (*func)(float [], void*),void* args);
    int i,ibig,j;
    float del,fp,fptt,t,*pt,*ptt,*xit;
    //	return;
    pt=vector(1,n);
    ptt=vector(1,n);
    xit=vector(1,n);
    *fret=(*func)(p,args);
    for (j=1; j<=n; j++) pt[j]=p[j];
    for (*iter=1;; ++(*iter)) {
        fp=(*fret);
        ibig=0;
        del=0.0;
        for (i=1; i<=n; i++) {
            for (j=1; j<=n; j++) xit[j]=xi[j][i];
            fptt=(*fret);
            linmin(p,xit,n,fret,func,args);
            if (fptt-(*fret) > del) {
                del=fptt-(*fret);
                ibig=i;
            }
        }
        if (2.0*(fp-(*fret)) <= ftol*(fabs(fp)+fabs(*fret))+TINY) {
            free_vector(xit,1,n);
            free_vector(ptt,1,n);
            free_vector(pt,1,n);
            return;
        }
        if (*iter == ITMAX) nrerror("powell exceeding maximum iterations.");
        for (j=1; j<=n; j++) {
            ptt[j]=2.0*p[j]-pt[j];
            xit[j]=p[j]-pt[j];
            pt[j]=p[j];
        }
        fptt=(*func)(ptt,args);
        if (fptt < fp) {
            t=2.0*(fp-2.0*(*fret)+fptt)*SQR(fp-(*fret)-del)-del*SQR(fp-fptt);
            if (t < 0.0) {
                linmin(p,xit,n,fret,func,args);
                for (j=1; j<=n; j++) {
                    xi[j][ibig]=xi[j][n];
                    xi[j][n]=xit[j];
                }
            }
        }
    }
}
예제 #2
0
bool PreconditionedConjugateGradientType::improve_energy(bool verbose) {
  iter++;
  //printf("I am running ConjugateGradient::improve_energy\n");
  const double E0 = energy();
  if (E0 != E0) {
    // There is no point continuing, since we're starting with a NaN!
    // So we may as well quit here.
    if (verbose) {
      printf("The initial energy is a NaN, so I'm quitting early.\n");
      f.print_summary("has nan:", E0);
      fflush(stdout);
    }
    return false;
  }
  double beta;
  {
    // Note: my notation vaguely follows that of
    // [wikipedia](http://en.wikipedia.org/wiki/Nonlinear_conjugate_gradient_method).
    // I use the Polak-Ribiere method, with automatic direction reset.
    // Note that we could save some memory by using Fletcher-Reeves, and
    // it seems worth implementing that as an option for
    // memory-constrained problems (then we wouldn't need to store oldgrad).
    pgrad(); // compute pgrad first, since that computes both.
    beta = -pgrad().dot(-grad() - oldgrad)/oldgradsqr;
    oldgrad = -grad();
    if (beta < 0 || beta != beta || oldgradsqr == 0) beta = 0;
    if (verbose) printf("beta = %g\n", beta);
    oldgradsqr = -pgrad().dot(oldgrad);
    direction = -pgrad() + beta*direction;
    // Let's immediately free the cached gradient stored internally!
    invalidate_cache();
  } // free g and pg!

  const double gdotd = oldgrad.dot(direction);

  Minimizer lm = linmin(f, gd, kT, x, direction, -gdotd, &step);
  for (int i=0; i<100 && lm.improve_energy(verbose); i++) {
    if (verbose) lm.print_info("\t");
  }
  if (verbose) {
    //lm->print_info();
    print_info();
    printf("grad*dir/oldgrad*dir = %g\n", grad().dot(direction)/gdotd);
  }
  return (energy() < E0 || beta != 0);
}
예제 #3
0
파일: optimize2.cpp 프로젝트: sim0629/jhm
void frprmn(vectorN &p, int n, m_real ftol, int &iter, m_real &fret,
			m_real (*func)  (vectorN const&),
			m_real (*dfunc) (vectorN const&,vectorN&))
{
	m_real gg, gam, fp, dgg;

	static vectorN g;   g.setSize(n);
	static vectorN h;   h.setSize(n);
	static vectorN xi; xi.setSize(n);
  
	fp = (*dfunc) (p, xi);

	for (int j=0; j<n; j++)
	{
		g[j] = -xi[j];
		xi[j] = h[j] = g[j];
	}

	for (iter=0; iter<ITMAX; iter++)
	{
		linmin(p, xi, n, fret, func);
		if (2.0 * fabs(fret - fp) <= ftol * (fabs(fret) + fabs(fp) + EPS_jhm)) return;
		
		fp = (*dfunc) (p, xi);
		dgg = gg = 0.0;

		for (int j=0; j<n; j++)
		{
			gg += g[j] * g[j];
			dgg += (xi[j] + g[j]) * xi[j];
		}

		if (gg == 0.0) return;

		gam = dgg / gg;

		for (int j=0; j<n; j++)
		{
			g[j] = -xi[j];
			xi[j] = h[j] = g[j] + gam * h[j];
		}
	}

	error("Too many iterations in frprmn");
}
예제 #4
0
파일: optimize2.cpp 프로젝트: sim0629/jhm
void gradient_descent(vectorN &p, int n, m_real ftol, int &iter, m_real &fret,
			m_real (*func)  (vectorN const&),
			m_real (*dfunc) (vectorN const&,vectorN&))
{
	m_real fp;
	static vectorN xi; xi.setSize(n);

	for (iter=0; iter<ITMAX; iter++)
	{
		fp = (*dfunc) (p, xi);

		linmin(p, xi, n, fret, func);
		if (2.0 * fabs(fret - fp) <= ftol * (fabs(fret) + fabs(fp) + EPS_jhm))
   	    	return;
	}

	error("Too many iterations in gradient_descent");
}
예제 #5
0
void frprmn(double p[], int n, double ftol, int *iter, double *fret,
	double (*func)(double []), void (*dfunc)(double [], double []))
{
	void linmin(double p[], double xi[], int n, double *fret,
		double (*func)(double []));
	int j,its;
	double gg,gam,fp,dgg;
	double *g,*h,*xi;

	g=dvector(1,n);
	h=dvector(1,n);
	xi=dvector(1,n);
	fp=(*func)(p);
	(*dfunc)(p,xi);
	for (j=1;j<=n;j++) {
		g[j] = -xi[j];
		xi[j]=h[j]=g[j];
	}
	for (its=1;its<=ITMAX;its++) {
		*iter=its;
		linmin(p,xi,n,fret,func);
		if (2.0*fabs(*fret-fp) <= ftol*(fabs(*fret)+fabs(fp)+EPS)) {
			FREEALL
			return;
		}
		fp= *fret;
		(*dfunc)(p,xi);
		dgg=gg=0.0;
		for (j=1;j<=n;j++) {
			gg += g[j]*g[j];
			dgg += (xi[j]+g[j])*xi[j];
		}
		if (gg == 0.0) {
			FREEALL
			return;
		}
예제 #6
0
double FletcherMinimizer::Minimize(double ftol)
   {
   LineMinimizer linmin(*func);

   if (point.Length() == 0)
      return fmin = f(point);

   // Initialize direction vector
   linmin.line.Dimension(point.Length());

   // Evaluate function and derivatives
   fmin = f(point);

   while (true)
      {
      df(point, linmin.line, 0.1);

      // Minimizing so go against gradient
      linmin.line.Negate();
      h = linmin.line;
      g = linmin.line;

      iter = 1;
      while (true)
         {
         linmin.point = point;
         linmin.Bracket(0, 1);
         linmin.Brent(ftol);

         // If values tested while evaluating derivative
         // are closer to minimum than those found by
         // descending gradient, use those as starting points!

         if (func->dfmin < linmin.fmin)
            {
            linmin.point = point;
            linmin.line = func->dpmin;
            linmin.line.Subtract(point);
            linmin.Bracket(0,1);
            linmin.Brent(ftol);
            point = linmin.point;
            fmin = linmin.fmin;
            break;
            };

         point = linmin.point;

         if (2.0 * fabs(linmin.fmin - fmin) <= ftol * (fabs(linmin.fmin) + fabs(fmin) + ZEPS))
            return fmin = linmin.fmin;

         fmin = linmin.fmin;
         df(point, linmin.line, 0.1);

         double dgg = 0.0, gg = 0.0;

         for (int j = 0; j < linmin.line.Length(); j++)
            {
            gg  += g[j] * g[j];
            dgg += (linmin.line[j] + g[j]) * linmin.line[j];
            }

         // Gradient is exactly zero
         if (gg == 0.0)
            return fmin;

         double gamma = dgg / gg;

         for (int j = 0; j < linmin.line.Length(); j++)
            {
            g[j] = -linmin.line[j];
            h[j] = g[j] + gamma * h[j];
            linmin.line[j] = h[j];
            }

         // Normalize direction vector to avoid degenerate cases
         double norm = linmin.line.SumSquares();

         if (norm > 1.0)
            {
            norm = sqrt (1.0 / norm);
            g.Multiply(norm);
            h.Multiply(norm);
            linmin.line.Multiply(norm);
            }

          if (iter == ITMAX)
            error("Fletcher.Minimizer -- Failed to converge after %d iterations", ITMAX);

         iter++;
         }
      }
   }
예제 #7
0
double PowellMinimizer::Minimize(double ftol)
   {
   LineMinimizer linmin(*func);
   Vector pstart;

   fmin = f(point);

   iter = 1;
   while (true)
      {
      pstart = point;
      double fstart = fmin;

      double ybig = 0;
      int    ibig = 0;

      // Try all the directions in the current set
      for (int i = 0; i < directions.rows; i++)
         {
         linmin.point = point;
         linmin.line = directions[i];
         linmin.Bracket(0, 1);
         linmin.Brent(ftol);

         if ((fmin - linmin.fmin) > ybig)
            {
            ibig = i;
            ybig = fmin - linmin.fmin;
            }

         fmin = linmin.fmin;
         point = linmin.point;
         }

      // are we done?
      if (2 * (fstart - fmin) <= ftol * (fabs(fstart) + fabs(fmin)))
         return fmin;

      if (iter == ITMAX)
         error("Powell.Minimize - Exceeding maximum iterations");

      // Average direction moved
      linmin.line = point;
      linmin.line.Subtract(pstart);

      // Extrapolated point
      linmin.point.Add(linmin.line);

      double fextra = f(linmin.point);

      if (fextra < fstart)
         {
         double avgdir = fstart - fmin - ybig;
         double newdir = fstart - fextra;
         double promise = 2.0 * (fstart - 2.0 * fmin + fextra) *
                        avgdir * avgdir - ybig * newdir * newdir;

         if (promise < 0.0)
            {
            linmin.Bracket(0,1);
            linmin.Brent(ftol);

            directions.SwapRows(ibig, directions.rows);
            directions[directions.rows - 1] = linmin.line;
            }
         }

      iter++;
      }
   }
예제 #8
0
void PowellMin (TSIL_REAL p[],
		TSIL_REAL **xi,
		int n,
		TSIL_REAL ftol,
		int *iter,
		TSIL_REAL *fret,
		TSIL_REAL (*func)(TSIL_REAL []))
{
  int i, ibig, j;
  TSIL_REAL del, fp, fptt, t, *pt, *ptt, *xit;

  pt  = (TSIL_REAL *) calloc (n, sizeof(TSIL_REAL));
  ptt = (TSIL_REAL *) calloc (n, sizeof(TSIL_REAL));
  xit = (TSIL_REAL *) calloc (n, sizeof(TSIL_REAL));

  *fret = (*func)(p);
/*   printf("Initial fret = %Lf\n", *fret); */

  for (j=0; j<n; j++) pt[j] = p[j];

  for (*iter=1; ; ++(*iter)) {

    fp = *fret;
    ibig = 0;
    del = 0.0;
    for (i=0; i<n; i++) {
      for (j=0; j<n; j++) xit[j] = xi[j][i];
      fptt = *fret;
      linmin (p, xit, n, fret, func);
      if (fptt - *fret > del) {
	del = fptt - *fret;
	ibig = i;
      }
    }
    if (2.0L*(fp-(*fret)) <= ftol*(TSIL_FABS(fp)+TSIL_FABS(*fret))+TINY) {

/*       printf("Powell exiting...\n"); */
/*       printf("fp   = %Lf\n", fp); */
/*       printf("fret = %Lf\n", *fret); */

      free (xit);
      free (ptt);
      free (pt);
      return;
    }
    if (*iter == ITMAX)
      TSIL_Error ("PowellMin", "Max iterations exceeded", 42);

    for (j=0; j<n; j++) {
      ptt[j] = 2.0L*p[j] - pt[j];
      xit[j] = p[j] - pt[j];
      pt[j] = p[j];
    }
    fptt = (*func)(ptt);
    if (fptt < fp) {
      t = 2.0L*(fp - 2.0L*(*fret) + fptt)*TSIL_POW(fp - (*fret) - del, 2)
	- del*TSIL_POW(fp - fptt, 2);
      if (t < 0.0) {
	linmin (p, xit, n, fret, func);
	for (j=0; j<n; j++) {
	  xi[j][ibig] = xi[j][n-1];
	  xi[j][n-1] = xit[j];
	}
      }
    }
  }
}