Author: luc
Date: Sun Mar 15 21:33:31 2009
New Revision: 754763

URL: http://svn.apache.org/viewvc?rev=754763&view=rev
Log:
added all necessary multi-start optimizers types

Added:
    
commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultiStartScalarDifferentiableOptimizer.java
   (with props)
    
commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultiStartScalarOptimizer.java
   (contents, props changed)
      - copied, changed from r754499, 
commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultiStartOptimizer.java
    
commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultiStartVectorialDifferentiableOptimizer.java
   (with props)
Removed:
    
commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultiStartOptimizer.java

Added: 
commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultiStartScalarDifferentiableOptimizer.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultiStartScalarDifferentiableOptimizer.java?rev=754763&view=auto
==============================================================================
--- 
commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultiStartScalarDifferentiableOptimizer.java
 (added)
+++ 
commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultiStartScalarDifferentiableOptimizer.java
 Sun Mar 15 21:33:31 2009
@@ -0,0 +1,190 @@
+/*
+ * 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.ConvergenceException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.random.RandomVectorGenerator;
+
+/** 
+ * Special implementation of the {...@link ScalarDifferentiableOptimizer} 
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$ $Date$
+ * @since 2.0
+ */
+public class MultiStartScalarDifferentiableOptimizer implements 
ScalarDifferentiableOptimizer {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = 9008747186334431824L;
+
+    /** Underlying classical optimizer. */
+    private final ScalarDifferentiableOptimizer optimizer;
+
+    /** Number of evaluations already performed for all starts. */
+    private int totalEvaluations;
+
+    /** Maximal number of evaluations allowed. */
+    private int maxEvaluations;
+
+    /** Number of starts to go. */
+    private int starts;
+
+    /** Random generator for multi-start. */
+    private RandomVectorGenerator generator;
+
+    /** Found optima. */
+    private ScalarPointValuePair[] 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 MultiStartScalarDifferentiableOptimizer(final 
ScalarDifferentiableOptimizer optimizer,
+                                                   final int starts,
+                                                   final RandomVectorGenerator 
generator) {
+        this.optimizer        = optimizer;
+        this.totalEvaluations = 0;
+        this.maxEvaluations   = Integer.MAX_VALUE;
+        this.starts           = starts;
+        this.generator        = generator;
+        this.optima           = null;
+    }
+
+    /** Get all the optima found during the last call to {...@link
+     * #optimize(ScalarObjectiveFunction, GoalType, double[]) optimize}.
+     * <p>The optimizer stores all the optima found during a set of
+     * restarts. The {...@link #optimize(ScalarObjectiveFunction, 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(ScalarObjectiveFunction, 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(ScalarObjectiveFunction,
+     * GoalType, double[]) optimize} method did throw a {...@link
+     * 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(ScalarObjectiveFunction,
+     * GoalType, double[]) optimize} has not been called
+     */
+    public ScalarPointValuePair[] getOptima() throws IllegalStateException {
+        if (optima == null) {
+            throw MathRuntimeException.createIllegalStateException("no optimum 
computed yet");
+        }
+        return (ScalarPointValuePair[]) optima.clone();
+    }
+
+    /** {...@inheritdoc} */
+    public int getEvaluations() {
+        return totalEvaluations;
+    }
+
+    /** {...@inheritdoc} */
+    public void setMaxEvaluations(int maxEvaluations) {
+        this.maxEvaluations = maxEvaluations;
+    }
+
+    /** {...@inheritdoc} */
+    public int getMaxEvaluations() {
+        return maxEvaluations;
+    }
+
+    /** {...@inheritdoc} */
+    public void setConvergenceChecker(ScalarConvergenceChecker checker) {
+        optimizer.setConvergenceChecker(checker);
+    }
+
+    /** {...@inheritdoc} */
+    public ScalarConvergenceChecker getConvergenceChecker() {
+        return optimizer.getConvergenceChecker();
+    }
+
+    /** {...@inheritdoc} */
+    public ScalarPointValuePair optimize(final 
ScalarDifferentiableObjectiveFunction f,
+                                         final GoalType goalType,
+                                         double[] startPoint)
+        throws ObjectiveException, OptimizationException {
+
+        optima = new ScalarPointValuePair[starts];
+        totalEvaluations = 0;
+
+        // multi-start loop
+        for (int i = 0; i < starts; ++i) {
+
+            try {
+                optimizer.setMaxEvaluations(maxEvaluations - totalEvaluations);
+                optima[i] = optimizer.optimize(f, goalType,
+                                               (i == 0) ? startPoint : 
generator.nextVector());
+            } catch (ObjectiveException obe) {
+                optima[i] = null;
+            } catch (OptimizationException ope) {
+                optima[i] = null;
+            }
+
+            totalEvaluations += optimizer.getEvaluations();
+
+        }
+
+        // sort the optima from best to worst, followed by null elements
+        Arrays.sort(optima, new Comparator<ScalarPointValuePair>() {
+            public int compare(final ScalarPointValuePair o1, final 
ScalarPointValuePair 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(
+                    "none of the {0} start points lead to convergence",
+                    starts);
+        }
+
+        // return the found point given the best objective function value
+        return optima[0];
+
+    }
+
+}

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

Propchange: 
commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultiStartScalarDifferentiableOptimizer.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Copied: 
commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultiStartScalarOptimizer.java
 (from r754499, 
commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultiStartOptimizer.java)
URL: 
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultiStartScalarOptimizer.java?p2=commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultiStartScalarOptimizer.java&p1=commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultiStartOptimizer.java&r1=754499&r2=754763&rev=754763&view=diff
==============================================================================
--- 
commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultiStartOptimizer.java
 (original)
+++ 
commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultiStartScalarOptimizer.java
 Sun Mar 15 21:33:31 2009
@@ -35,7 +35,7 @@
  * @version $Revision$ $Date$
  * @since 2.0
  */
-public class MultiStartOptimizer implements ScalarOptimizer {
+public class MultiStartScalarOptimizer implements ScalarOptimizer {
 
     /** Serializable version identifier. */
     private static final long serialVersionUID = 6648351778723282863L;
@@ -66,8 +66,8 @@
      * equal to 1
      * @param generator random vector generator to use for restarts
      */
-    public MultiStartOptimizer(final ScalarOptimizer optimizer, final int 
starts,
-                               final RandomVectorGenerator generator) {
+    public MultiStartScalarOptimizer(final ScalarOptimizer optimizer, final 
int starts,
+                                     final RandomVectorGenerator generator) {
         this.optimizer        = optimizer;
         this.totalEvaluations = 0;
         this.maxEvaluations   = Integer.MAX_VALUE;
@@ -136,8 +136,8 @@
 
     /** {...@inheritdoc} */
     public ScalarPointValuePair optimize(final ScalarObjectiveFunction f,
-                                   final GoalType goalType,
-                                   double[] startPoint)
+                                         final GoalType goalType,
+                                         double[] startPoint)
         throws ObjectiveException, OptimizationException {
 
         optima = new ScalarPointValuePair[starts];

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

Propchange: 
commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultiStartScalarOptimizer.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: 
commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultiStartScalarOptimizer.java
------------------------------------------------------------------------------
    svn:mergeinfo = 

Added: 
commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultiStartVectorialDifferentiableOptimizer.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultiStartVectorialDifferentiableOptimizer.java?rev=754763&view=auto
==============================================================================
--- 
commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultiStartVectorialDifferentiableOptimizer.java
 (added)
+++ 
commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultiStartVectorialDifferentiableOptimizer.java
 Sun Mar 15 21:33:31 2009
@@ -0,0 +1,207 @@
+/*
+ * 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.ConvergenceException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.random.RandomVectorGenerator;
+
+/** 
+ * Special implementation of the {...@link VectorialDifferentiableOptimizer} 
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$ $Date$
+ * @since 2.0
+ */
+public class MultiStartVectorialDifferentiableOptimizer implements 
VectorialDifferentiableOptimizer {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = -6671992853686531955L;
+
+    /** Underlying classical optimizer. */
+    private final VectorialDifferentiableOptimizer optimizer;
+
+    /** Number of evaluations already performed for all starts. */
+    private int totalEvaluations;
+
+    /** Number of jacobian evaluations already performed for all starts. */
+    private int totalJacobianEvaluations;
+
+    /** Maximal number of evaluations allowed. */
+    private int maxEvaluations;
+
+    /** Number of starts to go. */
+    private int starts;
+
+    /** Random generator for multi-start. */
+    private RandomVectorGenerator generator;
+
+    /** Found optima. */
+    private VectorialPointValuePair[] 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 MultiStartVectorialDifferentiableOptimizer(final 
VectorialDifferentiableOptimizer optimizer,
+                                                      final int starts,
+                                                      final 
RandomVectorGenerator generator) {
+        this.optimizer                = optimizer;
+        this.totalEvaluations         = 0;
+        this.totalJacobianEvaluations = 0;
+        this.maxEvaluations           = Integer.MAX_VALUE;
+        this.starts                   = starts;
+        this.generator                = generator;
+        this.optima                   = null;
+    }
+
+    /** Get all the optima found during the last call to {...@link
+     * #optimize(ScalarObjectiveFunction, GoalType, double[]) optimize}.
+     * <p>The optimizer stores all the optima found during a set of
+     * restarts. The {...@link #optimize(ScalarObjectiveFunction, 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(ScalarObjectiveFunction, 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(ScalarObjectiveFunction,
+     * GoalType, double[]) optimize} method did throw a {...@link
+     * 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(ScalarObjectiveFunction,
+     * GoalType, double[]) optimize} has not been called
+     */
+    public VectorialPointValuePair[] getOptima() throws IllegalStateException {
+        if (optima == null) {
+            throw MathRuntimeException.createIllegalStateException("no optimum 
computed yet");
+        }
+        return (VectorialPointValuePair[]) optima.clone();
+    }
+
+    /** {...@inheritdoc} */
+    public int getEvaluations() {
+        return totalEvaluations;
+    }
+
+    /** {...@inheritdoc} */
+    public int getJacobianEvaluations() {
+        return totalJacobianEvaluations;
+    }
+
+    /** {...@inheritdoc} */
+    public void setMaxEvaluations(int maxEvaluations) {
+        this.maxEvaluations = maxEvaluations;
+    }
+
+    /** {...@inheritdoc} */
+    public int getMaxEvaluations() {
+        return maxEvaluations;
+    }
+
+    /** {...@inheritdoc} */
+    public void setConvergenceChecker(VectorialConvergenceChecker checker) {
+        optimizer.setConvergenceChecker(checker);
+    }
+
+    /** {...@inheritdoc} */
+    public VectorialConvergenceChecker getConvergenceChecker() {
+        return optimizer.getConvergenceChecker();
+    }
+
+    /** {...@inheritdoc} */
+    public VectorialPointValuePair optimize(final 
VectorialDifferentiableObjectiveFunction f,
+                                            final double[] target, final 
double[] weights,
+                                            final double[] startPoint)
+        throws ObjectiveException, OptimizationException, 
IllegalArgumentException {
+
+        optima = new VectorialPointValuePair[starts];
+        totalEvaluations = 0;
+        totalJacobianEvaluations = 0;
+
+        // multi-start loop
+        for (int i = 0; i < starts; ++i) {
+
+            try {
+                optimizer.setMaxEvaluations(maxEvaluations - totalEvaluations);
+                optima[i] = optimizer.optimize(f, target, weights,
+                                               (i == 0) ? startPoint : 
generator.nextVector());
+            } catch (ObjectiveException obe) {
+                optima[i] = null;
+            } catch (OptimizationException ope) {
+                optima[i] = null;
+            }
+
+            totalEvaluations         += optimizer.getEvaluations();
+            totalJacobianEvaluations += optimizer.getJacobianEvaluations();
+
+        }
+
+        // sort the optima from best to worst, followed by null elements
+        Arrays.sort(optima, new Comparator<VectorialPointValuePair>() {
+            public int compare(final VectorialPointValuePair o1, final 
VectorialPointValuePair o2) {
+                if (o1 == null) {
+                    return (o2 == null) ? 0 : +1;
+                } else if (o2 == null) {
+                    return -1;
+                }
+                return Double.compare(weightedResidual(o1), 
weightedResidual(o2));
+            }
+            private double weightedResidual(final VectorialPointValuePair pv) {
+                final double[] value = pv.getValueRef();
+                double sum = 0;
+                for (int i = 0; i < value.length; ++i) {
+                    final double ri = value[i] - target[i];
+                    sum += weights[i] * ri * ri;
+                }
+                return sum;
+            }
+        });
+
+        if (optima[0] == null) {
+            throw new OptimizationException(
+                    "none of the {0} start points lead to convergence",
+                    starts);
+        }
+
+        // return the found point given the best objective function value
+        return optima[0];
+
+    }
+
+}

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

Propchange: 
commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultiStartVectorialDifferentiableOptimizer.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision


Reply via email to