1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation.semianalytical.dsst.utilities;
18
19 import org.hipparchus.util.CombinatoricsUtils;
20 import org.hipparchus.util.FastMath;
21 import org.junit.jupiter.api.Assertions;
22 import org.junit.jupiter.api.BeforeEach;
23 import org.junit.jupiter.api.Test;
24
25 import java.lang.reflect.Field;
26 import java.lang.reflect.InvocationTargetException;
27 import java.lang.reflect.Method;
28
29 public class GammaMnsFunctionTest {
30
31 int nMax;
32 double[] fact;
33
34 @Test
35 public void testIndex()
36 throws NoSuchMethodException, SecurityException,
37 IllegalAccessException, IllegalArgumentException, InvocationTargetException {
38 Method indexM = GammaMnsFunction.class.getDeclaredMethod("index",
39 Integer.TYPE, Integer.TYPE, Integer.TYPE);
40 indexM.setAccessible(true);
41 int i = 0;
42 for (int n = 0; n <= nMax; ++n) {
43 for (int m = 0; m <= n; ++m) {
44 for (int s = -n; s <= n; ++s) {
45 Assertions.assertEquals(i++, indexM.invoke(null, m, n, s));
46 }
47 }
48 }
49 }
50
51 @Test
52 public void testPrecomputedRatios()
53 throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
54 Field precomputedF = GammaMnsFunction.class.getDeclaredField("PRECOMPUTED_RATIOS");
55 precomputedF.setAccessible(true);
56 new GammaMnsFunction(nMax, 0.5, +1);
57 double[] precomputed = (double[]) precomputedF.get(null);
58 int i = 0;
59 for (int n = 0; n <= nMax; ++n) {
60 for (int m = 0; m <= n; ++m) {
61 for (int s = -n; s <= n; ++s) {
62
63 double r = naiveRatio(m, n, s);
64 Assertions.assertEquals(r, precomputed[i++], 2.0e-14 * r);
65 }
66 }
67 }
68 }
69
70 @Test
71 public void testReallocate()
72 throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
73 Field precomputedF = GammaMnsFunction.class.getDeclaredField("PRECOMPUTED_RATIOS");
74 precomputedF.setAccessible(true);
75 precomputedF.set(null, new double[0]);
76 new GammaMnsFunction(nMax, 0.5, +1);
77 double[] orginalPrecomputed = (double[]) precomputedF.get(null);
78 Assertions.assertEquals((nMax + 1) * (nMax + 2) * (4 * nMax + 3) / 6, orginalPrecomputed.length);
79 new GammaMnsFunction(nMax + 3, 0.5, +1);
80 double[] reallocatedPrecomputed = (double[]) precomputedF.get(null);
81 Assertions.assertEquals((nMax + 4) * (nMax + 5) * (4 * nMax + 15) / 6, reallocatedPrecomputed.length);
82 for (int i = 0; i < orginalPrecomputed.length; ++i) {
83 Assertions.assertEquals(orginalPrecomputed[i], reallocatedPrecomputed[i],
84 1.0e-15 * orginalPrecomputed[i]);
85 }
86 }
87
88 @Test
89 public void testValue() {
90 for (int bigI : new int[] { -1, +1 }) {
91 for (double gamma = 0; gamma <= 1; gamma += 1.0 / 64.0) {
92 GammaMnsFunction gammaMNS = new GammaMnsFunction(nMax, gamma, bigI);
93 for (int n = 0; n <= nMax; ++n) {
94 for (int m = 0; m <= n; ++m) {
95 for (int s = -n; s <= n; ++s) {
96
97 final double v = naiveValue(bigI, gamma, m, n, s);
98 final double g = gammaMNS.getValue(m, n, s);
99 if (Double.isInfinite(v)) {
100 Assertions.assertTrue(Double.isInfinite(g));
101 Assertions.assertTrue(v * g > 0);
102 } else {
103 Assertions.assertEquals(v, g, 2.0e-14 * FastMath.abs(v));
104 }
105 }
106 }
107 }
108 }
109 }
110 }
111
112 private double naiveValue(final int bigI, final double gamma,
113 final int m, final int n, final int s) {
114 final double f = 1 + bigI * gamma;
115 if (s <= -m) {
116 return FastMath.pow(-1, m - s ) * FastMath.pow(2, s) * FastMath.pow(f, -bigI * m);
117 } else if (s < m) {
118 return FastMath.pow(-1, m - s ) * FastMath.pow(2, -m) * naiveRatio(m, n, s) * FastMath.pow(f, bigI * s);
119 } else {
120 return FastMath.pow(2, -s) * FastMath.pow(f, bigI * m);
121 }
122 }
123
124 private double naiveRatio(final int m, final int n, final int s) {
125 return (CombinatoricsUtils.factorialDouble(n + m) * CombinatoricsUtils.factorialDouble(n - m)) /
126 (CombinatoricsUtils.factorialDouble(n + s) * CombinatoricsUtils.factorialDouble(n - s));
127 }
128
129 @BeforeEach
130 public void setUp() {
131 nMax = 12;
132 fact = new double[2 * nMax + 1];
133 fact[0] = 1;
134 for (int i = 1; i < fact.length; ++i) {
135 fact[i] = i * fact[i - 1];
136 }
137 }
138
139 }