1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.hipparchus.analysis.differentiation;
19
20 import java.lang.reflect.Array;
21
22 import org.hipparchus.CalculusFieldElement;
23 import org.hipparchus.Field;
24 import org.hipparchus.exception.LocalizedCoreFormats;
25 import org.hipparchus.exception.MathIllegalArgumentException;
26 import org.hipparchus.linear.FieldQRDecomposer;
27 import org.hipparchus.util.Binary64Field;
28 import org.hipparchus.util.FastMath;
29 import org.hipparchus.util.MathArrays;
30 import org.junit.Assert;
31 import org.junit.Test;
32
33
34
35
36 public class FieldTaylorMapTest {
37
38 @Test
39 public void testNullPoint() {
40 doTestNullPoint(Binary64Field.getInstance());
41 }
42
43 @Test
44 public void testDim0Point() {
45 doTestDim0Point(Binary64Field.getInstance());
46 }
47
48 @Test
49 public void testNullFunctions() {
50 doTestNullFunctions(Binary64Field.getInstance());
51 }
52
53 @Test
54 public void testNoFunctions() {
55 doTestNoFunctions(Binary64Field.getInstance());
56 }
57
58 @Test
59 public void testIncompatiblePointAndFunctions() {
60 doTestIncompatiblePointAndFunctions(Binary64Field.getInstance());
61 }
62
63 @Test
64 public void testIncompatible() {
65 doTestIncompatible(Binary64Field.getInstance());
66 }
67
68 @Test
69 public void testNbParameters() {
70 doTestNbParameters(Binary64Field.getInstance());
71 }
72
73 @Test
74 public void testNbFunctions() {
75 doTestNbFunctions(Binary64Field.getInstance());
76 }
77
78 @Test
79 public void testIdentity() {
80 doTestIdentity(Binary64Field.getInstance());
81 }
82
83 @Test
84 public void testValue() {
85 doTestValue(Binary64Field.getInstance());
86 }
87
88 @Test
89 public void testCompose() {
90 doTestCompose(Binary64Field.getInstance());
91 }
92
93 @Test
94 public void testInvertNonSquare() {
95 doTestInvertNonSquare(Binary64Field.getInstance());
96 }
97
98 @Test
99 public void testInvertMonoDimensional() {
100 doTestInvertMonoDimensional(Binary64Field.getInstance());
101 }
102
103 @Test
104 public void testInvertBiDimensional() {
105 doTestInvertBiDimensional(Binary64Field.getInstance());
106 }
107
108 @SuppressWarnings("unchecked")
109 private <T extends CalculusFieldElement<T>> void doTestNullPoint(final Field<T> field) {
110 try {
111 new FieldTaylorMap<>(null, (FieldDerivativeStructure<T>[]) Array.newInstance(FieldDerivativeStructure.class, 2));
112 Assert.fail("an exception should have been thrown");
113 } catch (MathIllegalArgumentException miae) {
114 Assert.assertEquals(LocalizedCoreFormats.NUMBER_OF_ELEMENTS_SHOULD_BE_POSITIVE, miae.getSpecifier());
115 Assert.assertEquals(0, ((Integer) miae.getParts()[0]).intValue());
116 }
117 }
118
119 @SuppressWarnings("unchecked")
120 private <T extends CalculusFieldElement<T>> void doTestDim0Point(final Field<T> field) {
121 try {
122 new FieldTaylorMap<>(MathArrays.buildArray(field, 0), (FieldDerivativeStructure<T>[]) Array.newInstance(FieldDerivativeStructure.class, 2));
123 Assert.fail("an exception should have been thrown");
124 } catch (MathIllegalArgumentException miae) {
125 Assert.assertEquals(LocalizedCoreFormats.NUMBER_OF_ELEMENTS_SHOULD_BE_POSITIVE, miae.getSpecifier());
126 Assert.assertEquals(0, ((Integer) miae.getParts()[0]).intValue());
127 }
128 }
129
130 private <T extends CalculusFieldElement<T>> void doTestNullFunctions(final Field<T> field) {
131 try {
132 new FieldTaylorMap<>(MathArrays.buildArray(field, 2), null);
133 Assert.fail("an exception should have been thrown");
134 } catch (MathIllegalArgumentException miae) {
135 Assert.assertEquals(LocalizedCoreFormats.NUMBER_OF_ELEMENTS_SHOULD_BE_POSITIVE, miae.getSpecifier());
136 Assert.assertEquals(0, ((Integer) miae.getParts()[0]).intValue());
137 }
138 }
139
140 @SuppressWarnings("unchecked")
141 private <T extends CalculusFieldElement<T>> void doTestNoFunctions(final Field<T> field) {
142 try {
143 new FieldTaylorMap<>(MathArrays.buildArray(field, 2), (FieldDerivativeStructure<T>[]) Array.newInstance(FieldDerivativeStructure.class, 0));
144 Assert.fail("an exception should have been thrown");
145 } catch (MathIllegalArgumentException miae) {
146 Assert.assertEquals(LocalizedCoreFormats.NUMBER_OF_ELEMENTS_SHOULD_BE_POSITIVE, miae.getSpecifier());
147 Assert.assertEquals(0, ((Integer) miae.getParts()[0]).intValue());
148 }
149 }
150
151 private <T extends CalculusFieldElement<T>> void doTestIncompatiblePointAndFunctions(final Field<T> field) {
152 FDSFactory<T> factory = new FDSFactory<>(field, 6, 6);
153 @SuppressWarnings("unchecked")
154 FieldDerivativeStructure<T>[] functions = (FieldDerivativeStructure<T>[]) Array.newInstance(FieldDerivativeStructure.class,
155 factory.getCompiler().getFreeParameters());
156 for (int i = 0; i < functions.length; ++i) {
157 functions[i] = factory.constant(0);
158 }
159 try {
160 new FieldTaylorMap<>(MathArrays.buildArray(field, functions.length - 1), functions);
161 Assert.fail("an exception should have been thrown");
162 } catch (MathIllegalArgumentException miae) {
163 Assert.assertEquals(LocalizedCoreFormats.DIMENSIONS_MISMATCH, miae.getSpecifier());
164 Assert.assertEquals(5, ((Integer) miae.getParts()[0]).intValue());
165 Assert.assertEquals(6, ((Integer) miae.getParts()[1]).intValue());
166 }
167 }
168
169 private <T extends CalculusFieldElement<T>> void doTestIncompatible(final Field<T> field) {
170 FDSFactory<T> factory = new FDSFactory<>(field, 6, 6);
171 @SuppressWarnings("unchecked")
172 FieldDerivativeStructure<T>[] functions = (FieldDerivativeStructure<T>[]) Array.newInstance(FieldDerivativeStructure.class,
173 factory.getCompiler().getFreeParameters());
174 for (int i = 0; i < functions.length - 1; ++i) {
175 functions[i] = factory.constant(0);
176 }
177 functions[functions.length - 1] = new FDSFactory<>(field,
178 factory.getCompiler().getFreeParameters(),
179 factory.getCompiler().getOrder() - 1).
180 constant(1.0);
181 try {
182 new FieldTaylorMap<>(MathArrays.buildArray(field, functions.length), functions);
183 Assert.fail("an exception should have been thrown");
184 } catch (MathIllegalArgumentException miae) {
185 Assert.assertEquals(LocalizedCoreFormats.DIMENSIONS_MISMATCH, miae.getSpecifier());
186 Assert.assertEquals(6, ((Integer) miae.getParts()[0]).intValue());
187 Assert.assertEquals(5, ((Integer) miae.getParts()[1]).intValue());
188 }
189 }
190
191 private <T extends CalculusFieldElement<T>> void doTestNbParameters(final Field<T> field) {
192 final int nbParameters = 6;
193 final int nbFunctions = 3;
194 FDSFactory<T> factory = new FDSFactory<>(field, nbParameters, 6);
195 @SuppressWarnings("unchecked")
196 FieldDerivativeStructure<T>[] functions = (FieldDerivativeStructure<T>[]) Array.newInstance(FieldDerivativeStructure.class,
197 nbFunctions);
198 for (int i = 0; i < functions.length; ++i) {
199 functions[i] = factory.constant(0);
200 }
201 Assert.assertEquals(nbParameters,
202 new FieldTaylorMap<>(MathArrays.buildArray(field, nbParameters), functions).getFreeParameters());
203 }
204
205 private <T extends CalculusFieldElement<T>> void doTestNbFunctions(final Field<T> field) {
206 final int nbParameters = 6;
207 final int nbFunctions = 3;
208 FDSFactory<T> factory = new FDSFactory<>(field, nbParameters, 6);
209 @SuppressWarnings("unchecked")
210 FieldDerivativeStructure<T>[] functions = (FieldDerivativeStructure<T>[]) Array.newInstance(FieldDerivativeStructure.class,
211 nbFunctions);
212 for (int i = 0; i < functions.length; ++i) {
213 functions[i] = factory.constant(0);
214 }
215 Assert.assertEquals(nbFunctions,
216 new FieldTaylorMap<>(MathArrays.buildArray(field, nbParameters), functions).getNbFunctions());
217 }
218
219 private <T extends CalculusFieldElement<T>> void doTestIdentity(final Field<T> field) {
220 final FieldTaylorMap<T> map = new FieldTaylorMap<>(field, 7, 3, 4);
221 for (int i = 0; i < map.getNbFunctions(); ++i) {
222
223 final FieldDerivativeStructure<T> mi = map.getFunction(i);
224
225 Assert.assertEquals(0.0, mi.getValue().getReal(), 1.0e-15);
226
227 int[] orders = new int[7];
228 orders[i] = 1;
229 int expectedOne = mi.getFactory().getCompiler().getPartialDerivativeIndex(orders);
230
231 for (int j = 0; j < mi.getFactory().getCompiler().getSize(); ++j) {
232 Assert.assertEquals(j == expectedOne ? 1.0 : 0.0, mi.getAllDerivatives()[j].getReal(), 1.0e-15);
233 }
234
235 }
236 }
237
238 @SuppressWarnings("unchecked")
239 private <T extends CalculusFieldElement<T>> void doTestValue(final Field<T> field) {
240
241 final FDSFactory<T> factory = new FDSFactory<>(field, 2, 3);
242 final FieldDerivativeStructure<T> p0 = factory.variable(0, field.getZero().newInstance( 1.0));
243 final FieldDerivativeStructure<T> p1 = factory.variable(1, field.getZero().newInstance(-3.0));
244 final FieldDerivativeStructure<T> f0 = p0.sin();
245 final FieldDerivativeStructure<T> f1 = p0.add(p1);
246 final T[] p = MathArrays.buildArray(field, 2);
247 p[0] = p0.getValue();
248 p[1] = p1.getValue();
249 final FieldDerivativeStructure<T>[] f = (FieldDerivativeStructure<T>[]) Array.newInstance(FieldDerivativeStructure.class, 2);
250 f[0] = f0;
251 f[1] = f1;
252 final FieldTaylorMap<T> map = new FieldTaylorMap<>(p, f);
253
254 for (double dp0 = -0.1; dp0 < 0.1; dp0 += 0.01) {
255 final T dp0T = field.getZero().newInstance(dp0);
256 for (double dp1 = -0.1; dp1 < 0.1; dp1 += 0.01) {
257 final T dp1T = field.getZero().newInstance(dp1);
258 Assert.assertEquals(f0.taylor(dp0, dp1).getReal(), map.value(dp0, dp1)[0].getReal(), 1.0e-15);
259 Assert.assertEquals(f1.taylor(dp0, dp1).getReal(), map.value(dp0, dp1)[1].getReal(), 1.0e-15);
260 Assert.assertEquals(f0.taylor(dp0, dp1).getReal(), map.value(dp0T, dp1T)[0].getReal(), 1.0e-15);
261 Assert.assertEquals(f1.taylor(dp0, dp1).getReal(), map.value(dp0T, dp1T)[1].getReal(), 1.0e-15);
262 }
263 }
264
265 }
266
267 private <T extends CalculusFieldElement<T>> void doTestCompose(final Field<T> field) {
268
269 final FDSFactory<T> factory2 = new FDSFactory<>(field, 2, 2);
270 final FDSFactory<T> factory3 = new FDSFactory<>(field, 3, factory2.getCompiler().getOrder());
271 final FieldDerivativeStructure<T> p0 = factory2.variable(0, 1.0);
272 final FieldDerivativeStructure<T> p1 = factory2.variable(1, -3.0);
273 final FieldDerivativeStructure<T> g0 = p0.sin();
274 final FieldDerivativeStructure<T> g1 = p0.add(p1);
275 final FieldDerivativeStructure<T> g2 = p1.multiply(p0);
276 final FieldDerivativeStructure<T> f0 = factory3.variable(0, g0.getValue()).
277 add(factory3.variable(1, g1.getValue()));
278 final FieldDerivativeStructure<T> f1 = factory3.variable(0, g0.getValue()).
279 subtract(factory3.variable(1, g1.getValue())).
280 add(factory3.variable(2, g2.getValue()));
281 final T[] p = MathArrays.buildArray(field, 2);
282 p[0] = p0.getValue();
283 p[1] = p1.getValue();
284 @SuppressWarnings("unchecked")
285 final FieldDerivativeStructure<T>[] g = (FieldDerivativeStructure<T>[]) Array.newInstance(FieldDerivativeStructure.class, 3);
286 g[0] = g0;
287 g[1] = g1;
288 g[2] = g2;
289 final T[] gT = MathArrays.buildArray(field, 3);
290 gT[0] = g0.getValue();
291 gT[1] = g1.getValue();
292 gT[2] = g2.getValue();
293 @SuppressWarnings("unchecked")
294 final FieldDerivativeStructure<T>[] f = (FieldDerivativeStructure<T>[]) Array.newInstance(FieldDerivativeStructure.class, 2);
295 f[0] = f0;
296 f[1] = f1;
297 final FieldTaylorMap<T> mapG = new FieldTaylorMap<>(p, g);
298 final FieldTaylorMap<T> mapF = new FieldTaylorMap<>(gT, f);
299 final FieldTaylorMap<T> composed = mapF.compose(mapG);
300
301 for (double dp0 = -0.1; dp0 < 0.1; dp0 += 0.01) {
302 for (double dp1 = -0.1; dp1 < 0.1; dp1 += 0.01) {
303 Assert.assertEquals(g0.taylor(dp0, dp1).add(g1.taylor(dp0, dp1)).getReal(),
304 composed.value(dp0, dp1)[0].getReal(),
305 1.0e-15);
306 Assert.assertEquals(g0.taylor(dp0, dp1).subtract(g1.taylor(dp0, dp1)).add(g2.taylor(dp0, dp1)).getReal(),
307 composed.value(dp0, dp1)[1].getReal(),
308 1.0e-15);
309 }
310 }
311
312 Assert.assertEquals(p0.getValue().getReal(), mapG.getPoint()[0].getReal(), 1.0e-15);
313 Assert.assertEquals(p1.getValue().getReal(), mapG.getPoint()[1].getReal(), 1.0e-15);
314 Assert.assertEquals(g0.getValue().getReal(), mapF.getPoint()[0].getReal(), 1.0e-15);
315 Assert.assertEquals(g1.getValue().getReal(), mapF.getPoint()[1].getReal(), 1.0e-15);
316 Assert.assertEquals(g2.getValue().getReal(), mapF.getPoint()[2].getReal(), 1.0e-15);
317 Assert.assertEquals(p0.getValue().getReal(), composed.getPoint()[0].getReal(), 1.0e-15);
318 Assert.assertEquals(p1.getValue().getReal(), composed.getPoint()[1].getReal(), 1.0e-15);
319
320
321 Assert.assertEquals(+1.0, mapF.getFunction(0).getPartialDerivative(1, 0, 0).getReal(), 1.0e-15);
322 Assert.assertEquals(+1.0, mapF.getFunction(0).getPartialDerivative(0, 1, 0).getReal(), 1.0e-15);
323 Assert.assertEquals( 0.0, mapF.getFunction(0).getPartialDerivative(0, 0, 1).getReal(), 1.0e-15);
324 Assert.assertEquals(+1.0, mapF.getFunction(1).getPartialDerivative(1, 0, 0).getReal(), 1.0e-15);
325 Assert.assertEquals(-1.0, mapF.getFunction(1).getPartialDerivative(0, 1, 0).getReal(), 1.0e-15);
326 Assert.assertEquals(+1.0, mapF.getFunction(1).getPartialDerivative(0, 0, 1).getReal(), 1.0e-15);
327
328 Assert.assertEquals( 0.0, mapF.getFunction(0).getPartialDerivative(2, 0, 0).getReal(), 1.0e-15);
329 Assert.assertEquals( 0.0, mapF.getFunction(0).getPartialDerivative(1, 1, 0).getReal(), 1.0e-15);
330 Assert.assertEquals( 0.0, mapF.getFunction(0).getPartialDerivative(1, 0, 1).getReal(), 1.0e-15);
331 Assert.assertEquals( 0.0, mapF.getFunction(0).getPartialDerivative(0, 2, 0).getReal(), 1.0e-15);
332 Assert.assertEquals( 0.0, mapF.getFunction(0).getPartialDerivative(0, 1, 1).getReal(), 1.0e-15);
333 Assert.assertEquals( 0.0, mapF.getFunction(0).getPartialDerivative(0, 0, 2).getReal(), 1.0e-15);
334 Assert.assertEquals( 0.0, mapF.getFunction(1).getPartialDerivative(2, 0, 0).getReal(), 1.0e-15);
335 Assert.assertEquals( 0.0, mapF.getFunction(1).getPartialDerivative(1, 1, 0).getReal(), 1.0e-15);
336 Assert.assertEquals( 0.0, mapF.getFunction(1).getPartialDerivative(1, 0, 1).getReal(), 1.0e-15);
337 Assert.assertEquals( 0.0, mapF.getFunction(1).getPartialDerivative(0, 2, 0).getReal(), 1.0e-15);
338 Assert.assertEquals( 0.0, mapF.getFunction(1).getPartialDerivative(0, 1, 1).getReal(), 1.0e-15);
339 Assert.assertEquals( 0.0, mapF.getFunction(1).getPartialDerivative(0, 0, 2).getReal(), 1.0e-15);
340
341
342 Assert.assertEquals(FastMath.cos(p0.getValue()).getReal() + 1.0, composed.getFunction(0).getPartialDerivative(1, 0).getReal(), 1.0e-15);
343 Assert.assertEquals(+1.0, composed.getFunction(0).getPartialDerivative(0, 1).getReal(), 1.0e-15);
344 Assert.assertEquals(FastMath.cos(p0.getValue()).getReal() - 1.0 + p1.getValue().getReal(), composed.getFunction(1).getPartialDerivative(1, 0).getReal(), 1.0e-15);
345 Assert.assertEquals(-1.0 + p0.getValue().getReal(), composed.getFunction(1).getPartialDerivative(0, 1).getReal(), 1.0e-15);
346 Assert.assertEquals(-FastMath.sin(p0.getValue()).getReal(), composed.getFunction(0).getPartialDerivative(2, 0).getReal(), 1.0e-15);
347 Assert.assertEquals( 0.0, composed.getFunction(0).getPartialDerivative(1, 1).getReal(), 1.0e-15);
348 Assert.assertEquals( 0.0, composed.getFunction(0).getPartialDerivative(0, 2).getReal(), 1.0e-15);
349 Assert.assertEquals(-FastMath.sin(p0.getValue()).getReal(), composed.getFunction(1).getPartialDerivative(2, 0).getReal(), 1.0e-15);
350 Assert.assertEquals(+1.0, composed.getFunction(1).getPartialDerivative(1, 1).getReal(), 1.0e-15);
351 Assert.assertEquals( 0.0, composed.getFunction(1).getPartialDerivative(0, 2).getReal(), 1.0e-15);
352
353 }
354
355 private <T extends CalculusFieldElement<T>> void doTestInvertNonSquare(final Field<T> field) {
356 final FDSFactory<T> factory = new FDSFactory<>(field, 2, 2);
357 final FieldDerivativeStructure<T> p0 = factory.variable(0, 1.0);
358 final FieldDerivativeStructure<T> p1 = factory.variable(1, -3.0);
359 final T[] p = MathArrays.buildArray(field, 2);
360 p[0] = p0.getValue();
361 p[1] = p1.getValue();
362 @SuppressWarnings("unchecked")
363 final FieldDerivativeStructure<T>[] f = (FieldDerivativeStructure<T>[]) Array.newInstance(FieldDerivativeStructure.class, 3);
364 f[0] = p0;
365 f[1] = p1;
366 f[2] = p0.add(p1);
367 final FieldTaylorMap<T> nonSquare = new FieldTaylorMap<>(p, f);
368 Assert.assertEquals(2, nonSquare.getFreeParameters());
369 Assert.assertEquals(3, nonSquare.getNbFunctions());
370 try {
371 nonSquare.invert(new FieldQRDecomposer<>(field.getZero().newInstance(1.0e-10)));
372 Assert.fail("an exception should have been thrown");
373 } catch (MathIllegalArgumentException miae) {
374 Assert.assertEquals(LocalizedCoreFormats.DIMENSIONS_MISMATCH, miae.getSpecifier());
375 Assert.assertEquals(3, ((Integer) miae.getParts()[0]).intValue());
376 Assert.assertEquals(2, ((Integer) miae.getParts()[1]).intValue());
377 }
378 }
379
380 private <T extends CalculusFieldElement<T>> void doTestInvertMonoDimensional(final Field<T> field) {
381 final FDSFactory<T> factory = new FDSFactory<>(field, 1, 6);
382 for (double x = 0.0; x < 3.0; x += 0.01) {
383 final FieldDerivativeStructure<T> xDS = factory.variable(0, x);
384 final T[] p = MathArrays.buildArray(field, 1);
385 p[0] = xDS.getValue();
386 @SuppressWarnings("unchecked")
387 final FieldDerivativeStructure<T>[] f = (FieldDerivativeStructure<T>[]) Array.newInstance(FieldDerivativeStructure.class, 1);
388 f[0] = xDS.exp();
389 final FieldTaylorMap<T> expMap = new FieldTaylorMap<>(p, f);
390 final FieldTaylorMap<T> inverse = expMap.invert(new FieldQRDecomposer<>(field.getZero().newInstance(1.0e-10)));
391 final FieldDerivativeStructure<T> log = factory.variable(0, expMap.getFunction(0).getValue()).log();
392 FieldDerivativeStructureAbstractTest.checkEquals(log, inverse.getFunction(0), 4.7e-13);
393 }
394 }
395
396 private <T extends CalculusFieldElement<T>> void doTestInvertBiDimensional(final Field<T> field) {
397 final FDSFactory<T> factory = new FDSFactory<>(field, 2, 4);
398 for (double x = -2.0 + FastMath.scalb(1.0, -6); x < 2.0; x += FastMath.scalb(1.0, -5)) {
399 final FieldDerivativeStructure<T> xDS = factory.variable(0, x);
400 for (double y = -2.0 + FastMath.scalb(1.0, -6); y < 2.0; y += FastMath.scalb(1.0, -5)) {
401 final FieldDerivativeStructure<T> yDS = factory.variable(1, y);
402 final T[] p = MathArrays.buildArray(field, 2);
403 p[0] = xDS.getValue();
404 p[1] = yDS.getValue();
405 @SuppressWarnings("unchecked")
406 final FieldDerivativeStructure<T>[] f = (FieldDerivativeStructure<T>[]) Array.newInstance(FieldDerivativeStructure.class, 2);
407 f[0] = FastMath.hypot(xDS, yDS);
408 f[1] = FastMath.atan2(yDS, xDS);
409 final FieldTaylorMap<T> polarMap = new FieldTaylorMap<>(p, f);
410 final FieldTaylorMap<T> cartMap = polarMap.invert(new FieldQRDecomposer<>(field.getZero().newInstance(1.0e-10)));
411 final FieldTaylorMap<T> idMap = cartMap.compose(polarMap);
412 FieldDerivativeStructureAbstractTest.checkEquals(xDS, idMap.getFunction(0), 2.8e-9);
413 FieldDerivativeStructureAbstractTest.checkEquals(yDS, idMap.getFunction(1), 2.8e-9);
414 }
415 }
416 }
417
418 }