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]; } } } } }
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); }
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"); }
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"); }
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; }
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++; } } }
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++; } }
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]; } } } } }