20 #ifndef JDFTX_CORE_MINIMIZE_H 21 #define JDFTX_CORE_MINIMIZE_H 27 #include <core/MinimizeParams.h> 49 virtual void step(
const Vector& dir,
double alpha)=0;
52 virtual double compute(Vector* grad, Vector* Kgrad)=0;
56 virtual bool report(
int iter) {
return false; }
62 virtual double sync(
double x)
const {
return x; }
65 virtual double safeStepSize(
const Vector& dir)
const {
return DBL_MAX; }
76 Linmin getLinmin(
const MinimizeParams& params)
const;
77 double lBFGS(
const MinimizeParams& params);
90 virtual Vector hessian(
const Vector&)
const=0;
96 virtual double sync(
double x)
const {
return x; }
107 #include <core/Minimize_linmin.h> 108 #include <core/Minimize_lBFGS.h> 118 Vector d =
clone(Kg);
120 bool forceGradDirection =
true;
123 switch(currentDirUpdateScheme)
133 double alpha = alphaT;
135 double gKNorm = 0.0, gKNormPrev = 0.0;
138 Linmin linmin = getLinmin(p);
146 fprintf(p.
fpLog,
"%s\tState modified externally: resetting search direction.\n", p.
linePrefix);
148 forceGradDirection =
true;
154 fprintf(p.
fpLog,
" |grad|_K: %10.3le alpha: %10.3le",
sqrt(gKNorm/p.
nDim), alpha);
158 if(!forceGradDirection)
159 {
double dotgd =
sync(
dot(g,d));
160 double dotgPrevKg = gPrevUsed ?
sync(
dot(gPrev, Kg)) : 0.;
164 fprintf(p.
fpLog,
" cgtest: %10.3le", dotgPrevKg/
sqrt(gKNorm*gKNormPrev));
168 switch(currentDirUpdateScheme)
176 { fprintf(p.
fpLog,
"\n%sEncountered beta<0, resetting CG.", p.
linePrefix);
180 forceGradDirection =
false;
184 fflush(p.
fpLog);
return E;
186 if(ediffCheck.checkConvergence(E))
187 { fprintf(p.
fpLog,
"%sConverged (|Delta %s|<%le for %d iters).\n",
189 fflush(p.
fpLog);
return E;
191 if(!std::isfinite(gKNorm))
192 { fprintf(p.
fpLog,
"%s|grad|_K=%le. Stopping ...\n", p.
linePrefix, gKNorm);
193 fflush(p.
fpLog);
return E;
195 if(!std::isfinite(E))
197 fflush(p.
fpLog);
return E;
200 if(gPrevUsed) gPrev = g;
204 d *= beta;
axpy(-1.0, Kg, d);
209 if(linmin(*
this, p, d, alphaT, alpha, E, g, Kg))
224 fprintf(p.
fpLog,
"%s\tStep failed: resetting search direction.\n", p.
linePrefix);
226 forceGradDirection =
true;
230 fprintf(p.
fpLog,
"%s\tStep failed along negative gradient direction.\n", p.
linePrefix);
231 fprintf(p.
fpLog,
"%sProbably at roundoff error limit. (Stopping)\n", p.
linePrefix);
237 fprintf(p.
fpLog,
"%sNone of the convergence criteria satisfied after %d iterations.\n", p.
linePrefix, iter);
244 const double deltaMin = 1e-9;
245 const double deltaMax = 1e+1;
246 const double deltaScale = 1e+1;
248 const char* fdPrefix = fdPrefixString.c_str();
249 fprintf(p.
fpLog,
"%s--------------------------------------\n", fdPrefix);
261 double dE_ddelta =
sync(
dot(dx, g));
264 for(
double delta=deltaMin; delta<=deltaMax; delta*=deltaScale)
265 {
double dE = dE_ddelta*delta;
266 step(dx, delta-deltaPrev); deltaPrev=delta;
268 fprintf(p.
fpLog,
"%s delta=%le:\n", fdPrefix, delta);
269 fprintf(p.
fpLog,
"%s d%s Ratio: %19.16lf\n", fdPrefix, p.
energyLabel, deltaE/dE);
272 fprintf(p.
fpLog,
"%s--------------------------------------\n", fdPrefix);
273 step(dx, -deltaPrev);
279 Vector r =
clone(rhs);
axpy(-1.0, hessian(state), r);
280 Vector z = precondition(r), d = r;
281 double beta=0.0, rdotzPrev=0.0, rdotz =
sync(
dot(r, z));
284 double rzNorm =
sqrt(fabs(rdotz)/p.
nDim);
293 { beta = rdotz/rdotzPrev;
294 d *= beta;
axpy(1.0, z, d);
298 Vector w = hessian(d);
299 double alpha = rdotz/
sync(
dot(w,d));
300 axpy(alpha, d, state);
306 double rzNorm =
sqrt(fabs(rdotz)/p.
nDim);
307 fprintf(p.
fpLog,
"%sIter: %3d sqrt(|r.z|): %12.6le alpha: %12.6le beta: %13.6le t[s]: %9.2lf\n",
312 fprintf(p.
fpLog,
"%sGradient did not converge within threshold in %d iterations\n", p.
linePrefix, iter); fflush(p.
fpLog);
317 #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 &)
Constrain search directions to the space of free directions for minimize.
Definition: Minimize.h:59
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:85
void randomize(TptrCollection &x)
Initialize to normal random numbers:
Definition: ScalarFieldArray.h:154
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:56
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 compute(Vector *grad, Vector *Kgrad)=0
Returns the objective function at the current state and store the gradient in grad and preconditioned...
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
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
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:93
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:96
virtual double safeStepSize(const Vector &dir) const
Override to return maximum safe step size along a given direction. Steps can be arbitrarily large by ...
Definition: Minimize.h:65
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:46
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
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:87