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 2014/09/18 15:15:12 UTC

svn commit: r1625967 - in /commons/proper/math/trunk/src: changes/ main/java/org/apache/commons/math3/exception/util/ main/java/org/apache/commons/math3/fitting/leastsquares/ main/resources/assets/org/apache/commons/math3/exception/util/ test/java/org/...

Author: erans
Date: Thu Sep 18 13:15:12 2014
New Revision: 1625967

URL: http://svn.apache.org/r1625967
Log:
MATH-1151
New interface "ValueAndJacobianFunction" (to allow separate evaluation
of either quantity) is a precondition for lazy evaluation (and is enforced
by raising an exception early rather than wait for a failed cast).

Added:
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/leastsquares/ValueAndJacobianFunction.java   (with props)
Modified:
    commons/proper/math/trunk/src/changes/changes.xml
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/leastsquares/LeastSquaresFactory.java
    commons/proper/math/trunk/src/main/resources/assets/org/apache/commons/math3/exception/util/LocalizedFormats_fr.properties
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/exception/util/LocalizedFormatsTest.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/fitting/leastsquares/EvaluationTest.java

Modified: commons/proper/math/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/changes/changes.xml?rev=1625967&r1=1625966&r2=1625967&view=diff
==============================================================================
--- commons/proper/math/trunk/src/changes/changes.xml (original)
+++ commons/proper/math/trunk/src/changes/changes.xml Thu Sep 18 13:15:12 2014
@@ -73,6 +73,10 @@ Users are encouraged to upgrade to this 
   2. A few methods in the FastMath class are in fact slower that their
   counterpart in either Math or StrictMath (cf. MATH-740 and MATH-901).
 ">
+      <action dev="erans" type="fix" issue="MATH-1151">
+        Interface "ValueAndJacobianFunction" is a precondition for lazy
+        evaluation (in "o.a.c.m.fitting.leastsquares").
+      </action>
       <action dev="tn" type="fix" issue="MATH-1145" due-to="Anders Conbere">
         Fix potential integer overflows in "MannWhitneyUTest" when providing
         large sample arrays.

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java?rev=1625967&r1=1625966&r2=1625967&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java Thu Sep 18 13:15:12 2014
@@ -143,6 +143,7 @@ public enum LocalizedFormats implements 
     INVALID_BINARY_CHROMOSOME("binary mutation works on BinaryChromosome only"),
     INVALID_BRACKETING_PARAMETERS("invalid bracketing parameters:  lower bound={0},  initial={1}, upper bound={2}"),
     INVALID_FIXED_LENGTH_CHROMOSOME("one-point crossover only works with fixed-length chromosomes"),
+    INVALID_IMPLEMENTATION("required functionality is missing in {0}"),
     INVALID_INTERVAL_INITIAL_VALUE_PARAMETERS("invalid interval, initial value parameters:  lower={0}, initial={1}, upper={2}"),
     INVALID_ITERATIONS_LIMITS("invalid iteration limits: min={0}, max={1}"),
     INVALID_MAX_ITERATIONS("bad value for maximum iterations number: {0}"),

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/leastsquares/LeastSquaresFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/leastsquares/LeastSquaresFactory.java?rev=1625967&r1=1625966&r2=1625967&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/leastsquares/LeastSquaresFactory.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/leastsquares/LeastSquaresFactory.java Thu Sep 18 13:15:12 2014
@@ -16,6 +16,8 @@
  */
 package org.apache.commons.math3.fitting.leastsquares;
 
+import org.apache.commons.math3.exception.MathIllegalStateException;
+import org.apache.commons.math3.exception.util.LocalizedFormats;
 import org.apache.commons.math3.analysis.MultivariateMatrixFunction;
 import org.apache.commons.math3.analysis.MultivariateVectorFunction;
 import org.apache.commons.math3.fitting.leastsquares.LeastSquaresProblem.Evaluation;
@@ -275,9 +277,9 @@ public class LeastSquaresFactory {
      * @param jacobian the Jacobian function
      * @return a function that computes both at the same time
      */
-    public static MultivariateJacobianFunction model(final MultivariateVectorFunction value,
-                                                     final MultivariateMatrixFunction jacobian) {
-        return new LocalMultivariateJacobianFunction(value, jacobian);
+    public static ValueAndJacobianFunction model(final MultivariateVectorFunction value,
+                                                 final MultivariateMatrixFunction jacobian) {
+        return new LocalValueAndJacobianFunction(value, jacobian);
     }
 
     /**
@@ -288,20 +290,19 @@ public class LeastSquaresFactory {
      * @param jacobian the Jacobian function
      * @return a function that computes both at the same time
      */
-    private static class LocalMultivariateJacobianFunction
-        implements MultivariateJacobianFunction {
+    private static class LocalValueAndJacobianFunction
+        implements ValueAndJacobianFunction {
         /** Model. */
         private final MultivariateVectorFunction value;
         /** Model's Jacobian. */
         private final MultivariateMatrixFunction jacobian;
 
-
         /**
          * @param value Model function.
          * @param jacobian Model's Jacobian function.
          */
-        LocalMultivariateJacobianFunction(final MultivariateVectorFunction value,
-                                          final MultivariateMatrixFunction jacobian) {
+        LocalValueAndJacobianFunction(final MultivariateVectorFunction value,
+                                      final MultivariateMatrixFunction jacobian) {
             this.value = value;
             this.jacobian = jacobian;
         }
@@ -316,22 +317,12 @@ public class LeastSquaresFactory {
                                                     computeJacobian(p));
         }
 
-        /**
-         * Compute the value.
-         *
-         * @param params Point.
-         * @return the Jacobian at the given point.
-         */
+        /** {@inheritDoc} */
         public RealVector computeValue(final double[] params) {
             return new ArrayRealVector(value.value(params), false);
         }
 
-        /**
-         * Compute the Jacobian.
-         *
-         * @param params Point.
-         * @return the Jacobian at the given point.
-         */
+        /** {@inheritDoc} */
         public RealMatrix computeJacobian(final double[] params) {
             return new Array2DRowRealMatrix(jacobian.value(params), false);
         }
@@ -380,6 +371,14 @@ public class LeastSquaresFactory {
             this.model = model;
             this.start = start;
             this.lazyEvaluation = lazyEvaluation;
+
+            if (lazyEvaluation &&
+                !(model instanceof ValueAndJacobianFunction)) {
+                // Lazy evaluation requires that value and Jacobian
+                // can be computed separately.
+                throw new MathIllegalStateException(LocalizedFormats.INVALID_IMPLEMENTATION,
+                                                    model.getClass().getName());
+            }
         }
 
         /** {@inheritDoc} */
@@ -403,7 +402,7 @@ public class LeastSquaresFactory {
             final RealVector p = point.copy();
 
             if (lazyEvaluation) {
-                return new LazyUnweightedEvaluation(model,
+                return new LazyUnweightedEvaluation((ValueAndJacobianFunction) model,
                                                     target,
                                                     p);
             } else {
@@ -468,7 +467,7 @@ public class LeastSquaresFactory {
             /** Point of evaluation. */
             private final RealVector point;
             /** Model and Jacobian functions. */
-            private final LocalMultivariateJacobianFunction model;
+            private final ValueAndJacobianFunction model;
             /** Target values for the model function at optimum. */
             private final RealVector target;
 
@@ -479,12 +478,12 @@ public class LeastSquaresFactory {
              * @param target the observed values
              * @param point  the abscissa
              */
-            private LazyUnweightedEvaluation(final MultivariateJacobianFunction model,
+            private LazyUnweightedEvaluation(final ValueAndJacobianFunction model,
                                              final RealVector target,
                                              final RealVector point) {
                 super(target.getDimension());
                 // Safe to cast as long as we control usage of this class.
-                this.model = (LocalMultivariateJacobianFunction) model;
+                this.model = model;
                 this.point = point;
                 this.target = target;
             }

Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/leastsquares/ValueAndJacobianFunction.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/leastsquares/ValueAndJacobianFunction.java?rev=1625967&view=auto
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/leastsquares/ValueAndJacobianFunction.java (added)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/leastsquares/ValueAndJacobianFunction.java Thu Sep 18 13:15:12 2014
@@ -0,0 +1,45 @@
+/*
+ * 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.fitting.leastsquares;
+
+import org.apache.commons.math3.linear.RealMatrix;
+import org.apache.commons.math3.linear.RealVector;
+
+/**
+ * A interface for functions that compute a vector of values and can compute their
+ * derivatives (Jacobian).
+ *
+ * @version $Id$
+ * @since 3.3
+ */
+public interface ValueAndJacobianFunction extends MultivariateJacobianFunction {
+    /**
+     * Compute the value.
+     *
+     * @param params Point.
+     * @return the value at the given point.
+     */
+    RealVector computeValue(final double[] params);
+
+    /**
+     * Compute the Jacobian.
+     *
+     * @param params Point.
+     * @return the Jacobian at the given point.
+     */
+    RealMatrix computeJacobian(final double[] params);
+}

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

Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/fitting/leastsquares/ValueAndJacobianFunction.java
------------------------------------------------------------------------------
    svn:keywords = Id Revision

Modified: commons/proper/math/trunk/src/main/resources/assets/org/apache/commons/math3/exception/util/LocalizedFormats_fr.properties
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/resources/assets/org/apache/commons/math3/exception/util/LocalizedFormats_fr.properties?rev=1625967&r1=1625966&r2=1625967&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/resources/assets/org/apache/commons/math3/exception/util/LocalizedFormats_fr.properties (original)
+++ commons/proper/math/trunk/src/main/resources/assets/org/apache/commons/math3/exception/util/LocalizedFormats_fr.properties Thu Sep 18 13:15:12 2014
@@ -114,6 +114,7 @@ INVALID_BINARY_DIGIT = chiffre binaire i
 INVALID_BINARY_CHROMOSOME = la mutation binaire ne fonctionne qu''avec BinaryChromosome
 INVALID_BRACKETING_PARAMETERS = param\u00e8tres d''encadrement invalides : borne inf\u00e9rieure = {0}, valeur initiale = {1}, borne sup\u00e9rieure = {2}
 INVALID_FIXED_LENGTH_CHROMOSOME = le m\u00e9lange \u00e0 un point ne fonctionne qu''avec les chromosomes \u00e0 taille fixe
+INVALID_IMPLEMENTATION = une fonctionnalit\u00e9 requise est manquante dans {0}
 INVALID_INTERVAL_INITIAL_VALUE_PARAMETERS = param\u00e8tres de l''intervalle initial invalides : borne inf = {0}, valeur initiale = {1}, borne sup = {2}
 INVALID_ITERATIONS_LIMITS = limites d''it\u00e9rations invalides : min = {0}, max = {1}
 INVALID_MAX_ITERATIONS = valeur invalide pour le nombre maximal d''it\u00e9rations : {0}

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/exception/util/LocalizedFormatsTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/exception/util/LocalizedFormatsTest.java?rev=1625967&r1=1625966&r2=1625967&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/exception/util/LocalizedFormatsTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/exception/util/LocalizedFormatsTest.java Thu Sep 18 13:15:12 2014
@@ -30,7 +30,7 @@ public class LocalizedFormatsTest {
 
     @Test
     public void testMessageNumber() {
-        Assert.assertEquals(318, LocalizedFormats.values().length);
+        Assert.assertEquals(319, LocalizedFormats.values().length);
     }
 
     @Test

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/fitting/leastsquares/EvaluationTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/fitting/leastsquares/EvaluationTest.java?rev=1625967&r1=1625966&r2=1625967&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/fitting/leastsquares/EvaluationTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/fitting/leastsquares/EvaluationTest.java Thu Sep 18 13:15:12 2014
@@ -13,6 +13,7 @@
  */
 package org.apache.commons.math3.fitting.leastsquares;
 
+import org.apache.commons.math3.exception.MathIllegalStateException;
 import org.apache.commons.math3.TestUtils;
 import org.apache.commons.math3.analysis.MultivariateMatrixFunction;
 import org.apache.commons.math3.analysis.MultivariateVectorFunction;
@@ -247,6 +248,43 @@ public class EvaluationTest {
         }
     }
 
+    // MATH-1151
+    @Test
+    public void testLazyEvaluationPrecondition() {
+        final RealVector dummy = new ArrayRealVector(new double[] { 0 });
+
+        // "ValueAndJacobianFunction" is required but we implement only
+        // "MultivariateJacobianFunction".
+        final MultivariateJacobianFunction m1 = new MultivariateJacobianFunction() {
+                public Pair<RealVector, RealMatrix> value(RealVector notUsed) {
+                    return new Pair<RealVector, RealMatrix>(null, null);
+                }
+            };
+
+        try {
+            // Should throw.
+            LeastSquaresFactory.create(m1, dummy, dummy, null, 0, 0, true);
+            Assert.fail("Expecting MathIllegalStateException");
+        } catch (MathIllegalStateException e) {
+            // Expected.
+        }
+
+        final MultivariateJacobianFunction m2 = new ValueAndJacobianFunction() {
+                public Pair<RealVector, RealMatrix> value(RealVector notUsed) {
+                    return new Pair<RealVector, RealMatrix>(null, null);
+                }
+                public RealVector computeValue(final double[] params) {
+                    return null;
+                }
+                public RealMatrix computeJacobian(final double[] params) {
+                    return null;
+                }
+            };
+
+        // Should pass.
+        LeastSquaresFactory.create(m2, dummy, dummy, null, 0, 0, true);
+    }
+
     @Test
     public void testDirectEvaluation() {
         final RealVector dummy = new ArrayRealVector(new double[] { 0 });
@@ -261,7 +299,7 @@ public class EvaluationTest {
             Assert.fail("Exception expected");
         } catch (RuntimeException e) {
             // Expecting exception.
-            // Whether it is model of Jacobian that caused it is not significant.
+            // Whether it is model or Jacobian that caused it is not significant.
             final String msg = e.getMessage();
             Assert.assertTrue(msg.equals("dummyModel") ||
                               msg.equals("dummyJacobian"));