You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ps...@apache.org on 2011/01/31 20:14:14 UTC

svn commit: r1065714 - in /commons/proper/math/branches/MATH_2_X/src: main/java/org/apache/commons/math/optimization/general/ test/java/org/apache/commons/math/optimization/general/

Author: psteitz
Date: Mon Jan 31 19:14:14 2011
New Revision: 1065714

URL: http://svn.apache.org/viewvc?rev=1065714&view=rev
Log:
Reverted incompatible changes made in r985828

Modified:
    commons/proper/math/branches/MATH_2_X/src/main/java/org/apache/commons/math/optimization/general/AbstractLeastSquaresOptimizer.java
    commons/proper/math/branches/MATH_2_X/src/main/java/org/apache/commons/math/optimization/general/GaussNewtonOptimizer.java
    commons/proper/math/branches/MATH_2_X/src/main/java/org/apache/commons/math/optimization/general/LevenbergMarquardtOptimizer.java
    commons/proper/math/branches/MATH_2_X/src/test/java/org/apache/commons/math/optimization/general/LevenbergMarquardtOptimizerTest.java

Modified: commons/proper/math/branches/MATH_2_X/src/main/java/org/apache/commons/math/optimization/general/AbstractLeastSquaresOptimizer.java
URL: http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_X/src/main/java/org/apache/commons/math/optimization/general/AbstractLeastSquaresOptimizer.java?rev=1065714&r1=1065713&r2=1065714&view=diff
==============================================================================
--- commons/proper/math/branches/MATH_2_X/src/main/java/org/apache/commons/math/optimization/general/AbstractLeastSquaresOptimizer.java (original)
+++ commons/proper/math/branches/MATH_2_X/src/main/java/org/apache/commons/math/optimization/general/AbstractLeastSquaresOptimizer.java Mon Jan 31 19:14:14 2011
@@ -17,20 +17,21 @@
 
 package org.apache.commons.math.optimization.general;
 
+import org.apache.commons.math.FunctionEvaluationException;
 import org.apache.commons.math.MaxEvaluationsExceededException;
 import org.apache.commons.math.MaxIterationsExceededException;
 import org.apache.commons.math.analysis.DifferentiableMultivariateVectorialFunction;
 import org.apache.commons.math.analysis.MultivariateMatrixFunction;
-import org.apache.commons.math.exception.MathUserException;
 import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.exception.MathUserException;
 import org.apache.commons.math.linear.InvalidMatrixException;
 import org.apache.commons.math.linear.LUDecompositionImpl;
 import org.apache.commons.math.linear.MatrixUtils;
 import org.apache.commons.math.linear.RealMatrix;
-import org.apache.commons.math.optimization.DifferentiableMultivariateVectorialOptimizer;
 import org.apache.commons.math.optimization.OptimizationException;
 import org.apache.commons.math.optimization.SimpleVectorialValueChecker;
 import org.apache.commons.math.optimization.VectorialConvergenceChecker;
+import org.apache.commons.math.optimization.DifferentiableMultivariateVectorialOptimizer;
 import org.apache.commons.math.optimization.VectorialPointValuePair;
 import org.apache.commons.math.util.FastMath;
 
@@ -51,13 +52,13 @@ public abstract class AbstractLeastSquar
     protected VectorialConvergenceChecker checker;
 
     /**
-     * Jacobian matrix of the weighted residuals.
+     * Jacobian matrix.
      * <p>This matrix is in canonical form just after the calls to
      * {@link #updateJacobian()}, but may be modified by the solver
      * in the derived class (the {@link LevenbergMarquardtOptimizer
      * Levenberg-Marquardt optimizer} does this).</p>
      */
-    protected double[][] weightedResidualJacobian;
+    protected double[][] jacobian;
 
     /** Number of columns of the jacobian matrix. */
     protected int cols;
@@ -83,8 +84,14 @@ public abstract class AbstractLeastSquar
     /** Current objective function value. */
     protected double[] objective;
 
+    /** Current residuals. */
+    protected double[] residuals;
+    
+    /** Weighted Jacobian */
+    protected double[][] wjacobian;
+    
     /** Weighted residuals */
-    protected double[] weightedResiduals;
+    protected double[] wresiduals;
 
     /** Cost value (square root of the sum of the residuals). */
     protected double cost;
@@ -178,47 +185,50 @@ public abstract class AbstractLeastSquar
 
     /**
      * Update the jacobian matrix.
-     * @exception MathUserException if the function jacobian
+     * @exception FunctionEvaluationException if the function jacobian
      * cannot be evaluated or its dimension doesn't match problem dimension
      */
-    protected void updateJacobian() throws MathUserException {
+    protected void updateJacobian() throws FunctionEvaluationException {
         ++jacobianEvaluations;
-        weightedResidualJacobian = jF.value(point);
-        if (weightedResidualJacobian.length != rows) {
-            throw new MathUserException(LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE,
-                                        weightedResidualJacobian.length, rows);
+        jacobian = jF.value(point);
+        if (jacobian.length != rows) {
+            throw new FunctionEvaluationException(point, LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE,
+                                                  jacobian.length, rows);
         }
         for (int i = 0; i < rows; i++) {
-            final double[] ji = weightedResidualJacobian[i];
+            final double[] ji = jacobian[i];
             double wi = FastMath.sqrt(residualsWeights[i]);
             for (int j = 0; j < cols; ++j) {
-                //ji[j] *=  -1.0;
-                weightedResidualJacobian[i][j] = -ji[j]*wi;
+                ji[j] *=  -1.0;
+                wjacobian[i][j] = ji[j]*wi;
             }
         }
     }
 
     /**
      * Update the residuals array and cost function value.
-     * @exception MathUserException if the function cannot be evaluated
+     * @exception FunctionEvaluationException if the function cannot be evaluated
      * or its dimension doesn't match problem dimension or maximal number of
      * of evaluations is exceeded
      */
     protected void updateResidualsAndCost()
-        throws MathUserException {
+        throws FunctionEvaluationException {
 
         if (++objectiveEvaluations > maxEvaluations) {
-            throw new MathUserException(new MaxEvaluationsExceededException(maxEvaluations));
+            throw new FunctionEvaluationException(new MaxEvaluationsExceededException(maxEvaluations),
+                                                  point);
         }
         objective = function.value(point);
         if (objective.length != rows) {
-            throw new MathUserException(LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, objective.length, rows);
+            throw new FunctionEvaluationException(point, LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE,
+                                                  objective.length, rows);
         }
         cost = 0;
         int index = 0;
         for (int i = 0; i < rows; i++) {
             final double residual = targetValues[i] - objective[i];
-            weightedResiduals[i]= residual*FastMath.sqrt(residualsWeights[i]);
+            residuals[i] = residual;
+            wresiduals[i]= residual*FastMath.sqrt(residualsWeights[i]);
             cost += residualsWeights[i] * residual * residual;
             index += cols;
         }
@@ -253,13 +263,13 @@ public abstract class AbstractLeastSquar
     /**
      * Get the covariance matrix of optimized parameters.
      * @return covariance matrix
-     * @exception MathUserException if the function jacobian cannot
+     * @exception FunctionEvaluationException if the function jacobian cannot
      * be evaluated
      * @exception OptimizationException if the covariance matrix
      * cannot be computed (singular problem)
      */
     public double[][] getCovariances()
-        throws MathUserException, OptimizationException {
+        throws FunctionEvaluationException, OptimizationException {
 
         // set up the jacobian
         updateJacobian();
@@ -270,7 +280,7 @@ public abstract class AbstractLeastSquar
             for (int j = i; j < cols; ++j) {
                 double sum = 0;
                 for (int k = 0; k < rows; ++k) {
-                    sum += weightedResidualJacobian[k][i] * weightedResidualJacobian[k][j];
+                    sum += wjacobian[k][i] * wjacobian[k][j];
                 }
                 jTj[i][j] = sum;
                 jTj[j][i] = sum;
@@ -278,7 +288,7 @@ public abstract class AbstractLeastSquar
         }
 
         try {
-            // compute the covariances matrix
+            // compute the covariance matrix
             RealMatrix inverse =
                 new LUDecompositionImpl(MatrixUtils.createRealMatrix(jTj)).getSolver().getInverse();
             return inverse.getData();
@@ -292,13 +302,13 @@ public abstract class AbstractLeastSquar
      * Guess the errors in optimized parameters.
      * <p>Guessing is covariance-based, it only gives rough order of magnitude.</p>
      * @return errors in optimized parameters
-     * @exception MathUserException if the function jacobian cannot b evaluated
+     * @exception FunctionEvaluationException if the function jacobian cannot b evaluated
      * @exception OptimizationException if the covariances matrix cannot be computed
      * or the number of degrees of freedom is not positive (number of measurements
      * lesser or equal to number of parameters)
      */
     public double[] guessParametersErrors()
-        throws MathUserException, OptimizationException {
+        throws FunctionEvaluationException, OptimizationException {
         if (rows <= cols) {
             throw new OptimizationException(
                     LocalizedFormats.NO_DEGREES_OF_FREEDOM,
@@ -335,28 +345,35 @@ public abstract class AbstractLeastSquar
         targetValues     = target.clone();
         residualsWeights = weights.clone();
         this.point       = startPoint.clone();
+        this.residuals   = new double[target.length];
 
         // arrays shared with the other private methods
         rows      = target.length;
         cols      = point.length;
+        jacobian  = new double[rows][cols];
 
-        weightedResidualJacobian = new double[rows][cols];
-        this.weightedResiduals = new double[rows];
-
+        wjacobian = new double[rows][cols];
+        wresiduals = new double[rows];
+        
         cost = Double.POSITIVE_INFINITY;
 
-        return doOptimize();
+        try {
+            return doOptimize();
+        } catch (FunctionEvaluationException ex) {
+            throw new MathUserException(ex);
+        }
 
     }
 
     /** Perform the bulk of optimization algorithm.
      * @return the point/value pair giving the optimal value for objective function
-     * @exception MathUserException if the objective function throws one during
+     * @exception FunctionEvaluationException if the objective function throws one during
      * the search
      * @exception OptimizationException if the algorithm failed to converge
      * @exception IllegalArgumentException if the start point dimension is wrong
      */
     protected abstract VectorialPointValuePair doOptimize()
-        throws MathUserException, OptimizationException, IllegalArgumentException;
+        throws FunctionEvaluationException, OptimizationException, IllegalArgumentException;
+
 
 }

Modified: commons/proper/math/branches/MATH_2_X/src/main/java/org/apache/commons/math/optimization/general/GaussNewtonOptimizer.java
URL: http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_X/src/main/java/org/apache/commons/math/optimization/general/GaussNewtonOptimizer.java?rev=1065714&r1=1065713&r2=1065714&view=diff
==============================================================================
--- commons/proper/math/branches/MATH_2_X/src/main/java/org/apache/commons/math/optimization/general/GaussNewtonOptimizer.java (original)
+++ commons/proper/math/branches/MATH_2_X/src/main/java/org/apache/commons/math/optimization/general/GaussNewtonOptimizer.java Mon Jan 31 19:14:14 2011
@@ -17,6 +17,7 @@
 
 package org.apache.commons.math.optimization.general;
 
+import org.apache.commons.math.FunctionEvaluationException;
 import org.apache.commons.math.exception.MathUserException;
 import org.apache.commons.math.exception.util.LocalizedFormats;
 import org.apache.commons.math.linear.BlockRealMatrix;
@@ -72,8 +73,16 @@ public class GaussNewtonOptimizer extend
 
             // evaluate the objective function and its jacobian
             VectorialPointValuePair previous = current;
+            try {
             updateResidualsAndCost();
-            updateJacobian();
+            } catch (FunctionEvaluationException ex) {
+                throw new MathUserException(ex);
+            }
+            try {
+                updateJacobian();
+            } catch (FunctionEvaluationException ex) {
+                throw new MathUserException(ex);
+            }
             current = new VectorialPointValuePair(point, objective);
 
             // build the linear problem
@@ -81,7 +90,7 @@ public class GaussNewtonOptimizer extend
             final double[][] a = new double[cols][cols];
             for (int i = 0; i < rows; ++i) {
 
-                final double[] grad   = weightedResidualJacobian[i];
+                final double[] grad   = jacobian[i];
                 final double weight   = residualsWeights[i];
                 final double residual = objective[i] - targetValues[i];
 

Modified: commons/proper/math/branches/MATH_2_X/src/main/java/org/apache/commons/math/optimization/general/LevenbergMarquardtOptimizer.java
URL: http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_X/src/main/java/org/apache/commons/math/optimization/general/LevenbergMarquardtOptimizer.java?rev=1065714&r1=1065713&r2=1065714&view=diff
==============================================================================
--- commons/proper/math/branches/MATH_2_X/src/main/java/org/apache/commons/math/optimization/general/LevenbergMarquardtOptimizer.java (original)
+++ commons/proper/math/branches/MATH_2_X/src/main/java/org/apache/commons/math/optimization/general/LevenbergMarquardtOptimizer.java Mon Jan 31 19:14:14 2011
@@ -18,6 +18,7 @@ package org.apache.commons.math.optimiza
 
 import java.util.Arrays;
 
+import org.apache.commons.math.FunctionEvaluationException;
 import org.apache.commons.math.exception.MathUserException;
 import org.apache.commons.math.exception.util.LocalizedFormats;
 import org.apache.commons.math.optimization.OptimizationException;
@@ -263,7 +264,11 @@ public class LevenbergMarquardtOptimizer
         double[] work3   = new double[cols];
 
         // evaluate the function at the starting point and calculate its norm
-        updateResidualsAndCost();
+        try {
+            updateResidualsAndCost();
+        } catch (FunctionEvaluationException ex) {
+            throw new MathUserException(ex);
+        }
 
         // outer loop
         lmPar = 0;
@@ -271,13 +276,17 @@ public class LevenbergMarquardtOptimizer
         VectorialPointValuePair current = new VectorialPointValuePair(point, objective);
         while (true) {
             for (int i=0;i<rows;i++) {
-                qtf[i]=weightedResiduals[i];
+                qtf[i]=residuals[i];
             }
             incrementIterationsCounter();
 
             // compute the Q.R. decomposition of the jacobian matrix
             VectorialPointValuePair previous = current;
-            updateJacobian();
+            try {
+                updateJacobian(); 
+            } catch (FunctionEvaluationException ex) {
+                throw new MathUserException(ex);
+            }
             qrDecomposition();
 
             // compute Qt.res
@@ -286,7 +295,7 @@ public class LevenbergMarquardtOptimizer
             // so let jacobian contain the R matrix with its diagonal elements
             for (int k = 0; k < solvedCols; ++k) {
                 int pk = permutation[k];
-                weightedResidualJacobian[k][pk] = diagR[pk];
+                jacobian[k][pk] = diagR[pk];
             }
 
             if (firstIteration) {
@@ -319,7 +328,7 @@ public class LevenbergMarquardtOptimizer
                     if (s != 0) {
                         double sum = 0;
                         for (int i = 0; i <= j; ++i) {
-                            sum += weightedResidualJacobian[i][pj] * qtf[i];
+                            sum += jacobian[i][pj] * qtf[i];
                         }
                         maxCosine = FastMath.max(maxCosine, FastMath.abs(sum) / (s * cost));
                     }
@@ -327,7 +336,11 @@ public class LevenbergMarquardtOptimizer
             }
             if (maxCosine <= orthoTolerance) {
                 // convergence has been reached
-                updateResidualsAndCost();
+                try {
+                    updateResidualsAndCost();
+                } catch (FunctionEvaluationException ex) {
+                    throw new MathUserException(ex);
+                }
                 current = new VectorialPointValuePair(point, objective);
                 return current;
             }
@@ -346,8 +359,8 @@ public class LevenbergMarquardtOptimizer
                     oldX[pj] = point[pj];
                 }
                 double previousCost = cost;
-                double[] tmpVec = weightedResiduals;
-                weightedResiduals = oldRes;
+                double[] tmpVec = residuals;
+                residuals = oldRes;
                 oldRes    = tmpVec;
                 tmpVec    = objective;
                 objective = oldObj;
@@ -372,7 +385,11 @@ public class LevenbergMarquardtOptimizer
                 }
 
                 // evaluate the function at x + p and calculate its norm
-                updateResidualsAndCost();
+                try {
+                    updateResidualsAndCost();
+                } catch (FunctionEvaluationException ex) {
+                    throw new MathUserException(ex);
+                }
 
                 // compute the scaled actual reduction
                 double actRed = -1.0;
@@ -388,7 +405,7 @@ public class LevenbergMarquardtOptimizer
                     double dirJ = lmDir[pj];
                     work1[j] = 0;
                     for (int i = 0; i <= j; ++i) {
-                        work1[i] += weightedResidualJacobian[i][pj] * dirJ;
+                        work1[i] += jacobian[i][pj] * dirJ;
                     }
                 }
                 double coeff1 = 0;
@@ -444,8 +461,8 @@ public class LevenbergMarquardtOptimizer
                         int pj = permutation[j];
                         point[pj] = oldX[pj];
                     }
-                    tmpVec    = weightedResiduals;
-                    weightedResiduals = oldRes;
+                    tmpVec    = residuals;
+                    residuals = oldRes;
                     oldRes    = tmpVec;
                     tmpVec    = objective;
                     objective = oldObj;
@@ -515,7 +532,7 @@ public class LevenbergMarquardtOptimizer
             int pk = permutation[k];
             double ypk = lmDir[pk] / diagR[pk];
             for (int i = 0; i < k; ++i) {
-                lmDir[permutation[i]] -= ypk * weightedResidualJacobian[i][pk];
+                lmDir[permutation[i]] -= ypk * jacobian[i][pk];
             }
             lmDir[pk] = ypk;
         }
@@ -551,7 +568,7 @@ public class LevenbergMarquardtOptimizer
                 int pj = permutation[j];
                 double sum = 0;
                 for (int i = 0; i < j; ++i) {
-                    sum += weightedResidualJacobian[i][pj] * work1[permutation[i]];
+                    sum += jacobian[i][pj] * work1[permutation[i]];
                 }
                 double s = (work1[pj] - sum) / diagR[pj];
                 work1[pj] = s;
@@ -566,7 +583,7 @@ public class LevenbergMarquardtOptimizer
             int pj = permutation[j];
             double sum = 0;
             for (int i = 0; i <= j; ++i) {
-                sum += weightedResidualJacobian[i][pj] * qy[i];
+                sum += jacobian[i][pj] * qy[i];
             }
             sum /= diag[pj];
             sum2 += sum * sum;
@@ -626,7 +643,7 @@ public class LevenbergMarquardtOptimizer
                 work1[pj] /= work2[j];
                 double tmp = work1[pj];
                 for (int i = j + 1; i < solvedCols; ++i) {
-                    work1[permutation[i]] -= weightedResidualJacobian[i][pj] * tmp;
+                    work1[permutation[i]] -= jacobian[i][pj] * tmp;
                 }
             }
             sum2 = 0;
@@ -677,7 +694,7 @@ public class LevenbergMarquardtOptimizer
         for (int j = 0; j < solvedCols; ++j) {
             int pj = permutation[j];
             for (int i = j + 1; i < solvedCols; ++i) {
-                weightedResidualJacobian[i][pj] = weightedResidualJacobian[j][permutation[i]];
+                jacobian[i][pj] = jacobian[j][permutation[i]];
             }
             lmDir[j] = diagR[pj];
             work[j]  = qy[j];
@@ -708,8 +725,8 @@ public class LevenbergMarquardtOptimizer
 
                     final double sin;
                     final double cos;
-                    double rkk = weightedResidualJacobian[k][pk];
-                    if (FastMath.abs(rkk) < FastMath.abs(lmDiag[k])) {
+                    double rkk = jacobian[k][pk];
+                    if (Math.abs(rkk) < Math.abs(lmDiag[k])) {
                         final double cotan = rkk / lmDiag[k];
                         sin   = 1.0 / FastMath.sqrt(1.0 + cotan * cotan);
                         cos   = sin * cotan;
@@ -721,17 +738,17 @@ public class LevenbergMarquardtOptimizer
 
                     // compute the modified diagonal element of R and
                     // the modified element of (Qty,0)
-                    weightedResidualJacobian[k][pk] = cos * rkk + sin * lmDiag[k];
+                    jacobian[k][pk] = cos * rkk + sin * lmDiag[k];
                     final double temp = cos * work[k] + sin * qtbpj;
                     qtbpj = -sin * work[k] + cos * qtbpj;
                     work[k] = temp;
 
                     // accumulate the tranformation in the row of s
                     for (int i = k + 1; i < solvedCols; ++i) {
-                        double rik = weightedResidualJacobian[i][pk];
+                        double rik = jacobian[i][pk];
                         final double temp2 = cos * rik + sin * lmDiag[i];
                         lmDiag[i] = -sin * rik + cos * lmDiag[i];
-                        weightedResidualJacobian[i][pk] = temp2;
+                        jacobian[i][pk] = temp2;
                     }
 
                 }
@@ -739,8 +756,8 @@ public class LevenbergMarquardtOptimizer
 
             // store the diagonal element of s and restore
             // the corresponding diagonal element of R
-            lmDiag[j] = weightedResidualJacobian[j][permutation[j]];
-            weightedResidualJacobian[j][permutation[j]] = lmDir[j];
+            lmDiag[j] = jacobian[j][permutation[j]];
+            jacobian[j][permutation[j]] = lmDir[j];
 
         }
 
@@ -760,7 +777,7 @@ public class LevenbergMarquardtOptimizer
                 int pj = permutation[j];
                 double sum = 0;
                 for (int i = j + 1; i < nSing; ++i) {
-                    sum += weightedResidualJacobian[i][pj] * work[i];
+                    sum += jacobian[i][pj] * work[i];
                 }
                 work[j] = (work[j] - sum) / lmDiag[j];
             }
@@ -801,8 +818,8 @@ public class LevenbergMarquardtOptimizer
         for (int k = 0; k < cols; ++k) {
             permutation[k] = k;
             double norm2 = 0;
-            for (int i = 0; i < weightedResidualJacobian.length; ++i) {
-                double akk = weightedResidualJacobian[i][k];
+            for (int i = 0; i < jacobian.length; ++i) {
+                double akk = jacobian[i][k];
                 norm2 += akk * akk;
             }
             jacNorm[k] = FastMath.sqrt(norm2);
@@ -816,8 +833,8 @@ public class LevenbergMarquardtOptimizer
             double ak2 = Double.NEGATIVE_INFINITY;
             for (int i = k; i < cols; ++i) {
                 double norm2 = 0;
-                for (int j = k; j < weightedResidualJacobian.length; ++j) {
-                    double aki = weightedResidualJacobian[j][permutation[i]];
+                for (int j = k; j < jacobian.length; ++j) {
+                    double aki = jacobian[j][permutation[i]];
                     norm2 += aki * aki;
                 }
                 if (Double.isInfinite(norm2) || Double.isNaN(norm2)) {
@@ -838,24 +855,24 @@ public class LevenbergMarquardtOptimizer
             permutation[k]          = pk;
 
             // choose alpha such that Hk.u = alpha ek
-            double akk   = weightedResidualJacobian[k][pk];
-            double alpha = (akk > 0) ? -FastMath.sqrt(ak2) : FastMath.sqrt(ak2);
+            double akk   = jacobian[k][pk];
+            double alpha = (akk > 0) ? -Math.sqrt(ak2) : Math.sqrt(ak2);
             double betak = 1.0 / (ak2 - akk * alpha);
             beta[pk]     = betak;
 
             // transform the current column
             diagR[pk]        = alpha;
-            weightedResidualJacobian[k][pk] -= alpha;
+            jacobian[k][pk] -= alpha;
 
             // transform the remaining columns
             for (int dk = cols - 1 - k; dk > 0; --dk) {
                 double gamma = 0;
-                for (int j = k; j < weightedResidualJacobian.length; ++j) {
-                    gamma += weightedResidualJacobian[j][pk] * weightedResidualJacobian[j][permutation[k + dk]];
+                for (int j = k; j < jacobian.length; ++j) {
+                    gamma += jacobian[j][pk] * jacobian[j][permutation[k + dk]];
                 }
                 gamma *= betak;
-                for (int j = k; j < weightedResidualJacobian.length; ++j) {
-                    weightedResidualJacobian[j][permutation[k + dk]] -= gamma * weightedResidualJacobian[j][pk];
+                for (int j = k; j < jacobian.length; ++j) {
+                    jacobian[j][permutation[k + dk]] -= gamma * jacobian[j][pk];
                 }
             }
 
@@ -875,11 +892,11 @@ public class LevenbergMarquardtOptimizer
             int pk = permutation[k];
             double gamma = 0;
             for (int i = k; i < rows; ++i) {
-                gamma += weightedResidualJacobian[i][pk] * y[i];
+                gamma += jacobian[i][pk] * y[i];
             }
             gamma *= beta[pk];
             for (int i = k; i < rows; ++i) {
-                y[i] -= gamma * weightedResidualJacobian[i][pk];
+                y[i] -= gamma * jacobian[i][pk];
             }
         }
     }

Modified: commons/proper/math/branches/MATH_2_X/src/test/java/org/apache/commons/math/optimization/general/LevenbergMarquardtOptimizerTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_X/src/test/java/org/apache/commons/math/optimization/general/LevenbergMarquardtOptimizerTest.java?rev=1065714&r1=1065713&r2=1065714&view=diff
==============================================================================
--- commons/proper/math/branches/MATH_2_X/src/test/java/org/apache/commons/math/optimization/general/LevenbergMarquardtOptimizerTest.java (original)
+++ commons/proper/math/branches/MATH_2_X/src/test/java/org/apache/commons/math/optimization/general/LevenbergMarquardtOptimizerTest.java Mon Jan 31 19:14:14 2011
@@ -104,7 +104,7 @@ public class LevenbergMarquardtOptimizer
         super(name);
     }
 
-    public void testTrivial() throws MathUserException, OptimizationException {
+    public void testTrivial() throws Exception {
         LinearProblem problem =
             new LinearProblem(new double[][] { { 2 } }, new double[] { 3 });
         LevenbergMarquardtOptimizer optimizer = new LevenbergMarquardtOptimizer();
@@ -121,7 +121,7 @@ public class LevenbergMarquardtOptimizer
         assertEquals(3.0, optimum.getValue()[0], 1.0e-10);
     }
 
-    public void testQRColumnsPermutation() throws MathUserException, OptimizationException {
+    public void testQRColumnsPermutation() throws Exception {
 
         LinearProblem problem =
             new LinearProblem(new double[][] { { 1.0, -1.0 }, { 0.0, 2.0 }, { 1.0, -2.0 } },
@@ -139,7 +139,7 @@ public class LevenbergMarquardtOptimizer
 
     }
 
-    public void testNoDependency() throws MathUserException, OptimizationException {
+    public void testNoDependency() throws Exception {
         LinearProblem problem = new LinearProblem(new double[][] {
                 { 2, 0, 0, 0, 0, 0 },
                 { 0, 2, 0, 0, 0, 0 },
@@ -158,7 +158,7 @@ public class LevenbergMarquardtOptimizer
         }
     }
 
-    public void testOneSet() throws MathUserException, OptimizationException {
+    public void testOneSet() throws Exception {
 
         LinearProblem problem = new LinearProblem(new double[][] {
                 {  1,  0, 0 },
@@ -175,7 +175,7 @@ public class LevenbergMarquardtOptimizer
 
     }
 
-    public void testTwoSets() throws MathUserException, OptimizationException {
+    public void testTwoSets() throws Exception {
         double epsilon = 1.0e-7;
         LinearProblem problem = new LinearProblem(new double[][] {
                 {  2,  1,   0,  4,       0, 0 },
@@ -200,7 +200,7 @@ public class LevenbergMarquardtOptimizer
 
     }
 
-    public void testNonInversible() throws MathUserException, OptimizationException {
+    public void testNonInversible() throws Exception {
 
         LinearProblem problem = new LinearProblem(new double[][] {
                 {  1, 2, -3 },
@@ -220,7 +220,7 @@ public class LevenbergMarquardtOptimizer
 
     }
 
-    public void testIllConditioned() throws MathUserException, OptimizationException {
+    public void testIllConditioned() throws Exception {
         LinearProblem problem1 = new LinearProblem(new double[][] {
                 { 10.0, 7.0,  8.0,  7.0 },
                 {  7.0, 5.0,  6.0,  5.0 },
@@ -254,7 +254,7 @@ public class LevenbergMarquardtOptimizer
 
     }
 
-    public void testMoreEstimatedParametersSimple() throws MathUserException, OptimizationException {
+    public void testMoreEstimatedParametersSimple() throws Exception {
 
         LinearProblem problem = new LinearProblem(new double[][] {
                 { 3.0, 2.0,  0.0, 0.0 },
@@ -269,7 +269,7 @@ public class LevenbergMarquardtOptimizer
 
     }
 
-    public void testMoreEstimatedParametersUnsorted() throws MathUserException, OptimizationException {
+    public void testMoreEstimatedParametersUnsorted() throws Exception {
         LinearProblem problem = new LinearProblem(new double[][] {
                 { 1.0, 1.0,  0.0,  0.0, 0.0,  0.0 },
                 { 0.0, 0.0,  1.0,  1.0, 1.0,  0.0 },
@@ -290,7 +290,7 @@ public class LevenbergMarquardtOptimizer
 
     }
 
-    public void testRedundantEquations() throws MathUserException, OptimizationException {
+    public void testRedundantEquations() throws Exception {
         LinearProblem problem = new LinearProblem(new double[][] {
                 { 1.0,  1.0 },
                 { 1.0, -1.0 },
@@ -386,7 +386,7 @@ public class LevenbergMarquardtOptimizer
         }
     }
 
-    public void testCircleFitting() throws MathUserException, OptimizationException {
+    public void testCircleFitting() throws Exception {
         Circle circle = new Circle();
         circle.addPoint( 30.0,  68.0);
         circle.addPoint( 50.0,  -6.0);