1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.hipparchus.util;
15
16 import org.hipparchus.exception.MathIllegalArgumentException;
17 import org.hipparchus.exception.NullArgumentException;
18 import org.hipparchus.random.RandomDataGenerator;
19 import org.hipparchus.util.ResizableDoubleArray.ExpansionMode;
20 import org.junit.jupiter.api.AfterEach;
21 import org.junit.jupiter.api.BeforeEach;
22 import org.junit.jupiter.api.Test;
23
24 import java.util.Arrays;
25
26 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
27 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
28 import static org.junit.jupiter.api.Assertions.assertEquals;
29 import static org.junit.jupiter.api.Assertions.assertFalse;
30 import static org.junit.jupiter.api.Assertions.assertNotEquals;
31 import static org.junit.jupiter.api.Assertions.fail;
32
33
34
35
36 class ResizableDoubleArrayTest {
37
38 protected ResizableDoubleArray da = null;
39
40
41 protected ResizableDoubleArray ra = null;
42
43 @AfterEach
44 void tearDown()
45 throws Exception {
46 da = null;
47 ra = null;
48 }
49
50 @BeforeEach
51 void setUp()
52 throws Exception {
53 da = new ResizableDoubleArray();
54 ra = new ResizableDoubleArray();
55 }
56
57 @Test
58 void testConstructors() {
59 float defaultExpansionFactor = 2.0f;
60 double defaultContractionCriteria = 2.5;
61 ExpansionMode defaultMode = ResizableDoubleArray.ExpansionMode.MULTIPLICATIVE;
62
63 ResizableDoubleArray testDa = new ResizableDoubleArray(2);
64 assertEquals(0, testDa.getNumElements());
65 assertEquals(2, testDa.getCapacity());
66 assertEquals(defaultExpansionFactor, testDa.getExpansionFactor(), 0);
67 assertEquals(defaultContractionCriteria, testDa.getContractionCriterion(), 0);
68 assertEquals(defaultMode, testDa.getExpansionMode());
69 try {
70 da = new ResizableDoubleArray(-1);
71 fail("Expecting MathIllegalArgumentException");
72 } catch (MathIllegalArgumentException ex) {
73
74 }
75
76 testDa = new ResizableDoubleArray((double[]) null);
77 assertEquals(0, testDa.getNumElements());
78
79 double[] initialArray = new double[] { 0, 1, 2 };
80
81 testDa = new ResizableDoubleArray(initialArray);
82 assertEquals(3, testDa.getNumElements());
83
84 testDa = new ResizableDoubleArray(2, 2.0);
85 assertEquals(0, testDa.getNumElements());
86 assertEquals(2, testDa.getCapacity());
87 assertEquals(defaultExpansionFactor, testDa.getExpansionFactor(), 0);
88 assertEquals(defaultContractionCriteria, testDa.getContractionCriterion(), 0);
89 assertEquals(defaultMode, testDa.getExpansionMode());
90
91 try {
92 da = new ResizableDoubleArray(2, 0.5);
93 fail("Expecting MathIllegalArgumentException");
94 } catch (MathIllegalArgumentException ex) {
95
96 }
97
98 testDa = new ResizableDoubleArray(2, 3.0);
99 assertEquals(3.0f, testDa.getExpansionFactor(), 0);
100 assertEquals(3.5f, testDa.getContractionCriterion(), 0);
101
102 testDa = new ResizableDoubleArray(2, 2.0, 3.0);
103 assertEquals(0, testDa.getNumElements());
104 assertEquals(2, testDa.getCapacity());
105 assertEquals(defaultExpansionFactor, testDa.getExpansionFactor(), 0);
106 assertEquals(3.0f, testDa.getContractionCriterion(), 0);
107 assertEquals(defaultMode, testDa.getExpansionMode());
108
109 try {
110 da = new ResizableDoubleArray(2, 2.0, 1.5);
111 fail("Expecting MathIllegalArgumentException");
112 } catch (MathIllegalArgumentException ex) {
113
114 }
115
116 testDa = new ResizableDoubleArray(2, 2.0, 3.0, ResizableDoubleArray.ExpansionMode.ADDITIVE);
117 assertEquals(0, testDa.getNumElements());
118 assertEquals(2, testDa.getCapacity());
119 assertEquals(defaultExpansionFactor, testDa.getExpansionFactor(), 0);
120 assertEquals(3.0f, testDa.getContractionCriterion(), 0);
121 assertEquals(ResizableDoubleArray.ExpansionMode.ADDITIVE, testDa.getExpansionMode());
122
123 try {
124 da = new ResizableDoubleArray(2, 2.0d, 2.5d, null);
125 fail("Expecting NullArgumentException");
126 } catch (NullArgumentException ex) {
127
128 }
129
130
131 testDa = new ResizableDoubleArray(2, 2.0, 3.0, ResizableDoubleArray.ExpansionMode.ADDITIVE);
132 testDa.addElement(2.0);
133 testDa.addElement(3.2);
134 ResizableDoubleArray copyDa = new ResizableDoubleArray(testDa);
135 assertEquals(copyDa, testDa);
136 assertEquals(testDa, copyDa);
137
138
139 final double[] values = { 1 };
140 testDa = new ResizableDoubleArray(values);
141 assertArrayEquals(values, testDa.getElements(), 0);
142 assertEquals(1, testDa.getNumElements());
143 assertEquals(1, testDa.getElement(0), 0);
144 }
145
146 @Test
147 void testGetValues() {
148 double[] controlArray = {
149 2.0, 4.0, 6.0
150 };
151
152 da.addElement(2.0);
153 da.addElement(4.0);
154 da.addElement(6.0);
155
156 double[] testArray = da.getElements();
157
158 for (int i = 0; i < da.getNumElements(); i++) {
159 assertEquals(testArray[i],
160 controlArray[i], Double.MIN_VALUE, "The testArray values should equal the controlArray values, " +
161 "index i: " + i + " does not match");
162 }
163 }
164
165 @Test
166 void testMinMax() {
167 da.addElement(2.0);
168 da.addElement(22.0);
169 da.addElement(-2.0);
170 da.addElement(21.0);
171 da.addElement(22.0);
172 da.addElement(42.0);
173 da.addElement(62.0);
174 da.addElement(22.0);
175 da.addElement(122.0);
176 da.addElement(1212.0);
177
178 assertEquals(-2.0,
179 Arrays.stream(da.getElements()).min().getAsDouble(),
180 Double.MIN_VALUE,
181 "Min should be -2.0");
182
183 assertEquals(1212.0,
184 Arrays.stream(da.getElements()).max().getAsDouble(),
185 Double.MIN_VALUE,
186 "Max should be 1212.0");
187 }
188
189 @Test
190 void testSetElementArbitraryExpansion1() {
191
192
193 da.addElement(2.0);
194 da.addElement(4.0);
195 da.addElement(6.0);
196 da.setElement(1, 3.0);
197
198
199 da.setElement(1000, 3.4);
200
201 assertEquals(1001, da.getNumElements(), "The number of elements should now be 1001, it isn't");
202
203 assertEquals(0.0, da.getElement(760), Double.MIN_VALUE, "Uninitialized Elements are default value of 0.0, index 766 wasn't");
204
205 assertEquals(3.4,
206 da.getElement(1000), Double.MIN_VALUE, "The 1000th index should be 3.4, it isn't");
207 assertEquals(2.0,
208 da.getElement(0), Double.MIN_VALUE, "The 0th index should be 2.0, it isn't");
209 }
210
211 @Test
212 void testSetElementArbitraryExpansion2() {
213
214
215 da.addElement(2.0);
216 da.addElement(4.0);
217 da.addElement(6.0);
218 assertEquals(16, da.getCapacity());
219 assertEquals(3, da.getNumElements());
220 da.setElement(3, 7.0);
221 assertEquals(16, da.getCapacity());
222 assertEquals(4, da.getNumElements());
223 da.setElement(10, 10.0);
224 assertEquals(16, da.getCapacity());
225 assertEquals(11, da.getNumElements());
226 da.setElement(9, 10.0);
227 assertEquals(16, da.getCapacity());
228 assertEquals(11, da.getNumElements());
229
230 try {
231 da.setElement(-2, 3);
232 fail("Expecting ArrayIndexOutOfBoundsException for negative index");
233 } catch (ArrayIndexOutOfBoundsException ex) {
234
235 }
236
237
238
239 ResizableDoubleArray testDa =
240 new ResizableDoubleArray(2, 2.0, 3.0, ResizableDoubleArray.ExpansionMode.ADDITIVE);
241 assertEquals(2, testDa.getCapacity());
242 testDa.addElement(1d);
243 testDa.addElement(1d);
244 assertEquals(2, testDa.getCapacity());
245 testDa.addElement(1d);
246 assertEquals(4, testDa.getCapacity());
247 }
248
249 @Test
250 void testAdd1000() {
251 for (int i = 0; i < 1000; i++) {
252 da.addElement(i);
253 }
254
255 assertEquals(1000, da.getNumElements(), "Number of elements should be equal to 1000 after adding 1000 values");
256
257 assertEquals(56.0,
258 da.getElement(56), Double.MIN_VALUE, "The element at the 56th index should be 56");
259
260 assertEquals(1024,
261 da.getCapacity(),
262 "Internal Storage length should be 1024 if we started out with initial capacity of " +
263 "16 and an expansion factor of 2.0");
264 }
265
266 @Test
267 void testAddElements() {
268 ResizableDoubleArray testDa = new ResizableDoubleArray();
269
270
271 testDa.addElements(new double[] { 4, 5, 6 });
272 assertEquals(3, testDa.getNumElements(), 0);
273 assertEquals(4, testDa.getElement(0), 0);
274 assertEquals(5, testDa.getElement(1), 0);
275 assertEquals(6, testDa.getElement(2), 0);
276
277 testDa.addElements(new double[] { 4, 5, 6 });
278 assertEquals(6, testDa.getNumElements());
279
280
281 testDa = new ResizableDoubleArray(2, 2.0, 2.5, ResizableDoubleArray.ExpansionMode.ADDITIVE);
282 assertEquals(2, testDa.getCapacity());
283 testDa.addElements(new double[] { 1d });
284 testDa.addElements(new double[] { 2d });
285 testDa.addElements(new double[] { 3d });
286 assertEquals(1d, testDa.getElement(0), 0);
287 assertEquals(2d, testDa.getElement(1), 0);
288 assertEquals(3d, testDa.getElement(2), 0);
289 assertEquals(4, testDa.getCapacity());
290 assertEquals(3, testDa.getNumElements());
291 }
292
293 @Test
294 void testAddElementRolling() {
295 ra.addElement(0.5);
296 ra.addElement(1.0);
297 ra.addElement(1.0);
298 ra.addElement(1.0);
299 ra.addElement(1.0);
300 ra.addElement(1.0);
301 ra.addElementRolling(2.0);
302
303 assertEquals(6,
304 ra.getNumElements(),
305 "There should be 6 elements in the eda");
306 assertEquals(2.0,
307 Arrays.stream(ra.getElements()).max().getAsDouble(),
308 Double.MIN_VALUE,
309 "The max element should be 2.0");
310 assertEquals(1.0,
311 Arrays.stream(ra.getElements()).min().getAsDouble(),
312 Double.MIN_VALUE,
313 "The min element should be 1.0");
314
315 for (int i = 0; i < 1024; i++) {
316 ra.addElementRolling(i);
317 }
318
319 assertEquals(6, ra.getNumElements(), "We just inserted 1024 rolling elements, num elements should still be 6");
320
321
322 da.clear();
323 da.addElement(1);
324 da.addElement(2);
325 da.addElementRolling(3);
326 assertEquals(3, da.getElement(1), 0);
327 da.addElementRolling(4);
328 assertEquals(3, da.getElement(0), 0);
329 assertEquals(4, da.getElement(1), 0);
330 da.addElement(5);
331 assertEquals(5, da.getElement(2), 0);
332 da.addElementRolling(6);
333 assertEquals(4, da.getElement(0), 0);
334 assertEquals(5, da.getElement(1), 0);
335 assertEquals(6, da.getElement(2), 0);
336
337
338 ResizableDoubleArray testDa =
339 new ResizableDoubleArray(2, 2.0, 2.5, ResizableDoubleArray.ExpansionMode.ADDITIVE);
340 assertEquals(2, testDa.getCapacity());
341 testDa.addElement(1d);
342 testDa.addElement(2d);
343 testDa.addElement(3d);
344 assertEquals(1d, testDa.getElement(0), 0);
345 assertEquals(2d, testDa.getElement(1), 0);
346 assertEquals(3d, testDa.getElement(2), 0);
347 assertEquals(4, testDa.getCapacity());
348 assertEquals(3, testDa.getNumElements());
349 testDa.addElementRolling(4d);
350 assertEquals(2d, testDa.getElement(0), 0);
351 assertEquals(3d, testDa.getElement(1), 0);
352 assertEquals(4d, testDa.getElement(2), 0);
353 assertEquals(4, testDa.getCapacity());
354 assertEquals(3, testDa.getNumElements());
355 testDa.addElementRolling(5d);
356 assertEquals(3d, testDa.getElement(0), 0);
357 assertEquals(4d, testDa.getElement(1), 0);
358 assertEquals(5d, testDa.getElement(2), 0);
359 assertEquals(4, testDa.getCapacity());
360 assertEquals(3, testDa.getNumElements());
361 try {
362 testDa.getElement(4);
363 fail("Expecting ArrayIndexOutOfBoundsException");
364 } catch (ArrayIndexOutOfBoundsException ex) {
365
366 }
367 try {
368 testDa.getElement(-1);
369 fail("Expecting ArrayIndexOutOfBoundsException");
370 } catch (ArrayIndexOutOfBoundsException ex) {
371
372 }
373 }
374
375 @Test
376 void testSetNumberOfElements() {
377 da.addElement(1.0);
378 da.addElement(1.0);
379 da.addElement(1.0);
380 da.addElement(1.0);
381 da.addElement(1.0);
382 da.addElement(1.0);
383 assertEquals(6, da.getNumElements(), "Number of elements should equal 6");
384
385 da.setNumElements(3);
386 assertEquals(3, da.getNumElements(), "Number of elements should equal 3");
387
388 try {
389 da.setNumElements(-3);
390 fail("Setting number of elements to negative should've thrown an exception");
391 } catch (MathIllegalArgumentException iae) {
392 }
393
394 da.setNumElements(1024);
395 assertEquals(1024, da.getNumElements(), "Number of elements should now be 1024");
396 assertEquals(0.0, da.getElement(453), Double.MIN_VALUE, "Element 453 should be a default double");
397 }
398
399 @Test
400 void testWithInitialCapacity() {
401
402 ResizableDoubleArray eDA2 = new ResizableDoubleArray(2);
403 assertEquals(0, eDA2.getNumElements(), "Initial number of elements should be 0");
404
405 final RandomDataGenerator gen = new RandomDataGenerator(1000);
406 final int iterations = gen.nextInt(100, 1000);
407
408 for (int i = 0; i < iterations; i++) {
409 eDA2.addElement(i);
410 }
411
412 assertEquals(iterations, eDA2.getNumElements(), "Number of elements should be equal to " + iterations);
413
414 eDA2.addElement(2.0);
415
416 assertEquals(iterations + 1, eDA2.getNumElements(), "Number of elements should be equals to " +
417 (iterations + 1));
418 }
419
420 @Test
421 void testWithInitialCapacityAndExpansionFactor() {
422
423 ResizableDoubleArray eDA3 = new ResizableDoubleArray(3, 3.0, 3.5);
424 assertEquals(0, eDA3.getNumElements(), "Initial number of elements should be 0");
425
426 final RandomDataGenerator gen = new RandomDataGenerator(1000);
427 final int iterations = gen.nextInt(100, 1000);
428
429 for (int i = 0; i < iterations; i++) {
430 eDA3.addElement(i);
431 }
432
433 assertEquals(iterations, eDA3.getNumElements(), "Number of elements should be equal to " + iterations);
434
435 eDA3.addElement(2.0);
436
437 assertEquals(iterations + 1, eDA3.getNumElements(), "Number of elements should be equals to " +
438 (iterations + 1));
439
440 assertEquals(3.0f,
441 eDA3.getExpansionFactor(), Double.MIN_VALUE, "Expansion factor should equal 3.0");
442 }
443
444 @Test
445 void testDiscard() {
446 da.addElement(2.0);
447 da.addElement(2.0);
448 da.addElement(2.0);
449 da.addElement(2.0);
450 da.addElement(2.0);
451 da.addElement(2.0);
452 da.addElement(2.0);
453 da.addElement(2.0);
454 da.addElement(2.0);
455 da.addElement(2.0);
456 da.addElement(2.0);
457 assertEquals(11, da.getNumElements(), "Number of elements should be 11");
458
459 da.discardFrontElements(5);
460 assertEquals(6, da.getNumElements(), "Number of elements should be 6");
461
462 da.addElement(2.0);
463 da.addElement(2.0);
464 da.addElement(2.0);
465 da.addElement(2.0);
466 assertEquals(10, da.getNumElements(), "Number of elements should be 10");
467
468 da.discardMostRecentElements(2);
469 assertEquals(8, da.getNumElements(), "Number of elements should be 8");
470
471 try {
472 da.discardFrontElements(-1);
473 fail("Trying to discard a negative number of element is not allowed");
474 } catch (Exception e) {
475 }
476
477 try {
478 da.discardMostRecentElements(-1);
479 fail("Trying to discard a negative number of element is not allowed");
480 } catch (Exception e) {
481 }
482
483 try {
484 da.discardFrontElements(10000);
485 fail("You can't discard more elements than the array contains");
486 } catch (Exception e) {
487 }
488
489 try {
490 da.discardMostRecentElements(10000);
491 fail("You can't discard more elements than the array contains");
492 } catch (Exception e) {
493 }
494
495 }
496
497 @Test
498 void testSubstitute() {
499
500 da.addElement(2.0);
501 da.addElement(2.0);
502 da.addElement(2.0);
503 da.addElement(2.0);
504 da.addElement(2.0);
505 da.addElement(2.0);
506 da.addElement(2.0);
507 da.addElement(2.0);
508 da.addElement(2.0);
509 da.addElement(2.0);
510 da.addElement(2.0);
511 assertEquals(11, da.getNumElements(), "Number of elements should be 11");
512
513 da.substituteMostRecentElement(24);
514
515 assertEquals(11, da.getNumElements(), "Number of elements should be 11");
516
517 assertDoesNotThrow(() -> {
518 da.discardMostRecentElements(10);
519 }, "Trying to discard a negative number of element is not allowed");
520
521 da.substituteMostRecentElement(24);
522
523 assertEquals(1, da.getNumElements(), "Number of elements should be 1");
524
525 }
526
527 @SuppressWarnings("unlikely-arg-type")
528 @Test
529 void testEqualsAndHashCode()
530 throws Exception {
531
532
533 ResizableDoubleArray first = new ResizableDoubleArray();
534 Double other = Double.valueOf(2);
535 assertNotEquals(first, other);
536
537
538 other = null;
539 assertNotEquals(first, other);
540
541
542 assertEquals(first, first);
543
544
545 ResizableDoubleArray second = new ResizableDoubleArray();
546 verifyEquality(first, second);
547
548
549 ResizableDoubleArray third = new ResizableDoubleArray(3, 2.0, 2.0);
550 verifyInequality(third, first);
551 ResizableDoubleArray fourth = new ResizableDoubleArray(3, 2.0, 2.0);
552 ResizableDoubleArray fifth = new ResizableDoubleArray(2, 2.0, 2.0);
553 verifyEquality(third, fourth);
554 verifyInequality(third, fifth);
555 third.addElement(4.1);
556 third.addElement(4.2);
557 third.addElement(4.3);
558 fourth.addElement(4.1);
559 fourth.addElement(4.2);
560 fourth.addElement(4.3);
561 verifyEquality(third, fourth);
562
563
564 fourth.addElement(4.4);
565 verifyInequality(third, fourth);
566 third.addElement(4.4);
567 verifyEquality(third, fourth);
568 fourth.addElement(4.4);
569 verifyInequality(third, fourth);
570 third.addElement(4.4);
571 verifyEquality(third, fourth);
572 fourth.addElementRolling(4.5);
573 third.addElementRolling(4.5);
574 verifyEquality(third, fourth);
575
576
577 third.discardFrontElements(1);
578 verifyInequality(third, fourth);
579 fourth.discardFrontElements(1);
580 verifyEquality(third, fourth);
581
582
583 third.discardMostRecentElements(2);
584 fourth.discardMostRecentElements(2);
585 verifyEquality(third, fourth);
586
587
588 third.addElement(18);
589 fourth.addElement(17);
590 third.addElement(17);
591 fourth.addElement(18);
592 verifyInequality(third, fourth);
593
594
595 verifyEquality(fourth, new ResizableDoubleArray(fourth));
596
597
598 verifyEquality(fourth, fourth.copy());
599 }
600
601 @Test
602 void testGetArrayRef() {
603 final ResizableDoubleArray a = new ResizableDoubleArray();
604
605
606 final int index = 20;
607 final double v1 = 1.2;
608 a.setElement(index, v1);
609
610
611 final double v2 = v1 + 3.4;
612 final double[] aInternalArray = a.getArrayRef();
613 aInternalArray[a.getStartIndex() + index] = v2;
614
615 assertEquals(v2, a.getElement(index), 0d);
616 }
617
618 @Test
619 void testCompute() {
620 final ResizableDoubleArray a = new ResizableDoubleArray();
621 final int max = 20;
622 for (int i = 1; i <= max; i++) {
623 a.setElement(i, i);
624 }
625
626 final MathArrays.Function add = new MathArrays.Function() {
627
628 @Override
629 public double evaluate(double[] a, int index, int num) {
630 double sum = 0;
631 final int max = index + num;
632 for (int i = index; i < max; i++) {
633 sum += a[i];
634 }
635 return sum;
636 }
637
638 @Override
639 public double evaluate(double[] a) {
640 return evaluate(a, 0, a.length);
641 }
642 };
643
644 final double sum = a.compute(add);
645 assertEquals(0.5 * max * (max + 1), sum, 0);
646 }
647
648 private void verifyEquality(ResizableDoubleArray a,
649 ResizableDoubleArray b) {
650 assertEquals(b, a);
651 assertEquals(a, b);
652 assertEquals(a.hashCode(), b.hashCode());
653 }
654
655 private void verifyInequality(ResizableDoubleArray a,
656 ResizableDoubleArray b) {
657 assertNotEquals(b, a);
658 assertNotEquals(a, b);
659 assertFalse(a.hashCode() == b.hashCode());
660 }
661
662 }