    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: 1.1 $ $Date: 2004/06/14 21:41:33 $
    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 }