1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF 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.apache.commons.math.util;
18  import org.apache.commons.math.random.RandomDataImpl;
19  import org.apache.commons.math.random.RandomData;
20  
21  
22  /**
23   * This class contains test cases for the ResizableDoubleArray.
24   * 
25   * @version $Revision: 480442 $ $Date: 2006-11-29 00:21:22 -0700 (Wed, 29 Nov 2006) $
26   */
27  public class ResizableDoubleArrayTest extends DoubleArrayAbstractTest {
28      
29      public ResizableDoubleArrayTest(String name) {
30          super( name );
31      }
32        
33      protected void tearDown() throws Exception {
34          da = null;
35          ra = null;
36      }
37         
38      protected void setUp() throws Exception {
39          da = new ResizableDoubleArray();
40          ra = new ResizableDoubleArray();
41      }
42      
43      public void testConstructors() {
44          float defaultExpansionFactor = 2.0f;
45          float defaultContractionCriteria = 2.5f;
46          int defaultMode = ResizableDoubleArray.MULTIPLICATIVE_MODE;
47          
48          ResizableDoubleArray testDa = new ResizableDoubleArray(2);
49          assertEquals(0, testDa.getNumElements());
50          assertEquals(2, testDa.getInternalLength());
51          assertEquals(defaultExpansionFactor, testDa.getExpansionFactor(), 0);
52          assertEquals(defaultContractionCriteria, testDa.getContractionCriteria(), 0);
53          assertEquals(defaultMode, testDa.getExpansionMode());
54          try {
55              da = new ResizableDoubleArray(-1);
56              fail("Expecting IllegalArgumentException");
57          } catch (IllegalArgumentException ex) {
58              // expected
59          }
60          
61          testDa = new ResizableDoubleArray(2, 2.0f);
62          assertEquals(0, testDa.getNumElements());
63          assertEquals(2, testDa.getInternalLength());
64          assertEquals(defaultExpansionFactor, testDa.getExpansionFactor(), 0);
65          assertEquals(defaultContractionCriteria, testDa.getContractionCriteria(), 0);
66          assertEquals(defaultMode, testDa.getExpansionMode());
67          
68          try {
69              da = new ResizableDoubleArray(2, 0.5f);
70              fail("Expecting IllegalArgumentException");
71          } catch (IllegalArgumentException ex) {
72              // expected
73          }
74          
75          testDa = new ResizableDoubleArray(2, 3.0f);
76          assertEquals(3.0f, testDa.getExpansionFactor(), 0);
77          assertEquals(3.5f, testDa.getContractionCriteria(), 0);
78          
79          testDa = new ResizableDoubleArray(2, 2.0f, 3.0f);
80          assertEquals(0, testDa.getNumElements());
81          assertEquals(2, testDa.getInternalLength());
82          assertEquals(defaultExpansionFactor, testDa.getExpansionFactor(), 0);
83          assertEquals(3.0f, testDa.getContractionCriteria(), 0);
84          assertEquals(defaultMode, testDa.getExpansionMode());
85          
86          try {
87              da = new ResizableDoubleArray(2, 2.0f, 1.5f);
88              fail("Expecting IllegalArgumentException");
89          } catch (IllegalArgumentException ex) {
90              // expected
91          }
92          
93          testDa = new ResizableDoubleArray(2, 2.0f, 3.0f, 
94                  ResizableDoubleArray.ADDITIVE_MODE);
95          assertEquals(0, testDa.getNumElements());
96          assertEquals(2, testDa.getInternalLength());
97          assertEquals(defaultExpansionFactor, testDa.getExpansionFactor(), 0);
98          assertEquals(3.0f, testDa.getContractionCriteria(), 0);
99          assertEquals(ResizableDoubleArray.ADDITIVE_MODE, 
100                 testDa.getExpansionMode());
101         
102         try {
103             da = new ResizableDoubleArray(2, 2.0f, 2.5f, -1);
104             fail("Expecting IllegalArgumentException");
105         } catch (IllegalArgumentException ex) {
106             // expected
107         }
108         
109     }
110     
111     
112     public void testSetElementArbitraryExpansion() {
113         
114         // MULTIPLICATIVE_MODE 
115         da.addElement(2.0);
116         da.addElement(4.0);
117         da.addElement(6.0);
118         da.setElement(1, 3.0);
119         
120         // Expand the array arbitrarily to 1000 items
121         da.setElement(1000, 3.4);
122         
123         assertEquals( "The number of elements should now be 1001, it isn't", 
124                 da.getNumElements(), 1001);
125         
126         assertEquals( "Uninitialized Elements are default value of 0.0, index 766 wasn't", 0.0,
127                 da.getElement( 760 ), Double.MIN_VALUE );
128         
129         assertEquals( "The 1000th index should be 3.4, it isn't", 3.4, da.getElement(1000), 
130                 Double.MIN_VALUE );
131         assertEquals( "The 0th index should be 2.0, it isn't", 2.0, da.getElement(0), 
132                 Double.MIN_VALUE); 
133         
134         // Make sure numElements and expansion work correctly for expansion boundary cases
135         da.clear();
136         da.addElement(2.0);
137         da.addElement(4.0);
138         da.addElement(6.0);
139         assertEquals(4, ((ResizableDoubleArray) da).getInternalLength());
140         assertEquals(3, da.getNumElements());
141         da.setElement(3, 7.0);
142         assertEquals(4, ((ResizableDoubleArray) da).getInternalLength());
143         assertEquals(4, da.getNumElements());
144         da.setElement(10, 10.0);
145         assertEquals(11, ((ResizableDoubleArray) da).getInternalLength());
146         assertEquals(11, da.getNumElements());
147         da.setElement(9, 10.0);
148         assertEquals(11, ((ResizableDoubleArray) da).getInternalLength());
149         assertEquals(11, da.getNumElements());
150         
151         try {
152             da.setElement(-2, 3);
153             fail("Expecting ArrayIndexOutOfBoundsException for negative index");
154         } catch (ArrayIndexOutOfBoundsException ex) {
155             // expected
156         }
157         
158         // ADDITIVE_MODE
159         
160         ResizableDoubleArray testDa = new ResizableDoubleArray(2, 2.0f, 3.0f, 
161                 ResizableDoubleArray.ADDITIVE_MODE);
162         assertEquals(2, testDa.getInternalLength());
163         testDa.addElement(1d);
164         testDa.addElement(1d);
165         assertEquals(2, testDa.getInternalLength());
166         testDa.addElement(1d);
167         assertEquals(4, testDa.getInternalLength());         
168     }
169     
170     public void testAdd1000() {
171         super.testAdd1000();
172         assertEquals("Internal Storage length should be 1024 if we started out with initial capacity of " +
173                 "16 and an expansion factor of 2.0",
174                 1024, ((ResizableDoubleArray) da).getInternalLength());
175     }
176     
177     public void testAddElementRolling() {
178         super.testAddElementRolling();
179         
180         // MULTIPLICATIVE_MODE
181         da.clear();
182         da.addElement(1);
183         da.addElement(2);
184         da.addElementRolling(3);
185         assertEquals(3, da.getElement(1), 0);
186         da.addElementRolling(4);
187         assertEquals(3, da.getElement(0), 0);
188         assertEquals(4, da.getElement(1), 0);
189         da.addElement(5);
190         assertEquals(5, da.getElement(2), 0);
191         da.addElementRolling(6);
192         assertEquals(4, da.getElement(0), 0);
193         assertEquals(5, da.getElement(1), 0);
194         assertEquals(6, da.getElement(2), 0);   
195         
196         // ADDITIVE_MODE  (x's are occupied storage locations, 0's are open)
197         ResizableDoubleArray testDa = new ResizableDoubleArray(2, 2.0f, 2.5f, 
198                 ResizableDoubleArray.ADDITIVE_MODE);
199         assertEquals(2, testDa.getInternalLength());
200         testDa.addElement(1d); // x,0
201         testDa.addElement(2d); // x,x
202         testDa.addElement(3d); // x,x,x,0 -- expanded
203         assertEquals(1d, testDa.getElement(0), 0);
204         assertEquals(2d, testDa.getElement(1), 0);
205         assertEquals(3d, testDa.getElement(2), 0);   
206         assertEquals(4, testDa.getInternalLength());  // x,x,x,0 
207         assertEquals(3, testDa.getNumElements());
208         testDa.addElementRolling(4d);
209         assertEquals(2d, testDa.getElement(0), 0);
210         assertEquals(3d, testDa.getElement(1), 0);
211         assertEquals(4d, testDa.getElement(2), 0);   
212         assertEquals(4, testDa.getInternalLength());  // 0,x,x,x
213         assertEquals(3, testDa.getNumElements());
214         testDa.addElementRolling(5d);   // 0,0,x,x,x,0 -- time to contract
215         assertEquals(3d, testDa.getElement(0), 0);
216         assertEquals(4d, testDa.getElement(1), 0);
217         assertEquals(5d, testDa.getElement(2), 0);   
218         assertEquals(4, testDa.getInternalLength());  // contracted -- x,x,x,0     
219         assertEquals(3, testDa.getNumElements());
220         try {
221             testDa.getElement(4);
222             fail("Expecting ArrayIndexOutOfBoundsException");
223         } catch (ArrayIndexOutOfBoundsException ex) {
224             // expected
225         }  
226         try {
227             testDa.getElement(-1);
228             fail("Expecting ArrayIndexOutOfBoundsException");
229         } catch (ArrayIndexOutOfBoundsException ex) {
230             // expected
231         }
232     }
233     
234     public void testSetNumberOfElements() {
235         da.addElement( 1.0 );
236         da.addElement( 1.0 );
237         da.addElement( 1.0 );
238         da.addElement( 1.0 );
239         da.addElement( 1.0 );
240         da.addElement( 1.0 );
241         assertEquals( "Number of elements should equal 6", da.getNumElements(), 6);
242         
243         ((ResizableDoubleArray) da).setNumElements( 3 );
244         assertEquals( "Number of elements should equal 3", da.getNumElements(), 3);
245         
246         try {
247             ((ResizableDoubleArray) da).setNumElements( -3 );
248             fail( "Setting number of elements to negative should've thrown an exception");
249         } catch( IllegalArgumentException iae ) {
250         }
251         
252         ((ResizableDoubleArray) da).setNumElements(1024);
253         assertEquals( "Number of elements should now be 1024", da.getNumElements(), 1024);
254         assertEquals( "Element 453 should be a default double", da.getElement( 453 ), 0.0, Double.MIN_VALUE);
255         
256     }
257     
258     public void testWithInitialCapacity() {
259         
260         ResizableDoubleArray eDA2 = new ResizableDoubleArray(2);
261         assertEquals("Initial number of elements should be 0", 0, eDA2.getNumElements());
262         
263         RandomData randomData = new RandomDataImpl();
264         int iterations = randomData.nextInt(100, 1000);
265         
266         for( int i = 0; i < iterations; i++) {
267             eDA2.addElement( i );
268         }
269         
270         assertEquals("Number of elements should be equal to " + iterations, iterations, eDA2.getNumElements());
271         
272         eDA2.addElement( 2.0 );
273         
274         assertEquals("Number of elements should be equals to " + (iterations +1),
275                 iterations + 1 , eDA2.getNumElements() );
276     }
277     
278     public void testWithInitialCapacityAndExpansionFactor() {
279         
280         ResizableDoubleArray eDA3 = new ResizableDoubleArray(3, 3.0f, 3.5f);
281         assertEquals("Initial number of elements should be 0", 0, eDA3.getNumElements() );
282         
283         RandomData randomData = new RandomDataImpl();
284         int iterations = randomData.nextInt(100, 3000);
285         
286         for( int i = 0; i < iterations; i++) {
287             eDA3.addElement( i );
288         }
289         
290         assertEquals("Number of elements should be equal to " + iterations, iterations,eDA3.getNumElements());
291         
292         eDA3.addElement( 2.0 );
293         
294         assertEquals("Number of elements should be equals to " + (iterations +1),
295                 iterations +1, eDA3.getNumElements() );
296         
297         assertEquals("Expansion factor should equal 3.0", 3.0f, eDA3.getExpansionFactor(), Double.MIN_VALUE);
298     }
299     
300     public void testDiscard() {
301         da.addElement(2.0);
302         da.addElement(2.0);
303         da.addElement(2.0);
304         da.addElement(2.0);
305         da.addElement(2.0);
306         da.addElement(2.0);
307         da.addElement(2.0);
308         da.addElement(2.0);
309         da.addElement(2.0);
310         da.addElement(2.0);
311         da.addElement(2.0);
312         assertEquals( "Number of elements should be 11", 11, da.getNumElements());
313         
314         ((ResizableDoubleArray)da).discardFrontElements(5);
315         assertEquals( "Number of elements should be 6", 6, da.getNumElements());
316         
317         try {
318             ((ResizableDoubleArray)da).discardFrontElements(-1);
319             fail( "Trying to discard a negative number of element is not allowed");
320         } catch( Exception e ){
321         }
322         
323         try {
324             ((ResizableDoubleArray)da).discardFrontElements( 10000 );
325             fail( "You can't discard more elements than the array contains");
326         } catch( Exception e ){
327         }
328     }
329     
330     public void testMutators() {
331         ((ResizableDoubleArray)da).setContractionCriteria(10f);
332         assertEquals(10f, ((ResizableDoubleArray)da).getContractionCriteria(), 0);
333         ((ResizableDoubleArray)da).setExpansionFactor(8f);  
334         assertEquals(8f, ((ResizableDoubleArray)da).getExpansionFactor(), 0);
335         try {
336             ((ResizableDoubleArray)da).setExpansionFactor(11f);  // greater than contractionCriteria
337             fail("Expecting IllegalArgumentException");
338         } catch (IllegalArgumentException ex) {
339             // expected
340         }
341         ((ResizableDoubleArray)da).setExpansionMode(
342                 ResizableDoubleArray.ADDITIVE_MODE);
343         assertEquals(ResizableDoubleArray.ADDITIVE_MODE, 
344                 ((ResizableDoubleArray)da).getExpansionMode());
345         try {
346             ((ResizableDoubleArray)da).setExpansionMode(-1);
347             fail ("Expecting IllegalArgumentException");
348         } catch (IllegalArgumentException ex) {
349             // expected
350         }
351     }
352 }