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 // 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.IsEqual(-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); Utils.QL_FAIL("optimization failed: unexpected behaviour"); return(0); }
public override EndCriteria.Type minimize(Problem P, EndCriteria endCriteria) { int stationaryStateIterations_ = 0; EndCriteria.Type ecType = EndCriteria.Type.None; P.reset(); Vector x = P.currentValue(); iteration_ = 0; n_ = x.size(); ptry_ = new Vector(n_, 0.0); // build vertices vertices_ = new InitializedList <Vector>(n_ + 1, x); for (i_ = 0; i_ < n_; i_++) { Vector direction = new Vector(n_, 0.0); direction[i_] = 1.0; Vector tmp = vertices_[i_ + 1]; P.constraint().update(ref tmp, direction, lambda_); vertices_[i_ + 1] = tmp; } values_ = new Vector(n_ + 1, 0.0); for (i_ = 0; i_ <= n_; i_++) { if (!P.constraint().test(vertices_[i_])) { values_[i_] = Double.MaxValue; } else { values_[i_] = P.value(vertices_[i_]); } if (Double.IsNaN(ytry_)) { // handle NAN values_[i_] = Double.MaxValue; } } // minimize T_ = T0_; yb_ = Double.MaxValue; pb_ = new Vector(n_, 0.0); do { iterationT_ = iteration_; do { sum_ = new Vector(n_, 0.0); for (i_ = 0; i_ <= n_; i_++) { sum_ += vertices_[i_]; } tt_ = -T_; ilo_ = 0; ihi_ = 1; ynhi_ = values_[0] + tt_ * Math.Log(rng_.next().value); ylo_ = ynhi_; yhi_ = values_[1] + tt_ * Math.Log(rng_.next().value); if (ylo_ > yhi_) { ihi_ = 0; ilo_ = 1; ynhi_ = yhi_; yhi_ = ylo_; ylo_ = ynhi_; } for (i_ = 2; i_ < n_ + 1; i_++) { yt_ = values_[i_] + tt_ * Math.Log(rng_.next().value); if (yt_ <= ylo_) { ilo_ = i_; ylo_ = yt_; } if (yt_ > yhi_) { ynhi_ = yhi_; ihi_ = i_; yhi_ = yt_; } else { if (yt_ > ynhi_) { ynhi_ = yt_; } } } // GSL end criterion in x (cf. above) if (endCriteria.checkStationaryPoint(simplexSize(), 0.0, ref stationaryStateIterations_, ref ecType) || endCriteria.checkMaxIterations(iteration_, ref ecType)) { // no matter what, we return the best ever point ! P.setCurrentValue(pb_); P.setFunctionValue(yb_); return(ecType); } iteration_ += 2; amotsa(P, -1.0); if (ytry_ <= ylo_) { amotsa(P, 2.0); } else { if (ytry_ >= ynhi_) { ysave_ = yhi_; amotsa(P, 0.5); if (ytry_ >= ysave_) { for (i_ = 0; i_ < n_ + 1; i_++) { if (i_ != ilo_) { for (j_ = 0; j_ < n_; j_++) { sum_[j_] = 0.5 * (vertices_[i_][j_] + vertices_[ilo_][j_]); vertices_[i_][j_] = sum_[j_]; } values_[i_] = P.value(sum_); } } iteration_ += n_; for (i_ = 0; i_ < n_; i_++) { sum_[i_] = 0.0; } for (i_ = 0; i_ <= n_; i_++) { sum_ += vertices_[i_]; } } } else { iteration_ += 1; } } }while (iteration_ < iterationT_ + (scheme_ == Scheme.ConstantFactor ? m_ : 1)); switch (scheme_) { case Scheme.ConstantFactor: T_ *= (1.0 - epsilon_); break; case Scheme.ConstantBudget: if (iteration_ <= K_) { T_ = T0_ * Math.Pow(1.0 - Convert.ToDouble(iteration_) / Convert.ToDouble(K_), alpha_); } else { T_ = 0.0; } break; } }while (true); }