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.forces.gravity.potential;
18  
19  import org.hipparchus.util.FastMath;
20  import org.junit.jupiter.api.Assertions;
21  import org.junit.jupiter.api.Test;
22  import org.orekit.errors.OrekitException;
23  import org.orekit.errors.OrekitMessages;
24  
25  public class FlattenerTest {
26  
27      @Test
28      void testFullTriangle() {
29          final Flattener full = new Flattener(5, 5);
30          Assertions.assertEquals(5, full.getDegree());
31          Assertions.assertEquals(5, full.getOrder());
32          Assertions.assertEquals(21, full.arraySize());
33          Assertions.assertEquals( 0, full.index(5, 5));
34          Assertions.assertEquals( 1, full.index(4, 4));
35          Assertions.assertEquals( 2, full.index(5, 4));
36          Assertions.assertEquals( 3, full.index(3, 3));
37          Assertions.assertEquals( 4, full.index(4, 3));
38          Assertions.assertEquals( 5, full.index(5, 3));
39          Assertions.assertEquals( 6, full.index(2, 2));
40          Assertions.assertEquals( 7, full.index(3, 2));
41          Assertions.assertEquals( 8, full.index(4, 2));
42          Assertions.assertEquals( 9, full.index(5, 2));
43          Assertions.assertEquals(10, full.index(1, 1));
44          Assertions.assertEquals(11, full.index(2, 1));
45          Assertions.assertEquals(12, full.index(3, 1));
46          Assertions.assertEquals(13, full.index(4, 1));
47          Assertions.assertEquals(14, full.index(5, 1));
48          Assertions.assertEquals(15, full.index(0, 0));
49          Assertions.assertEquals(16, full.index(1, 0));
50          Assertions.assertEquals(17, full.index(2, 0));
51          Assertions.assertEquals(18, full.index(3, 0));
52          Assertions.assertEquals(19, full.index(4, 0));
53          Assertions.assertEquals(20, full.index(5, 0));
54      }
55  
56      @Test
57      void testTruncatedTriangle() {
58          final Flattener truncated = new Flattener(5, 3);
59          Assertions.assertEquals(5, truncated.getDegree());
60          Assertions.assertEquals(3, truncated.getOrder());
61          Assertions.assertEquals(18, truncated.arraySize());
62          Assertions.assertEquals( 0, truncated.index(3, 3));
63          Assertions.assertEquals( 1, truncated.index(4, 3));
64          Assertions.assertEquals( 2, truncated.index(5, 3));
65          Assertions.assertEquals( 3, truncated.index(2, 2));
66          Assertions.assertEquals( 4, truncated.index(3, 2));
67          Assertions.assertEquals( 5, truncated.index(4, 2));
68          Assertions.assertEquals( 6, truncated.index(5, 2));
69          Assertions.assertEquals( 7, truncated.index(1, 1));
70          Assertions.assertEquals( 8, truncated.index(2, 1));
71          Assertions.assertEquals( 9, truncated.index(3, 1));
72          Assertions.assertEquals(10, truncated.index(4, 1));
73          Assertions.assertEquals(11, truncated.index(5, 1));
74          Assertions.assertEquals(12, truncated.index(0, 0));
75          Assertions.assertEquals(13, truncated.index(1, 0));
76          Assertions.assertEquals(14, truncated.index(2, 0));
77          Assertions.assertEquals(15, truncated.index(3, 0));
78          Assertions.assertEquals(16, truncated.index(4, 0));
79          Assertions.assertEquals(17, truncated.index(5, 0));
80      }
81  
82      @Test
83      void testFlatten() {
84          final Flattener flattener = new Flattener(5, 3);
85          double[][] triangular = {
86              { 12 },
87              { 13,  7 },
88              { 14,  8, 3 },
89              { 15,  9, 4, 0 },
90              { 16, 10, 5, 1 },
91              { 17, 11, 6, 2 }
92          };
93          final double[] flat = flattener.flatten(triangular);
94          for (int i = 0; i < flat.length; ++i) {
95              Assertions.assertEquals(i, flat[i], 1.0e-15);
96          }
97      }
98  
99      @Test
100     void testSize() {
101         for (int degree = 0; degree <= 60; ++degree) {
102             for (int order = 0; order <= degree; ++order) {
103                 Assertions.assertEquals(loop(degree, order, degree, 0) + 1,
104                                     new Flattener(degree, order).arraySize());
105             }
106         }
107     }
108 
109     @Test
110     void testIndices() {
111         for (int degree = 0; degree <= 60; ++degree) {
112             for (int order = 0; order <= degree; ++order) {
113                 final Flattener flattener = new Flattener(degree, order);
114                 for (int n = 0; n <= degree; ++n) {
115                     for (int m = 0; m <= FastMath.min(n, order); ++m) {
116                         Assertions.assertEquals(loop(degree, order, n, m),
117                                             flattener.index(n, m));
118                     }
119                 }
120             }
121         }
122     }
123 
124     @Test
125     void testLimits() {
126         for (int degree = 0; degree <= 20; ++degree) {
127             for (int order = 0; order <= degree; ++order) {
128                 final Flattener flattener = new Flattener(degree, order);
129                 Assertions.assertEquals(degree, flattener.getDegree());
130                 Assertions.assertEquals(order, flattener.getOrder());
131                 for (int n = -2; n < degree + 2; ++n) {
132                     for (int m = -2; m <= FastMath.min(n, order) + 2; ++m) {
133                         if (n < 0 || n > degree || m < 0 || m > FastMath.min(n, order)) {
134                             try {
135                                 flattener.index(n, m);
136                                 Assertions.fail("an exception should have been thrown");
137                             } catch (OrekitException oe) {
138                                 Assertions.assertEquals(OrekitMessages.WRONG_DEGREE_OR_ORDER, oe.getSpecifier());
139                                 Assertions.assertEquals(n,      ((Integer) oe.getParts()[0]).intValue());
140                                 Assertions.assertEquals(m,      ((Integer) oe.getParts()[1]).intValue());
141                                 Assertions.assertEquals(degree, ((Integer) oe.getParts()[2]).intValue());
142                                 Assertions.assertEquals(order,  ((Integer) oe.getParts()[3]).intValue());
143                                 Assertions.assertFalse(flattener.withinRange(n, m));
144                             }
145                         } else {
146                             Assertions.assertTrue(flattener.index(n, m) >= 0);
147                             Assertions.assertTrue(flattener.withinRange(n, m));
148                         }
149                     }
150                 }
151             }
152         }
153     }
154 
155     private int loop(final int degree, final int order, final int n, final int m) {
156         int count = 0;
157         for (int i = order; i > m; --i) {
158             for (int j = i; j <= degree; ++j) {
159                 ++count;
160             }
161         }
162         for (int j = m; j <= n; ++j) {
163             ++count;
164         }
165         return count - 1;
166     }
167 
168 }