View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  
23  package org.hipparchus.analysis.differentiation;
24  
25  import org.hipparchus.UnitTestUtils;
26  import org.hipparchus.util.FastMath;
27  import org.junit.Assert;
28  import org.junit.Test;
29  
30  
31  /**
32   * Test for class {@link JacobianFunction}.
33   */
34  public class JacobianFunctionTest {
35  
36      @Test
37      public void testSphere() {
38          SphereMapping    f = new SphereMapping(10.0);
39          JacobianFunction j = new JacobianFunction(f);
40          for (double latitude = -1.5; latitude < 1.5; latitude += 0.1) {
41              for (double longitude = -3.1; longitude < 3.1; longitude += 0.1) {
42                  double[] point = new double[] { latitude, longitude };
43                  double[][] referenceJacobian  = f.jacobian(point);
44                  double[][] testJacobian       = j.value(point);
45                  Assert.assertEquals(referenceJacobian.length, testJacobian.length);
46                  for (int i = 0; i < 3; ++i) {
47                      UnitTestUtils.assertEquals(referenceJacobian[i], testJacobian[i], 2.0e-15);
48                  }
49              }
50          }
51      }
52  
53      /* Maps (latitude, longitude) to (x, y, z) */
54      private static class SphereMapping implements MultivariateDifferentiableVectorFunction {
55  
56          private final double radius;
57  
58          public SphereMapping(final double radius) {
59              this.radius = radius;
60          }
61  
62          @Override
63          public double[] value(double[] point) {
64              final double cLat = FastMath.cos(point[0]);
65              final double sLat = FastMath.sin(point[0]);
66              final double cLon = FastMath.cos(point[1]);
67              final double sLon = FastMath.sin(point[1]);
68              return new double[] {
69                  radius * cLon * cLat,
70                  radius * sLon * cLat,
71                  radius * sLat
72              };
73          }
74  
75          @Override
76          public DerivativeStructure[] value(DerivativeStructure[] point) {
77              final DerivativeStructure cLat = point[0].cos();
78              final DerivativeStructure sLat = point[0].sin();
79              final DerivativeStructure cLon = point[1].cos();
80              final DerivativeStructure sLon = point[1].sin();
81              return new DerivativeStructure[] {
82                  cLon.multiply(cLat).multiply(radius),
83                  sLon.multiply(cLat).multiply(radius),
84                  sLat.multiply(radius)
85              };
86          }
87  
88          public double[][] jacobian(double[] point) {
89              final double cLat = FastMath.cos(point[0]);
90              final double sLat = FastMath.sin(point[0]);
91              final double cLon = FastMath.cos(point[1]);
92              final double sLon = FastMath.sin(point[1]);
93              return new double[][] {
94                  { -radius * cLon * sLat, -radius * sLon * cLat },
95                  { -radius * sLon * sLat,  radius * cLon * cLat },
96                  {  radius * cLat,         0  }
97              };
98          }
99  
100     }
101 
102 }