1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
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
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 }