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