32 MinimumState NegativeG2LineSearch::operator()(
const MnFcn& fcn,
const MinimumState& st,
const GradientCalculator& gc,
const MnMachinePrecision& prec)
const {
40 bool negG2 = HasNegativeG2(st.Gradient(), prec);
43 unsigned int n = st.Parameters().Vec().size();
44 FunctionGradient dgrad = st.Gradient();
45 MinimumParameters pa = st.Parameters();
47 unsigned int iter = 0;
50 for(
unsigned int i = 0; i < n; i++) {
53 std::cout <<
"negative G2 - iter " << iter <<
" param " << i <<
" " << pa.Vec()(i) <<
" grad2 " << dgrad.G2()(i) <<
" grad " << dgrad.Vec()(i)
54 <<
" grad step " << dgrad.Gstep()(i) <<
" step size " << pa.Dirin()(i) << std::endl;
56 if(dgrad.G2()(i) <= 0) {
60 if ( std::fabs(dgrad.Vec()(i) ) < prec.Eps() && std::fabs(dgrad.G2()(i) ) < prec.Eps() )
continue;
63 MnAlgebraicVector step(n);
66 if ( dgrad.Vec()(i) < 0)
67 step(i) = dgrad.Gstep()(i);
69 step(i) = - dgrad.Gstep()(i);
71 double gdel = step(i)*dgrad.Vec()(i);
78 std::cout <<
"step(i) " << step(i) <<
" gdel " << gdel << std::endl;
82 MnParabolaPoint pp = lsearch(fcn, pa, step, gdel, prec,debugLS);
87 std::cout <<
"\nLine search result " << pp.X() <<
" f(0) " << pa.Fval() <<
" f(1) " << pp.Y() << std::endl;
91 pa = MinimumParameters(pa.Vec() + step, pp.Y());
93 dgrad = gc(pa, dgrad);
96 std::cout <<
"Line search - iter" << iter <<
" param " << i <<
" " << pa.Vec()(i) <<
" step " << step(i) <<
" new grad2 " << dgrad.G2()(i) <<
" new grad " << dgrad.Vec()(i) <<
" grad step " << dgrad.Gstep()(i) << std::endl;
103 }
while(iter++ < 2*n && iterate);
105 MnAlgebraicSymMatrix mat(n);
106 for(
unsigned int i = 0; i < n; i++)
107 mat(i,i) = (fabs(dgrad.G2()(i)) > prec.Eps2() ? 1./dgrad.G2()(i) : 1.);
109 MinimumError err(mat, 1.);
110 double edm = VariableMetricEDMEstimator().Estimate(dgrad, err);
113 err = MinimumError(mat, MinimumError::MnNotPosDef() );
116 return MinimumState(pa, err, dgrad, edm, fcn.NumOfCalls());
119 bool NegativeG2LineSearch::HasNegativeG2(
const FunctionGradient& grad,
const MnMachinePrecision& )
const {
122 for(
unsigned int i = 0; i < grad.Vec().size(); i++)
124 if(grad.G2()(i) <= 0 ) {