public override EndCriteria.Type minimize(Problem P, EndCriteria endCriteria) { // set up of the problem //double ftol = endCriteria.functionEpsilon(); // end criteria on f(x) (see Numerical Recipes in C++, p.410) double xtol = endCriteria.rootEpsilon(); // end criteria on x (see GSL v. 1.9, http://www.gnu.org/software/gsl/) int maxStationaryStateIterations_ = endCriteria.maxStationaryStateIterations(); EndCriteria.Type ecType = EndCriteria.Type.None; P.reset(); Vector x_ = P.currentValue(); int iterationNumber_ = 0; // Initialize vertices of the simplex bool end = false; int n = x_.Count; vertices_ = new InitializedList <Vector>(n + 1, x_); for (int i = 0; i < n; i++) { Vector direction = new Vector(n, 0.0); Vector vertice = vertices_[i + 1]; direction[i] = 1.0; P.constraint().update(ref vertice, direction, lambda_); vertices_[i + 1] = vertice; } // Initialize function values at the vertices of the simplex values_ = new Vector(n + 1, 0.0); for (int i = 0; i <= n; i++) { values_[i] = P.value(vertices_[i]); } // Loop looking for minimum do { sum_ = new Vector(n, 0.0); for (int i = 0; i <= n; i++) { sum_ += vertices_[i]; } // Determine the best (iLowest), worst (iHighest) // and 2nd worst (iNextHighest) vertices int iLowest = 0; int iHighest; int iNextHighest; if (values_[0] < values_[1]) { iHighest = 1; iNextHighest = 0; } else { iHighest = 0; iNextHighest = 1; } for (int i = 1; i <= n; i++) { if (values_[i] > values_[iHighest]) { iNextHighest = iHighest; iHighest = i; } else { if ((values_[i] > values_[iNextHighest]) && i != iHighest) { iNextHighest = i; } } if (values_[i] < values_[iLowest]) { iLowest = i; } } // Now compute accuracy, update iteration number and check end criteria //// Numerical Recipes exit strategy on fx (see NR in C++, p.410) //double low = values_[iLowest]; //double high = values_[iHighest]; //double rtol = 2.0*std::fabs(high - low)/ // (std::fabs(high) + std::fabs(low) + QL_EPSILON); //++iterationNumber_; //if (rtol < ftol || // endCriteria.checkMaxIterations(iterationNumber_, ecType)) { // GSL exit strategy on x (see GSL v. 1.9, http://www.gnu.org/software/gsl double simplexSize = Utils.computeSimplexSize(vertices_); ++iterationNumber_; if (simplexSize < xtol || endCriteria.checkMaxIterations(iterationNumber_, ref ecType)) { endCriteria.checkStationaryPoint(0.0, 0.0, ref maxStationaryStateIterations_, ref ecType); endCriteria.checkMaxIterations(iterationNumber_, ref ecType); x_ = vertices_[iLowest]; double low = values_[iLowest]; P.setFunctionValue(low); P.setCurrentValue(x_); return(ecType); } // If end criteria is not met, continue double factor = -1.0; double vTry = extrapolate(ref P, iHighest, ref factor); if ((vTry <= values_[iLowest]) && (factor == -1.0)) { factor = 2.0; extrapolate(ref P, iHighest, ref factor); } else if (Math.Abs(factor) > Const.QL_EPSILON) { if (vTry >= values_[iNextHighest]) { double vSave = values_[iHighest]; factor = 0.5; vTry = extrapolate(ref P, iHighest, ref factor); if (vTry >= vSave && Math.Abs(factor) > Const.QL_EPSILON) { for (int i = 0; i <= n; i++) { if (i != iLowest) { #if QL_ARRAY_EXPRESSIONS vertices_[i] = 0.5 * (vertices_[i] + vertices_[iLowest]); #else vertices_[i] += vertices_[iLowest]; vertices_[i] *= 0.5; #endif values_[i] = P.value(vertices_[i]); } } } } } // If can't extrapolate given the constraints, exit if (Math.Abs(factor) <= Const.QL_EPSILON) { x_ = vertices_[iLowest]; double low = values_[iLowest]; P.setFunctionValue(low); P.setCurrentValue(x_); return(EndCriteria.Type.StationaryFunctionValue); } } while (end == false); throw new Exception("optimization failed: unexpected behaviour"); }
public override EndCriteria.Type minimize(Problem P, EndCriteria endCriteria) { // set up of the problem //double ftol = endCriteria.functionEpsilon(); // end criteria on f(x) (see Numerical Recipes in C++, p.410) double xtol = endCriteria.rootEpsilon(); // end criteria on x (see GSL v. 1.9, http://www.gnu.org/software/gsl/) int maxStationaryStateIterations_ = endCriteria.maxStationaryStateIterations(); EndCriteria.Type ecType = EndCriteria.Type.None; P.reset(); Vector x_ = P.currentValue(); int iterationNumber_ = 0; // Initialize vertices of the simplex bool end = false; int n = x_.Count; vertices_ = new InitializedList<Vector>(n + 1, x_); for (int i = 0; i < n; i++) { Vector direction = new Vector(n, 0.0); direction[i] = 1.0; P.constraint().update(vertices_[i + 1], direction, lambda_); } // Initialize function values at the vertices of the simplex values_ = new Vector(n + 1, 0.0); for (int i = 0; i <= n; i++) values_[i] = P.value(vertices_[i]); // Loop looking for minimum do { sum_ = new Vector(n, 0.0); for (int i = 0; i <= n; i++) sum_ += vertices_[i]; // Determine the best (iLowest), worst (iHighest) // and 2nd worst (iNextHighest) vertices int iLowest = 0; int iHighest; int iNextHighest; if (values_[0] < values_[1]) { iHighest = 1; iNextHighest = 0; } else { iHighest = 0; iNextHighest = 1; } for (int i = 1; i <= n; i++) { if (values_[i] > values_[iHighest]) { iNextHighest = iHighest; iHighest = i; } else { if ((values_[i] > values_[iNextHighest]) && i != iHighest) iNextHighest = i; } if (values_[i] < values_[iLowest]) iLowest = i; } // Now compute accuracy, update iteration number and check end criteria //// Numerical Recipes exit strategy on fx (see NR in C++, p.410) //double low = values_[iLowest]; //double high = values_[iHighest]; //double rtol = 2.0*std::fabs(high - low)/ // (std::fabs(high) + std::fabs(low) + QL_EPSILON); //++iterationNumber_; //if (rtol < ftol || // endCriteria.checkMaxIterations(iterationNumber_, ecType)) { // GSL exit strategy on x (see GSL v. 1.9, http://www.gnu.org/software/gsl double simplexSize = Utils.computeSimplexSize(vertices_); ++iterationNumber_; if (simplexSize < xtol || endCriteria.checkMaxIterations(iterationNumber_, ref ecType)) { endCriteria.checkStationaryPoint(0.0, 0.0, ref maxStationaryStateIterations_, ref ecType); endCriteria.checkMaxIterations(iterationNumber_, ref ecType); x_ = vertices_[iLowest]; double low = values_[iLowest]; P.setFunctionValue(low); P.setCurrentValue(x_); return ecType; } // If end criteria is not met, continue double factor = -1.0; double vTry = extrapolate(ref P, iHighest, ref factor); if ((vTry <= values_[iLowest]) && (factor == -1.0)) { factor = 2.0; extrapolate(ref P, iHighest, ref factor); } else if (Math.Abs(factor) > Const.QL_Epsilon) { if (vTry >= values_[iNextHighest]) { double vSave = values_[iHighest]; factor = 0.5; vTry = extrapolate(ref P, iHighest, ref factor); if (vTry >= vSave && Math.Abs(factor) > Const.QL_Epsilon) { for (int i = 0; i <= n; i++) { if (i != iLowest) { #if QL_ARRAY_EXPRESSIONS vertices_[i] = 0.5 * (vertices_[i] + vertices_[iLowest]); #else vertices_[i] += vertices_[iLowest]; vertices_[i] *= 0.5; #endif values_[i] = P.value(vertices_[i]); } } } } } // If can't extrapolate given the constraints, exit if (Math.Abs(factor) <= Const.QL_Epsilon) { x_ = vertices_[iLowest]; double low = values_[iLowest]; P.setFunctionValue(low); P.setCurrentValue(x_); return EndCriteria.Type.StationaryFunctionValue; } } while (end == false); throw new ApplicationException("optimization failed: unexpected behaviour"); }
//! solve the optimization problem P public override EndCriteria.Type minimize(Problem P, EndCriteria endCriteria) { // Initializations double ftol = endCriteria.functionEpsilon(); int maxStationaryStateIterations_ = endCriteria.maxStationaryStateIterations(); EndCriteria.Type ecType = EndCriteria.Type.None; // reset end criteria P.reset(); // reset problem Vector x_ = P.currentValue(); // store the starting point int iterationNumber_ = 0; // stationaryStateIterationNumber_=0 lineSearch_.searchDirection = new Vector(x_.Count); // dimension line search bool done = false; // function and squared norm of gradient values; double fnew; double fold; double gold2; double c; double fdiff; double normdiff; // classical initial value for line-search step double t = 1.0; // Set gradient g at the size of the optimization problem search direction int sz = lineSearch_.searchDirection.Count; Vector g = new Vector(sz); Vector d = new Vector(sz); Vector sddiff = new Vector(sz); // Initialize cost function, gradient g and search direction P.setFunctionValue(P.valueAndGradient(g, x_)); P.setGradientNormValue(Vector.DotProduct(g, g)); lineSearch_.searchDirection = g * -1.0; // Loop over iterations do { // Linesearch t = lineSearch_.value(P, ref ecType, endCriteria, t); // don't throw: it can fail just because maxIterations exceeded //QL_REQUIRE(lineSearch_->succeed(), "line-search failed!"); if (lineSearch_.succeed()) { // Updates d = lineSearch_.searchDirection; // New point x_ = lineSearch_.lastX(); // New function value fold = P.functionValue(); P.setFunctionValue(lineSearch_.lastFunctionValue()); // New gradient and search direction vectors g = lineSearch_.lastGradient(); // orthogonalization coef gold2 = P.gradientNormValue(); P.setGradientNormValue(lineSearch_.lastGradientNorm2()); c = P.gradientNormValue() / gold2; // conjugate gradient search direction sddiff = ((g * -1.0) + c * d) - lineSearch_.searchDirection; normdiff = Math.Sqrt(Vector.DotProduct(sddiff, sddiff)); lineSearch_.searchDirection = (g * -1.0) + c * d; // 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 * Math.Abs(fnew - fold) / (Math.Abs(fnew) + Math.Abs(fold) + Double.Epsilon); if (fdiff < ftol || endCriteria.checkMaxIterations(iterationNumber_, ref ecType)) { endCriteria.checkStationaryFunctionValue(0.0, 0.0, ref maxStationaryStateIterations_, ref ecType); endCriteria.checkMaxIterations(iterationNumber_, ref ecType); return(ecType); } //done = endCriteria(iterationNumber_, // stationaryStateIterationNumber_, // true, //FIXME: it should be in the problem // fold, // std::sqrt(gold2), // P.functionValue(), // std::sqrt(P.gradientNormValue()), // ecType); P.setCurrentValue(x_); // update problem current value ++iterationNumber_; // Increase iteration number } else { done = true; } } while (!done); P.setCurrentValue(x_); return(ecType); }
//! solve the optimization problem P public override EndCriteria.Type minimize(Problem P, EndCriteria endCriteria) { // Initializations double ftol = endCriteria.functionEpsilon(); int maxStationaryStateIterations_ = endCriteria.maxStationaryStateIterations(); EndCriteria.Type ecType = EndCriteria.Type.None; // reset end criteria P.reset(); // reset problem Vector x_ = P.currentValue(); // store the starting point int iterationNumber_ =0; // stationaryStateIterationNumber_=0 lineSearch_.searchDirection = new Vector(x_.Count); // dimension line search bool done = false; // function and squared norm of gradient values; double fnew; double fold; double gold2; double c; double fdiff; double normdiff; // classical initial value for line-search step double t = 1.0; // Set gradient g at the size of the optimization problem search direction int sz = lineSearch_.searchDirection.Count; Vector g = new Vector(sz); Vector d = new Vector(sz); Vector sddiff = new Vector(sz); // Initialize cost function, gradient g and search direction P.setFunctionValue(P.valueAndGradient(g, x_)); P.setGradientNormValue(Vector.DotProduct(g, g)); lineSearch_.searchDirection = g * -1.0; // Loop over iterations do { // Linesearch t = lineSearch_.value(P, ref ecType, endCriteria, t); // don't throw: it can fail just because maxIterations exceeded //QL_REQUIRE(lineSearch_->succeed(), "line-search failed!"); if (lineSearch_.succeed()) { // Updates d = lineSearch_.searchDirection; // New point x_ = lineSearch_.lastX(); // New function value fold = P.functionValue(); P.setFunctionValue(lineSearch_.lastFunctionValue()); // New gradient and search direction vectors g = lineSearch_.lastGradient(); // orthogonalization coef gold2 = P.gradientNormValue(); P.setGradientNormValue(lineSearch_.lastGradientNorm2()); c = P.gradientNormValue() / gold2; // conjugate gradient search direction sddiff = ((g*-1.0) + c * d) - lineSearch_.searchDirection; normdiff = Math.Sqrt(Vector.DotProduct(sddiff, sddiff)); lineSearch_.searchDirection = (g*-1.0) + c * d; // 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 *Math.Abs(fnew-fold) / (Math.Abs(fnew) + Math.Abs(fold) + Double.Epsilon); if (fdiff < ftol || endCriteria.checkMaxIterations(iterationNumber_, ref ecType)) { endCriteria.checkStationaryFunctionValue(0.0, 0.0, ref maxStationaryStateIterations_, ref ecType); endCriteria.checkMaxIterations(iterationNumber_, ref ecType); return ecType; } //done = endCriteria(iterationNumber_, // stationaryStateIterationNumber_, // true, //FIXME: it should be in the problem // fold, // std::sqrt(gold2), // P.functionValue(), // std::sqrt(P.gradientNormValue()), // ecType); P.setCurrentValue(x_); // update problem current value ++iterationNumber_; // Increase iteration number } else { done =true; } } while (!done); P.setCurrentValue(x_); return ecType; }
public override EndCriteria.Type minimize(Problem P, EndCriteria endCriteria) { // Initializations double ftol = endCriteria.functionEpsilon(); int maxStationaryStateIterations_ = endCriteria.maxStationaryStateIterations(); EndCriteria.Type ecType = EndCriteria.Type.None; // reset end criteria P.reset(); // reset problem Vector x_ = P.currentValue(); // store the starting point int iterationNumber_ = 0; // dimension line search lineSearch_.searchDirection = new Vector(x_.size()); bool done = false; // function and squared norm of gradient values double fnew, fold, gold2; double fdiff; // classical initial value for line-search step double t = 1.0; // Set gradient g at the size of the optimization problem // search direction int sz = lineSearch_.searchDirection.size(); Vector prevGradient = new Vector(sz), d = new Vector(sz), sddiff = new Vector(sz), direction = new Vector(sz); // Initialize cost function, gradient prevGradient and search direction P.setFunctionValue(P.valueAndGradient(prevGradient, x_)); P.setGradientNormValue(Vector.DotProduct(prevGradient, prevGradient)); lineSearch_.searchDirection = prevGradient * -1; bool first_time = true; // Loop over iterations do { // Linesearch if (!first_time) { prevGradient = lineSearch_.lastGradient(); } t = (lineSearch_.value(P, ref ecType, endCriteria, t)); // don't throw: it can fail just because maxIterations exceeded 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 * Math.Abs(fnew - fold) / (Math.Abs(fnew) + Math.Abs(fold) + Const.QL_EPSILON); if (fdiff < ftol || endCriteria.checkMaxIterations(iterationNumber_, ref ecType)) { endCriteria.checkStationaryFunctionValue(0.0, 0.0, ref maxStationaryStateIterations_, ref ecType); endCriteria.checkMaxIterations(iterationNumber_, ref 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); }