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.Assert;
28 import org.junit.Test;
29
30
31
32
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
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 }