summaryrefslogtreecommitdiff
path: root/src/main/java/org/apache/commons/math/optimization/MultiStartDifferentiableMultivariateRealOptimizer.java
diff options
context:
space:
mode:
authorRaymond <siuchow@google.com>2015-04-02 10:43:13 -0700
committerRaymond <siuchow@google.com>2015-04-02 10:43:13 -0700
commitdee0849a9704d532af0b550146cbafbaa6ee1d19 (patch)
tree8ccce3a046c214fb609977b7fc53c40cef7f9ea5 /src/main/java/org/apache/commons/math/optimization/MultiStartDifferentiableMultivariateRealOptimizer.java
parent55b0a5efc929efa9615babd3e760547f94e3518e (diff)
downloadapache-commons-math-dee0849a9704d532af0b550146cbafbaa6ee1d19.tar.gz
third party library: apache-commons-mathandroid-cts-6.0_r9android-cts-6.0_r8android-cts-6.0_r7android-cts-6.0_r6android-cts-6.0_r5android-cts-6.0_r4android-cts-6.0_r32android-cts-6.0_r31android-cts-6.0_r30android-cts-6.0_r3android-cts-6.0_r29android-cts-6.0_r28android-cts-6.0_r27android-cts-6.0_r26android-cts-6.0_r25android-cts-6.0_r24android-cts-6.0_r23android-cts-6.0_r22android-cts-6.0_r21android-cts-6.0_r20android-cts-6.0_r2android-cts-6.0_r19android-cts-6.0_r18android-cts-6.0_r17android-cts-6.0_r16android-cts-6.0_r15android-cts-6.0_r14android-cts-6.0_r13android-cts-6.0_r12android-cts-6.0_r1android-6.0.1_r9android-6.0.1_r81android-6.0.1_r80android-6.0.1_r8android-6.0.1_r79android-6.0.1_r78android-6.0.1_r77android-6.0.1_r74android-6.0.1_r73android-6.0.1_r72android-6.0.1_r70android-6.0.1_r7android-6.0.1_r69android-6.0.1_r68android-6.0.1_r67android-6.0.1_r66android-6.0.1_r65android-6.0.1_r63android-6.0.1_r62android-6.0.1_r61android-6.0.1_r60android-6.0.1_r59android-6.0.1_r58android-6.0.1_r57android-6.0.1_r56android-6.0.1_r55android-6.0.1_r54android-6.0.1_r53android-6.0.1_r52android-6.0.1_r51android-6.0.1_r50android-6.0.1_r5android-6.0.1_r49android-6.0.1_r48android-6.0.1_r47android-6.0.1_r46android-6.0.1_r45android-6.0.1_r43android-6.0.1_r42android-6.0.1_r41android-6.0.1_r40android-6.0.1_r4android-6.0.1_r33android-6.0.1_r32android-6.0.1_r31android-6.0.1_r30android-6.0.1_r3android-6.0.1_r28android-6.0.1_r27android-6.0.1_r26android-6.0.1_r25android-6.0.1_r24android-6.0.1_r22android-6.0.1_r21android-6.0.1_r20android-6.0.1_r18android-6.0.1_r17android-6.0.1_r16android-6.0.1_r13android-6.0.1_r12android-6.0.1_r11android-6.0.1_r10android-6.0.1_r1android-6.0.0_r7android-6.0.0_r6android-6.0.0_r5android-6.0.0_r41android-6.0.0_r4android-6.0.0_r3android-6.0.0_r26android-6.0.0_r25android-6.0.0_r24android-6.0.0_r23android-6.0.0_r2android-6.0.0_r13android-6.0.0_r12android-6.0.0_r11android-6.0.0_r1marshmallow-releasemarshmallow-mr3-releasemarshmallow-mr2-releasemarshmallow-mr1-releasemarshmallow-mr1-devmarshmallow-dr1.6-releasemarshmallow-dr1.5-releasemarshmallow-dr1.5-devmarshmallow-dr-releasemarshmallow-dr-dragon-releasemarshmallow-dr-devmarshmallow-devmarshmallow-cts-release
Change-Id: I52a325624a7f0dd652b362a9840626d6d9f3c42b
Diffstat (limited to 'src/main/java/org/apache/commons/math/optimization/MultiStartDifferentiableMultivariateRealOptimizer.java')
-rw-r--r--src/main/java/org/apache/commons/math/optimization/MultiStartDifferentiableMultivariateRealOptimizer.java228
1 files changed, 228 insertions, 0 deletions
diff --git a/src/main/java/org/apache/commons/math/optimization/MultiStartDifferentiableMultivariateRealOptimizer.java b/src/main/java/org/apache/commons/math/optimization/MultiStartDifferentiableMultivariateRealOptimizer.java
new file mode 100644
index 0000000..9cde37b
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/MultiStartDifferentiableMultivariateRealOptimizer.java
@@ -0,0 +1,228 @@
+/*
+ * 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;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.analysis.DifferentiableMultivariateRealFunction;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.random.RandomVectorGenerator;
+
+/**
+ * Special implementation of the {@link DifferentiableMultivariateRealOptimizer} interface adding
+ * multi-start features to an existing optimizer.
+ * <p>
+ * This class wraps a classical optimizer to use it several times in
+ * turn with different starting points in order to avoid being trapped
+ * into a local extremum when looking for a global one.
+ * </p>
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.0
+ */
+public class MultiStartDifferentiableMultivariateRealOptimizer
+ implements DifferentiableMultivariateRealOptimizer {
+
+ /** Underlying classical optimizer. */
+ private final DifferentiableMultivariateRealOptimizer optimizer;
+
+ /** Maximal number of iterations allowed. */
+ private int maxIterations;
+
+ /** Number of iterations already performed for all starts. */
+ private int totalIterations;
+
+ /** Maximal number of evaluations allowed. */
+ private int maxEvaluations;
+
+ /** Number of evaluations already performed for all starts. */
+ private int totalEvaluations;
+
+ /** Number of gradient evaluations already performed for all starts. */
+ private int totalGradientEvaluations;
+
+ /** Number of starts to go. */
+ private int starts;
+
+ /** Random generator for multi-start. */
+ private RandomVectorGenerator generator;
+
+ /** Found optima. */
+ private RealPointValuePair[] optima;
+
+ /**
+ * Create a multi-start optimizer from a single-start optimizer
+ * @param optimizer single-start optimizer to wrap
+ * @param starts number of starts to perform (including the
+ * first one), multi-start is disabled if value is less than or
+ * equal to 1
+ * @param generator random vector generator to use for restarts
+ */
+ public MultiStartDifferentiableMultivariateRealOptimizer(final DifferentiableMultivariateRealOptimizer optimizer,
+ final int starts,
+ final RandomVectorGenerator generator) {
+ this.optimizer = optimizer;
+ this.totalIterations = 0;
+ this.totalEvaluations = 0;
+ this.totalGradientEvaluations = 0;
+ this.starts = starts;
+ this.generator = generator;
+ this.optima = null;
+ setMaxIterations(Integer.MAX_VALUE);
+ setMaxEvaluations(Integer.MAX_VALUE);
+ }
+
+ /** Get all the optima found during the last call to {@link
+ * #optimize(DifferentiableMultivariateRealFunction, GoalType, double[])
+ * optimize}.
+ * <p>The optimizer stores all the optima found during a set of
+ * restarts. The {@link #optimize(DifferentiableMultivariateRealFunction,
+ * GoalType, double[]) optimize} method returns the best point only. This
+ * method returns all the points found at the end of each starts,
+ * including the best one already returned by the {@link
+ * #optimize(DifferentiableMultivariateRealFunction, GoalType, double[])
+ * optimize} method.
+ * </p>
+ * <p>
+ * The returned array as one element for each start as specified
+ * in the constructor. It is ordered with the results from the
+ * runs that did converge first, sorted from best to worst
+ * objective value (i.e in ascending order if minimizing and in
+ * descending order if maximizing), followed by and null elements
+ * corresponding to the runs that did not converge. This means all
+ * elements will be null if the {@link #optimize(DifferentiableMultivariateRealFunction,
+ * GoalType, double[]) optimize} method did throw a {@link
+ * org.apache.commons.math.ConvergenceException ConvergenceException}).
+ * This also means that if the first element is non null, it is the best
+ * point found across all starts.</p>
+ * @return array containing the optima
+ * @exception IllegalStateException if {@link #optimize(DifferentiableMultivariateRealFunction,
+ * GoalType, double[]) optimize} has not been called
+ */
+ public RealPointValuePair[] getOptima() throws IllegalStateException {
+ if (optima == null) {
+ throw MathRuntimeException.createIllegalStateException(LocalizedFormats.NO_OPTIMUM_COMPUTED_YET);
+ }
+ return optima.clone();
+ }
+
+ /** {@inheritDoc} */
+ public void setMaxIterations(int maxIterations) {
+ this.maxIterations = maxIterations;
+ }
+
+ /** {@inheritDoc} */
+ public int getMaxIterations() {
+ return maxIterations;
+ }
+
+ /** {@inheritDoc} */
+ public int getIterations() {
+ return totalIterations;
+ }
+
+ /** {@inheritDoc} */
+ public void setMaxEvaluations(int maxEvaluations) {
+ this.maxEvaluations = maxEvaluations;
+ }
+
+ /** {@inheritDoc} */
+ public int getMaxEvaluations() {
+ return maxEvaluations;
+ }
+
+ /** {@inheritDoc} */
+ public int getEvaluations() {
+ return totalEvaluations;
+ }
+
+ /** {@inheritDoc} */
+ public int getGradientEvaluations() {
+ return totalGradientEvaluations;
+ }
+
+ /** {@inheritDoc} */
+ public void setConvergenceChecker(RealConvergenceChecker checker) {
+ optimizer.setConvergenceChecker(checker);
+ }
+
+ /** {@inheritDoc} */
+ public RealConvergenceChecker getConvergenceChecker() {
+ return optimizer.getConvergenceChecker();
+ }
+
+ /** {@inheritDoc} */
+ public RealPointValuePair optimize(final DifferentiableMultivariateRealFunction f,
+ final GoalType goalType,
+ double[] startPoint)
+ throws FunctionEvaluationException, OptimizationException, FunctionEvaluationException {
+
+ optima = new RealPointValuePair[starts];
+ totalIterations = 0;
+ totalEvaluations = 0;
+ totalGradientEvaluations = 0;
+
+ // multi-start loop
+ for (int i = 0; i < starts; ++i) {
+
+ try {
+ optimizer.setMaxIterations(maxIterations - totalIterations);
+ optimizer.setMaxEvaluations(maxEvaluations - totalEvaluations);
+ optima[i] = optimizer.optimize(f, goalType,
+ (i == 0) ? startPoint : generator.nextVector());
+ } catch (FunctionEvaluationException fee) {
+ optima[i] = null;
+ } catch (OptimizationException oe) {
+ optima[i] = null;
+ }
+
+ totalIterations += optimizer.getIterations();
+ totalEvaluations += optimizer.getEvaluations();
+ totalGradientEvaluations += optimizer.getGradientEvaluations();
+
+ }
+
+ // sort the optima from best to worst, followed by null elements
+ Arrays.sort(optima, new Comparator<RealPointValuePair>() {
+ public int compare(final RealPointValuePair o1, final RealPointValuePair o2) {
+ if (o1 == null) {
+ return (o2 == null) ? 0 : +1;
+ } else if (o2 == null) {
+ return -1;
+ }
+ final double v1 = o1.getValue();
+ final double v2 = o2.getValue();
+ return (goalType == GoalType.MINIMIZE) ?
+ Double.compare(v1, v2) : Double.compare(v2, v1);
+ }
+ });
+
+ if (optima[0] == null) {
+ throw new OptimizationException(
+ LocalizedFormats.NO_CONVERGENCE_WITH_ANY_START_POINT,
+ starts);
+ }
+
+ // return the found point given the best objective function value
+ return optima[0];
+
+ }
+
+}