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