1   /* Copyright 2002-2022 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.utils;
18  
19  
20  import java.util.HashMap;
21  import java.util.Map;
22  import java.util.function.Consumer;
23  
24  import org.hipparchus.CalculusFieldElement;
25  import org.hipparchus.Field;
26  import org.hipparchus.util.Decimal64Field;
27  import org.hipparchus.util.MathArrays;
28  import org.junit.Assert;
29  import org.junit.Test;
30  
31  public class FieldArrayDictionaryTest {
32  
33      @Test
34      public void testEmpty() {
35          doTestEmpty(Decimal64Field.getInstance());
36      }
37  
38      @Test
39      public void testPutGet() {
40          doTestPutGet(Decimal64Field.getInstance());
41      }
42  
43      @Test
44      public void testFromDictionary() {
45          doTestFromDictionary(Decimal64Field.getInstance());
46      }
47  
48      @Test
49      public void testFromMap() {
50          doTestFromMap(Decimal64Field.getInstance());
51      }
52  
53      @Test
54      public void testArraysAreCopied() {
55          doTestArraysAreCopied(Decimal64Field.getInstance());
56      }
57  
58      @Test
59      public void testIncrementField() {
60          doTestIncrementField(Decimal64Field.getInstance());
61      }
62  
63      @Test
64      public void testIncrementDouble() {
65          doTestIncrementDouble(Decimal64Field.getInstance());
66      }
67  
68      @Test
69      public void testScaledIncrementField() {
70          doTestScaledIncrementField(Decimal64Field.getInstance());
71      }
72  
73      @Test
74      public void testScaledIncrementDouble() {
75          doTestScaledIncrementDouble(Decimal64Field.getInstance());
76      }
77  
78      @Test
79      public void testZero() {
80          doTestZero(Decimal64Field.getInstance());
81      }
82  
83      @Test
84      public void testSize() {
85          doTestSize(Decimal64Field.getInstance());
86      }
87  
88      @Test
89      public void testDataManagement() {
90          doTestDataManagement(Decimal64Field.getInstance());
91      }
92  
93      @Test
94      public void testReplace() {
95          doTestReplace(Decimal64Field.getInstance());
96      }
97  
98      @Test
99      public void testPutAllMap() {
100         doTestPutAllMap(Decimal64Field.getInstance());
101     }
102 
103     @Test
104     public void testPutAllDictionary() {
105         doTestPutAllDictionary(Decimal64Field.getInstance());
106     }
107 
108     @Test
109     public void testToMap() {
110         doTestToMap(Decimal64Field.getInstance());
111     }
112 
113     @Test
114     public void testView() {
115         doTestView(Decimal64Field.getInstance());
116     }
117 
118     private <T extends CalculusFieldElement<T>> void doTestEmpty(Field<T> field) {
119         Assert.assertTrue(new FieldArrayDictionary<>(field).getData().isEmpty());
120     }
121 
122     private <T extends CalculusFieldElement<T>> void doTestPutGet(Field<T> field) {
123 
124         FieldArrayDictionary<T> dictionary = new FieldArrayDictionary<>(field);
125         dictionary.put("a",       new double[] { 1.0, 2.0, 3.0 });
126         dictionary.put("b",       convert(field, new double[] { 4.0 }));
127         dictionary.put("another", convert(field, new double[] { 17.0 }));
128 
129         checkArray(new double[] { 1.0, 2.0, 3.0 }, dictionary.get("a"),       1.0e-15);
130         checkArray(new double[] { 17.0 },          dictionary.get("another"), 1.0e-15);
131         checkArray(new double[] { 4.0 },           dictionary.get("b"),       1.0e-15);
132 
133         Assert.assertNull(dictionary.get("not-a-key"));
134 
135     }
136 
137     private <T extends CalculusFieldElement<T>> void doTestFromDictionary(Field<T> field) {
138         FieldArrayDictionary<T> original = new FieldArrayDictionary<>(field);
139         original.put("a",       new double[] { 1.0, 2.0, 3.0 });
140         original.put("b",       new double[] { 4.0 });
141         original.put("another", new double[] { 17.0 });
142 
143         FieldArrayDictionary<T> copy = new FieldArrayDictionary<>(original);
144 
145         checkArray(new double[] { 1.0, 2.0, 3.0 }, copy.get("a"),       1.0e-15);
146         checkArray(new double[] { 17.0 },          copy.get("another"), 1.0e-15);
147         checkArray(new double[] { 4.0 },           copy.get("b"),       1.0e-15);
148 
149         Assert.assertNull(copy.get("not-a-key"));
150 
151     }
152 
153     private <T extends CalculusFieldElement<T>> void doTestFromMap(Field<T> field) {
154         final Map<String, T[]> map = new HashMap<>();
155         map.put("a",       convert(field, new double[] { 1.0, 2.0, 3.0 }));
156         map.put("b",       convert(field, new double[] { 4.0 }));
157         map.put("another", convert(field, new double[] { 17.0 }));
158 
159         FieldArrayDictionary<T> dictionary = new FieldArrayDictionary<>(field, map);
160 
161         checkArray(new double[] { 1.0, 2.0, 3.0 }, dictionary.get("a"),       1.0e-15);
162         checkArray(new double[] { 17.0 },          dictionary.get("another"), 1.0e-15);
163         checkArray(new double[] { 4.0 },           dictionary.get("b"),       1.0e-15);
164 
165         Assert.assertNull(dictionary.get("not-a-key"));
166 
167     }
168 
169     private <T extends CalculusFieldElement<T>> void doTestArraysAreCopied(Field<T> field) {
170         FieldArrayDictionary<T> dictionary = new FieldArrayDictionary<>(field);
171         T[] original = convert(field, new double[] { 1.0, 2.0, 3.0 });
172         dictionary.put("a", original);
173         T[] retrieved = dictionary.get("a");
174         checkArray(new double[] { 1.0, 2.0, 3.0 }, retrieved, 1.0e-15);
175         Assert.assertNotSame(original, retrieved);
176     }
177 
178     private <T extends CalculusFieldElement<T>> void doTestIncrementField(Field<T> field) {
179         FieldArrayDictionary<T> dictionary = new FieldArrayDictionary<>(field);
180         dictionary.put("a",       convert(field, new double[] { 1.0, 2.0, 3.0 }));
181         dictionary.getEntry("a").increment(convert(field, new double[] { 2.0, 4.0, 8.0 }));
182         checkArray(new double[] { 3.0, 6.0, 11.0 }, dictionary.get("a"), 1.0e-15);
183     }
184 
185     private <T extends CalculusFieldElement<T>> void doTestIncrementDouble(Field<T> field) {
186         FieldArrayDictionary<T> dictionary = new FieldArrayDictionary<>(field);
187         dictionary.put("a",       convert(field, new double[] { 1.0, 2.0, 3.0 }));
188         dictionary.getEntry("a").increment(new double[] { 2.0, 4.0, 8.0 });
189         checkArray(new double[] { 3.0, 6.0, 11.0 }, dictionary.get("a"), 1.0e-15);
190     }
191 
192     private <T extends CalculusFieldElement<T>> void doTestScaledIncrementField(Field<T> field) {
193         FieldArrayDictionary<T> dictionary = new FieldArrayDictionary<>(field);
194         dictionary.put("a",       convert(field, new double[] { 1.0, 2.0, 3.0 }));
195         FieldArrayDictionary<T> other = new FieldArrayDictionary<>(field);
196         other.put("aDot",       convert(field, new double[] { 3.0, 2.0, 1.0 }));
197         dictionary.getEntry("a").scaledIncrement(field.getZero().newInstance(2.0), other.getEntry("aDot"));
198         checkArray(new double[] { 7.0, 6.0, 5.0 }, dictionary.get("a"), 1.0e-15);
199     }
200 
201     private <T extends CalculusFieldElement<T>> void doTestScaledIncrementDouble(Field<T> field) {
202         FieldArrayDictionary<T> dictionary = new FieldArrayDictionary<>(field);
203         dictionary.put("a",       convert(field, new double[] { 1.0, 2.0, 3.0 }));
204         FieldArrayDictionary<T> other = new FieldArrayDictionary<>(field);
205         other.put("aDot",       convert(field, new double[] { 3.0, 2.0, 1.0 }));
206         dictionary.getEntry("a").scaledIncrement(2.0, other.getEntry("aDot"));
207         checkArray(new double[] { 7.0, 6.0, 5.0 }, dictionary.get("a"), 1.0e-15);
208     }
209 
210     private <T extends CalculusFieldElement<T>> void doTestZero(Field<T> field) {
211         FieldArrayDictionary<T> dictionary = new FieldArrayDictionary<>(field);
212         dictionary.put("a",       new double[] { 1.0, 2.0, 3.0 });
213         dictionary.getEntry("a").zero();
214         checkArray(new double[] { 0.0, 0.0, 0.0 }, dictionary.get("a"), 1.0e-15);
215     }
216 
217     private <T extends CalculusFieldElement<T>> void doTestSize(Field<T> field) {
218         FieldArrayDictionary<T> dictionary = new FieldArrayDictionary<>(field);
219         dictionary.put("a",       new double[] { 1.0, 2.0, 3.0 });
220          Assert.assertEquals(3, dictionary.getEntry("a").size(), 1.0e-15);
221     }
222 
223     private <T extends CalculusFieldElement<T>> void doTestDataManagement(Field<T> field) {
224         FieldArrayDictionary<T> dictionary = new FieldArrayDictionary<>(field);
225         dictionary.put("a",       new double[] { 1.0, 2.0, 3.0 });
226         dictionary.put("b",       new double[] { 4.0 });
227         dictionary.put("another", new double[] { 17.0 });
228 
229         Assert.assertEquals(3, dictionary.size());
230         Assert.assertEquals("{a[3], b[1], another[1]}", dictionary.toString());
231 
232         Assert.assertTrue(dictionary.remove("another"));
233         Assert.assertEquals(2, dictionary.size());
234         Assert.assertFalse(dictionary.remove("not-a-key"));
235         Assert.assertEquals(2, dictionary.size());
236 
237         Assert.assertEquals("a", dictionary.getData().get(0).getKey());
238         Assert.assertEquals("b", dictionary.getData().get(1).getKey());
239 
240         dictionary.clear();
241         Assert.assertTrue(dictionary.getData().isEmpty());
242 
243         Assert.assertSame(field, dictionary.getField());
244 
245     }
246 
247     private <T extends CalculusFieldElement<T>> void doTestReplace(Field<T> field) {
248 
249         FieldArrayDictionary<T> dictionary = new FieldArrayDictionary<>(field);
250         dictionary.put("a",       new double[] { 1.0, 2.0, 3.0 });
251         dictionary.put("b",       new double[] { 4.0 });
252         dictionary.put("another", new double[] { 17.0 });
253         Assert.assertEquals(3, dictionary.size());
254 
255         dictionary.put("b",       new double[] { -1.0, -1.0 });
256         Assert.assertEquals(3, dictionary.size());
257 
258         checkArray(new double[] { 1.0, 2.0, 3.0 }, dictionary.get("a"),       1.0e-15);
259         checkArray(new double[] { 17.0 },          dictionary.get("another"), 1.0e-15);
260         checkArray(new double[] { -1.0, -1.0 },    dictionary.get("b"),       1.0e-15);
261         Assert.assertEquals("a",       dictionary.getData().get(0).getKey());
262         Assert.assertEquals("another", dictionary.getData().get(1).getKey());
263         Assert.assertEquals("b",       dictionary.getData().get(2).getKey());
264 
265     }
266 
267     private <T extends CalculusFieldElement<T>> void doTestPutAllMap(Field<T> field) {
268 
269         FieldArrayDictionary<T> dictionary = new FieldArrayDictionary<>(field);
270         dictionary.put("a",       new double[] { 1.0, 2.0, 3.0 });
271         dictionary.put("b",       new double[] { 4.0 });
272         dictionary.put("another", new double[] { 17.0 });
273         Assert.assertEquals(3, dictionary.size());
274 
275         final Map<String, T[]> map = new HashMap<>();
276         map.put("f", convert(field, new double[] {  12.0 }));
277         map.put("g", convert(field, new double[] { -12.0 }));
278         map.put("b", convert(field, new double[] {  19.0 }));
279 
280         dictionary.putAll(map);
281         Assert.assertEquals(5, dictionary.size());
282 
283         checkArray(new double[] { 1.0, 2.0, 3.0 }, dictionary.get("a"),       1.0e-15);
284         checkArray(new double[] {  19.0 },         dictionary.get("b"),       1.0e-15);
285         checkArray(new double[] {  17.0 },         dictionary.get("another"), 1.0e-15);
286         checkArray(new double[] {  12.0 },         dictionary.get("f"),       1.0e-15);
287         checkArray(new double[] { -12.0 },         dictionary.get("g"),       1.0e-15);
288 
289     }
290 
291     private <T extends CalculusFieldElement<T>> void doTestPutAllDictionary(Field<T> field) {
292 
293         FieldArrayDictionary<T> dictionary = new FieldArrayDictionary<>(field);
294         dictionary.put("a",       new double[] { 1.0, 2.0, 3.0 });
295         dictionary.put("b",       new double[] { 4.0 });
296         dictionary.put("another", new double[] { 17.0 });
297         Assert.assertEquals(3, dictionary.size());
298 
299         FieldArrayDictionary<T> other = new FieldArrayDictionary<>(field);
300         other.put("f", new double[] {  12.0 });
301         other.put("g", new double[] { -12.0 });
302         other.put("b", new double[] {  19.0 });
303 
304         dictionary.putAll(other);
305         Assert.assertEquals(5, dictionary.size());
306 
307         checkArray(new double[] { 1.0, 2.0, 3.0 }, dictionary.get("a"),       1.0e-15);
308         checkArray(new double[] {  19.0 },         dictionary.get("b"),       1.0e-15);
309         checkArray(new double[] {  17.0 },         dictionary.get("another"), 1.0e-15);
310         checkArray(new double[] {  12.0 },         dictionary.get("f"),       1.0e-15);
311         checkArray(new double[] { -12.0 },         dictionary.get("g"),       1.0e-15);
312 
313     }
314 
315     private <T extends CalculusFieldElement<T>> void doTestToMap(Field<T> field) {
316         FieldArrayDictionary<T> dictionary = new FieldArrayDictionary<>(field);
317         dictionary.put("a",       new double[] { 1.0, 2.0, 3.0 });
318         dictionary.put("b",       new double[] { 4.0 });
319         dictionary.put("another", new double[] { 17.0 });
320         Assert.assertEquals(3, dictionary.size());
321 
322         Map<String, T[]> map = dictionary.toMap();
323         Assert.assertEquals(3, map.size());
324 
325         checkArray(new double[] { 1.0, 2.0, 3.0 }, map.get("a"),       1.0e-15);
326         checkArray(new double[] {   4.0 },         map.get("b"),       1.0e-15);
327         checkArray(new double[] {  17.0 },         map.get("another"), 1.0e-15);
328 
329         dictionary.clear();
330         Assert.assertEquals(0, dictionary.size());
331         Assert.assertEquals(3, map.size());
332         map.put("z", MathArrays.buildArray(field, 0));
333         Assert.assertEquals(4, map.size());
334         Assert.assertEquals(0, dictionary.size());
335        
336     }
337 
338     private <T extends CalculusFieldElement<T>> void doTestView(Field<T> field) {
339         FieldArrayDictionary<T> dictionary = new FieldArrayDictionary<>(field);
340         dictionary.put("a",       new double[] { 1.0, 2.0, 3.0 });
341         dictionary.put("b",       new double[] { 4.0 });
342         dictionary.put("another", new double[] { 17.0 });
343 
344         FieldArrayDictionary<T> view = dictionary.unmodifiableView();
345         Assert.assertEquals(3, view.size());
346         Assert.assertEquals(3, view.getData().size());
347         Assert.assertEquals(3, view.toMap().size());
348         checkArray(new double[] { 1.0, 2.0, 3.0 }, view.get("a"),       1.0e-15);
349         checkArray(new double[] {   4.0 },         view.get("b"),       1.0e-15);
350         checkArray(new double[] {  17.0 }, view.getEntry("another").getValue(), 1.0e-15);
351 
352         dictionary.put("z", new double[] { 25.0 });
353         Assert.assertEquals(4, view.size());
354         checkArray(new double[] { 25.0 },         view.get("z"), 1.0e-15);
355 
356         checkUnsupported(view, v -> v.clear());
357         checkUnsupported(view, v -> v.put("tF", convert(field, new double[1])));
358         checkUnsupported(view, v -> v.put("tD", new double[1]));
359         checkUnsupported(view, v -> v.putAll(new FieldArrayDictionary<>(field)));
360         checkUnsupported(view, v -> v.putAll(new HashMap<>()));
361         checkUnsupported(view, v -> v.remove("a"));
362 
363     }
364 
365     private <T extends CalculusFieldElement<T>> void checkArray(final double[] expected, final T[] actual, final double eps) {
366         Assert.assertEquals(expected.length, actual.length);
367         for (int i = 0; i < expected.length; ++i) {
368             Assert.assertEquals(expected[i], actual[i].getReal(), eps);
369         }
370     }
371 
372     private <T extends CalculusFieldElement<T>> T[] convert(final Field<T> field, final double[] a) {
373         final T[] converted = MathArrays.buildArray(field, a.length);
374         for (int i = 0; i < a.length; ++i) {
375             converted[i] = field.getZero().newInstance(a[i]);
376         }
377         return converted;
378     }
379 
380     private <T extends CalculusFieldElement<T>> void checkUnsupported(FieldArrayDictionary<T> d, Consumer<FieldArrayDictionary<T>> c) {
381         try {
382             c.accept(d);
383             Assert.fail("an exception should have been thrown");
384         } catch (UnsupportedOperationException uoe) {
385             // expected
386         }
387     }
388 
389 }