20 #ifndef JDFTX_CORE_MINIMIZE_H 21 #define JDFTX_CORE_MINIMIZE_H 26 #include <core/MinimizeParams.h> 48 virtual void step(
const Vector& dir,
double alpha)=0;
51 virtual double compute(Vector* grad)=0;
59 virtual bool report(
int iter) {
return false; }
66 virtual double sync(
double x)
const {
return x; }
77 Linmin getLinmin(
const MinimizeParams& params)
const;
78 double lBFGS(
const MinimizeParams& params);
91 virtual Vector hessian(
const Vector&)
const=0;
97 virtual double sync(
double x)
const {
return x; }
108 #include <core/Minimize_linmin.h> 109 #include <core/Minimize_lBFGS.h> 120 bool forceGradDirection =
true;
124 double alpha = alphaT;
126 double gKNorm = 0.0, gKNormPrev = 0.0;
129 Linmin linmin = getLinmin(p);
137 fprintf(p.
fpLog,
"%s\tState modified externally: resetting search direction.\n", p.
linePrefix);
139 forceGradDirection =
true;
146 fprintf(p.
fpLog,
" |grad|_K: %10.3le alpha: %10.3le",
sqrt(gKNorm/p.
nDim), alpha);
150 if(!forceGradDirection)
151 {
double dotgd =
sync(
dot(g,d));
152 double dotgPrevKg =
sync(
dot(gPrev, Kg));
155 double cgtest = dotgPrevKg/
sqrt(gKNorm*gKNormPrev);
156 fprintf(p.
fpLog,
" linmin: %10.3le", linmin);
157 fprintf(p.
fpLog,
" cgtest: %10.3le", cgtest);
161 switch(currentDirUpdateScheme)
169 { fprintf(p.
fpLog,
"\n%sEncountered beta<0, resetting CG.", p.
linePrefix);
173 forceGradDirection =
false;
177 fflush(p.
fpLog);
return E;
179 if(ediffCheck.checkConvergence(E))
180 { fprintf(p.
fpLog,
"%sConverged (|Delta %s|<%le for %d iters).\n",
182 fflush(p.
fpLog);
return E;
184 if(!std::isfinite(gKNorm))
185 { fprintf(p.
fpLog,
"%s|grad|_K=%le. Stopping ...\n", p.
linePrefix, gKNorm);
186 fflush(p.
fpLog);
return E;
188 if(!std::isfinite(E))
190 fflush(p.
fpLog);
return E;
197 d *= beta;
axpy(-1.0, Kg, d);
200 if(linmin(*
this, p, d, alphaT, alpha, E, g))
215 fprintf(p.
fpLog,
"%s\tStep failed: resetting search direction.\n", p.
linePrefix);
217 forceGradDirection =
true;
221 fprintf(p.
fpLog,
"%s\tStep failed along negative gradient direction.\n", p.
linePrefix);
222 fprintf(p.
fpLog,
"%sProbably at roundoff error limit. (Stopping)\n", p.
linePrefix);
228 fprintf(p.
fpLog,
"%sNone of the convergence criteria satisfied after %d iterations.\n", p.
linePrefix, iter);
235 const double deltaMin = 1e-9;
236 const double deltaMax = 1e+1;
237 const double deltaScale = 1e+1;
239 const char* fdPrefix = fdPrefixString.c_str();
240 fprintf(p.
fpLog,
"%s--------------------------------------\n", fdPrefix);
253 double dE_ddelta =
sync(
dot(dx, g));
256 for(
double delta=deltaMin; delta<=deltaMax; delta*=deltaScale)
257 {
double dE = dE_ddelta*delta;
258 step(dx, delta-deltaPrev); deltaPrev=delta;
260 fprintf(p.
fpLog,
"%s delta=%le:\n", fdPrefix, delta);
261 fprintf(p.
fpLog,
"%s d%s Ratio: %19.16lf\n", fdPrefix, p.
energyLabel, deltaE/dE);
264 fprintf(p.
fpLog,
"%s--------------------------------------\n", fdPrefix);
265 step(dx, -deltaPrev);
271 Vector r =
clone(rhs);
axpy(-1.0, hessian(state), r);
273 double beta=0.0, rdotzPrev=0.0, rdotz =
sync(
dot(r, z));
276 double rzNorm =
sqrt(fabs(rdotz)/p.
nDim);
285 { beta = rdotz/rdotzPrev;
286 d *= beta;
axpy(1.0, z, d);
290 Vector w = hessian(d);
291 double alpha = rdotz/
sync(
dot(w,d));
292 axpy(alpha, d, state);
298 double rzNorm =
sqrt(fabs(rdotz)/p.
nDim);
299 fprintf(p.
fpLog,
"%sIter: %3d sqrt(|r.z|): %12.6le alpha: %12.6le beta: %13.6le t[s]: %9.2lf\n",
304 fprintf(p.
fpLog,
"%sGradient did not converge within threshold in %d iterations\n", p.
linePrefix, iter); fflush(p.
fpLog);
309 #endif // JDFTX_CORE_MINIMIZE_H double alphaTmin
minimum value of the test-step size (algorithm gives up when difficulties cause alphaT to fall below ...
Definition: MinimizeParams.h:60
virtual void constrain(Vector &)
Definition: Minimize.h:63
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)
Definition: Minimize.h:86
void randomize(TptrCollection &x)
Initialize to normal random numbers:
Definition: ScalarFieldArray.h:157
int nIterations
Maximum number of iterations (default 100)
Definition: MinimizeParams.h:48
complex dot(const Tptr &X, const Tptr &Y)
Definition: Operators.h:196
Hestenes-Stiefel (preconditioned) conjugate gradients.
Definition: MinimizeParams.h:35
virtual bool report(int iter)
Definition: Minimize.h:59
Parameters to control the minimization algorithm.
Definition: MinimizeParams.h:29
double energyDiffThreshold
stop when energy change is below this for nEnergyDiff successive iterations (default: 0) ...
Definition: MinimizeParams.h:56
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:66
double alphaTstart
initial value for the test-step size (default: 1.0)
Definition: MinimizeParams.h:59
int nEnergyDiff
number of successive iterations for energyDiffThreshold check (default: 2)
Definition: MinimizeParams.h:57
Steepest Descent (always along negative (preconditioned) gradient)
Definition: MinimizeParams.h:37
virtual Vector precondition(const Vector &grad)
Definition: Minimize.h:55
double knormThreshold
stop when norm of residual against preconditioner falls below this (default: 0)
Definition: MinimizeParams.h:55
void fdTest(const MinimizeParams ¶ms)
Tptr clone(const Tptr &X)
Clone (NOTE: operator= is by reference for the ScalarField classes)
Definition: Operators.h:111
virtual Vector precondition(const Vector &v) const
Override to enable preconditioning: return the preconditioned vector, given a vector.
Definition: Minimize.h:94
bool updateTestStepSize
set alphaT=alpha after every iteration if true (default: true)
Definition: MinimizeParams.h:61
double clock_sec()
Elapsed time in microseconds (from start of program)
bool killFlag
Flag set by signal handlers - all compute loops should quit cleanly when this is set.
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:97
double minimize(const MinimizeParams ¶ms)
Minimize this objective function with algorithm controlled by params and return the minimized value...
Polak-Ribiere (preconditioned) conjugate gradients (default)
Definition: MinimizeParams.h:33
const char * linePrefix
prefix for each output line of minimizer, useful for nested minimizations (default "CG\t") ...
Definition: MinimizeParams.h:52
const char * energyLabel
Label for the minimized quantity (default "E")
Definition: MinimizeParams.h:53
Fletcher-Reeves (preconditioned) conjugate gradients.
Definition: MinimizeParams.h:34
int nDim
Dimension of optimization space; used only for knormThreshold (default 1)
Definition: MinimizeParams.h:49
int solve(const Vector &rhs, const MinimizeParams ¶ms)
const char * energyFormat
printf format for the minimized quantity (default "%22.15le")
Definition: MinimizeParams.h:54
FILE * fpLog
Stream to log iterations to.
Definition: MinimizeParams.h:51
Definition: Minimize.h:45
DirectionUpdateScheme
Search direction update scheme.
Definition: MinimizeParams.h:32
virtual void step(const Vector &dir, double alpha)=0
Move the state in parameter space along direction dir with scale alpha.
void axpy(double alpha, const Tptr &X, Tptr &Y)
Generic axpy for complex data types (Note: null pointers are treated as zero)
Definition: Operators.h:158
std::basic_string< char, ichar_traits > string
Case-insensitive string.
Definition: string.h:42
virtual double compute(Vector *grad)=0
Returns the objective function at the current state and store the gradient in grad, if non-null.
bool fdTest
whether to perform a finite difference test before each minimization (default false) ...
Definition: MinimizeParams.h:70
Vector state
the location of the minimum, obtained by solving hessian * state == rhs
Definition: Minimize.h:88