13 #ifndef _CGOPTIMIZE_H_ 14 #define _CGOPTIMIZE_H_ 17 #include "parstream.H" 20 #include "NamespaceHeader.H" 21 #include "CH_assert.H" 24 inline Real
sqr(
const Real& a)
43 virtual Real
dotProduct(X& a ,
const X& b) = 0;
59 virtual void assign(X& y,
const X& x) = 0;
62 virtual void incr(X& y,
const X& x, Real s) = 0;
65 virtual void create (X &a,
const X &b) = 0;
68 virtual void free (X &a) = 0;
71 virtual void scale(X &a,
const Real s) = 0;
74 virtual void preCond(X &a,
const X &b) = 0;
80 virtual int nDoF(
const X& x) = 0;
99 int a_maxIter, Real a_initialStep, Real a_stepMaxGrow, Real a_tol)
105 Real initialStep = a_initialStep;
106 Real alpha = -initialStep;
108 a_F.
incr(y,d,initialStep);
113 pout() <<
" ... initial secant ||f'(x+sd).f'(x)||^2 = " 114 << -etaPrev <<
" s = " << initialStep <<
" f(x+sd) = " << fms << std::endl;
116 while ( (fms + fps < a_fx) && (-etaPrev > -eta))
121 pout() <<
" d is a descent direction for f(x+sd) but not for f'(x+sd).f'(x) " 122 <<
" so walking the line (remind SLC to look up a better method) " << std::endl;
123 alpha -= initialStep;
124 a_F.
incr(y,d,initialStep);
128 pout() <<
" ... initial secant f'(x+ sd).f'(x) = " 129 << -etaPrev <<
" s = " << alpha <<
" f(x+ sd) = " << a_fx << std::endl;
132 while ( (fms + fps > a_fx) && initialStep > 0.015624 * a_initialStep )
136 pout() <<
" d is a not descent direction for f(x+sd), reducing s ";
137 a_F.
incr(y,d,-0.5*initialStep);
139 alpha = - initialStep;
143 pout() <<
" ... initial secant f'(x+ sd).f'(x) = " 144 << -etaPrev <<
" s = " << initialStep <<
" f(x+ sd) = " << a_fx << std::endl;
148 Real q = -(alpha + a_initialStep);
152 alpha = -a_initialStep;
162 pout() <<
" ... secant iteration j = " << j <<
" f'(x[0]+qd).f'(x[0]) = " << -eta
163 <<
" a = " << alpha <<
" q = " << q << std::endl;
165 Real absAlphaPrev = std::abs(alpha);
166 alpha = alpha * eta / (etaPrev-eta);
169 if ( (a_stepMaxGrow > 0.0) && (std::abs(alpha) > a_stepMaxGrow * absAlphaPrev) )
171 alpha = ((alpha > 0.0)?(1.0):(-1.0)) * a_stepMaxGrow * absAlphaPrev;
175 pout() <<
" ... testing a = " << alpha <<
" q = " << q << std::endl;
180 }
while (j < a_maxIter
181 &&
sqr(alpha) * deltaD >
sqr(a_tol));
196 Real a_secantParameter,
197 Real a_secantStepMaxGrow,
227 Real deltaZero = deltaNew;
228 int iter = a_iter;
int k = 0;
231 int niter = a_maxIter;
232 if ( (iter > a_maxIter) && (a_maxIter > 0)) niter += (iter/a_maxIter) * a_maxIter;
234 while ( (iter < niter)
235 && (deltaNew >
sqr(a_tol) * deltaZero)
237 && ( (iter - a_iter < 1 ) || (fm/fmOld < a_hang) ) )
240 pout() <<
"CGOptimize iteration " << iter
241 <<
" ||f'(x)||^2 = " << deltaNew
242 <<
" ||fm(x)||^2 = " << fm
243 <<
" ||fp(x)||^2 = " << fp
244 <<
" ||fm(x)||^2 + ||fp(x)||^ = " << fm + fp;
245 if (iter - a_iter > 0)
247 pout() <<
" ||fm(x)||^2/||fm_old(x)||^2 = " << fm/fmOld;
256 a_secantParameter, a_secantStepMaxGrow, a_secantTol);
260 Real deltaOld = deltaNew;
264 Real beta = (deltaNew - deltaMid)/deltaOld;
266 if (k == a_F.
nDoF(x) || beta <= 0.0 )
268 pout() <<
"CGOptimize restart k = " << k
269 <<
" beta = " << beta << std::endl;
283 pout() <<
"CGOptimize iteration " << iter
284 <<
" ||f'(x)||^2 = " << deltaNew
285 <<
" ||fm(x)||^2 = " << fm
286 <<
" ||fp(x)||^2 = " << fp
287 <<
" ||fm(x)||^2 + ||fp(x)||^ = " << fm + fp
288 <<
" ||fm(x)||^2/||fm_old(x)||^2 = " << fm/fmOld
303 #include "NamespaceFooter.H" virtual void restart()=0
carry out whatver operations are required prior to a restart
int CGOptimize(ObjectiveWithGradient< X > &a_F, X &a_x, int a_maxIter, Real a_tol, Real a_hang, Real a_secantParameter, Real a_secantStepMaxGrow, int a_secantMaxIter, Real a_secantTol, int a_iter=0)
Definition: CGOptimize.H:192
virtual ~ObjectiveWithGradient()
virtual destructor
Definition: CGOptimize.H:37
virtual void computeObjectiveAndGradient(Real &fm, Real &fp, X &g, const X &x, bool inner)=0
virtual void preCond(X &a, const X &b)=0
apply precoditioner K, so a = Kb
Specify operations required to carry out gradient based optimization.
Definition: CGOptimize.H:32
virtual void scale(X &a, const Real s)=0
set a = a * s
void secantLineSearch(ObjectiveWithGradient< X > &a_F, X &x, X &r, X &d, X &y, X &p, Real a_fx, int a_maxIter, Real a_initialStep, Real a_stepMaxGrow, Real a_tol)
find y = x + s*d such that f'(y).f'(x) << f'(x).f'(x)
Definition: CGOptimize.H:98
virtual void free(X &a)=0
free storage
Real sqr(const Real &a)
Definition: CGOptimize.H:24
virtual void incr(X &y, const X &x, Real s)=0
Set y = y + s * x.
virtual Real dotProduct(X &a, const X &b)=0
virtual void create(X &a, const X &b)=0
resize a / allocate storage to conform with b
virtual void assign(X &y, const X &x)=0
Copy x to y.
virtual int nDoF(const X &x)=0
number of degrees-of-freedom (maximum number of iterations before restart)