summaryrefslogtreecommitdiff
path: root/src/main/java/org/apache/commons/math/optimization/direct/MultiDirectional.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/apache/commons/math/optimization/direct/MultiDirectional.java')
-rw-r--r--src/main/java/org/apache/commons/math/optimization/direct/MultiDirectional.java144
1 files changed, 144 insertions, 0 deletions
diff --git a/src/main/java/org/apache/commons/math/optimization/direct/MultiDirectional.java b/src/main/java/org/apache/commons/math/optimization/direct/MultiDirectional.java
new file mode 100644
index 0000000..ea8816b
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/direct/MultiDirectional.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.math.optimization.direct;
+
+import java.util.Comparator;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.optimization.OptimizationException;
+import org.apache.commons.math.optimization.RealConvergenceChecker;
+import org.apache.commons.math.optimization.RealPointValuePair;
+
+/**
+ * This class implements the multi-directional direct search method.
+ *
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ * @see NelderMead
+ * @since 1.2
+ */
+public class MultiDirectional extends DirectSearchOptimizer {
+
+ /** Expansion coefficient. */
+ private final double khi;
+
+ /** Contraction coefficient. */
+ private final double gamma;
+
+ /** Build a multi-directional optimizer with default coefficients.
+ * <p>The default values are 2.0 for khi and 0.5 for gamma.</p>
+ */
+ public MultiDirectional() {
+ this.khi = 2.0;
+ this.gamma = 0.5;
+ }
+
+ /** Build a multi-directional optimizer with specified coefficients.
+ * @param khi expansion coefficient
+ * @param gamma contraction coefficient
+ */
+ public MultiDirectional(final double khi, final double gamma) {
+ this.khi = khi;
+ this.gamma = gamma;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void iterateSimplex(final Comparator<RealPointValuePair> comparator)
+ throws FunctionEvaluationException, OptimizationException, IllegalArgumentException {
+
+ final RealConvergenceChecker checker = getConvergenceChecker();
+ while (true) {
+
+ incrementIterationsCounter();
+
+ // save the original vertex
+ final RealPointValuePair[] original = simplex;
+ final RealPointValuePair best = original[0];
+
+ // perform a reflection step
+ final RealPointValuePair reflected = evaluateNewSimplex(original, 1.0, comparator);
+ if (comparator.compare(reflected, best) < 0) {
+
+ // compute the expanded simplex
+ final RealPointValuePair[] reflectedSimplex = simplex;
+ final RealPointValuePair expanded = evaluateNewSimplex(original, khi, comparator);
+ if (comparator.compare(reflected, expanded) <= 0) {
+ // accept the reflected simplex
+ simplex = reflectedSimplex;
+ }
+
+ return;
+
+ }
+
+ // compute the contracted simplex
+ final RealPointValuePair contracted = evaluateNewSimplex(original, gamma, comparator);
+ if (comparator.compare(contracted, best) < 0) {
+ // accept the contracted simplex
+ return;
+ }
+
+ // check convergence
+ final int iter = getIterations();
+ boolean converged = true;
+ for (int i = 0; i < simplex.length; ++i) {
+ converged &= checker.converged(iter, original[i], simplex[i]);
+ }
+ if (converged) {
+ return;
+ }
+
+ }
+
+ }
+
+ /** Compute and evaluate a new simplex.
+ * @param original original simplex (to be preserved)
+ * @param coeff linear coefficient
+ * @param comparator comparator to use to sort simplex vertices from best to poorest
+ * @return best point in the transformed simplex
+ * @exception FunctionEvaluationException if the function cannot be evaluated at some point
+ * @exception OptimizationException if the maximal number of evaluations is exceeded
+ */
+ private RealPointValuePair evaluateNewSimplex(final RealPointValuePair[] original,
+ final double coeff,
+ final Comparator<RealPointValuePair> comparator)
+ throws FunctionEvaluationException, OptimizationException {
+
+ final double[] xSmallest = original[0].getPointRef();
+ final int n = xSmallest.length;
+
+ // create the linearly transformed simplex
+ simplex = new RealPointValuePair[n + 1];
+ simplex[0] = original[0];
+ for (int i = 1; i <= n; ++i) {
+ final double[] xOriginal = original[i].getPointRef();
+ final double[] xTransformed = new double[n];
+ for (int j = 0; j < n; ++j) {
+ xTransformed[j] = xSmallest[j] + coeff * (xSmallest[j] - xOriginal[j]);
+ }
+ simplex[i] = new RealPointValuePair(xTransformed, Double.NaN, false);
+ }
+
+ // evaluate it
+ evaluateSimplex(comparator);
+ return simplex[0];
+
+ }
+
+}