You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by er...@apache.org on 2012/10/15 14:16:53 UTC

svn commit: r1398263 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math3/optimization/ main/java/org/apache/commons/math3/optimization/direct/ test/java/org/apache/commons/math3/optimization/direct/

Author: erans
Date: Mon Oct 15 12:16:53 2012
New Revision: 1398263

URL: http://svn.apache.org/viewvc?rev=1398263&view=rev
Log:
MATH-874
Simple bounds expressed as a kind of "0ptimizationData".
The specification of simple bounds is handled in "BaseAbstractMultivariateOptimizer";
hence "BaseAbstractMultivariateSimpleBoundsOptimizer" is deprecated.

Added:
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/SimpleBounds.java   (with props)
Modified:
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/direct/BaseAbstractMultivariateOptimizer.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/direct/BaseAbstractMultivariateSimpleBoundsOptimizer.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/direct/BOBYQAOptimizerTest.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/direct/CMAESOptimizerTest.java

Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/SimpleBounds.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/SimpleBounds.java?rev=1398263&view=auto
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/SimpleBounds.java (added)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/SimpleBounds.java Mon Oct 15 12:16:53 2012
@@ -0,0 +1,62 @@
+/*
+ * 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.math3.optimization;
+
+/**
+ * Simple optimization constraints: lower and upper bounds.
+ * The valid range of the parameters is an interval that can be infinite
+ * (in one or both directions).
+ * <br/>
+ * Immutable class.
+ *
+ * @version $Id$
+ * @since 3.1
+ */
+public class SimpleBounds implements OptimizationData {
+    /** Lower bounds. */
+    private final double[] lower;
+    /** Upper bounds. */
+    private final double[] upper;
+
+    /**
+     * @param lB Lower bounds.
+     * @param uB Upper bounds.
+     */
+    public SimpleBounds(double[] lB,
+                        double[] uB) {
+        lower = lB.clone();
+        upper = uB.clone();
+    }
+
+    /**
+     * Gets the lower bounds.
+     *
+     * @return the initial guess.
+     */
+    public double[] getLower() {
+        return lower.clone();
+    }
+    /**
+     * Gets the lower bounds.
+     *
+     * @return the initial guess.
+     */
+    public double[] getUpper() {
+        return upper.clone();
+    }
+}

Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/SimpleBounds.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/direct/BaseAbstractMultivariateOptimizer.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/direct/BaseAbstractMultivariateOptimizer.java?rev=1398263&r1=1398262&r2=1398263&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/direct/BaseAbstractMultivariateOptimizer.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/direct/BaseAbstractMultivariateOptimizer.java Mon Oct 15 12:16:53 2012
@@ -25,14 +25,18 @@ import org.apache.commons.math3.optimiza
 import org.apache.commons.math3.optimization.OptimizationData;
 import org.apache.commons.math3.optimization.GoalType;
 import org.apache.commons.math3.optimization.InitialGuess;
+import org.apache.commons.math3.optimization.SimpleBounds;
 import org.apache.commons.math3.optimization.ConvergenceChecker;
 import org.apache.commons.math3.optimization.PointValuePair;
 import org.apache.commons.math3.optimization.SimpleValueChecker;
+import org.apache.commons.math3.exception.DimensionMismatchException;
+import org.apache.commons.math3.exception.NumberIsTooSmallException;
+import org.apache.commons.math3.exception.NumberIsTooLargeException;
 
 /**
  * Base class for implementing optimizers for multivariate scalar functions.
- * This base class handles the boiler-plate methods associated to thresholds
- * settings, iterations and evaluations counting.
+ * This base class handles the boiler-plate methods associated to thresholds,
+ * evaluations counting, initial guess and simple bounds settings.
  *
  * @param <FUNC> Type of the objective function to be optimized.
  *
@@ -49,6 +53,10 @@ public abstract class BaseAbstractMultiv
     private GoalType goal;
     /** Initial guess. */
     private double[] start;
+    /** Lower bounds. */
+    private double[] lowerBound;
+    /** Upper bounds. */
+    private double[] upperBound;
     /** Objective function. */
     private MultivariateFunction function;
 
@@ -121,6 +129,7 @@ public abstract class BaseAbstractMultiv
      * @param optData Optimization data. The following data will be looked for:
      * <ul>
      *  <li>{@link InitialGuess}</li>
+     *  <li>{@link SimpleBounds}</li>
      * </ul>
      * @return the point/value pair giving the optimal value of the objective
      * function.
@@ -167,6 +176,7 @@ public abstract class BaseAbstractMultiv
      * @param optData Optimization data. The following data will be looked for:
      * <ul>
      *  <li>{@link InitialGuess}</li>
+     *  <li>{@link SimpleBounds}</li>
      * </ul>
      * @return the point/value pair giving the optimal value of the objective
      * function.
@@ -178,12 +188,15 @@ public abstract class BaseAbstractMultiv
                                               GoalType goalType,
                                               OptimizationData... optData)
         throws TooManyEvaluationsException {
+        // Set internal state.
         evaluations.setMaximalCount(maxEval);
         evaluations.resetCount();
         function = f;
         goal = goalType;
+        // Retrieve other settings.
         parseOptimizationData(optData);
-
+        // Check input consistency.
+        checkParameters();
         // Perform computation.
         return doOptimize();
     }
@@ -195,6 +208,7 @@ public abstract class BaseAbstractMultiv
      * @param optData Optimization data. The following data will be looked for:
      * <ul>
      *  <li>{@link InitialGuess}</li>
+     *  <li>{@link SimpleBounds}</li>
      * </ul>
      */
     private void parseOptimizationData(OptimizationData... optData) {
@@ -205,6 +219,12 @@ public abstract class BaseAbstractMultiv
                 start = ((InitialGuess) data).getInitialGuess();
                 continue;
             }
+            if (data instanceof SimpleBounds) {
+                final SimpleBounds bounds = (SimpleBounds) data;
+                lowerBound = bounds.getLower();
+                upperBound = bounds.getUpper();
+                continue;
+            }
         }
     }
 
@@ -219,7 +239,19 @@ public abstract class BaseAbstractMultiv
      * @return the initial guess.
      */
     public double[] getStartPoint() {
-        return start.clone();
+        return start == null ? null : start.clone();
+    }
+    /**
+     * @return the lower bounds.
+     */
+    public double[] getLowerBound() {
+        return lowerBound == null ? null : lowerBound.clone();
+    }
+    /**
+     * @return the upper bounds.
+     */
+    public double[] getUpperBound() {
+        return upperBound == null ? null : upperBound.clone();
     }
 
     /**
@@ -229,4 +261,52 @@ public abstract class BaseAbstractMultiv
      * objective function.
      */
     protected abstract PointValuePair doOptimize();
+
+    /**
+     * Check parameters consistency.
+     */
+    private void checkParameters() {
+        if (start != null) {
+            final int dim = start.length;
+            if (lowerBound != null) {
+                if (lowerBound.length != dim) {
+                    throw new DimensionMismatchException(lowerBound.length, dim);
+                }
+                for (int i = 0; i < dim; i++) {
+                    final double v = start[i];
+                    final double lo = lowerBound[i];
+                    if (v < lo) {
+                        throw new NumberIsTooSmallException(v, lo, true);
+                    }
+                }
+            }
+            if (upperBound != null) {
+                if (upperBound.length != dim) {
+                    throw new DimensionMismatchException(upperBound.length, dim);
+                }
+                for (int i = 0; i < dim; i++) {
+                    final double v = start[i];
+                    final double hi = upperBound[i];
+                    if (v > hi) {
+                        throw new NumberIsTooLargeException(v, hi, true);
+                    }
+                }
+            }
+
+            // If the bounds were not specified, the allowed interval is
+            // assumed to be [-inf, +inf].
+            if (lowerBound == null) {
+                lowerBound = new double[dim];
+                for (int i = 0; i < dim; i++) {
+                    lowerBound[i] = Double.NEGATIVE_INFINITY;
+                }
+            }
+            if (upperBound == null) {
+                upperBound = new double[dim];
+                for (int i = 0; i < dim; i++) {
+                    upperBound[i] = Double.POSITIVE_INFINITY;
+                }
+            }
+        }
+    }
 }

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/direct/BaseAbstractMultivariateSimpleBoundsOptimizer.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/direct/BaseAbstractMultivariateSimpleBoundsOptimizer.java?rev=1398263&r1=1398262&r2=1398263&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/direct/BaseAbstractMultivariateSimpleBoundsOptimizer.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/direct/BaseAbstractMultivariateSimpleBoundsOptimizer.java Mon Oct 15 12:16:53 2012
@@ -21,11 +21,10 @@ import org.apache.commons.math3.analysis
 import org.apache.commons.math3.optimization.BaseMultivariateOptimizer;
 import org.apache.commons.math3.optimization.BaseMultivariateSimpleBoundsOptimizer;
 import org.apache.commons.math3.optimization.GoalType;
+import org.apache.commons.math3.optimization.InitialGuess;
+import org.apache.commons.math3.optimization.SimpleBounds;
 import org.apache.commons.math3.optimization.PointValuePair;
 import org.apache.commons.math3.optimization.ConvergenceChecker;
-import org.apache.commons.math3.exception.DimensionMismatchException;
-import org.apache.commons.math3.exception.NumberIsTooSmallException;
-import org.apache.commons.math3.exception.NumberIsTooLargeException;
 
 /**
  * Base class for implementing optimizers for multivariate scalar functions,
@@ -38,16 +37,14 @@ import org.apache.commons.math3.exceptio
  *
  * @version $Id$
  * @since 3.0
+ * @deprecated As of 3.1 since the {@link BaseAbstractMultivariateSimpleBoundsOptimizer
+ * base class} contains similar functionality.
  */
+@Deprecated
 public abstract class BaseAbstractMultivariateSimpleBoundsOptimizer<FUNC extends MultivariateFunction>
     extends BaseAbstractMultivariateOptimizer<FUNC>
     implements BaseMultivariateOptimizer<FUNC>,
                BaseMultivariateSimpleBoundsOptimizer<FUNC> {
-    /** Lower bounds. */
-    private double[] lowerBound;
-    /** Upper bounds. */
-    private double[] upperBound;
-
     /**
      * Simple constructor with default settings.
      * The convergence checker is set to a
@@ -70,73 +67,30 @@ public abstract class BaseAbstractMultiv
      * @return the lower bounds.
      */
     public double[] getLowerBound() {
-        return lowerBound.clone();
+        return super.getLowerBound();
     }
 
     /**
      * @return the upper bounds.
      */
     public double[] getUpperBound() {
-        return upperBound.clone();
+        return super.getUpperBound();
     }
 
     /** {@inheritDoc} */
     @Override
     public PointValuePair optimize(int maxEval, FUNC f, GoalType goalType,
-                                       double[] startPoint) {
-        return optimize(maxEval, f, goalType, startPoint, null, null);
+                                   double[] startPoint) {
+        return super.optimizeInternal(maxEval, f, goalType,
+                                      new InitialGuess(startPoint));
     }
 
     /** {@inheritDoc} */
     public PointValuePair optimize(int maxEval, FUNC f, GoalType goalType,
-                                       double[] startPoint,
-                                       double[] lower, double[] upper) {
-        // Checks.
-        final int dim = startPoint.length;
-        if (lower != null) {
-            if (lower.length != dim) {
-                throw new DimensionMismatchException(lower.length, dim);
-            }
-            for (int i = 0; i < dim; i++) {
-                final double v = startPoint[i];
-                final double lo = lower[i];
-                if (v < lo) {
-                    throw new NumberIsTooSmallException(v, lo, true);
-                }
-            }
-        }
-        if (upper != null) {
-            if (upper.length != dim) {
-                throw new DimensionMismatchException(upper.length, dim);
-            }
-            for (int i = 0; i < dim; i++) {
-                final double v = startPoint[i];
-                final double hi = upper[i];
-                if (v > hi) {
-                    throw new NumberIsTooLargeException(v, hi, true);
-                }
-            }
-        }
-
-        // Initialization.
-        if (lower == null) {
-            lowerBound = new double[dim];
-            for (int i = 0; i < dim; i++) {
-                lowerBound[i] = Double.NEGATIVE_INFINITY;
-            }
-        } else {
-            lowerBound = lower.clone();
-        }
-        if (upper == null) {
-            upperBound = new double[dim];
-            for (int i = 0; i < dim; i++) {
-                upperBound[i] = Double.POSITIVE_INFINITY;
-            }
-        } else {
-            upperBound = upper.clone();
-        }
-
-        // Base class method performs the non bound-specific initializations.
-        return super.optimize(maxEval, f, goalType, startPoint);
+                                   double[] startPoint,
+                                   double[] lower, double[] upper) {
+        return super.optimizeInternal(maxEval, f, goalType,
+                                      new InitialGuess(startPoint),
+                                      new SimpleBounds(lower, upper));
     }
 }

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/direct/BOBYQAOptimizerTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/direct/BOBYQAOptimizerTest.java?rev=1398263&r1=1398262&r2=1398263&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/direct/BOBYQAOptimizerTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/direct/BOBYQAOptimizerTest.java Mon Oct 15 12:16:53 2012
@@ -26,6 +26,8 @@ import org.apache.commons.math3.exceptio
 import org.apache.commons.math3.exception.NumberIsTooSmallException;
 import org.apache.commons.math3.optimization.GoalType;
 import org.apache.commons.math3.optimization.PointValuePair;
+import org.apache.commons.math3.optimization.InitialGuess;
+import org.apache.commons.math3.optimization.SimpleBounds;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -318,7 +320,12 @@ public class BOBYQAOptimizerTest {
         final double[] uB = boundaries == null ? null : boundaries[1];
         final int numIterpolationPoints = 2 * dim + 1 + additionalInterpolationPoints;
         BOBYQAOptimizer optim = new BOBYQAOptimizer(numIterpolationPoints);
-        PointValuePair result = optim.optimize(maxEvaluations, func, goal, startPoint, lB, uB);
+        PointValuePair result = boundaries == null ?
+            optim.optimize(maxEvaluations, func, goal,
+                           new InitialGuess(startPoint)) :
+            optim.optimize(maxEvaluations, func, goal,
+                           new InitialGuess(startPoint),
+                           new SimpleBounds(lB, uB));
 //        System.out.println(func.getClass().getName() + " = " 
 //              + optim.getEvaluations() + " f(");
 //        for (double x: result.getPoint())  System.out.print(x + " ");

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/direct/CMAESOptimizerTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/direct/CMAESOptimizerTest.java?rev=1398263&r1=1398262&r2=1398263&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/direct/CMAESOptimizerTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/direct/CMAESOptimizerTest.java Mon Oct 15 12:16:53 2012
@@ -31,6 +31,8 @@ import org.apache.commons.math3.exceptio
 import org.apache.commons.math3.exception.OutOfRangeException;
 import org.apache.commons.math3.optimization.GoalType;
 import org.apache.commons.math3.optimization.PointValuePair;
+import org.apache.commons.math3.optimization.InitialGuess;
+import org.apache.commons.math3.optimization.SimpleBounds;
 import org.apache.commons.math3.random.MersenneTwister;
 import org.apache.commons.math3.util.FastMath;
 import org.junit.Assert;
@@ -462,7 +464,12 @@ public class CMAESOptimizerTest {
                                                   0, new MersenneTwister(), false);
         final double[] lB = boundaries == null ? null : boundaries[0];
         final double[] uB = boundaries == null ? null : boundaries[1];
-        PointValuePair result = optim.optimize(maxEvaluations, func, goal, startPoint, lB, uB);
+        PointValuePair result = boundaries == null ?
+            optim.optimize(maxEvaluations, func, goal,
+                           new InitialGuess(startPoint)) :
+            optim.optimize(maxEvaluations, func, goal,
+                           new InitialGuess(startPoint),
+                           new SimpleBounds(lB, uB));
         // System.out.println("sol=" + Arrays.toString(result.getPoint()));
         Assert.assertEquals(expected.getValue(), result.getValue(), fTol);
         for (int i = 0; i < dim; i++) {