EndCriteria::Type LineSearchBasedMethod::minimize(Problem& P, const EndCriteria& endCriteria) { // Initializations RealType ftol = endCriteria.functionEpsilon(); size_t maxStationaryStateIterations_ = endCriteria.maxStationaryStateIterations(); EndCriteria::Type ecType = EndCriteria::None; // reset end criteria P.reset(); // reset problem DynamicVector<RealType> x_ = P.currentValue(); // store the starting point size_t iterationNumber_ = 0; // dimension line search lineSearch_->searchDirection() = DynamicVector<RealType>(x_.size()); bool done = false; // function and squared norm of gradient values; RealType fnew, fold, gold2; RealType fdiff; // classical initial value for line-search step RealType t = 1.0; // Set gradient g at the size of the optimization problem // search direction size_t sz = lineSearch_->searchDirection().size(); DynamicVector<RealType> prevGradient(sz), d(sz), sddiff(sz), direction(sz); // Initialize objective function, gradient prevGradient and // search direction P.setFunctionValue(P.valueAndGradient(prevGradient, x_)); P.setGradientNormValue(P.DotProduct(prevGradient, prevGradient)); lineSearch_->searchDirection() = -prevGradient; bool first_time = true; // Loop over iterations do { // Linesearch if (!first_time) prevGradient = lineSearch_->lastGradient(); t = (*lineSearch_)(P, ecType, endCriteria, t); // don't throw: it can fail just because maxIterations exceeded //QL_REQUIRE(lineSearch_->succeed(), "line-search failed!"); if (lineSearch_->succeed()) { // Updates // New point x_ = lineSearch_->lastX(); // New function value fold = P.functionValue(); P.setFunctionValue(lineSearch_->lastFunctionValue()); // New gradient and search direction vectors // orthogonalization coef gold2 = P.gradientNormValue(); P.setGradientNormValue(lineSearch_->lastGradientNorm2()); // conjugate gradient search direction direction = getUpdatedDirection(P, gold2, prevGradient); sddiff = direction - lineSearch_->searchDirection(); lineSearch_->searchDirection() = direction; // Now compute accuracy and check end criteria // Numerical Recipes exit strategy on fx (see NR in C++, p.423) fnew = P.functionValue(); fdiff = 2.0*std::fabs(fnew-fold) / (std::fabs(fnew) + std::fabs(fold) + std::numeric_limits<RealType>::epsilon()); if (fdiff < ftol || endCriteria.checkMaxIterations(iterationNumber_, ecType)) { endCriteria.checkStationaryFunctionValue(0.0, 0.0, maxStationaryStateIterations_, ecType); endCriteria.checkMaxIterations(iterationNumber_, ecType); return ecType; } P.setCurrentValue(x_); // update problem current value ++iterationNumber_; // Increase iteration number first_time = false; } else { done = true; } } while (!done); P.setCurrentValue(x_); return ecType; }