20 #ifndef JDFTX_CORE_MINIMIZE_LINMIN_H 21 #define JDFTX_CORE_MINIMIZE_LINMIN_H 31 EdiffCheck(
unsigned nDiff,
double threshold) : nDiff(nDiff), threshold(fabs(threshold))
34 bool checkConvergence(
double E)
35 {
if(!size()) { push_back(E);
return false; }
36 if(E >= back()) { clear(); push_back(E);
return false; }
39 if(size()==nDiff+2) pop_front();
41 {
for(
unsigned i=0; i<nDiff; i++)
42 if(at(i+1) < at(i)-threshold)
61 template<
typename Vector>
63 const Vector& d,
double alphaT,
double& alpha,
double& E, Vector& g, Vector& Kg)
77 template<
typename Vector>
79 const Vector& d,
double alphaT,
double& alpha,
double& E, Vector& g, Vector& Kg)
81 double alphaPrev = 0.0;
83 double gdotd = obj.
sync(
dot(g,d));
99 obj.
step(d, alphaT-alphaPrev); alphaPrev = alphaT;
102 if(!std::isfinite(ET))
104 fprintf(p.
fpLog,
"%s\tTest step failed with %s = %le, reducing alphaT to %le.\n",
109 alpha = 0.5*
pow(alphaT,2)*gdotd/(alphaT*gdotd + E - ET);
115 fprintf(p.
fpLog,
"%s\tWrong curvature in test step, increasing alphaT to %le.\n", p.
linePrefix, alphaT); fflush(p.
fpLog);
121 fprintf(p.
fpLog,
"%s\tPredicted alpha/alphaT>%lf, increasing alphaT to %le.\n",
127 fprintf(p.
fpLog,
"%s\tPredicted alpha/alphaT<%lf, reducing alphaT to %le.\n",
134 if(!std::isfinite(E))
143 obj.
step(d, alpha-alphaPrev); alphaPrev=alpha;
145 if(!std::isfinite(E))
147 fprintf(p.
fpLog,
"%s\tStep failed with %s = %le, reducing alpha to %le.\n",
153 fprintf(p.
fpLog,
"%s\tStep increased %s by %le, reducing alpha to %le.\n",
160 if(!std::isfinite(E) || E>Eorig)
161 { fprintf(p.
fpLog,
"%s\tStep failed to reduce %s after %d attempts. Quitting step.\n",
170 template<
typename Vector>
172 const Vector& d,
double alphaT,
double& alpha,
double& E, Vector& g, Vector& Kg)
175 double gdotdPrev = obj.
sync(
dot(g,d));
181 double E0 = Eprev, gdotd0 =gdotdPrev;
184 double alphaPrev = 0;
185 double alphaState = 0.;
188 obj.
step(d, alpha-alphaState); alphaState=alpha;
190 double gdotd = obj.
sync(
dot(g,d));
193 if(!std::isfinite(E))
195 fprintf(p.
fpLog,
"%s\tStep failed with %s = %le, reducing alpha to %le.\n",
202 double Ep0 = gdotdPrev*(alpha-alphaPrev);
203 double Ep1 = gdotd*(alpha-alphaPrev);
204 double deltaE = E-Eprev;
206 double A = 3*(Ep0 + Ep1 - 2*deltaE);
207 double B = 2*Ep0 + Ep1 - 3*deltaE;
211 {
double disc =
sqrt(B*B-A*C);
212 double tOpt = B>0 ? (B+disc)/A : C/(B-disc);
213 double Eopt = Eprev + tOpt*(C + tOpt*(-B + tOpt*A/3));
214 if(std::isfinite(tOpt) && Eopt<=E && Eopt<=Eprev)
217 if(std::isfinite(tMin))
227 double alphaNew = alphaPrev + tMin*(alpha-alphaPrev);
229 if(E <= E0 + p.wolfeEnergy*alpha*gdotd0 && gdotd >= p.
wolfeGradient*gdotd0)
233 fprintf(p.
fpLog,
"%s\tWolfe criterion not satisfied: alpha: %lg (E-E0)/|gdotd0|: %lg gdotd/gdotd0: %lg (taking cubic step)\n",
234 p.
linePrefix, alpha, (E-E0)/fabs(gdotd0), gdotd/gdotd0); fflush(p.
fpLog);
236 if(E<Eprev) { alphaPrev = alpha; Eprev=E; gdotdPrev=gdotd; }
240 if(!std::isfinite(E) || E>E0)
return false;
247 switch(p.linminMethod)
249 {
switch(p.dirUpdateScheme)
252 default:
return linminQuad<Vector>;
262 #endif //JDFTX_CORE_MINIMIZE_LINMIN_H ScalarField pow(const ScalarField &, double alpha)
Elementwise power (preserve input)
double alphaTmin
minimum value of the test-step size (algorithm gives up when difficulties cause alphaT to fall below ...
Definition: MinimizeParams.h:60
Limited memory version of the BFGS algorithm.
Definition: MinimizeParams.h:36
Definition: Minimize_linmin.h:27
ScalarField sqrt(const ScalarField &)
Elementwise square root (preserve input)
complex dot(const Tptr &X, const Tptr &Y)
Definition: Operators.h:196
Definition: Minimize_linmin.h:50
Parameters to control the minimization algorithm.
Definition: MinimizeParams.h:29
virtual double compute(Vector *grad, Vector *Kgrad)=0
Returns the objective function at the current state and store the gradient in grad and preconditioned...
Cubic line search terminated by Wolfe conditions, possibly without a test step.
Definition: MinimizeParams.h:45
double alphaTreduceFactor
Factor to reduce alphaT on difficulties (default 0.1)
Definition: MinimizeParams.h:63
move by a constant multiple (=alphaTstart) of the search direction (not recommended for CG) ...
Definition: MinimizeParams.h:43
virtual double sync(double x) const
Override to synchronize scalars over MPI processes (if the same minimization is happening in sync ove...
Definition: Minimize.h:62
Steepest Descent (always along negative (preconditioned) gradient)
Definition: MinimizeParams.h:37
default method recommended by the direction update scheme
Definition: MinimizeParams.h:42
double wolfeGradient
Wolfe criterion dimensionless threshold for gradient.
Definition: MinimizeParams.h:68
bool updateTestStepSize
set alphaT=alpha after every iteration if true (default: true)
Definition: MinimizeParams.h:61
double alphaTincreaseFactor
Max ratio of alpha to alphaT, increase alphaT by this factor otherwise (default 3.0)
Definition: MinimizeParams.h:64
const char * linePrefix
prefix for each output line of minimizer, useful for nested minimizations (default "CG\t") ...
Definition: MinimizeParams.h:52
Nonlinear minimization templates.
const char * energyLabel
Label for the minimized quantity (default "E")
Definition: MinimizeParams.h:53
int nAlphaAdjustMax
maximum number of times to alpha adjust attempts (default 3)
Definition: MinimizeParams.h:65
FILE * fpLog
Stream to log iterations to.
Definition: MinimizeParams.h:51
Definition: Minimize.h:46
virtual void step(const Vector &dir, double alpha)=0
Move the state in parameter space along direction dir with scale alpha.
use the energy at a test step location to find the minimum along the line (default) ...
Definition: MinimizeParams.h:44