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.jupiter.api.Test;
28  
29  import static org.junit.jupiter.api.Assertions.assertEquals;
30  
31  
32  /**
33   * Test for class {@link JacobianFunction}.
34   */
35  class JacobianFunctionTest {
36  
37      @Test
38      void testSphere() {
39          SphereMapping    f = new SphereMapping(10.0);
40          JacobianFunction j = new JacobianFunction(f);
41          for (double latitude = -1.5; latitude < 1.5; latitude += 0.1) {
42              for (double longitude = -3.1; longitude < 3.1; longitude += 0.1) {
43                  double[] point = new double[] { latitude, longitude };
44                  double[][] referenceJacobian  = f.jacobian(point);
45                  double[][] testJacobian       = j.value(point);
46                  assertEquals(referenceJacobian.length, testJacobian.length);
47                  for (int i = 0; i < 3; ++i) {
48                      UnitTestUtils.customAssertEquals(referenceJacobian[i], testJacobian[i], 2.0e-15);
49                  }
50              }
51          }
52      }
53  
54      /* Maps (latitude, longitude) to (x, y, z) */
55      private static class SphereMapping implements MultivariateDifferentiableVectorFunction {
56  
57          private final double radius;
58  
59          public SphereMapping(final double radius) {
60              this.radius = radius;
61          }
62  
63          @Override
64          public double[] value(double[] point) {
65              final double cLat = FastMath.cos(point[0]);
66              final double sLat = FastMath.sin(point[0]);
67              final double cLon = FastMath.cos(point[1]);
68              final double sLon = FastMath.sin(point[1]);
69              return new double[] {
70                  radius * cLon * cLat,
71                  radius * sLon * cLat,
72                  radius * sLat
73              };
74          }
75  
76          @Override
77          public DerivativeStructure[] value(DerivativeStructure[] point) {
78              final DerivativeStructure cLat = point[0].cos();
79              final DerivativeStructure sLat = point[0].sin();
80              final DerivativeStructure cLon = point[1].cos();
81              final DerivativeStructure sLon = point[1].sin();
82              return new DerivativeStructure[] {
83                  cLon.multiply(cLat).multiply(radius),
84                  sLon.multiply(cLat).multiply(radius),
85                  sLat.multiply(radius)
86              };
87          }
88  
89          public double[][] jacobian(double[] point) {
90              final double cLat = FastMath.cos(point[0]);
91              final double sLat = FastMath.sin(point[0]);
92              final double cLon = FastMath.cos(point[1]);
93              final double sLon = FastMath.sin(point[1]);
94              return new double[][] {
95                  { -radius * cLon * sLat, -radius * sLon * cLat },
96                  { -radius * sLon * sLat,  radius * cLon * cLat },
97                  {  radius * cLat,         0  }
98              };
99          }
100 
101     }
102 
103 }