/** {@inheritDoc} */ @Override protected PointValuePair doOptimize() { if (simplex == null) { throw new NullArgumentException(); } // Indirect call to "computeObjectiveValue" in order to update the // evaluations counter. final MultivariateFunction evalFunc = new MultivariateFunction() { public double value(double[] point) { return computeObjectiveValue(point); } }; final boolean isMinim = getGoalType() == GoalType.MINIMIZE; final Comparator<PointValuePair> comparator = new Comparator<PointValuePair>() { public int compare(final PointValuePair o1, final PointValuePair o2) { final double v1 = o1.getValue(); final double v2 = o2.getValue(); return isMinim ? Double.compare(v1, v2) : Double.compare(v2, v1); } }; // Initialize search. simplex.build(getStartPoint()); simplex.evaluate(evalFunc, comparator); PointValuePair[] previous = null; int iteration = 0; final ConvergenceChecker<PointValuePair> checker = getConvergenceChecker(); while (true) { if (iteration > 0) { boolean converged = true; for (int i = 0; i < simplex.getSize(); i++) { PointValuePair prev = previous[i]; converged = converged && checker.converged(iteration, prev, simplex.getPoint(i)); } if (converged) { // We have found an optimum. return simplex.getPoint(0); } } // We still need to search. previous = simplex.getPoints(); simplex.iterate(evalFunc, comparator); ++iteration; } }
/** {@inheritDoc} */ @Override protected PointValuePair doOptimize() { final GoalType goal = getGoalType(); final double[] guess = getStartPoint(); final int n = guess.length; final double[][] direc = new double[n][n]; for (int i = 0; i < n; i++) { direc[i][i] = 1; } final ConvergenceChecker<PointValuePair> checker = getConvergenceChecker(); double[] x = guess; double fVal = computeObjectiveValue(x); double[] x1 = x.clone(); int iter = 0; while (true) { ++iter; double fX = fVal; double fX2 = 0; double delta = 0; int bigInd = 0; double alphaMin = 0; for (int i = 0; i < n; i++) { final double[] d = MathArrays.copyOf(direc[i]); fX2 = fVal; final UnivariatePointValuePair optimum = line.search(x, d); fVal = optimum.getValue(); alphaMin = optimum.getPoint(); final double[][] result = newPointAndDirection(x, d, alphaMin); x = result[0]; if ((fX2 - fVal) > delta) { delta = fX2 - fVal; bigInd = i; } } // Default convergence check. boolean stop = 2 * (fX - fVal) <= (relativeThreshold * (FastMath.abs(fX) + FastMath.abs(fVal)) + absoluteThreshold); final PointValuePair previous = new PointValuePair(x1, fX); final PointValuePair current = new PointValuePair(x, fVal); if (!stop) { // User-defined stopping criteria. if (checker != null) { stop = checker.converged(iter, previous, current); } } if (stop) { if (goal == GoalType.MINIMIZE) { return (fVal < fX) ? current : previous; } else { return (fVal > fX) ? current : previous; } } final double[] d = new double[n]; final double[] x2 = new double[n]; for (int i = 0; i < n; i++) { d[i] = x[i] - x1[i]; x2[i] = 2 * x[i] - x1[i]; } x1 = x.clone(); fX2 = computeObjectiveValue(x2); if (fX > fX2) { double t = 2 * (fX + fX2 - 2 * fVal); double temp = fX - fVal - delta; t *= temp * temp; temp = fX - fX2; t -= delta * temp * temp; if (t < 0.0) { final UnivariatePointValuePair optimum = line.search(x, d); fVal = optimum.getValue(); alphaMin = optimum.getPoint(); final double[][] result = newPointAndDirection(x, d, alphaMin); x = result[0]; final int lastInd = n - 1; direc[bigInd] = direc[lastInd]; direc[lastInd] = result[1]; } } } }
/* 56: */ /* 57: */ protected PointValuePair doOptimize() /* 58: */ { /* 59:147 */ ConvergenceChecker<PointValuePair> checker = getConvergenceChecker(); /* 60:148 */ this.point = getStartPoint(); /* 61:149 */ GoalType goal = getGoalType(); /* 62:150 */ int n = this.point.length; /* 63:151 */ double[] r = computeObjectiveGradient(this.point); /* 64:152 */ if (goal == GoalType.MINIMIZE) { /* 65:153 */ for (int i = 0; i < n; i++) { /* 66:154 */ r[i] = (-r[i]); /* 67: */ } /* 68: */ } /* 69:159 */ double[] steepestDescent = this.preconditioner.precondition(this.point, r); /* 70:160 */ double[] searchDirection = (double[]) steepestDescent.clone(); /* 71: */ /* 72:162 */ double delta = 0.0D; /* 73:163 */ for (int i = 0; i < n; i++) { /* 74:164 */ delta += r[i] * searchDirection[i]; /* 75: */ } /* 76:167 */ PointValuePair current = null; /* 77:168 */ int iter = 0; /* 78:169 */ int maxEval = getMaxEvaluations(); /* 79: */ for (; ; ) /* 80: */ { /* 81:171 */ iter++; /* 82: */ /* 83:173 */ double objective = computeObjectiveValue(this.point); /* 84:174 */ PointValuePair previous = current; /* 85:175 */ current = new PointValuePair(this.point, objective); /* 86:176 */ if ((previous != null) && /* 87:177 */ (checker.converged(iter, previous, current))) { /* 88:179 */ return current; /* 89: */ } /* 90:184 */ UnivariateFunction lsf = new LineSearchFunction(searchDirection); /* 91:185 */ double uB = findUpperBound(lsf, 0.0D, this.initialStep); /* 92: */ /* 93: */ /* 94: */ /* 95:189 */ double step = this.solver.solve(maxEval, lsf, 0.0D, uB, 1.E-015D); /* 96:190 */ maxEval -= this.solver.getEvaluations(); /* 97:193 */ for (int i = 0; i < this.point.length; i++) { /* 98:194 */ this.point[i] += step * searchDirection[i]; /* 99: */ } /* 100:197 */ r = computeObjectiveGradient(this.point); /* 101:198 */ if (goal == GoalType.MINIMIZE) { /* 102:199 */ for (int i = 0; i < n; i++) { /* 103:200 */ r[i] = (-r[i]); /* 104: */ } /* 105: */ } /* 106:205 */ double deltaOld = delta; /* 107:206 */ double[] newSteepestDescent = this.preconditioner.precondition(this.point, r); /* 108:207 */ delta = 0.0D; /* 109:208 */ for (int i = 0; i < n; i++) { /* 110:209 */ delta += r[i] * newSteepestDescent[i]; /* 111: */ } /* 112: */ double beta; /* 113: */ /* 114:213 */ if (this.updateFormula == ConjugateGradientFormula.FLETCHER_REEVES) /* 115: */ { /* 116:214 */ beta = delta / deltaOld; /* 117: */ } /* 118: */ else /* 119: */ { /* 120:216 */ double deltaMid = 0.0D; /* 121:217 */ for (int i = 0; i < r.length; i++) { /* 122:218 */ deltaMid += r[i] * steepestDescent[i]; /* 123: */ } /* 124:220 */ beta = (delta - deltaMid) / deltaOld; /* 125: */ } /* 126:222 */ steepestDescent = newSteepestDescent; /* 127:225 */ if ((iter % n == 0) || (beta < 0.0D)) { /* 128:228 */ searchDirection = (double[]) steepestDescent.clone(); /* 129: */ } else { /* 130:231 */ for (int i = 0; i < n; i++) { /* 131:232 */ steepestDescent[i] += beta * searchDirection[i]; /* 132: */ } /* 133: */ } /* 134: */ } /* 135: */ }