Author: luc
Date: Wed Sep 12 11:23:23 2012
New Revision: 1383886

URL: http://svn.apache.org/viewvc?rev=1383886&view=rev
Log:
Added a wrapper class to compute Jacobian from differentiable function.

Added:
    
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/analysis/differentiation/JacobianFunction.java
   (with props)
    
commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/differentiation/JacobianFunctionTest.java
   (with props)

Added: 
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/analysis/differentiation/JacobianFunction.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/analysis/differentiation/JacobianFunction.java?rev=1383886&view=auto
==============================================================================
--- 
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/analysis/differentiation/JacobianFunction.java
 (added)
+++ 
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/analysis/differentiation/JacobianFunction.java
 Wed Sep 12 11:23:23 2012
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math3.analysis.differentiation;
+
+import org.apache.commons.math3.analysis.MultivariateMatrixFunction;
+
+/** Class representing the Jacobian of a multivariate vector function.
+ * <p>
+ * The rows iterate on the model functions while the columns iterate on the 
parameters; thus,
+ * the numbers of rows is equal to the dimension of the underlying function 
vector
+ * value and the number of columns is equal to the number of free parameters of
+ * the underlying function.
+ * </p>
+ * @version $Id$
+ * @since 3.1
+ */
+public class JacobianFunction implements MultivariateMatrixFunction {
+
+    /** Underlying vector-valued function. */
+    private final MultivariateDifferentiableVectorFunction f;
+
+    /** Simple constructor.
+     * @param f underlying vector-valued function
+     */
+    public JacobianFunction(final MultivariateDifferentiableVectorFunction f) {
+        this.f = f;
+    }
+
+    /** {@inheritDoc} */
+    public double[][] value(double[] point)
+        throws IllegalArgumentException {
+
+        // set up parameters
+        final DerivativeStructure[] dsX = new 
DerivativeStructure[point.length];
+        for (int i = 0; i < point.length; ++i) {
+            dsX[i] = new DerivativeStructure(point.length, 1, i, point[i]);
+        }
+
+        // compute the derivatives
+        final DerivativeStructure[] dsY = f.value(dsX);
+
+        // extract the Jacobian
+        final double[][] y = new double[dsY.length][point.length];
+        final int[] orders = new int[point.length];
+        for (int i = 0; i < dsY.length; ++i) {
+            for (int j = 0; j < point.length; ++j) {
+                orders[j] = 1;
+                y[i][j] = dsY[i].getPartialDerivative(orders);
+                orders[j] = 0;
+            }
+        }
+
+        return y;
+
+    }
+
+}

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

Propchange: 
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/analysis/differentiation/JacobianFunction.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: 
commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/differentiation/JacobianFunctionTest.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/differentiation/JacobianFunctionTest.java?rev=1383886&view=auto
==============================================================================
--- 
commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/differentiation/JacobianFunctionTest.java
 (added)
+++ 
commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/differentiation/JacobianFunctionTest.java
 Wed Sep 12 11:23:23 2012
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.math3.analysis.differentiation;
+
+import junit.framework.Assert;
+
+import org.apache.commons.math3.TestUtils;
+import org.apache.commons.math3.util.FastMath;
+import org.junit.Test;
+
+
+/**
+ * Test for class {@link JacobianFunction}.
+ */
+public class JacobianFunctionTest {
+
+    @Test
+    public void testSphere() {
+        SphereMapping    f = new SphereMapping(10.0);
+        JacobianFunction j = new JacobianFunction(f);
+        for (double latitude = -1.5; latitude < 1.5; latitude += 0.1) {
+            for (double longitude = -3.1; longitude < 3.1; longitude += 0.1) {
+                double[] point = new double[] { latitude, longitude };
+                double[][] referenceJacobian  = f.jacobian(point);
+                double[][] testJacobian       = j.value(point);
+                Assert.assertEquals(referenceJacobian.length, 
testJacobian.length);
+                for (int i = 0; i < 3; ++i) {
+                    TestUtils.assertEquals(referenceJacobian[i], 
testJacobian[i], 2.0e-15);
+                }
+            }
+        }
+    }
+
+    /* Maps (latitude, longitude) to (x, y, z) */
+    private static class SphereMapping implements 
MultivariateDifferentiableVectorFunction {
+
+        private final double radius;
+
+        public SphereMapping(final double radius) {
+            this.radius = radius;
+        }
+        
+        public double[] value(double[] point) {
+            final double cLat = FastMath.cos(point[0]);
+            final double sLat = FastMath.sin(point[0]);
+            final double cLon = FastMath.cos(point[1]);
+            final double sLon = FastMath.sin(point[1]);
+            return new double[] {
+                radius * cLon * cLat,
+                radius * sLon * cLat,
+                radius * sLat
+            };
+        }
+        
+        public DerivativeStructure[] value(DerivativeStructure[] point) {
+            final DerivativeStructure cLat = point[0].cos();
+            final DerivativeStructure sLat = point[0].sin();
+            final DerivativeStructure cLon = point[1].cos();
+            final DerivativeStructure sLon = point[1].sin();
+            return new DerivativeStructure[] {
+                cLon.multiply(cLat).multiply(radius),
+                sLon.multiply(cLat).multiply(radius),
+                sLat.multiply(radius)
+            };
+        }
+
+        public double[][] jacobian(double[] point) {
+            final double cLat = FastMath.cos(point[0]);
+            final double sLat = FastMath.sin(point[0]);
+            final double cLon = FastMath.cos(point[1]);
+            final double sLon = FastMath.sin(point[1]);
+            return new double[][] {
+                { -radius * cLon * sLat, -radius * sLon * cLat },
+                { -radius * sLon * sLat,  radius * cLon * cLat },
+                {  radius * cLat,         0  }
+            };
+        }
+
+    }
+
+}

Propchange: 
commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/differentiation/JacobianFunctionTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
commons/proper/math/trunk/src/test/java/org/apache/commons/math3/analysis/differentiation/JacobianFunctionTest.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"


Reply via email to