1   /* Copyright 2002-2025 CS GROUP
2    * Licensed to CS GROUP (CS) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * CS 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    *   http://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  package org.orekit.propagation.semianalytical.dsst.utilities.hansen;
18  
19  import org.hipparchus.CalculusFieldElement;
20  import org.hipparchus.Field;
21  import org.hipparchus.util.Binary64;
22  import org.hipparchus.util.Binary64Field;
23  import org.hipparchus.util.FastMath;
24  import org.junit.jupiter.api.Assertions;
25  import org.junit.jupiter.api.Test;
26  
27  public class FieldHansenThirdBodyLinearTest {
28  
29  
30      private static <T extends CalculusFieldElement<T>> T hansen(int n, int s, T chi, final Field<T> field) {
31          final T zero = field.getZero();
32          if (n == 0 && s == 0) {
33              return zero.add(1.0);
34          } else if (n == 0 && s == 1) {
35              return zero.subtract(1.0);
36          } else if (n == 1 && s == 0) {
37              return (((chi.multiply(chi)).reciprocal()).negate().add(1.)).multiply(0.5).add(1.);
38          } else if (n >= 1 && n == s - 1) {
39              return hansen(s - 2, s - 1, chi, field).multiply( -(2 * (double)s - 1) / (double)s );
40          } else if (n >= 1 && n == s) {
41              return hansen(s - 1, s, chi, field).multiply( (2 * (double)s + 1) / ((double)s + 1) );
42          } else {
43              return hansen(n - 1, s, chi, field).multiply((2 * (double)n + 1) / ((double)n + 1)).
44                     subtract(hansen(n - 2, s, chi, field).multiply(((chi.multiply(chi).multiply((double)n + 1).multiply((double)n)).divide(((double)n + (double)s) * ((double)n - (double)s))).reciprocal()));
45          }
46      }
47  
48      @Test
49      public void testLinearVsRecursive00() {
50          final Binary64 zero = Binary64Field.getInstance().getZero();
51          doTestLinearVsRecursive(zero, zero.add(1.1e-12), Binary64Field.getInstance());
52      }
53  
54      @Test
55      public void testLinearVsRecursive01() {
56          final Binary64 zero = Binary64Field.getInstance().getZero();
57          doTestLinearVsRecursive(zero.add(0.1), zero.add(2.8e-13), Binary64Field.getInstance());
58      }
59  
60      @Test
61      public void testLinearVsRecursive02() {
62          final Binary64 zero = Binary64Field.getInstance().getZero();
63          doTestLinearVsRecursive(zero.add(0.2), zero.add(9.5e-14), Binary64Field.getInstance());
64      }
65  
66      @Test
67      public void testLinearVsRecursive03() {
68          final Binary64 zero = Binary64Field.getInstance().getZero();
69          doTestLinearVsRecursive(zero.add(0.3), zero.add(6.0e-14), Binary64Field.getInstance());
70      }
71  
72      @Test
73      public void testLinearVsRecursive04() {
74          final Binary64 zero = Binary64Field.getInstance().getZero();
75          doTestLinearVsRecursive(zero.add(0.4), zero.add(1.5e-14), Binary64Field.getInstance());
76      }
77  
78      @Test
79      public void testLinearVsRecursive05() {
80          final Binary64 zero = Binary64Field.getInstance().getZero();
81          doTestLinearVsRecursive(zero.add(0.5), zero.add(6.4e-15), Binary64Field.getInstance());
82      }
83  
84      @Test
85      public void testLinearVsRecursive06() {
86          final Binary64 zero = Binary64Field.getInstance().getZero();
87          doTestLinearVsRecursive(zero.add(0.6), zero.add(3.7e-15), Binary64Field.getInstance());
88      }
89  
90      @Test
91      public void testLinearVsRecursive07() {
92          final Binary64 zero = Binary64Field.getInstance().getZero();
93          doTestLinearVsRecursive(zero.add(0.7), zero.add(1.7e-15), Binary64Field.getInstance());
94      }
95  
96      @Test
97      public void testLinearVsRecursive08() {
98          final Binary64 zero = Binary64Field.getInstance().getZero();
99          doTestLinearVsRecursive(zero.add(0.8), zero.add(1.6e-15), Binary64Field.getInstance());
100     }
101 
102     @Test
103     public void testLinearVsRecursive09() {
104         final Binary64 zero = Binary64Field.getInstance().getZero();
105         doTestLinearVsRecursive(zero.add(0.9), zero.add(8.9e-16), Binary64Field.getInstance());
106     }
107 
108     private <T extends CalculusFieldElement<T>> void doTestLinearVsRecursive(final T ecc, final T tol, final Field<T> field) {
109         final T zero = field.getZero();
110         final int N = 22;
111         final T chi = FastMath.sqrt(ecc.multiply(ecc.negate()).add(1.)).reciprocal();
112 
113         @SuppressWarnings("unchecked")
114         final FieldHansenThirdBodyLinear<T>[] htbl = new FieldHansenThirdBodyLinear[N + 1];
115 
116         for (int s = 0; s <= N; s++) {
117             htbl[s] = new FieldHansenThirdBodyLinear<>(N, s, field);
118             htbl[s].computeInitValues(chi.reciprocal(), (chi.multiply(chi)).reciprocal(), (chi.multiply(chi).multiply(chi)).reciprocal());
119         }
120 
121         T maxRelativeError = zero;
122         for (int s = 0; s <= N; s++) {
123             for (int n = FastMath.max(2, s); n <= N; n++) {
124                 final T hansenRec = hansen(n, s, chi, field);
125                 final T hansenLin = htbl[s].getValue(n, chi.reciprocal());
126                 final T relativeError = FastMath.abs((hansenLin.subtract(hansenRec)).divide(hansenRec));
127                 maxRelativeError = FastMath.max(maxRelativeError, relativeError);
128             }
129         }
130         Assertions.assertEquals(0.0, maxRelativeError.getReal(), tol.getReal());
131 
132     }
133 
134 
135 }