You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by lu...@apache.org on 2012/09/14 22:17:01 UTC

svn commit: r1384907 [2/2] - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math3/analysis/ main/java/org/apache/commons/math3/optimization/ main/java/org/apache/commons/math3/optimization/direct/ main/java/org/apache/commons/math3/opt...

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/CircleScalar.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/CircleScalar.java?rev=1384907&r1=1384906&r2=1384907&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/CircleScalar.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/CircleScalar.java Fri Sep 14 20:17:00 2012
@@ -17,59 +17,55 @@
 
 package org.apache.commons.math3.optimization.general;
 
-import java.awt.geom.Point2D;
 import java.util.ArrayList;
-import org.apache.commons.math3.analysis.DifferentiableMultivariateFunction;
-import org.apache.commons.math3.analysis.MultivariateFunction;
-import org.apache.commons.math3.analysis.MultivariateVectorFunction;
+
+import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
+import org.apache.commons.math3.analysis.differentiation.MultivariateDifferentiableFunction;
+import org.apache.commons.math3.geometry.euclidean.twod.Vector2D;
 
 /**
  * Class used in the tests.
  */
-class CircleScalar implements DifferentiableMultivariateFunction {
-    private ArrayList<Point2D.Double> points;
+public class CircleScalar implements MultivariateDifferentiableFunction {
+    private ArrayList<Vector2D> points;
 
     public CircleScalar() {
-        points  = new ArrayList<Point2D.Double>();
+        points  = new ArrayList<Vector2D>();
     }
 
     public void addPoint(double px, double py) {
-        points.add(new Point2D.Double(px, py));
+        points.add(new Vector2D(px, py));
     }
 
-    public double getRadius(Point2D.Double center) {
+    public double getRadius(Vector2D center) {
         double r = 0;
-        for (Point2D.Double point : points) {
+        for (Vector2D point : points) {
             r += point.distance(center);
         }
         return r / points.size();
     }
 
-    private double[] gradient(double[] point) {
-        // optimal radius
-        Point2D.Double center = new Point2D.Double(point[0], point[1]);
-        double radius = getRadius(center);
+    private DerivativeStructure distance(Vector2D point,
+                                         DerivativeStructure cx, DerivativeStructure cy) {
+        DerivativeStructure dx = cx.subtract(point.getX());
+        DerivativeStructure dy = cy.subtract(point.getY());
+        return dx.multiply(dx).add(dy.multiply(dy)).sqrt();
+    }
 
-        // gradient of the sum of squared residuals
-        double dJdX = 0;
-        double dJdY = 0;
-        for (Point2D.Double pk : points) {
-            double dk = pk.distance(center);
-            dJdX += (center.x - pk.x) * (dk - radius) / dk;
-            dJdY += (center.y - pk.y) * (dk - radius) / dk;
+    public DerivativeStructure getRadius(DerivativeStructure cx, DerivativeStructure cy) {
+        DerivativeStructure r = cx.getField().getZero();
+        for (Vector2D point : points) {
+            r = r.add(distance(point, cx, cy));
         }
-        dJdX *= 2;
-        dJdY *= 2;
-
-        return new double[] { dJdX, dJdY };
+        return r.divide(points.size());
     }
 
     public double value(double[] variables)  {
-        Point2D.Double center = new Point2D.Double(variables[0], variables[1]);
+        Vector2D center = new Vector2D(variables[0], variables[1]);
         double radius = getRadius(center);
 
         double sum = 0;
-        for (Point2D.Double point : points) {
+        for (Vector2D point : points) {
             double di = point.distance(center) - radius;
             sum += di * di;
         }
@@ -77,19 +73,16 @@ class CircleScalar implements Differenti
         return sum;
     }
 
-    public MultivariateVectorFunction gradient() {
-        return new MultivariateVectorFunction() {
-            public double[] value(double[] point) {
-                return gradient(point);
-            }
-        };
-    }
+    public DerivativeStructure value(DerivativeStructure[] variables)  {
+        DerivativeStructure radius = getRadius(variables[0], variables[1]);
 
-    public MultivariateFunction partialDerivative(final int k) {
-        return new MultivariateFunction() {
-            public double value(double[] point) {
-                return gradient(point)[k];
-            }
-        };
+        DerivativeStructure sum = variables[0].getField().getZero();
+        for (Vector2D point : points) {
+            DerivativeStructure di = distance(point, variables[0], variables[1]).subtract(radius);
+            sum = sum.add(di.multiply(di));
+        }
+
+        return sum;
     }
+
 }

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/CircleVectorial.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/CircleVectorial.java?rev=1384907&r1=1384906&r2=1384907&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/CircleVectorial.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/CircleVectorial.java Fri Sep 14 20:17:00 2012
@@ -17,66 +17,55 @@
 
 package org.apache.commons.math3.optimization.general;
 
-import java.awt.geom.Point2D;
 import java.util.ArrayList;
-import org.apache.commons.math3.analysis.DifferentiableMultivariateVectorFunction;
-import org.apache.commons.math3.analysis.MultivariateMatrixFunction;
+
+import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
+import org.apache.commons.math3.analysis.differentiation.MultivariateDifferentiableVectorFunction;
+import org.apache.commons.math3.geometry.euclidean.twod.Vector2D;
 
 /**
  * Class used in the tests.
  */
-class CircleVectorial implements DifferentiableMultivariateVectorFunction {
-    private ArrayList<Point2D.Double> points;
+class CircleVectorial implements MultivariateDifferentiableVectorFunction {
+    private ArrayList<Vector2D> points;
 
     public CircleVectorial() {
-        points  = new ArrayList<Point2D.Double>();
+        points  = new ArrayList<Vector2D>();
     }
 
     public void addPoint(double px, double py) {
-        points.add(new Point2D.Double(px, py));
+        points.add(new Vector2D(px, py));
     }
 
     public int getN() {
         return points.size();
     }
 
-    public double getRadius(Point2D.Double center) {
+    public double getRadius(Vector2D center) {
         double r = 0;
-        for (Point2D.Double point : points) {
+        for (Vector2D point : points) {
             r += point.distance(center);
         }
         return r / points.size();
     }
 
-    private double[][] jacobian(double[] point) {
-        int n = points.size();
-        Point2D.Double center = new Point2D.Double(point[0], point[1]);
-
-        // gradient of the optimal radius
-        double dRdX = 0;
-        double dRdY = 0;
-        for (Point2D.Double pk : points) {
-            double dk = pk.distance(center);
-            dRdX += (center.x - pk.x) / dk;
-            dRdY += (center.y - pk.y) / dk;
-        }
-        dRdX /= n;
-        dRdY /= n;
+    private DerivativeStructure distance(Vector2D point,
+                                         DerivativeStructure cx, DerivativeStructure cy) {
+        DerivativeStructure dx = cx.subtract(point.getX());
+        DerivativeStructure dy = cy.subtract(point.getY());
+        return dx.multiply(dx).add(dy.multiply(dy)).sqrt();
+    }
 
-        // jacobian of the radius residuals
-        double[][] jacobian = new double[n][2];
-        for (int i = 0; i < n; ++i) {
-            Point2D.Double pi = points.get(i);
-            double di   = pi.distance(center);
-            jacobian[i][0] = (center.x - pi.x) / di - dRdX;
-            jacobian[i][1] = (center.y - pi.y) / di - dRdY;
+    public DerivativeStructure getRadius(DerivativeStructure cx, DerivativeStructure cy) {
+        DerivativeStructure r = cx.getField().getZero();
+        for (Vector2D point : points) {
+            r = r.add(distance(point, cx, cy));
         }
-
-        return jacobian;
+        return r.divide(points.size());
     }
 
     public double[] value(double[] variables) {
-        Point2D.Double center = new Point2D.Double(variables[0], variables[1]);
+        Vector2D center = new Vector2D(variables[0], variables[1]);
         double radius = getRadius(center);
 
         double[] residuals = new double[points.size()];
@@ -87,11 +76,15 @@ class CircleVectorial implements Differe
         return residuals;
     }
 
-    public MultivariateMatrixFunction jacobian() {
-        return new MultivariateMatrixFunction() {
-            public double[][] value(double[] point) {
-                return jacobian(point);
-            }
-        };
+    public DerivativeStructure[] value(DerivativeStructure[] variables) {
+        DerivativeStructure radius = getRadius(variables[0], variables[1]);
+
+        DerivativeStructure[] residuals = new DerivativeStructure[points.size()];
+        for (int i = 0; i < residuals.length; ++i) {
+            residuals[i] = distance(points.get(i), variables[0], variables[1]).subtract(radius);
+        }
+
+        return residuals;
     }
+
 }

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/LevenbergMarquardtOptimizerTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/LevenbergMarquardtOptimizerTest.java?rev=1384907&r1=1384906&r2=1384907&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/LevenbergMarquardtOptimizerTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/LevenbergMarquardtOptimizerTest.java Fri Sep 14 20:17:00 2012
@@ -17,16 +17,16 @@
 
 package org.apache.commons.math3.optimization.general;
 
-import java.awt.geom.Point2D;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.commons.math3.analysis.DifferentiableMultivariateVectorFunction;
-import org.apache.commons.math3.analysis.MultivariateMatrixFunction;
+import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
+import org.apache.commons.math3.analysis.differentiation.MultivariateDifferentiableVectorFunction;
 import org.apache.commons.math3.exception.ConvergenceException;
 import org.apache.commons.math3.exception.DimensionMismatchException;
 import org.apache.commons.math3.exception.TooManyEvaluationsException;
+import org.apache.commons.math3.geometry.euclidean.twod.Vector2D;
 import org.apache.commons.math3.linear.SingularMatrixException;
 import org.apache.commons.math3.optimization.PointVectorValuePair;
 import org.apache.commons.math3.util.FastMath;
@@ -120,7 +120,7 @@ public class LevenbergMarquardtOptimizer
         optimizer.optimize(100, problem, problem.target, new double[] { 1, 1, 1 }, new double[] { 0, 0, 0 });
         Assert.assertTrue(FastMath.sqrt(problem.target.length) * optimizer.getRMS() > 0.6);
 
-        double[][] cov = optimizer.getCovariances(1.5e-14);
+        optimizer.getCovariances(1.5e-14);
     }
 
     @Test
@@ -138,7 +138,7 @@ public class LevenbergMarquardtOptimizer
         checkEstimate(circle, 0.1, 20, 1.0e-18, 1.0e-16, 1.0e-10, true);
     }
 
-    private void checkEstimate(DifferentiableMultivariateVectorFunction problem,
+    private void checkEstimate(MultivariateDifferentiableVectorFunction problem,
                                double initialStepBoundFactor, int maxCostEval,
                                double costRelativeTolerance, double parRelativeTolerance,
                                double orthoTolerance, boolean shouldFail) {
@@ -225,7 +225,6 @@ public class LevenbergMarquardtOptimizer
             optimizer.optimize(100, problem, dataPoints[1], weights,
                                new double[] { 10, 900, 80, 27, 225 });
 
-        final double chi2 = optimizer.getChiSquare();
         final double[] solution = optimum.getPoint();
         final double[] expectedSolution = { 10.4, 958.3, 131.4, 33.9, 205.0 };
 
@@ -274,8 +273,8 @@ public class LevenbergMarquardtOptimizer
         final CircleProblem circle = new CircleProblem(xSigma, ySigma);
 
         final int numPoints = 10;
-        for (Point2D.Double p : factory.generate(numPoints)) {
-            circle.addPoint(p.x, p.y);
+        for (Vector2D p : factory.generate(numPoints)) {
+            circle.addPoint(p);
             // System.out.println(p.x + " " + p.y);
         }
 
@@ -309,7 +308,7 @@ public class LevenbergMarquardtOptimizer
         Assert.assertEquals(radius, paramFound[2], asymptoticStandardErrorFound[2]);
     }
 
-    private static class QuadraticProblem implements DifferentiableMultivariateVectorFunction, Serializable {
+    private static class QuadraticProblem implements MultivariateDifferentiableVectorFunction, Serializable {
 
         private static final long serialVersionUID = 7072187082052755854L;
         private List<Double> x;
@@ -325,16 +324,6 @@ public class LevenbergMarquardtOptimizer
             this.y.add(y);
         }
 
-        private double[][] jacobian(double[] variables) {
-            double[][] jacobian = new double[x.size()][3];
-            for (int i = 0; i < jacobian.length; ++i) {
-                jacobian[i][0] = x.get(i) * x.get(i);
-                jacobian[i][1] = x.get(i);
-                jacobian[i][2] = 1.0;
-            }
-            return jacobian;
-        }
-
         public double[] value(double[] variables) {
             double[] values = new double[x.size()];
             for (int i = 0; i < values.length; ++i) {
@@ -343,17 +332,18 @@ public class LevenbergMarquardtOptimizer
             return values;
         }
 
-        public MultivariateMatrixFunction jacobian() {
-            return new MultivariateMatrixFunction() {
-                public double[][] value(double[] point) {
-                    return jacobian(point);
-                }
-            };
+        public DerivativeStructure[] value(DerivativeStructure[] variables) {
+            DerivativeStructure[] values = new DerivativeStructure[x.size()];
+            for (int i = 0; i < values.length; ++i) {
+                values[i] = (variables[0].multiply(x.get(i)).add(variables[1])).multiply(x.get(i)).add(variables[2]);
+            }
+            return values;
         }
+
     }
 
     private static class BevingtonProblem
-        implements DifferentiableMultivariateVectorFunction {
+        implements MultivariateDifferentiableVectorFunction {
         private List<Double> time;
         private List<Double> count;
 
@@ -367,25 +357,6 @@ public class LevenbergMarquardtOptimizer
             count.add(c);
         }
 
-        private double[][] jacobian(double[] params) {
-            double[][] jacobian = new double[time.size()][5];
-
-            for (int i = 0; i < jacobian.length; ++i) {
-                final double t = time.get(i);
-                jacobian[i][0] = 1;
-
-                final double p3 =  params[3];
-                final double p4 =  params[4];
-                final double tOp3 = t / p3;
-                final double tOp4 = t / p4;
-                jacobian[i][1] = Math.exp(-tOp3);
-                jacobian[i][2] = Math.exp(-tOp4);
-                jacobian[i][3] = params[1] * Math.exp(-tOp3) * tOp3 / p3;
-                jacobian[i][4] = params[2] * Math.exp(-tOp4) * tOp4 / p4;
-            }
-            return jacobian;
-        }
-
         public double[] value(double[] params) {
             double[] values = new double[time.size()];
             for (int i = 0; i < values.length; ++i) {
@@ -397,12 +368,16 @@ public class LevenbergMarquardtOptimizer
             return values;
         }
 
-        public MultivariateMatrixFunction jacobian() {
-            return new MultivariateMatrixFunction() {
-                public double[][] value(double[] point) {
-                    return jacobian(point);
-                }
-            };
+        public DerivativeStructure[] value(DerivativeStructure[] params) {
+            DerivativeStructure[] values = new DerivativeStructure[time.size()];
+            for (int i = 0; i < values.length; ++i) {
+                final double t = time.get(i);
+                values[i] = params[0].add(
+                    params[1].multiply(params[3].reciprocal().multiply(-t).exp())).add(
+                    params[2].multiply(params[4].reciprocal().multiply(-t).exp()));
+            }
+            return values;
         }
+
     }
 }

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/MinpackTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/MinpackTest.java?rev=1384907&r1=1384906&r2=1384907&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/MinpackTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/MinpackTest.java Fri Sep 14 20:17:00 2012
@@ -22,8 +22,8 @@ import java.util.Arrays;
 
 
 import org.apache.commons.math3.exception.TooManyEvaluationsException;
-import org.apache.commons.math3.analysis.DifferentiableMultivariateVectorFunction;
-import org.apache.commons.math3.analysis.MultivariateMatrixFunction;
+import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
+import org.apache.commons.math3.analysis.differentiation.MultivariateDifferentiableVectorFunction;
 import org.apache.commons.math3.optimization.PointVectorValuePair;
 import org.apache.commons.math3.util.FastMath;
 import org.junit.Assert;
@@ -522,7 +522,7 @@ public class MinpackTest {
   }
 
   private static abstract class MinpackFunction
-      implements DifferentiableMultivariateVectorFunction, Serializable {
+      implements MultivariateDifferentiableVectorFunction, Serializable {
 
       private static final long serialVersionUID = -6209760235478794233L;
       protected int      n;
@@ -590,17 +590,20 @@ public class MinpackTest {
           }
       }
 
-      public MultivariateMatrixFunction jacobian() {
-          return new MultivariateMatrixFunction() {
-            public double[][] value(double[] point) {
-                  return jacobian(point);
-              }
-          };
+      public double[] value(double[] variables) {
+          DerivativeStructure[] dsV = new DerivativeStructure[variables.length];
+          for (int i = 0; i < variables.length; ++i) {
+              dsV[i] = new DerivativeStructure(0, 0, variables[i]);
+          }
+          DerivativeStructure[] dsY = value(dsV);
+          double[] y = new double[dsY.length];
+          for (int i = 0; i < dsY.length; ++i) {
+              y[i] = dsY[i].getValue();
+          }
+          return y;
       }
 
-      public abstract double[][] jacobian(double[] variables);
-
-      public abstract double[] value(double[] variables);
+      public abstract DerivativeStructure[] value(DerivativeStructure[] variables);
 
   }
 
@@ -616,30 +619,17 @@ public class MinpackTest {
     }
 
     @Override
-    public double[][] jacobian(double[] variables) {
-      double t = 2.0 / m;
-      double[][] jacobian = new double[m][];
-      for (int i = 0; i < m; ++i) {
-        jacobian[i] = new double[n];
-        for (int j = 0; j < n; ++j) {
-          jacobian[i][j] = (i == j) ? (1 - t) : -t;
-        }
-      }
-      return jacobian;
-    }
-
-    @Override
-    public double[] value(double[] variables) {
-      double sum = 0;
+    public DerivativeStructure[] value(DerivativeStructure[] variables) {
+      DerivativeStructure sum = variables[0].getField().getZero();
       for (int i = 0; i < n; ++i) {
-        sum += variables[i];
+        sum = sum.add(variables[i]);
       }
-      double t  = 1 + 2 * sum / m;
-      double[] f = new double[m];
+      DerivativeStructure t  = sum.multiply(2.0 / m).add(1);
+      DerivativeStructure[] f = new DerivativeStructure[m];
       for (int i = 0; i < n; ++i) {
-        f[i] = variables[i] - t;
+        f[i] = variables[i].subtract(t);
       }
-      Arrays.fill(f, n, m, -t);
+      Arrays.fill(f, n, m, t.negate());
       return f;
     }
 
@@ -656,28 +646,16 @@ public class MinpackTest {
     }
 
     @Override
-    public double[][] jacobian(double[] variables) {
-      double[][] jacobian = new double[m][];
-      for (int i = 0; i < m; ++i) {
-        jacobian[i] = new double[n];
-        for (int j = 0; j < n; ++j) {
-          jacobian[i][j] = (i + 1) * (j + 1);
+    public DerivativeStructure[] value(DerivativeStructure[] variables) {
+        DerivativeStructure[] f = new DerivativeStructure[m];
+        DerivativeStructure sum = variables[0].getField().getZero();
+        for (int i = 0; i < n; ++i) {
+            sum = sum.add(variables[i].multiply(i + 1));
         }
-      }
-      return jacobian;
-    }
-
-    @Override
-    public double[] value(double[] variables) {
-      double[] f = new double[m];
-      double sum = 0;
-      for (int i = 0; i < n; ++i) {
-        sum += (i + 1) * variables[i];
-      }
-      for (int i = 0; i < m; ++i) {
-        f[i] = (i + 1) * sum - 1;
-      }
-      return f;
+        for (int i = 0; i < m; ++i) {
+            f[i] = sum.multiply(i + 1).subtract(1);
+        }
+        return f;
     }
 
   }
@@ -693,36 +671,16 @@ public class MinpackTest {
     }
 
     @Override
-    public double[][] jacobian(double[] variables) {
-      double[][] jacobian = new double[m][];
-      for (int i = 0; i < m; ++i) {
-        jacobian[i] = new double[n];
-        jacobian[i][0] = 0;
-        for (int j = 1; j < (n - 1); ++j) {
-          if (i == 0) {
-            jacobian[i][j] = 0;
-          } else if (i != (m - 1)) {
-            jacobian[i][j] = i * (j + 1);
-          } else {
-            jacobian[i][j] = 0;
-          }
-        }
-        jacobian[i][n - 1] = 0;
-      }
-      return jacobian;
-    }
-
-    @Override
-    public double[] value(double[] variables) {
-      double[] f = new double[m];
-      double sum = 0;
+    public DerivativeStructure[] value(DerivativeStructure[] variables) {
+        DerivativeStructure[] f = new DerivativeStructure[m];
+        DerivativeStructure sum = variables[0].getField().getZero();
       for (int i = 1; i < (n - 1); ++i) {
-        sum += (i + 1) * variables[i];
+          sum = sum.add(variables[i].multiply(i + 1));
       }
       for (int i = 0; i < (m - 1); ++i) {
-        f[i] = i * sum - 1;
+        f[i] = sum.multiply(i).subtract(1);
       }
-      f[m - 1] = -1;
+      f[m - 1] = variables[0].getField().getOne().negate();
       return f;
     }
 
@@ -737,16 +695,13 @@ public class MinpackTest {
     }
 
     @Override
-    public double[][] jacobian(double[] variables) {
-      double x1 = variables[0];
-      return new double[][] { { -20 * x1, 10 }, { -1, 0 } };
-    }
-
-    @Override
-    public double[] value(double[] variables) {
-      double x1 = variables[0];
-      double x2 = variables[1];
-      return new double[] { 10 * (x2 - x1 * x1), 1 - x1 };
+    public DerivativeStructure[] value(DerivativeStructure[] variables) {
+        DerivativeStructure x1 = variables[0];
+        DerivativeStructure x2 = variables[1];
+        return new DerivativeStructure[] {
+            x2.subtract(x1.multiply(x1)).multiply(10),
+            x1.negate().add(1)
+        };
     }
 
   }
@@ -761,39 +716,25 @@ public class MinpackTest {
     }
 
     @Override
-    public double[][] jacobian(double[] variables) {
-      double x1 = variables[0];
-      double x2 = variables[1];
-      double tmpSquare = x1 * x1 + x2 * x2;
-      double tmp1 = twoPi * tmpSquare;
-      double tmp2 = FastMath.sqrt(tmpSquare);
-      return new double[][] {
-        {  100 * x2 / tmp1, -100 * x1 / tmp1, 10 },
-        { 10 * x1 / tmp2, 10 * x2 / tmp2, 0 },
-        { 0, 0, 1 }
-      };
-    }
-
-    @Override
-    public double[] value(double[] variables) {
-      double x1 = variables[0];
-      double x2 = variables[1];
-      double x3 = variables[2];
-      double tmp1;
-      if (x1 == 0) {
-        tmp1 = (x2 >= 0) ? 0.25 : -0.25;
-      } else {
-        tmp1 = FastMath.atan(x2 / x1) / twoPi;
-        if (x1 < 0) {
-          tmp1 += 0.5;
+    public DerivativeStructure[] value(DerivativeStructure[] variables) {
+        DerivativeStructure x1 = variables[0];
+        DerivativeStructure x2 = variables[1];
+        DerivativeStructure x3 = variables[2];
+        DerivativeStructure tmp1 = variables[0].getField().getZero();
+        if (x1.getValue() == 0) {
+            tmp1 = tmp1.add((x2.getValue() >= 0) ? 0.25 : -0.25);
+        } else {
+            tmp1 = x2.divide(x1).atan().divide(twoPi);
+            if (x1.getValue() < 0) {
+                tmp1 = tmp1.add(0.5);
+            }
         }
-      }
-      double tmp2 = FastMath.sqrt(x1 * x1 + x2 * x2);
-      return new double[] {
-        10.0 * (x3 - 10 * tmp1),
-        10.0 * (tmp2 - 1),
-        x3
-      };
+        DerivativeStructure tmp2 = x1.multiply(x1).add(x2.multiply(x2)).sqrt();
+        return new DerivativeStructure[] {
+            x3.subtract(tmp1.multiply(10)).multiply(10),
+            tmp2.subtract(1).multiply(10),
+            x3
+        };
     }
 
     private static final double twoPi = 2.0 * FastMath.PI;
@@ -810,30 +751,16 @@ public class MinpackTest {
     }
 
     @Override
-    public double[][] jacobian(double[] variables) {
-      double x1 = variables[0];
-      double x2 = variables[1];
-      double x3 = variables[2];
-      double x4 = variables[3];
-      return new double[][] {
-        { 1, 10, 0, 0 },
-        { 0, 0, sqrt5, -sqrt5 },
-        { 0, 2 * (x2 - 2 * x3), -4 * (x2 - 2 * x3), 0 },
-        { 2 * sqrt10 * (x1 - x4), 0, 0, -2 * sqrt10 * (x1 - x4) }
-      };
-    }
-
-    @Override
-    public double[] value(double[] variables) {
-      double x1 = variables[0];
-      double x2 = variables[1];
-      double x3 = variables[2];
-      double x4 = variables[3];
-      return new double[] {
-        x1 + 10 * x2,
-        sqrt5 * (x3 - x4),
-        (x2 - 2 * x3) * (x2 - 2 * x3),
-        sqrt10 * (x1 - x4) * (x1 - x4)
+    public DerivativeStructure[] value(DerivativeStructure[] variables) {
+        DerivativeStructure x1 = variables[0];
+        DerivativeStructure x2 = variables[1];
+        DerivativeStructure x3 = variables[2];
+        DerivativeStructure x4 = variables[3];
+      return new DerivativeStructure[] {
+        x1.add(x2.multiply(10)),
+        x3.subtract(x4).multiply(sqrt5),
+        x2.subtract(x3.multiply(2)).multiply(x2.subtract(x3.multiply(2))),
+        x1.subtract(x4).multiply(x1.subtract(x4)).multiply(sqrt10)
       };
     }
 
@@ -855,22 +782,13 @@ public class MinpackTest {
     }
 
     @Override
-    public double[][] jacobian(double[] variables) {
-      double x2 = variables[1];
-      return new double[][] {
-        { 1, x2 * (10 - 3 * x2) -  2 },
-        { 1, x2 * ( 2 + 3 * x2) - 14, }
-      };
-    }
-
-    @Override
-    public double[] value(double[] variables) {
-      double x1 = variables[0];
-      double x2 = variables[1];
-      return new double[] {
-       -13.0 + x1 + ((5.0 - x2) * x2 -  2.0) * x2,
-       -29.0 + x1 + ((1.0 + x2) * x2 - 14.0) * x2
-      };
+    public DerivativeStructure[] value(DerivativeStructure[] variables) {
+        DerivativeStructure x1 = variables[0];
+        DerivativeStructure x2 = variables[1];
+        return new DerivativeStructure[] {
+            x1.subtract(13.0).add(x2.negate().add(5.0).multiply(x2).subtract(2).multiply(x2)),
+            x1.subtract(29.0).add(x2.add(1).multiply(x2).subtract(14).multiply(x2))
+        };
     }
 
   }
@@ -888,32 +806,16 @@ public class MinpackTest {
     }
 
     @Override
-    public double[][] jacobian(double[] variables) {
-      double   x2 = variables[1];
-      double   x3 = variables[2];
-      double[][] jacobian = new double[m][];
-      for (int i = 0; i < m; ++i) {
-        double tmp1 = i  + 1;
-        double tmp2 = 15 - i;
-        double tmp3 = (i <= 7) ? tmp1 : tmp2;
-        double tmp4 = x2 * tmp2 + x3 * tmp3;
-        tmp4 *= tmp4;
-        jacobian[i] = new double[] { -1, tmp1 * tmp2 / tmp4, tmp1 * tmp3 / tmp4 };
-      }
-      return jacobian;
-    }
-
-    @Override
-    public double[] value(double[] variables) {
-      double   x1 = variables[0];
-      double   x2 = variables[1];
-      double   x3 = variables[2];
-      double[] f = new double[m];
+    public DerivativeStructure[] value(DerivativeStructure[] variables) {
+        DerivativeStructure   x1 = variables[0];
+        DerivativeStructure   x2 = variables[1];
+        DerivativeStructure   x3 = variables[2];
+        DerivativeStructure[] f = new DerivativeStructure[m];
       for (int i = 0; i < m; ++i) {
         double tmp1 = i + 1;
         double tmp2 = 15 - i;
         double tmp3 = (i <= 7) ? tmp1 : tmp2;
-        f[i] = y[i] - (x1 + tmp1 / (x2 * tmp2 + x3 * tmp3));
+        f[i] = x1.add(x2.multiply(tmp2).add(x3.multiply(tmp3)).reciprocal().multiply(tmp1)).negate().add(y[i]);
       }
       return f;
     }
@@ -943,34 +845,16 @@ public class MinpackTest {
     }
 
     @Override
-    public double[][] jacobian(double[] variables) {
-      double   x1 = variables[0];
-      double   x2 = variables[1];
-      double   x3 = variables[2];
-      double   x4 = variables[3];
-      double[][] jacobian = new double[m][];
-      for (int i = 0; i < m; ++i) {
-        double tmp = v[i] * (v[i] + x3) + x4;
-        double j1  = -v[i] * (v[i] + x2) / tmp;
-        double j2  = -v[i] * x1 / tmp;
-        double j3  = j1 * j2;
-        double j4  = j3 / v[i];
-        jacobian[i] = new double[] { j1, j2, j3, j4 };
-      }
-      return jacobian;
-    }
-
-    @Override
-    public double[] value(double[] variables) {
-      double x1 = variables[0];
-      double x2 = variables[1];
-      double x3 = variables[2];
-      double x4 = variables[3];
-      double[] f = new double[m];
-      for (int i = 0; i < m; ++i) {
-        f[i] = y[i] - x1 * (v[i] * (v[i] + x2)) / (v[i] * (v[i] + x3) + x4);
-      }
-      return f;
+    public DerivativeStructure[] value(DerivativeStructure[] variables) {
+        DerivativeStructure x1 = variables[0];
+        DerivativeStructure x2 = variables[1];
+        DerivativeStructure x3 = variables[2];
+        DerivativeStructure x4 = variables[3];
+        DerivativeStructure[] f = new DerivativeStructure[m];
+        for (int i = 0; i < m; ++i) {
+            f[i] = x1.multiply(x2.add(v[i]).multiply(v[i])).divide(x4.add(x3.add(v[i]).multiply(v[i]))).negate().add(y[i]);
+        }
+        return f;
     }
 
     private static final double[] v = {
@@ -1001,29 +885,13 @@ public class MinpackTest {
     }
 
     @Override
-    public double[][] jacobian(double[] variables) {
-      double   x1 = variables[0];
-      double   x2 = variables[1];
-      double   x3 = variables[2];
-      double[][] jacobian = new double[m][];
+    public DerivativeStructure[] value(DerivativeStructure[] variables) {
+        DerivativeStructure x1 = variables[0];
+        DerivativeStructure x2 = variables[1];
+        DerivativeStructure x3 = variables[2];
+        DerivativeStructure[] f = new DerivativeStructure[m];
       for (int i = 0; i < m; ++i) {
-        double temp = 5.0 * (i + 1) + 45.0 + x3;
-        double tmp1 = x2 / temp;
-        double tmp2 = FastMath.exp(tmp1);
-        double tmp3 = x1 * tmp2 / temp;
-        jacobian[i] = new double[] { tmp2, tmp3, -tmp1 * tmp3 };
-      }
-      return jacobian;
-    }
-
-    @Override
-    public double[] value(double[] variables) {
-      double x1 = variables[0];
-      double x2 = variables[1];
-      double x3 = variables[2];
-      double[] f = new double[m];
-      for (int i = 0; i < m; ++i) {
-        f[i] = x1 * FastMath.exp(x2 / (5.0 * (i + 1) + 45.0 + x3)) - y[i];
+        f[i] = x1.multiply(x2.divide(x3.add(5.0 * (i + 1) + 45.0)).exp()).subtract(y[i]);
       }
      return f;
     }
@@ -1050,64 +918,31 @@ public class MinpackTest {
     }
 
     @Override
-    public double[][] jacobian(double[] variables) {
-
-      double[][] jacobian = new double[m][];
-
-      for (int i = 0; i < (m - 2); ++i) {
-        double div = (i + 1) / 29.0;
-        double s2  = 0.0;
-        double dx  = 1.0;
-        for (int j = 0; j < n; ++j) {
-          s2 += dx * variables[j];
-          dx *= div;
-        }
-        double temp= 2 * div * s2;
-        dx = 1.0 / div;
-        jacobian[i] = new double[n];
-        for (int j = 0; j < n; ++j) {
-          jacobian[i][j] = dx * (j - temp);
-          dx *= div;
+    public DerivativeStructure[] value(DerivativeStructure[] variables) {
+        DerivativeStructure[] f = new DerivativeStructure[m];
+        for (int i = 0; i < (m - 2); ++i) {
+            double div = (i + 1) / 29.0;
+            DerivativeStructure s1 = variables[0].getField().getZero();
+            DerivativeStructure dx = variables[0].getField().getOne();
+            for (int j = 1; j < n; ++j) {
+                s1 = s1.add(dx.multiply(j).multiply(variables[j]));
+                dx = dx.multiply(div);
+            }
+            DerivativeStructure s2 = variables[0].getField().getZero();
+            dx = variables[0].getField().getOne();
+            for (int j = 0; j < n; ++j) {
+                s2 = s2.add(dx.multiply(variables[j]));
+                dx = dx.multiply(div);
+            }
+            f[i] = s1.subtract(s2.multiply(s2)).subtract(1);
         }
-      }
-
-      jacobian[m - 2]    = new double[n];
-      jacobian[m - 2][0] = 1;
-
-      jacobian[m - 1]   = new double[n];
-      jacobian[m - 1][0]= -2 * variables[0];
-      jacobian[m - 1][1]= 1;
-
-      return jacobian;
-
-    }
 
-    @Override
-    public double[] value(double[] variables) {
-     double[] f = new double[m];
-     for (int i = 0; i < (m - 2); ++i) {
-       double div = (i + 1) / 29.0;
-       double s1 = 0;
-       double dx = 1;
-       for (int j = 1; j < n; ++j) {
-         s1 += j * dx * variables[j];
-         dx *= div;
-       }
-       double s2 =0;
-       dx =1;
-       for (int j = 0; j < n; ++j) {
-         s2 += dx * variables[j];
-         dx *= div;
-       }
-       f[i] = s1 - s2 * s2 - 1;
-     }
-
-     double x1 = variables[0];
-     double x2 = variables[1];
-     f[m - 2] = x1;
-     f[m - 1] = x2 - x1 * x1 - 1;
+        DerivativeStructure x1 = variables[0];
+        DerivativeStructure x2 = variables[1];
+        f[m - 2] = x1;
+        f[m - 1] = x2.subtract(x1.multiply(x1)).subtract(1);
 
-     return f;
+        return f;
 
     }
 
@@ -1124,31 +959,15 @@ public class MinpackTest {
    }
 
     @Override
-    public double[][] jacobian(double[] variables) {
-      double   x1 = variables[0];
-      double   x2 = variables[1];
-      double[][] jacobian = new double[m][];
+    public DerivativeStructure[] value(DerivativeStructure[] variables) {
+        DerivativeStructure x1 = variables[0];
+        DerivativeStructure x2 = variables[1];
+        DerivativeStructure x3 = variables[2];
+        DerivativeStructure[] f = new DerivativeStructure[m];
       for (int i = 0; i < m; ++i) {
         double tmp = (i + 1) / 10.0;
-        jacobian[i] = new double[] {
-          -tmp * FastMath.exp(-tmp * x1),
-           tmp * FastMath.exp(-tmp * x2),
-          FastMath.exp(-i - 1) - FastMath.exp(-tmp)
-        };
-      }
-      return jacobian;
-    }
-
-    @Override
-    public double[] value(double[] variables) {
-      double x1 = variables[0];
-      double x2 = variables[1];
-      double x3 = variables[2];
-      double[] f = new double[m];
-      for (int i = 0; i < m; ++i) {
-        double tmp = (i + 1) / 10.0;
-        f[i] = FastMath.exp(-tmp * x1) - FastMath.exp(-tmp * x2)
-             + (FastMath.exp(-i - 1) - FastMath.exp(-tmp)) * x3;
+        f[i] = x1.multiply(-tmp).exp().subtract(x2.multiply(-tmp).exp()).add(
+                  x3.multiply(FastMath.exp(-i - 1) - FastMath.exp(-tmp)));
       }
       return f;
     }
@@ -1168,27 +987,15 @@ public class MinpackTest {
     }
 
     @Override
-    public double[][] jacobian(double[] variables) {
-      double   x1 = variables[0];
-      double   x2 = variables[1];
-      double[][] jacobian = new double[m][];
-      for (int i = 0; i < m; ++i) {
-        double t = i + 1;
-        jacobian[i] = new double[] { -t * FastMath.exp(t * x1), -t * FastMath.exp(t * x2) };
-      }
-      return jacobian;
-    }
-
-    @Override
-    public double[] value(double[] variables) {
-      double x1 = variables[0];
-      double x2 = variables[1];
-      double[] f = new double[m];
-      for (int i = 0; i < m; ++i) {
-        double temp = i + 1;
-        f[i] = 2 + 2 * temp - FastMath.exp(temp * x1) - FastMath.exp(temp * x2);
-      }
-      return f;
+    public DerivativeStructure[] value(DerivativeStructure[] variables) {
+        DerivativeStructure x1 = variables[0];
+        DerivativeStructure x2 = variables[1];
+        DerivativeStructure[] f = new DerivativeStructure[m];
+        for (int i = 0; i < m; ++i) {
+            double temp = i + 1;
+            f[i] = x1.multiply(temp).exp().add(x2.multiply(temp).exp()).subtract(2 + 2 * temp).negate();
+        }
+        return f;
     }
 
   }
@@ -1207,38 +1014,19 @@ public class MinpackTest {
     }
 
     @Override
-    public double[][] jacobian(double[] variables) {
-      double   x1 = variables[0];
-      double   x2 = variables[1];
-      double   x3 = variables[2];
-      double   x4 = variables[3];
-      double[][] jacobian = new double[m][];
-      for (int i = 0; i < m; ++i) {
-        double temp = (i + 1) / 5.0;
-        double ti   = FastMath.sin(temp);
-        double tmp1 = x1 + temp * x2 - FastMath.exp(temp);
-        double tmp2 = x3 + ti   * x4 - FastMath.cos(temp);
-        jacobian[i] = new double[] {
-          2 * tmp1, 2 * temp * tmp1, 2 * tmp2, 2 * ti * tmp2
-        };
-      }
-      return jacobian;
-    }
-
-    @Override
-    public double[] value(double[] variables) {
-      double x1 = variables[0];
-      double x2 = variables[1];
-      double x3 = variables[2];
-      double x4 = variables[3];
-      double[] f = new double[m];
-      for (int i = 0; i < m; ++i) {
-        double temp = (i + 1) / 5.0;
-        double tmp1 = x1 + temp * x2 - FastMath.exp(temp);
-        double tmp2 = x3 + FastMath.sin(temp) * x4 - FastMath.cos(temp);
-        f[i] = tmp1 * tmp1 + tmp2 * tmp2;
-      }
-      return f;
+    public DerivativeStructure[] value(DerivativeStructure[] variables) {
+        DerivativeStructure x1 = variables[0];
+        DerivativeStructure x2 = variables[1];
+        DerivativeStructure x3 = variables[2];
+        DerivativeStructure x4 = variables[3];
+        DerivativeStructure[] f = new DerivativeStructure[m];
+        for (int i = 0; i < m; ++i) {
+            double temp = (i + 1) / 5.0;
+            DerivativeStructure tmp1 = x1.add(x2.multiply(temp)).subtract(FastMath.exp(temp));
+            DerivativeStructure tmp2 = x3.add(x4.multiply(FastMath.sin(temp))).subtract(FastMath.cos(temp));
+            f[i] = tmp1.multiply(tmp1).add(tmp2.multiply(tmp2));
+        }
+        return f;
     }
 
   }
@@ -1265,63 +1053,34 @@ public class MinpackTest {
     }
 
     @Override
-    public double[][] jacobian(double[] variables) {
+    public DerivativeStructure[] value(DerivativeStructure[] variables) {
 
-      double[][] jacobian = new double[m][];
-      for (int i = 0; i < m; ++i) {
-        jacobian[i] = new double[n];
-      }
+        DerivativeStructure[] f = new DerivativeStructure[m];
+        Arrays.fill(f, variables[0].getField().getZero());
 
-      double dx = 1.0 / n;
-      for (int j = 0; j < n; ++j) {
-        double tmp1 = 1;
-        double tmp2 = 2 * variables[j] - 1;
-        double temp = 2 * tmp2;
-        double tmp3 = 0;
-        double tmp4 = 2;
-        for (int i = 0; i < m; ++i) {
-          jacobian[i][j] = dx * tmp4;
-          double ti = 4 * tmp2 + temp * tmp4 - tmp3;
-          tmp3 = tmp4;
-          tmp4 = ti;
-          ti   = temp * tmp2 - tmp1;
-          tmp1 = tmp2;
-          tmp2 = ti;
+        for (int j = 0; j < n; ++j) {
+            DerivativeStructure tmp1 = variables[0].getField().getOne();
+            DerivativeStructure tmp2 = variables[j].multiply(2).subtract(1);
+            DerivativeStructure temp = tmp2.multiply(2);
+            for (int i = 0; i < m; ++i) {
+                f[i] = f[i].add(tmp2);
+                DerivativeStructure ti = temp.multiply(tmp2).subtract(tmp1);
+                tmp1 = tmp2;
+                tmp2 = ti;
+            }
         }
-      }
-
-      return jacobian;
-
-    }
-
-    @Override
-    public double[] value(double[] variables) {
-
-      double[] f = new double[m];
 
-      for (int j = 0; j < n; ++j) {
-        double tmp1 = 1;
-        double tmp2 = 2 * variables[j] - 1;
-        double temp = 2 * tmp2;
+        double dx = 1.0 / n;
+        boolean iev = false;
         for (int i = 0; i < m; ++i) {
-          f[i] += tmp2;
-          double ti = temp * tmp2 - tmp1;
-          tmp1 = tmp2;
-          tmp2 = ti;
+            f[i] = f[i].multiply(dx);
+            if (iev) {
+                f[i] = f[i].add(1.0 / (i * (i + 2)));
+            }
+            iev = ! iev;
         }
-      }
 
-      double dx = 1.0 / n;
-      boolean iev = false;
-      for (int i = 0; i < m; ++i) {
-        f[i] *= dx;
-        if (iev) {
-          f[i] += 1.0 / (i * (i + 2));
-        }
-        iev = ! iev;
-      }
-
-      return f;
+        return f;
 
     }
 
@@ -1340,52 +1099,18 @@ public class MinpackTest {
     }
 
     @Override
-    public double[][] jacobian(double[] variables) {
-      double[][] jacobian = new double[m][];
-      for (int i = 0; i < m; ++i) {
-        jacobian[i] = new double[n];
-      }
-
-      double prod = 1;
-      for (int j = 0; j < n; ++j) {
-        prod *= variables[j];
-        for (int i = 0; i < n; ++i) {
-          jacobian[i][j] = 1;
-        }
-        jacobian[j][j] = 2;
-      }
-
-      for (int j = 0; j < n; ++j) {
-        double temp = variables[j];
-        if (temp == 0) {
-          temp = 1;
-          prod = 1;
-          for (int k = 0; k < n; ++k) {
-            if (k != j) {
-              prod *= variables[k];
-            }
-          }
-        }
-        jacobian[n - 1][j] = prod / temp;
-      }
-
-      return jacobian;
-
-    }
-
-    @Override
-    public double[] value(double[] variables) {
-      double[] f = new double[m];
-      double sum  = -(n + 1);
-      double prod = 1;
+    public DerivativeStructure[] value(DerivativeStructure[] variables) {
+        DerivativeStructure[] f = new DerivativeStructure[m];
+        DerivativeStructure sum  = variables[0].getField().getZero().subtract(n + 1);
+        DerivativeStructure prod = variables[0].getField().getOne();
       for (int j = 0; j < n; ++j) {
-        sum  += variables[j];
-        prod *= variables[j];
+        sum  = sum.add(variables[j]);
+        prod = prod.multiply(variables[j]);
       }
       for (int i = 0; i < n; ++i) {
-        f[i] = variables[i] + sum;
+        f[i] = variables[i].add(sum);
       }
-      f[n - 1] = prod - 1;
+      f[n - 1] = prod.subtract(1);
       return f;
     }
 
@@ -1404,36 +1129,18 @@ public class MinpackTest {
     }
 
     @Override
-    public double[][] jacobian(double[] variables) {
-      double   x2 = variables[1];
-      double   x3 = variables[2];
-      double   x4 = variables[3];
-      double   x5 = variables[4];
-      double[][] jacobian = new double[m][];
-      for (int i = 0; i < m; ++i) {
-        double temp = 10.0 * i;
-        double tmp1 = FastMath.exp(-temp * x4);
-        double tmp2 = FastMath.exp(-temp * x5);
-        jacobian[i] = new double[] {
-          -1, -tmp1, -tmp2, temp * x2 * tmp1, temp * x3 * tmp2
-        };
-      }
-      return jacobian;
-    }
-
-    @Override
-    public double[] value(double[] variables) {
-      double x1 = variables[0];
-      double x2 = variables[1];
-      double x3 = variables[2];
-      double x4 = variables[3];
-      double x5 = variables[4];
-      double[] f = new double[m];
+    public DerivativeStructure[] value(DerivativeStructure[] variables) {
+        DerivativeStructure x1 = variables[0];
+        DerivativeStructure x2 = variables[1];
+        DerivativeStructure x3 = variables[2];
+        DerivativeStructure x4 = variables[3];
+        DerivativeStructure x5 = variables[4];
+        DerivativeStructure[] f = new DerivativeStructure[m];
       for (int i = 0; i < m; ++i) {
         double temp = 10.0 * i;
-        double tmp1 = FastMath.exp(-temp * x4);
-        double tmp2 = FastMath.exp(-temp * x5);
-        f[i] = y[i] - (x1 + x2 * tmp1 + x3 * tmp2);
+        DerivativeStructure tmp1 = x4.multiply(-temp).exp();
+        DerivativeStructure tmp2 = x5.multiply(-temp).exp();
+        f[i] = x1.add(x2.multiply(tmp1)).add(x3.multiply(tmp2)).negate().add(y[i]);
       }
       return f;
     }
@@ -1459,65 +1166,28 @@ public class MinpackTest {
     }
 
     @Override
-    public double[][] jacobian(double[] variables) {
-      double   x01 = variables[0];
-      double   x02 = variables[1];
-      double   x03 = variables[2];
-      double   x04 = variables[3];
-      double   x05 = variables[4];
-      double   x06 = variables[5];
-      double   x07 = variables[6];
-      double   x08 = variables[7];
-      double   x09 = variables[8];
-      double   x10 = variables[9];
-      double   x11 = variables[10];
-      double[][] jacobian = new double[m][];
-      for (int i = 0; i < m; ++i) {
-        double temp = i / 10.0;
-        double tmp1 = FastMath.exp(-x05 * temp);
-        double tmp2 = FastMath.exp(-x06 * (temp - x09) * (temp - x09));
-        double tmp3 = FastMath.exp(-x07 * (temp - x10) * (temp - x10));
-        double tmp4 = FastMath.exp(-x08 * (temp - x11) * (temp - x11));
-        jacobian[i] = new double[] {
-          -tmp1,
-          -tmp2,
-          -tmp3,
-          -tmp4,
-          temp * x01 * tmp1,
-          x02 * (temp - x09) * (temp - x09) * tmp2,
-          x03 * (temp - x10) * (temp - x10) * tmp3,
-          x04 * (temp - x11) * (temp - x11) * tmp4,
-          -2 * x02 * x06 * (temp - x09) * tmp2,
-          -2 * x03 * x07 * (temp - x10) * tmp3,
-          -2 * x04 * x08 * (temp - x11) * tmp4
-        };
-      }
-      return jacobian;
-    }
-
-    @Override
-    public double[] value(double[] variables) {
-      double x01 = variables[0];
-      double x02 = variables[1];
-      double x03 = variables[2];
-      double x04 = variables[3];
-      double x05 = variables[4];
-      double x06 = variables[5];
-      double x07 = variables[6];
-      double x08 = variables[7];
-      double x09 = variables[8];
-      double x10 = variables[9];
-      double x11 = variables[10];
-      double[] f = new double[m];
-      for (int i = 0; i < m; ++i) {
-        double temp = i / 10.0;
-        double tmp1 = FastMath.exp(-x05 * temp);
-        double tmp2 = FastMath.exp(-x06 * (temp - x09) * (temp - x09));
-        double tmp3 = FastMath.exp(-x07 * (temp - x10) * (temp - x10));
-        double tmp4 = FastMath.exp(-x08 * (temp - x11) * (temp - x11));
-        f[i] = y[i] - (x01 * tmp1 + x02 * tmp2 + x03 * tmp3 + x04 * tmp4);
-      }
-      return f;
+    public DerivativeStructure[] value(DerivativeStructure[] variables) {
+        DerivativeStructure x01 = variables[0];
+        DerivativeStructure x02 = variables[1];
+        DerivativeStructure x03 = variables[2];
+        DerivativeStructure x04 = variables[3];
+        DerivativeStructure x05 = variables[4];
+        DerivativeStructure x06 = variables[5];
+        DerivativeStructure x07 = variables[6];
+        DerivativeStructure x08 = variables[7];
+        DerivativeStructure x09 = variables[8];
+        DerivativeStructure x10 = variables[9];
+        DerivativeStructure x11 = variables[10];
+        DerivativeStructure[] f = new DerivativeStructure[m];
+        for (int i = 0; i < m; ++i) {
+            double temp = i / 10.0;
+            DerivativeStructure tmp1 = x05.multiply(-temp).exp();
+            DerivativeStructure tmp2 = x06.negate().multiply(x09.subtract(temp).multiply(x09.subtract(temp))).exp();
+            DerivativeStructure tmp3 = x07.negate().multiply(x10.subtract(temp).multiply(x10.subtract(temp))).exp();
+            DerivativeStructure tmp4 = x08.negate().multiply(x11.subtract(temp).multiply(x11.subtract(temp))).exp();
+            f[i] = x01.multiply(tmp1).add(x02.multiply(tmp2)).add(x03.multiply(tmp3)).add(x04.multiply(tmp4)).negate().add(y[i]);
+        }
+        return f;
     }
 
     private static final double[] y = {

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/NonLinearConjugateGradientOptimizerTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/NonLinearConjugateGradientOptimizerTest.java?rev=1384907&r1=1384906&r2=1384907&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/NonLinearConjugateGradientOptimizerTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/NonLinearConjugateGradientOptimizerTest.java Fri Sep 14 20:17:00 2012
@@ -17,12 +17,17 @@
 
 package org.apache.commons.math3.optimization.general;
 
-import java.awt.geom.Point2D;
 import java.io.Serializable;
+
 import org.apache.commons.math3.analysis.DifferentiableMultivariateFunction;
 import org.apache.commons.math3.analysis.MultivariateFunction;
 import org.apache.commons.math3.analysis.MultivariateVectorFunction;
+import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
+import org.apache.commons.math3.analysis.differentiation.MultivariateDifferentiableFunction;
 import org.apache.commons.math3.analysis.solvers.BrentSolver;
+import org.apache.commons.math3.exception.DimensionMismatchException;
+import org.apache.commons.math3.exception.MathIllegalArgumentException;
+import org.apache.commons.math3.geometry.euclidean.twod.Vector2D;
 import org.apache.commons.math3.linear.BlockRealMatrix;
 import org.apache.commons.math3.linear.RealMatrix;
 import org.apache.commons.math3.optimization.GoalType;
@@ -337,13 +342,13 @@ public class NonLinearConjugateGradientO
                                                     new BrentSolver(1e-15, 1e-13));
         PointValuePair optimum =
             optimizer.optimize(100, circle, GoalType.MINIMIZE, new double[] { 98.680, 47.345 });
-        Point2D.Double center = new Point2D.Double(optimum.getPointRef()[0], optimum.getPointRef()[1]);
+        Vector2D center = new Vector2D(optimum.getPointRef()[0], optimum.getPointRef()[1]);
         Assert.assertEquals(69.960161753, circle.getRadius(center), 1.0e-8);
-        Assert.assertEquals(96.075902096, center.x, 1.0e-8);
-        Assert.assertEquals(48.135167894, center.y, 1.0e-8);
+        Assert.assertEquals(96.075902096, center.getX(), 1.0e-8);
+        Assert.assertEquals(48.135167894, center.getY(), 1.0e-8);
     }
 
-    private static class LinearProblem implements DifferentiableMultivariateFunction, Serializable {
+    private static class LinearProblem implements MultivariateDifferentiableFunction, Serializable {
 
         private static final long serialVersionUID = 703247177355019415L;
         final RealMatrix factors;
@@ -353,18 +358,6 @@ public class NonLinearConjugateGradientO
             this.target  = target;
         }
 
-        private double[] gradient(double[] point) {
-            double[] r = factors.operate(point);
-            for (int i = 0; i < r.length; ++i) {
-                r[i] -= target[i];
-            }
-            double[] p = factors.transpose().operate(r);
-            for (int i = 0; i < p.length; ++i) {
-                p[i] *= 2;
-            }
-            return p;
-        }
-
         public double value(double[] variables) {
             double[] y = factors.operate(variables);
             double sum = 0;
@@ -375,20 +368,22 @@ public class NonLinearConjugateGradientO
             return sum;
         }
 
-        public MultivariateVectorFunction gradient() {
-            return new MultivariateVectorFunction() {
-                public double[] value(double[] point) {
-                    return gradient(point);
+        public DerivativeStructure value(DerivativeStructure[] variables) {
+            DerivativeStructure[] y = new DerivativeStructure[factors.getRowDimension()];
+            for (int i = 0; i < y.length; ++i) {
+                y[i] = variables[0].getField().getZero();
+                for (int j = 0; j < factors.getColumnDimension(); ++j) {
+                    y[i] = y[i].add(variables[j].multiply(factors.getEntry(i, j)));
                 }
-            };
-        }
+            }
 
-        public MultivariateFunction partialDerivative(final int k) {
-            return new MultivariateFunction() {
-                public double value(double[] point) {
-                    return gradient(point)[k];
-                }
-            };
+            DerivativeStructure sum = variables[0].getField().getZero();
+            for (int i = 0; i < y.length; ++i) {
+                DerivativeStructure ri = y[i].subtract(target[i]);
+                sum = sum.add(ri.multiply(ri));
+            }
+            return sum;
         }
+
     }
 }

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/RandomCirclePointGenerator.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/RandomCirclePointGenerator.java?rev=1384907&r1=1384906&r2=1384907&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/RandomCirclePointGenerator.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/RandomCirclePointGenerator.java Fri Sep 14 20:17:00 2012
@@ -17,7 +17,6 @@
 
 package org.apache.commons.math3.optimization.general;
 
-import java.awt.geom.Point2D;
 import org.apache.commons.math3.random.RandomGenerator;
 import org.apache.commons.math3.random.Well44497b;
 import org.apache.commons.math3.util.MathUtils;
@@ -25,6 +24,7 @@ import org.apache.commons.math3.util.Fas
 import org.apache.commons.math3.distribution.RealDistribution;
 import org.apache.commons.math3.distribution.UniformRealDistribution;
 import org.apache.commons.math3.distribution.NormalDistribution;
+import org.apache.commons.math3.geometry.euclidean.twod.Vector2D;
 
 /**
  * Factory for generating a cloud of points that approximate a circle.
@@ -69,8 +69,8 @@ public class RandomCirclePointGenerator 
      * @param n Number of points to create.
      * @return the cloud of {@code n} points.
      */
-    public Point2D.Double[] generate(int n) {
-        final Point2D.Double[] cloud = new Point2D.Double[n];
+    public Vector2D[] generate(int n) {
+        final Vector2D[] cloud = new Vector2D[n];
         for (int i = 0; i < n; i++) {
             cloud[i] = create();
         }
@@ -82,11 +82,11 @@ public class RandomCirclePointGenerator 
      *
      * @return a point.
      */
-    private Point2D.Double create() {
+    private Vector2D create() {
         final double t = tP.sample();
         final double pX = cX.sample() + radius * FastMath.cos(t);
         final double pY = cY.sample() + radius * FastMath.sin(t);
 
-        return new Point2D.Double(pX, pY);
+        return new Vector2D(pX, pY);
     }
 }

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/StatisticalReferenceDataset.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/StatisticalReferenceDataset.java?rev=1384907&r1=1384906&r2=1384907&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/StatisticalReferenceDataset.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/StatisticalReferenceDataset.java Fri Sep 14 20:17:00 2012
@@ -20,8 +20,8 @@ import java.io.BufferedReader;
 import java.io.IOException;
 import java.util.ArrayList;
 
-import org.apache.commons.math3.analysis.DifferentiableMultivariateVectorFunction;
-import org.apache.commons.math3.analysis.MultivariateMatrixFunction;
+import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
+import org.apache.commons.math3.analysis.differentiation.MultivariateDifferentiableVectorFunction;
 import org.apache.commons.math3.util.MathArrays;
 
 /**
@@ -67,7 +67,7 @@ public abstract class StatisticalReferen
     private double residualSumOfSquares;
 
     /** The least-squares problem. */
-    private final DifferentiableMultivariateVectorFunction problem;
+    private final MultivariateDifferentiableVectorFunction problem;
 
     /**
      * Creates a new instance of this class from the specified data file. The
@@ -150,29 +150,30 @@ public abstract class StatisticalReferen
         }
         this.name = dummyString;
 
-        this.problem = new DifferentiableMultivariateVectorFunction() {
+        this.problem = new MultivariateDifferentiableVectorFunction() {
+
             public double[] value(final double[] a) {
+                DerivativeStructure[] dsA = new DerivativeStructure[a.length];
+                for (int i = 0; i < a.length; ++i) {
+                    dsA[i] = new DerivativeStructure(a.length, 0, a[i]);
+                }
                 final int n = getNumObservations();
                 final double[] yhat = new double[n];
                 for (int i = 0; i < n; i++) {
-                    yhat[i] = getModelValue(getX(i), a);
+                    yhat[i] = getModelValue(getX(i), dsA).getValue();
                 }
                 return yhat;
             }
 
-            public MultivariateMatrixFunction jacobian() {
-                return new MultivariateMatrixFunction() {
-                    public double[][] value(final double[] a)
-                        throws IllegalArgumentException {
-                        final int n = getNumObservations();
-                        final double[][] j = new double[n][];
-                        for (int i = 0; i < n; i++) {
-                            j[i] = getModelDerivatives(getX(i), a);
-                        }
-                        return j;
-                    }
-                };
+            public DerivativeStructure[] value(final DerivativeStructure[] a) {
+                final int n = getNumObservations();
+                final DerivativeStructure[] yhat = new DerivativeStructure[n];
+                for (int i = 0; i < n; i++) {
+                    yhat[i] = getModelValue(getX(i), a);
+                }
+                return yhat;
             }
+
         };
     }
 
@@ -309,7 +310,7 @@ public abstract class StatisticalReferen
      *
      * @return the least-squares problem
      */
-    public DifferentiableMultivariateVectorFunction getLeastSquaresProblem() {
+    public MultivariateDifferentiableVectorFunction getLeastSquaresProblem() {
         return problem;
     }
 
@@ -321,18 +322,7 @@ public abstract class StatisticalReferen
      * @param a the parameters
      * @return the value of the model
      */
-    public abstract double getModelValue(final double x, final double[] a);
-
-    /**
-     * Returns the values of the partial derivatives of the model with respect
-     * to the parameters.
-     *
-     * @param x the predictor variable
-     * @param a the parameters
-     * @return the partial derivatives
-     */
-    public abstract double[] getModelDerivatives(final double x,
-                                                 final double[] a);
+    public abstract DerivativeStructure getModelValue(final double x, final DerivativeStructure[] a);
 
     /**
      * <p>

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/StatisticalReferenceDatasetFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/StatisticalReferenceDatasetFactory.java?rev=1384907&r1=1384906&r2=1384907&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/StatisticalReferenceDatasetFactory.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/StatisticalReferenceDatasetFactory.java Fri Sep 14 20:17:00 2012
@@ -21,7 +21,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 
-import org.apache.commons.math3.util.FastMath;
+import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
 
 /**
  * A factory to create instances of {@link StatisticalReferenceDataset} from
@@ -59,25 +59,12 @@ public class StatisticalReferenceDataset
             dataset = new StatisticalReferenceDataset(in) {
 
                 @Override
-                public double getModelValue(final double x, final double[] a) {
-                    final double p = a[0] + x * (a[1] + x * a[2]);
-                    final double q = 1.0 + x * (a[3] + x * a[4]);
-                    return p / q;
+                public DerivativeStructure getModelValue(final double x, final DerivativeStructure[] a) {
+                    final DerivativeStructure p = a[0].add(a[1].add(a[2].multiply(x)).multiply(x));
+                    final DerivativeStructure q = a[3].add(a[4].multiply(x)).multiply(x).add(1.0);
+                    return p.divide(q);
                 }
 
-                @Override
-                public double[] getModelDerivatives(final double x,
-                                                    final double[] a) {
-                    final double[] dy = new double[5];
-                    final double p = a[0] + x * (a[1] + x * a[2]);
-                    final double q = 1.0 + x * (a[3] + x * a[4]);
-                    dy[0] = 1.0 / q;
-                    dy[1] = x / q;
-                    dy[2] = x * dy[1];
-                    dy[3] = -x * p / (q * q);
-                    dy[4] = x * dy[3];
-                    return dy;
-                }
             };
         } finally {
             in.close();
@@ -93,27 +80,12 @@ public class StatisticalReferenceDataset
             dataset = new StatisticalReferenceDataset(in) {
 
                 @Override
-                public double getModelValue(final double x, final double[] a) {
-                    final double p = a[0] + x * (a[1] + x * (a[2] + x * a[3]));
-                    final double q = 1.0 + x * (a[4] + x * (a[5] + x * a[6]));
-                    return p / q;
+                public DerivativeStructure getModelValue(final double x, final DerivativeStructure[] a) {
+                    final DerivativeStructure p = a[0].add(a[1].add(a[2].add(a[3].multiply(x)).multiply(x)).multiply(x));
+                    final DerivativeStructure q = a[4].add(a[5].add(a[6].multiply(x)).multiply(x)).multiply(x).add(1.0);
+                    return p.divide(q);
                 }
 
-                @Override
-                public double[] getModelDerivatives(final double x,
-                                                    final double[] a) {
-                    final double[] dy = new double[7];
-                    final double p = a[0] + x * (a[1] + x * (a[2] + x * a[3]));
-                    final double q = 1.0 + x * (a[4] + x * (a[5] + x * a[6]));
-                    dy[0] = 1.0 / q;
-                    dy[1] = x * dy[0];
-                    dy[2] = x * dy[1];
-                    dy[3] = x * dy[2];
-                    dy[4] = -x * p / (q * q);
-                    dy[5] = x * dy[4];
-                    dy[6] = x * dy[5];
-                    return dy;
-                }
             };
         } finally {
             in.close();
@@ -129,22 +101,10 @@ public class StatisticalReferenceDataset
             dataset = new StatisticalReferenceDataset(in) {
 
                 @Override
-                public double getModelValue(final double x, final double[] a) {
-                    return a[0] + a[1] * FastMath.exp(-a[3] * x) + a[2] *
-                           FastMath.exp(-a[4] * x);
+                public DerivativeStructure getModelValue(final double x, final DerivativeStructure[] a) {
+                    return a[0].add(a[1].multiply(a[3].multiply(-x).exp())).add(a[2].multiply(a[4].multiply(-x).exp()));
                 }
 
-                @Override
-                public double[] getModelDerivatives(final double x,
-                                                    final double[] a) {
-                    final double[] dy = new double[5];
-                    dy[0] = 1.0;
-                    dy[1] = FastMath.exp(-x * a[3]);
-                    dy[2] = FastMath.exp(-x * a[4]);
-                    dy[3] = -x * a[1] * dy[1];
-                    dy[4] = -x * a[2] * dy[2];
-                    return dy;
-                }
             };
         } finally {
             in.close();
@@ -161,25 +121,12 @@ public class StatisticalReferenceDataset
             dataset = new StatisticalReferenceDataset(in) {
 
                 @Override
-                public double getModelValue(final double x, final double[] a) {
-                    System.out.println(a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]);
-                    return a[0] * FastMath.exp(-a[3] * x) +
-                           a[1] * FastMath.exp(-a[4] * x) +
-                           a[2] * FastMath.exp(-a[5] * x);
+                public DerivativeStructure getModelValue(final double x, final DerivativeStructure[] a) {
+                    return a[0].multiply(a[3].multiply(-x).exp()).add(
+                                a[1].multiply(a[4].multiply(-x).exp())).add(
+                                     a[2].multiply(a[5].multiply(-x).exp()));
                 }
 
-                @Override
-                public double[] getModelDerivatives(final double x,
-                    final double[] a) {
-                    final double[] dy = new double[6];
-                    dy[0] = FastMath.exp(-x * a[3]);
-                    dy[1] = FastMath.exp(-x * a[4]);
-                    dy[2] = FastMath.exp(-x * a[5]);
-                    dy[3] = -x * a[0] * dy[0];
-                    dy[4] = -x * a[1] * dy[1];
-                    dy[5] = -x * a[2] * dy[2];
-                    return dy;
-                }
             };
         } finally {
             in.close();

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/StraightLineProblem.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/StraightLineProblem.java?rev=1384907&r1=1384906&r2=1384907&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/StraightLineProblem.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/general/StraightLineProblem.java Fri Sep 14 20:17:00 2012
@@ -18,9 +18,10 @@
 package org.apache.commons.math3.optimization.general;
 
 import java.util.ArrayList;
-import org.apache.commons.math3.analysis.DifferentiableMultivariateVectorFunction;
-import org.apache.commons.math3.analysis.MultivariateMatrixFunction;
-import org.apache.commons.math3.analysis.UnivariateFunction;
+
+import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
+import org.apache.commons.math3.analysis.differentiation.MultivariateDifferentiableVectorFunction;
+import org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction;
 import org.apache.commons.math3.stat.regression.SimpleRegression;
 
 /**
@@ -35,7 +36,7 @@ import org.apache.commons.math3.stat.reg
  *  <li>for each pair (a, b), the y-coordinate of the line.</li>
  * </ul>
  */
-class StraightLineProblem implements DifferentiableMultivariateVectorFunction {
+class StraightLineProblem implements MultivariateDifferentiableVectorFunction {
     /** Cloud of points assumed to be fitted by a straight line. */
     private final ArrayList<double[]> points;
     /** Error (on the y-coordinate of the points). */
@@ -94,7 +95,8 @@ class StraightLineProblem implements Dif
     }
 
     public double[] value(double[] params) {
-        final Model line = new Model(params[0], params[1]);
+        final Model line = new Model(new DerivativeStructure(0, 0, params[0]),
+                                     new DerivativeStructure(0, 0, params[1]));
 
         final double[] model = new double[points.size()];
         for (int i = 0; i < points.size(); i++) {
@@ -105,12 +107,16 @@ class StraightLineProblem implements Dif
         return model;
     }
 
-    public MultivariateMatrixFunction jacobian() {
-        return new MultivariateMatrixFunction() {
-            public double[][] value(double[] point) {
-                return jacobian(point);
-            }
-        };
+    public DerivativeStructure[] value(DerivativeStructure[] params) {
+        final Model line = new Model(params[0], params[1]);
+
+        final DerivativeStructure[] model = new DerivativeStructure[points.size()];
+        for (int i = 0; i < points.size(); i++) {
+            final DerivativeStructure p0 = params[0].getField().getZero().add(points.get(i)[0]);
+            model[i] = line.value(p0);
+        }
+
+        return model;
     }
 
     /**
@@ -127,35 +133,26 @@ class StraightLineProblem implements Dif
         return result;
     }
 
-    private double[][] jacobian(double[] params) {
-        final double[][] jacobian = new double[points.size()][2];
-
-        for (int i = 0; i < points.size(); i++) {
-            final double[] p = points.get(i);
-            // Partial derivative wrt "a".
-            jacobian[i][0] = p[0];
-            // Partial derivative wrt "b".
-            jacobian[i][1] = 1;
-        }
-
-        return jacobian;
-    }
-
     /**
      * Linear function.
      */
-    public static class Model implements UnivariateFunction {
-        final double a;
-        final double b;
+    public static class Model implements UnivariateDifferentiableFunction {
+        final DerivativeStructure a;
+        final DerivativeStructure b;
 
-        public Model(double a,
-                     double b) {
+        public Model(DerivativeStructure a,
+                     DerivativeStructure b) {
             this.a = a;
             this.b = b;
         }
 
         public double value(double x) {
-            return a * x + b;
+            return a.getValue() * x + b.getValue();
+        }
+
+        public DerivativeStructure value(DerivativeStructure x) {
+            return x.multiply(a).add(b);
         }
+
     }
 }