001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.math.util;
018 import org.apache.commons.math.random.RandomDataImpl;
019 import org.apache.commons.math.random.RandomData;
020
021
022 /**
023 * This class contains test cases for the ResizableDoubleArray.
024 *
025 * @version $Revision: 762087 $ $Date: 2009-04-05 10:20:18 -0400 (Sun, 05 Apr 2009) $
026 */
027 public class ResizableDoubleArrayTest extends DoubleArrayAbstractTest {
028
029 public ResizableDoubleArrayTest(String name) {
030 super( name );
031 }
032
033 @Override
034 protected void tearDown() throws Exception {
035 da = null;
036 ra = null;
037 }
038
039 @Override
040 protected void setUp() throws Exception {
041 da = new ResizableDoubleArray();
042 ra = new ResizableDoubleArray();
043 }
044
045 public void testConstructors() {
046 float defaultExpansionFactor = 2.0f;
047 float defaultContractionCriteria = 2.5f;
048 int defaultMode = ResizableDoubleArray.MULTIPLICATIVE_MODE;
049
050 ResizableDoubleArray testDa = new ResizableDoubleArray(2);
051 assertEquals(0, testDa.getNumElements());
052 assertEquals(2, testDa.getInternalLength());
053 assertEquals(defaultExpansionFactor, testDa.getExpansionFactor(), 0);
054 assertEquals(defaultContractionCriteria, testDa.getContractionCriteria(), 0);
055 assertEquals(defaultMode, testDa.getExpansionMode());
056 try {
057 da = new ResizableDoubleArray(-1);
058 fail("Expecting IllegalArgumentException");
059 } catch (IllegalArgumentException ex) {
060 // expected
061 }
062
063 testDa = new ResizableDoubleArray(2, 2.0f);
064 assertEquals(0, testDa.getNumElements());
065 assertEquals(2, testDa.getInternalLength());
066 assertEquals(defaultExpansionFactor, testDa.getExpansionFactor(), 0);
067 assertEquals(defaultContractionCriteria, testDa.getContractionCriteria(), 0);
068 assertEquals(defaultMode, testDa.getExpansionMode());
069
070 try {
071 da = new ResizableDoubleArray(2, 0.5f);
072 fail("Expecting IllegalArgumentException");
073 } catch (IllegalArgumentException ex) {
074 // expected
075 }
076
077 testDa = new ResizableDoubleArray(2, 3.0f);
078 assertEquals(3.0f, testDa.getExpansionFactor(), 0);
079 assertEquals(3.5f, testDa.getContractionCriteria(), 0);
080
081 testDa = new ResizableDoubleArray(2, 2.0f, 3.0f);
082 assertEquals(0, testDa.getNumElements());
083 assertEquals(2, testDa.getInternalLength());
084 assertEquals(defaultExpansionFactor, testDa.getExpansionFactor(), 0);
085 assertEquals(3.0f, testDa.getContractionCriteria(), 0);
086 assertEquals(defaultMode, testDa.getExpansionMode());
087
088 try {
089 da = new ResizableDoubleArray(2, 2.0f, 1.5f);
090 fail("Expecting IllegalArgumentException");
091 } catch (IllegalArgumentException ex) {
092 // expected
093 }
094
095 testDa = new ResizableDoubleArray(2, 2.0f, 3.0f,
096 ResizableDoubleArray.ADDITIVE_MODE);
097 assertEquals(0, testDa.getNumElements());
098 assertEquals(2, testDa.getInternalLength());
099 assertEquals(defaultExpansionFactor, testDa.getExpansionFactor(), 0);
100 assertEquals(3.0f, testDa.getContractionCriteria(), 0);
101 assertEquals(ResizableDoubleArray.ADDITIVE_MODE,
102 testDa.getExpansionMode());
103
104 try {
105 da = new ResizableDoubleArray(2, 2.0f, 2.5f, -1);
106 fail("Expecting IllegalArgumentException");
107 } catch (IllegalArgumentException ex) {
108 // expected
109 }
110
111 // Copy constructor
112 testDa = new ResizableDoubleArray(2, 2.0f, 3.0f,
113 ResizableDoubleArray.ADDITIVE_MODE);
114 testDa.addElement(2.0);
115 testDa.addElement(3.2);
116 ResizableDoubleArray copyDa = new ResizableDoubleArray(testDa);
117 assertEquals(copyDa, testDa);
118 assertEquals(testDa, copyDa);
119 }
120
121
122 public void testSetElementArbitraryExpansion() {
123
124 // MULTIPLICATIVE_MODE
125 da.addElement(2.0);
126 da.addElement(4.0);
127 da.addElement(6.0);
128 da.setElement(1, 3.0);
129
130 // Expand the array arbitrarily to 1000 items
131 da.setElement(1000, 3.4);
132
133 assertEquals( "The number of elements should now be 1001, it isn't",
134 da.getNumElements(), 1001);
135
136 assertEquals( "Uninitialized Elements are default value of 0.0, index 766 wasn't", 0.0,
137 da.getElement( 760 ), Double.MIN_VALUE );
138
139 assertEquals( "The 1000th index should be 3.4, it isn't", 3.4, da.getElement(1000),
140 Double.MIN_VALUE );
141 assertEquals( "The 0th index should be 2.0, it isn't", 2.0, da.getElement(0),
142 Double.MIN_VALUE);
143
144 // Make sure numElements and expansion work correctly for expansion boundary cases
145 da.clear();
146 da.addElement(2.0);
147 da.addElement(4.0);
148 da.addElement(6.0);
149 assertEquals(4, ((ResizableDoubleArray) da).getInternalLength());
150 assertEquals(3, da.getNumElements());
151 da.setElement(3, 7.0);
152 assertEquals(4, ((ResizableDoubleArray) da).getInternalLength());
153 assertEquals(4, da.getNumElements());
154 da.setElement(10, 10.0);
155 assertEquals(11, ((ResizableDoubleArray) da).getInternalLength());
156 assertEquals(11, da.getNumElements());
157 da.setElement(9, 10.0);
158 assertEquals(11, ((ResizableDoubleArray) da).getInternalLength());
159 assertEquals(11, da.getNumElements());
160
161 try {
162 da.setElement(-2, 3);
163 fail("Expecting ArrayIndexOutOfBoundsException for negative index");
164 } catch (ArrayIndexOutOfBoundsException ex) {
165 // expected
166 }
167
168 // ADDITIVE_MODE
169
170 ResizableDoubleArray testDa = new ResizableDoubleArray(2, 2.0f, 3.0f,
171 ResizableDoubleArray.ADDITIVE_MODE);
172 assertEquals(2, testDa.getInternalLength());
173 testDa.addElement(1d);
174 testDa.addElement(1d);
175 assertEquals(2, testDa.getInternalLength());
176 testDa.addElement(1d);
177 assertEquals(4, testDa.getInternalLength());
178 }
179
180 @Override
181 public void testAdd1000() {
182 super.testAdd1000();
183 assertEquals("Internal Storage length should be 1024 if we started out with initial capacity of " +
184 "16 and an expansion factor of 2.0",
185 1024, ((ResizableDoubleArray) da).getInternalLength());
186 }
187
188 @Override
189 public void testAddElementRolling() {
190 super.testAddElementRolling();
191
192 // MULTIPLICATIVE_MODE
193 da.clear();
194 da.addElement(1);
195 da.addElement(2);
196 da.addElementRolling(3);
197 assertEquals(3, da.getElement(1), 0);
198 da.addElementRolling(4);
199 assertEquals(3, da.getElement(0), 0);
200 assertEquals(4, da.getElement(1), 0);
201 da.addElement(5);
202 assertEquals(5, da.getElement(2), 0);
203 da.addElementRolling(6);
204 assertEquals(4, da.getElement(0), 0);
205 assertEquals(5, da.getElement(1), 0);
206 assertEquals(6, da.getElement(2), 0);
207
208 // ADDITIVE_MODE (x's are occupied storage locations, 0's are open)
209 ResizableDoubleArray testDa = new ResizableDoubleArray(2, 2.0f, 2.5f,
210 ResizableDoubleArray.ADDITIVE_MODE);
211 assertEquals(2, testDa.getInternalLength());
212 testDa.addElement(1d); // x,0
213 testDa.addElement(2d); // x,x
214 testDa.addElement(3d); // x,x,x,0 -- expanded
215 assertEquals(1d, testDa.getElement(0), 0);
216 assertEquals(2d, testDa.getElement(1), 0);
217 assertEquals(3d, testDa.getElement(2), 0);
218 assertEquals(4, testDa.getInternalLength()); // x,x,x,0
219 assertEquals(3, testDa.getNumElements());
220 testDa.addElementRolling(4d);
221 assertEquals(2d, testDa.getElement(0), 0);
222 assertEquals(3d, testDa.getElement(1), 0);
223 assertEquals(4d, testDa.getElement(2), 0);
224 assertEquals(4, testDa.getInternalLength()); // 0,x,x,x
225 assertEquals(3, testDa.getNumElements());
226 testDa.addElementRolling(5d); // 0,0,x,x,x,0 -- time to contract
227 assertEquals(3d, testDa.getElement(0), 0);
228 assertEquals(4d, testDa.getElement(1), 0);
229 assertEquals(5d, testDa.getElement(2), 0);
230 assertEquals(4, testDa.getInternalLength()); // contracted -- x,x,x,0
231 assertEquals(3, testDa.getNumElements());
232 try {
233 testDa.getElement(4);
234 fail("Expecting ArrayIndexOutOfBoundsException");
235 } catch (ArrayIndexOutOfBoundsException ex) {
236 // expected
237 }
238 try {
239 testDa.getElement(-1);
240 fail("Expecting ArrayIndexOutOfBoundsException");
241 } catch (ArrayIndexOutOfBoundsException ex) {
242 // expected
243 }
244 }
245
246 public void testSetNumberOfElements() {
247 da.addElement( 1.0 );
248 da.addElement( 1.0 );
249 da.addElement( 1.0 );
250 da.addElement( 1.0 );
251 da.addElement( 1.0 );
252 da.addElement( 1.0 );
253 assertEquals( "Number of elements should equal 6", da.getNumElements(), 6);
254
255 ((ResizableDoubleArray) da).setNumElements( 3 );
256 assertEquals( "Number of elements should equal 3", da.getNumElements(), 3);
257
258 try {
259 ((ResizableDoubleArray) da).setNumElements( -3 );
260 fail( "Setting number of elements to negative should've thrown an exception");
261 } catch( IllegalArgumentException iae ) {
262 }
263
264 ((ResizableDoubleArray) da).setNumElements(1024);
265 assertEquals( "Number of elements should now be 1024", da.getNumElements(), 1024);
266 assertEquals( "Element 453 should be a default double", da.getElement( 453 ), 0.0, Double.MIN_VALUE);
267
268 }
269
270 public void testWithInitialCapacity() {
271
272 ResizableDoubleArray eDA2 = new ResizableDoubleArray(2);
273 assertEquals("Initial number of elements should be 0", 0, eDA2.getNumElements());
274
275 RandomData randomData = new RandomDataImpl();
276 int iterations = randomData.nextInt(100, 1000);
277
278 for( int i = 0; i < iterations; i++) {
279 eDA2.addElement( i );
280 }
281
282 assertEquals("Number of elements should be equal to " + iterations, iterations, eDA2.getNumElements());
283
284 eDA2.addElement( 2.0 );
285
286 assertEquals("Number of elements should be equals to " + (iterations +1),
287 iterations + 1 , eDA2.getNumElements() );
288 }
289
290 public void testWithInitialCapacityAndExpansionFactor() {
291
292 ResizableDoubleArray eDA3 = new ResizableDoubleArray(3, 3.0f, 3.5f);
293 assertEquals("Initial number of elements should be 0", 0, eDA3.getNumElements() );
294
295 RandomData randomData = new RandomDataImpl();
296 int iterations = randomData.nextInt(100, 3000);
297
298 for( int i = 0; i < iterations; i++) {
299 eDA3.addElement( i );
300 }
301
302 assertEquals("Number of elements should be equal to " + iterations, iterations,eDA3.getNumElements());
303
304 eDA3.addElement( 2.0 );
305
306 assertEquals("Number of elements should be equals to " + (iterations +1),
307 iterations +1, eDA3.getNumElements() );
308
309 assertEquals("Expansion factor should equal 3.0", 3.0f, eDA3.getExpansionFactor(), Double.MIN_VALUE);
310 }
311
312 public void testDiscard() {
313 da.addElement(2.0);
314 da.addElement(2.0);
315 da.addElement(2.0);
316 da.addElement(2.0);
317 da.addElement(2.0);
318 da.addElement(2.0);
319 da.addElement(2.0);
320 da.addElement(2.0);
321 da.addElement(2.0);
322 da.addElement(2.0);
323 da.addElement(2.0);
324 assertEquals( "Number of elements should be 11", 11, da.getNumElements());
325
326 ((ResizableDoubleArray)da).discardFrontElements(5);
327 assertEquals( "Number of elements should be 6", 6, da.getNumElements());
328
329 da.addElement(2.0);
330 da.addElement(2.0);
331 da.addElement(2.0);
332 da.addElement(2.0);
333 assertEquals( "Number of elements should be 10", 10, da.getNumElements());
334
335 ((ResizableDoubleArray)da).discardMostRecentElements(2);
336 assertEquals( "Number of elements should be 8", 8, da.getNumElements());
337
338 try {
339 ((ResizableDoubleArray)da).discardFrontElements(-1);
340 fail( "Trying to discard a negative number of element is not allowed");
341 } catch( Exception e ){
342 }
343
344 try {
345 ((ResizableDoubleArray)da).discardMostRecentElements(-1);
346 fail( "Trying to discard a negative number of element is not allowed");
347 } catch( Exception e ){
348 }
349
350 try {
351 ((ResizableDoubleArray)da).discardFrontElements( 10000 );
352 fail( "You can't discard more elements than the array contains");
353 } catch( Exception e ){
354 }
355
356 try {
357 ((ResizableDoubleArray)da).discardMostRecentElements( 10000 );
358 fail( "You can't discard more elements than the array contains");
359 } catch( Exception e ){
360 }
361
362 }
363
364 public void testSubstitute() {
365
366 da.addElement(2.0);
367 da.addElement(2.0);
368 da.addElement(2.0);
369 da.addElement(2.0);
370 da.addElement(2.0);
371 da.addElement(2.0);
372 da.addElement(2.0);
373 da.addElement(2.0);
374 da.addElement(2.0);
375 da.addElement(2.0);
376 da.addElement(2.0);
377 assertEquals( "Number of elements should be 11", 11, da.getNumElements());
378
379 ((ResizableDoubleArray)da).substituteMostRecentElement(24);
380
381 assertEquals( "Number of elements should be 11", 11, da.getNumElements());
382
383 try {
384 ((ResizableDoubleArray)da).discardMostRecentElements(10);
385 } catch( Exception e ){
386 fail( "Trying to discard a negative number of element is not allowed");
387 }
388
389 ((ResizableDoubleArray)da).substituteMostRecentElement(24);
390
391 assertEquals( "Number of elements should be 1", 1, da.getNumElements());
392
393 }
394
395 public void testMutators() {
396 ((ResizableDoubleArray)da).setContractionCriteria(10f);
397 assertEquals(10f, ((ResizableDoubleArray)da).getContractionCriteria(), 0);
398 ((ResizableDoubleArray)da).setExpansionFactor(8f);
399 assertEquals(8f, ((ResizableDoubleArray)da).getExpansionFactor(), 0);
400 try {
401 ((ResizableDoubleArray)da).setExpansionFactor(11f); // greater than contractionCriteria
402 fail("Expecting IllegalArgumentException");
403 } catch (IllegalArgumentException ex) {
404 // expected
405 }
406 ((ResizableDoubleArray)da).setExpansionMode(
407 ResizableDoubleArray.ADDITIVE_MODE);
408 assertEquals(ResizableDoubleArray.ADDITIVE_MODE,
409 ((ResizableDoubleArray)da).getExpansionMode());
410 try {
411 ((ResizableDoubleArray)da).setExpansionMode(-1);
412 fail ("Expecting IllegalArgumentException");
413 } catch (IllegalArgumentException ex) {
414 // expected
415 }
416 }
417
418 public void testEqualsAndHashCode() throws Exception {
419
420 // Wrong type
421 ResizableDoubleArray first = new ResizableDoubleArray();
422 Double other = new Double(2);
423 assertFalse(first.equals(other));
424
425 // Null
426 other = null;
427 assertFalse(first.equals(other));
428
429 // Reflexive
430 assertTrue(first.equals(first));
431
432 // Argumentless constructor
433 ResizableDoubleArray second = new ResizableDoubleArray();
434 verifyEquality(first, second);
435
436 // Equals iff same data, same properties
437 ResizableDoubleArray third = new ResizableDoubleArray(3, 2.0f, 2.0f);
438 verifyInequality(third, first);
439 ResizableDoubleArray fourth = new ResizableDoubleArray(3, 2.0f, 2.0f);
440 ResizableDoubleArray fifth = new ResizableDoubleArray(2, 2.0f, 2.0f);
441 verifyEquality(third, fourth);
442 verifyInequality(third, fifth);
443 third.addElement(4.1);
444 third.addElement(4.2);
445 third.addElement(4.3);
446 fourth.addElement(4.1);
447 fourth.addElement(4.2);
448 fourth.addElement(4.3);
449 verifyEquality(third, fourth);
450
451 // expand
452 fourth.addElement(4.4);
453 verifyInequality(third, fourth);
454 third.addElement(4.4);
455 verifyEquality(third, fourth);
456 fourth.addElement(4.4);
457 verifyInequality(third, fourth);
458 third.addElement(4.4);
459 verifyEquality(third, fourth);
460 fourth.addElementRolling(4.5);
461 third.addElementRolling(4.5);
462 verifyEquality(third, fourth);
463
464 // discard
465 third.discardFrontElements(1);
466 verifyInequality(third, fourth);
467 fourth.discardFrontElements(1);
468 verifyEquality(third, fourth);
469
470 // discard recent
471 third.discardMostRecentElements(2);
472 fourth.discardMostRecentElements(2);
473 verifyEquality(third, fourth);
474
475 // wrong order
476 third.addElement(18);
477 fourth.addElement(17);
478 third.addElement(17);
479 fourth.addElement(18);
480 verifyInequality(third, fourth);
481
482 // copy
483 ResizableDoubleArray.copy(fourth, fifth);
484 verifyEquality(fourth, fifth);
485
486 // Copy constructor
487 verifyEquality(fourth, new ResizableDoubleArray(fourth));
488
489 // Instance copy
490 verifyEquality(fourth, fourth.copy());
491
492 }
493
494 private void verifyEquality(ResizableDoubleArray a, ResizableDoubleArray b) {
495 assertTrue(b.equals(a));
496 assertTrue(a.equals(b));
497 assertEquals(a.hashCode(), b.hashCode());
498 }
499
500 private void verifyInequality(ResizableDoubleArray a, ResizableDoubleArray b) {
501 assertFalse(b.equals(a));
502 assertFalse(a.equals(b));
503 assertFalse(a.hashCode() == b.hashCode());
504 }
505
506 }