Added a FixedDoubleArray. FixedDoubleArray supports a rolling mechanism

that reuses an array of fixed length.  This classes was added to an efficient
rolling mechanism.

FixedDoubleArray was influenced by discussions on the commons-dev list and
patches submitted by Mark Diggory.


git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/math/trunk@140836 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Tim O'Brien 2003-05-17 23:24:21 +00:00
parent 71dfdabde1
commit d6f7028269
8 changed files with 591 additions and 179 deletions

View File

@ -79,17 +79,16 @@
<report>maven-changes-plugin</report>
<report>maven-checkstyle-plugin</report>
<report>maven-clover-plugin</report>
<report>maven-developer-activity-plugin</report>
<report>maven-file-activity-plugin</report>
<!-- <report>maven-developer-activity-plugin</report>
<report>maven-file-activity-plugin</report> -->
<report>maven-javadoc-plugin</report>
<report>maven-jdepend-plugin</report>
<report>maven-jellydoc-plugin</report>
<!-- <report>maven-jdepend-plugin</report> -->
<report>maven-junit-report-plugin</report>
<report>maven-jxr-plugin</report>
<report>maven-license-plugin</report>
<!-- <report>maven-license-plugin</report>
<report>maven-linkcheck-plugin</report>
<report>maven-statcvs-plugin</report>
<report>maven-tasklist-plugin</report>
<report>maven-tasklist-plugin</report> -->
</reports>
</project>

View File

@ -306,7 +306,7 @@ public class ExpandableDoubleArray implements Serializable, DoubleArray {
startIndex += 1;
// Add the new value
internalArray[startIndex + (numElements -1)] = value;
internalArray[startIndex + (numElements - 1)] = value;
return discarded;
}
@ -365,7 +365,7 @@ public class ExpandableDoubleArray implements Serializable, DoubleArray {
public double getMax() {
double max = internalArray[startIndex];
for( int i = startIndex + 1; i < numElements; i++) {
for( int i = startIndex + 1; i < (numElements + startIndex); i++) {
if( internalArray[i] > max ) {
max = internalArray[i];
}
@ -380,7 +380,7 @@ public class ExpandableDoubleArray implements Serializable, DoubleArray {
public double getMin() {
double min = internalArray[startIndex];
for( int i = startIndex + 1; i < numElements; i++) {
for( int i = startIndex + 1; i < (numElements + startIndex); i++) {
if( internalArray[i] < min ) {
min = internalArray[i];
}

View File

@ -0,0 +1,199 @@
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.commons.math;
import java.util.NoSuchElementException;
/**
* Provides a fixed size implementation of the DoubleArray with
* support to true "rolling" functionality. If a program attempts to add
* a value to a fixed array which has reach a maximum number of
* elements a ArrayIndexOutOfBoundsException will be thrown.
*
* @author <a href="mailto:tobrien@apache.org">Tim O'Brien</a>
*/
public class FixedDoubleArray implements DoubleArray {
double[] internalArray;
int size = 0;
int nextAdd = 0;
int maxElements = 0;
public FixedDoubleArray(int maxElements) {
this.maxElements = maxElements;
internalArray = new double[maxElements];
}
/* (non-Javadoc)
* @see org.apache.commons.math.DoubleArray#getNumElements()
*/
public int getNumElements() {
return size;
}
/* (non-Javadoc)
* @see org.apache.commons.math.DoubleArray#getElement(int)
*/
public double getElement(int index) throws NoSuchElementException {
if( index > (size-1) ) {
throw new ArrayIndexOutOfBoundsException("Attempted to retrieve an element outside of" + "the element array");
} else {
return internalArray[index];
}
}
/* (non-Javadoc)
* @see org.apache.commons.math.DoubleArray#setElement(int, double)
*/
public void setElement(int index, double value) {
if( index > (size-1) ) {
throw new ArrayIndexOutOfBoundsException("Attempted to set an element outside of" +
"the element array");
} else {
internalArray[index] = value;
}
}
/* (non-Javadoc)
* @see org.apache.commons.math.DoubleArray#addElement(double)
*/
public void addElement(double value) {
if( size < internalArray.length ) {
size++;
internalArray[nextAdd] = value;
nextAdd++;
nextAdd = nextAdd % (maxElements);
} else {
throw new ArrayIndexOutOfBoundsException("Attempted to add a value to an array of fixed size, please " + "use addElementRolling to avoid this exception");
}
}
/* (non-Javadoc)
* @see org.apache.commons.math.DoubleArray#addElementRolling(double)
*/
public double addElementRolling(double value) {
if( size < internalArray.length ) {
size++;
}
double discarded = internalArray[nextAdd];
internalArray[nextAdd] = value;
nextAdd++;
nextAdd = nextAdd % maxElements;
// but we return the value which was "replaced"
return( discarded );
}
/* (non-Javadoc)
* @see org.apache.commons.math.DoubleArray#getElements()
*/
public double[] getElements() {
double[] copy = new double[internalArray.length];
System.arraycopy(internalArray, 0, copy, 0, internalArray.length);
return copy;
}
/* (non-Javadoc)
* @see org.apache.commons.math.DoubleArray#clear()
*/
public void clear() {
size = 0;
nextAdd = 0;
internalArray = new double[maxElements];
}
/* (non-Javadoc)
* @see org.apache.commons.math.DoubleArray#discardFrontElements(int)
*/
public void discardFrontElements(int i) {
// TODO: AH! implemented there is not concept of "front"
// in an array that discards values when rolling..... anyone?
throw new RuntimeException("Discarding front element not supported in FixedDoubleArray");
}
/* (non-Javadoc)
* @see org.apache.commons.math.DoubleArray#getMin()
*/
public double getMin() {
double min = internalArray[0];
for( int i = 1; i < size; i++) {
if( internalArray[i] < min ) {
min = internalArray[i];
}
}
return min;
}
/* (non-Javadoc)
* @see org.apache.commons.math.DoubleArray#getMax()
*/
public double getMax() {
double max = internalArray[0];
for( int i = 1; i < size; i++) {
if( internalArray[i] > max ) {
max = internalArray[i];
}
}
return max;
}
}

View File

@ -64,7 +64,7 @@ import java.io.Serializable;
* to doubles by addValue().
*
* @author Phil Steitz
* @version $Revision: 1.3 $ $Date: 2003/05/16 05:23:29 $
* @version $Revision: 1.4 $ $Date: 2003/05/17 23:24:21 $
*
*/
public class UnivariateImpl implements Univariate, Serializable {
@ -75,9 +75,8 @@ public class UnivariateImpl implements Univariate, Serializable {
/** Just in case, the windowSize is not inifinite, we need to
* keep an array to remember values 0 to N
*/
private DoubleArray doubleArray =
new ContractableDoubleArray();
private DoubleArray doubleArray;
/** running sum of values that have been added */
private double sum = 0.0;
@ -97,6 +96,12 @@ public class UnivariateImpl implements Univariate, Serializable {
public UnivariateImpl() {
clear();
}
/** Create a new univariate with a fixed window **/
public UnivariateImpl(int window) {
windowSize = window;
doubleArray = new FixedDoubleArray( window );
}
/**
* Adds the value, updating running sums.
@ -154,9 +159,14 @@ public class UnivariateImpl implements Univariate, Serializable {
if( windowSize == n ) {
double discarded = doubleArray.addElementRolling( v );
// Remove the influence of the discarded
sum -= discarded;
sumsq -= discarded * discarded;
// Remove the influence of discarded value ONLY
// if the discard value has any meaning. In other words
// don't discount until we "roll".
if( windowSize > doubleArray.getNumElements() ) {
// Remove the influence of the discarded
sum -= discarded;
sumsq -= discarded * discarded;
}
// Include the influence of the new
// TODO: The next two lines seems rather expensive, but
@ -264,7 +274,7 @@ public class UnivariateImpl implements Univariate, Serializable {
* @see org.apache.commons.math.Univariate#setWindowSize(int)
*/
public void setWindowSize(int windowSize) {
this.windowSize = windowSize;
throw new RuntimeException( "A fixed window size must be set via the UnivariateImpl constructor");
}
}

View File

@ -59,7 +59,7 @@ package org.apache.commons.math;
*
* @author <a href="mailto:tobrien@apache.org">Tim O'Brien</a>
*/
public class ContractableDoubleArrayTest extends DoubleArrayAbstractTest {
public class ContractableDoubleArrayTest extends ExpandableDoubleArrayTest {
public ContractableDoubleArrayTest(String name) {
super( name );
@ -70,69 +70,7 @@ public class ContractableDoubleArrayTest extends DoubleArrayAbstractTest {
*/
protected void setUp() throws Exception {
da = new ContractableDoubleArray();
ra = new ContractableDoubleArray();
}
/** Test normal operations and then test internal storage */
public void testAdd1000() {
super.testAdd1000();
assertEquals("Internal Storage length should be 1024 if we started out with initial capacity of " +
"16 and an expansion factor of 2.0",
1024, ((ExpandableDoubleArray) da).getInternalLength());
}
public void testSetElementArbitraryExpansion() {
super.testSetElementArbitraryExpansion();
assertEquals( "The length of the internal array should now be 1001, it isn't", ((ExpandableDoubleArray) da).getInternalLength(), 1001);
}
public void testAddElementRolling() {
super.testAddElementRolling();
assertTrue( "Even though there are only 6 element, internal storage should be less than 2.5 times the number of elements",
((ExpandableDoubleArray) da).getInternalLength() < ((int) 6 * 2.5) );
}
/** Test ERROR conditions */
/** TEST ERROR CONDITIONS **/
public void testIllegalInitialCapacity() {
try {
ContractableDoubleArray eDA = new ContractableDoubleArray(-3, 2.0f);
fail( "That constructor should have thrown an IllegalArgumentException because " +
"the initialCapacity was negative, if it didn't then" +
" the range checking of initialCapacity is not working properly" );
} catch( IllegalArgumentException iae ) {
}
try {
ContractableDoubleArray eDA = new ContractableDoubleArray(0, 2.0f);
fail( "That constructor should have thrown an IllegalArgumentException because " +
"the initialCapacity was ZERO if it didn't then" +
" the range checking of initialCapacity is not working properly" );
} catch( IllegalArgumentException iae ) {
}
}
public void testIllegalExpansionFactor() {
try {
ContractableDoubleArray eDA = new ContractableDoubleArray(3, 0.66f);
fail( "That constructor should have thrown an IllegalArgumentException because " +
"the expansionFactor for 0.66 which would shrink the array instead of expand the array");
} catch( IllegalArgumentException iae ) {
}
try {
ContractableDoubleArray eDA = new ContractableDoubleArray(3, 0.0f);
fail( "That constructor should have thrown an IllegalArgumentException because " +
"the expansionFactor for 0.0");
} catch( IllegalArgumentException iae) {
}
try {
ContractableDoubleArray eDA = new ContractableDoubleArray(3, -4.35f);
fail( "That constructor should have thrown an IllegalArgumentException because " +
"the expansionFactor for -4.35");
} catch( IllegalArgumentException iae) {
}
}
}

View File

@ -64,108 +64,104 @@ public abstract class DoubleArrayAbstractTest extends TestCase {
protected DoubleArray da = null;
// Array used to test rolling
protected DoubleArray ra = null;
public DoubleArrayAbstractTest(String name) {
super( name );
super(name);
}
/** TEST NORMAL OPERATIONS **/
public void testAdd1000() {
for( int i = 0; i < 1000; i++) {
da.addElement( i );
for (int i = 0; i < 1000; i++) {
da.addElement(i);
}
assertEquals("Number of elements should be equal to 1000 after adding 1000 values",
1000, da.getNumElements() );
assertEquals("The element at the 56th index should be 56",
56.0, da.getElement(56), Double.MIN_VALUE );
assertEquals(
"Number of elements should be equal to 1000 after adding 1000 values",
1000,
da.getNumElements());
assertEquals(
"The element at the 56th index should be 56",
56.0,
da.getElement(56),
Double.MIN_VALUE);
}
public void testGetValues() {
double[] controlArray = {2.0, 4.0, 6.0};
double[] controlArray = { 2.0, 4.0, 6.0 };
da.addElement(2.0);
da.addElement(4.0);
da.addElement(6.0);
double[] testArray = da.getElements();
for( int i = 0; i < da.getNumElements(); i++) {
assertEquals( "The testArray values should equal the controlArray values, index i: " + i +
" does not match", testArray[i], controlArray[i], Double.MIN_VALUE);
}
}
public void testSetElementArbitraryExpansion() {
double[] controlArray = {2.0, 4.0, 6.0};
da.addElement(2.0);
da.addElement(4.0);
da.addElement(6.0);
da.setElement(1, 3.0);
// Expand the array arbitrarily to 1000 items
da.setElement(1000, 3.4);
assertEquals( "The number of elements should now be 1001, it isn't", da.getNumElements(), 1001);
assertEquals( "Uninitialized Elements are default value of 0.0, index 766 wasn't", 0.0,
da.getElement( 760 ), Double.MIN_VALUE );
assertEquals( "The 1000th index should be 3.4, it isn't", 3.4, da.getElement(1000), Double.MIN_VALUE );
assertEquals( "The 0th index should be 2.0, it isn't", 2.0, da.getElement(0), Double.MIN_VALUE);
}
public void testSetNumberOfElements() {
da.addElement( 1.0 );
da.addElement( 1.0 );
da.addElement( 1.0 );
da.addElement( 1.0 );
da.addElement( 1.0 );
da.addElement( 1.0 );
assertEquals( "Number of elements should equal 6", da.getNumElements(), 6);
((ExpandableDoubleArray) da).setNumElements( 3 );
assertEquals( "Number of elements should equal 3", da.getNumElements(), 3);
try {
((ExpandableDoubleArray) da).setNumElements( -3 );
fail( "Setting number of elements to negative should've thrown an exception");
} catch( IllegalArgumentException iae ) {
for (int i = 0; i < da.getNumElements(); i++) {
assertEquals(
"The testArray values should equal the controlArray values, index i: "
+ i
+ " does not match",
testArray[i],
controlArray[i],
Double.MIN_VALUE);
}
((ExpandableDoubleArray) da).setNumElements(1024);
assertEquals( "Number of elements should now be 1024", da.getNumElements(), 1024);
assertEquals( "Element 453 should be a default double", da.getElement( 453 ), 0.0, Double.MIN_VALUE);
}
public void testAddElementRolling() {
da.addElement( 1.0 );
da.addElement( 1.0 );
da.addElement( 1.0 );
da.addElement( 1.0 );
da.addElement( 1.0 );
da.addElement( 1.0 );
da.addElementRolling( 2.0 );
assertEquals( "There should be 6 elements in the eda", da.getNumElements(), 6);
assertEquals( "The last element should be 2.0", da.getElement( da.getNumElements() -1 ), 2.0, Double.MIN_VALUE);
for( int i = 0; i < 1024; i++ ) {
da.addElementRolling( i );
ra.addElement(0.5);
ra.addElement(1.0);
ra.addElement(1.0);
ra.addElement(1.0);
ra.addElement(1.0);
ra.addElement(1.0);
ra.addElementRolling(2.0);
assertEquals(
"There should be 6 elements in the eda",
6,
ra.getNumElements());
assertEquals(
"The max element should be 2.0",
2.0,
ra.getMax(),
Double.MIN_VALUE);
assertEquals(
"The min element should be 1.0",
1.0,
ra.getMin(),
Double.MIN_VALUE);
for (int i = 0; i < 1024; i++) {
ra.addElementRolling(i);
}
assertEquals( "We just inserted 1024 rolling elements, num elements should still be 6", da.getNumElements(), 6);
assertEquals(
"We just inserted 1024 rolling elements, num elements should still be 6",
6,
ra.getNumElements());
}
public void testMinMax() {
da.addElement(2.0);
da.addElement(22.0);
da.addElement(-2.0);
da.addElement(21.0);
da.addElement(22.0);
da.addElement(42.0);
da.addElement(62.0);
da.addElement(22.0);
da.addElement(122.0);
da.addElement(1212.0);
assertEquals("Min should be -2.0", -2.0, da.getMin(), Double.MIN_VALUE);
assertEquals(
"Max should be 1212.0",
1212.0,
da.getMax(),
Double.MIN_VALUE);
}
}

View File

@ -70,6 +70,7 @@ public class ExpandableDoubleArrayTest extends DoubleArrayAbstractTest {
*/
protected void setUp() throws Exception {
da = new ExpandableDoubleArray();
ra = new ExpandableDoubleArray();
}
/* (non-Javadoc)
@ -77,12 +78,35 @@ public class ExpandableDoubleArrayTest extends DoubleArrayAbstractTest {
*/
protected void tearDown() throws Exception {
da = null;
ra = null;
}
/** TEST NORMAL OPERATIONS - calling super class test and then checking internal
* storage **/
public void testSetElementArbitraryExpansion() {
double[] controlArray = {2.0, 4.0, 6.0};
da.addElement(2.0);
da.addElement(4.0);
da.addElement(6.0);
da.setElement(1, 3.0);
// Expand the array arbitrarily to 1000 items
da.setElement(1000, 3.4);
assertEquals( "The number of elements should now be 1001, it isn't", da.getNumElements(), 1001);
assertEquals( "Uninitialized Elements are default value of 0.0, index 766 wasn't", 0.0,
da.getElement( 760 ), Double.MIN_VALUE );
assertEquals( "The 1000th index should be 3.4, it isn't", 3.4, da.getElement(1000), Double.MIN_VALUE );
assertEquals( "The 0th index should be 2.0, it isn't", 2.0, da.getElement(0), Double.MIN_VALUE);
}
public void testAdd1000() {
super.testAdd1000();
assertEquals("Internal Storage length should be 1024 if we started out with initial capacity of " +
@ -90,14 +114,32 @@ public class ExpandableDoubleArrayTest extends DoubleArrayAbstractTest {
1024, ((ExpandableDoubleArray) da).getInternalLength());
}
public void testSetElementArbitraryExpansion() {
super.testSetElementArbitraryExpansion();
assertEquals( "The length of the internal array should now be 1001, it isn't", ((ExpandableDoubleArray) da).getInternalLength(), 1001);
}
public void testAddElementRolling() {
super.testAddElementRolling();
assertEquals( "Even though there are only 6 element, internal storage should be 2048", ((ExpandableDoubleArray) da).getInternalLength(), 2048);
}
public void testSetNumberOfElements() {
da.addElement( 1.0 );
da.addElement( 1.0 );
da.addElement( 1.0 );
da.addElement( 1.0 );
da.addElement( 1.0 );
da.addElement( 1.0 );
assertEquals( "Number of elements should equal 6", da.getNumElements(), 6);
((ExpandableDoubleArray) da).setNumElements( 3 );
assertEquals( "Number of elements should equal 3", da.getNumElements(), 3);
try {
((ExpandableDoubleArray) da).setNumElements( -3 );
fail( "Setting number of elements to negative should've thrown an exception");
} catch( IllegalArgumentException iae ) {
}
((ExpandableDoubleArray) da).setNumElements(1024);
assertEquals( "Number of elements should now be 1024", da.getNumElements(), 1024);
assertEquals( "Element 453 should be a default double", da.getElement( 453 ), 0.0, Double.MIN_VALUE);
}
/** TESTS WHICH FOCUS ON ExpandableSpecific internal storage */
@ -105,7 +147,6 @@ public class ExpandableDoubleArrayTest extends DoubleArrayAbstractTest {
public void testWithInitialCapacity() {
ExpandableDoubleArray eDA2 = new ExpandableDoubleArray(2);
assertEquals("Initial internal length should be 2", 2, eDA2.getInternalLength());
assertEquals("Initial number of elements should be 0", 0, eDA2.getNumElements());
int iterations = (int) Math.pow(2.0, 15.0);
@ -115,19 +156,16 @@ public class ExpandableDoubleArrayTest extends DoubleArrayAbstractTest {
}
assertEquals("Number of elements should be equal to 2^15", (int) Math.pow(2.0, 15.0), eDA2.getNumElements());
assertEquals("Internal length should be 2^15", (int) Math.pow(2.0, 15.0), eDA2.getInternalLength());
eDA2.addElement( 2.0 );
assertEquals("Number of elements should be equals to 2^15 + 1",
( (int) Math.pow(2.0, 15.0) + 1 ), eDA2.getNumElements() );
assertEquals("Internal length should be 2^16", (int) Math.pow(2.0, 16.0), eDA2.getInternalLength());
}
public void testWithInitialCapacityAndExpansionFactor() {
ExpandableDoubleArray eDA3 = new ExpandableDoubleArray(3, 3.0f);
assertEquals("Initial internal length should be 3", 3, eDA3.getInternalLength() );
assertEquals("Initial number of elements should be 0", 0, eDA3.getNumElements() );
int iterations = (int) Math.pow(3.0, 7.0);
@ -137,18 +175,46 @@ public class ExpandableDoubleArrayTest extends DoubleArrayAbstractTest {
}
assertEquals("Number of elements should be equal to 3^7", (int) Math.pow(3.0, 7.0), eDA3.getNumElements());
assertEquals("Internal length should be 3^7", (int) Math.pow(3.0, 7.0), eDA3.getInternalLength());
eDA3.addElement( 2.0 );
assertEquals("Number of elements should be equals to 3^7 + 1",
( (int) Math.pow(3.0, 7.0) + 1 ), eDA3.getNumElements() );
assertEquals("Internal length should be 3^8", (int) Math.pow(3.0, 8.0), eDA3.getInternalLength());
assertEquals("Expansion factor should equal 3.0", 3.0f, eDA3.getExpansionFactor(), Double.MIN_VALUE);
}
public void testDiscard() {
da.addElement(2.0);
da.addElement(2.0);
da.addElement(2.0);
da.addElement(2.0);
da.addElement(2.0);
da.addElement(2.0);
da.addElement(2.0);
da.addElement(2.0);
da.addElement(2.0);
da.addElement(2.0);
da.addElement(2.0);
assertEquals( "Number of elements should be 11", 11, da.getNumElements());
da.discardFrontElements(5);
assertEquals( "Number of elements should be 6", 6, da.getNumElements());
try {
da.discardFrontElements(-1);
fail( "Trying to discard a negative number of element is not allowed");
} catch( Exception e ){
}
try {
da.discardFrontElements( 10000 );
fail( "You can't discard more elements than the array contains");
} catch( Exception e ){
}
}
/** TEST ERROR CONDITIONS **/
public void testIllegalInitialCapacity() {
@ -187,4 +253,26 @@ public class ExpandableDoubleArrayTest extends DoubleArrayAbstractTest {
}
}
public void testSetOutOfBounds() {
try {
da.setElement( -1, 2.0);
fail( "Cannot set a negative index");
} catch( Exception e ){
}
}
public void testGetOutOfBounds() {
try {
da.getElement(10000);
fail( "Cannot get an element that is larger than the number of elements");
} catch( Exception e ) {
}
try {
da.getElement(-3);
fail("Cannot get a negative index");
} catch( Exception e ){
}
}
}

View File

@ -0,0 +1,182 @@
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.commons.math;
/**
* This class contains test cases for the ExpandableDoubleArray.
*
* @author <a href="mailto:tobrien@apache.org">Tim O'Brien</a>
*/
public class FixedDoubleArrayTest extends DoubleArrayAbstractTest {
public FixedDoubleArrayTest(String name) {
super( name );
}
/* (non-Javadoc)
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
da = new FixedDoubleArray(4000);
}
/* (non-Javadoc)
* @see junit.framework.TestCase#tearDown()
*/
protected void tearDown() throws Exception {
da = null;
}
/** TEST NORMAL OPERATIONS - calling super class test and then checking internal
* storage **/
public void testAddElementRolling() {
ra = new FixedDoubleArray(6);
super.testAddElementRolling();
assertEquals( "FixedDoubleArray should have 6 size internal storage",
6, ((FixedDoubleArray) ra).internalArray.length);
}
public void testExceedingElements() {
for( int i = 0; i < 3999; i++) {
da.addElement( 1.0 );
}
da.addElement( 1.0 );
try {
da.addElement( 2.0 );
fail( " Adding more than 4000 elements should cause an exception ");
} catch( Exception e ) {
}
da.addElementRolling(2.0);
assertEquals( "This is the first rolling add, the first element should be 2.0",
2.0, da.getElement(0), Double.MIN_VALUE);
}
public void testGetExceeding() {
try {
da.getElement(100);
fail( "I haven't added 100 elements to the list yet, trying to getElement(100) should " + "thrown an error");
} catch (Exception e ){
}
}
public void testSetElement() {
da.addElement( 1.0 );
da.addElement( 1.0 );
da.addElement( 1.0 );
da.addElement( 1.0 );
da.addElement( 1.0 );
da.addElement( 1.0 );
da.addElement( 1.0 );
da.setElement( 2, 4.0 );
assertEquals( "Index 2 should be 4.0", 4.0, da.getElement(2), Double.MIN_VALUE);
try {
da.setElement(2000, 45.0);
fail( "The array does not contain 2000 elements yet, setting this element should" + " cause an excpetion");
} catch(Exception e) {
}
}
public void testOnlyRolling() {
for( int i = 0; i < 8000; i++) {
da.addElementRolling( i );
}
assertEquals( "The 2000th element should equal 6000",
6000.0, da.getElement(2000), Double.MIN_VALUE);
}
public void testClear() {
for( int i = 0; i < 10; i++) {
da.addElementRolling(1.0);
}
assertEquals( "There should be ten elements in the array",
10, da.getNumElements() );
da.clear();
assertEquals( "There should be zero elements in the array",
0, da.getNumElements() );
for( int i = 0; i < 10; i++) {
da.addElementRolling(1.0);
}
assertEquals( "There should be ten elements in the array",
10, da.getNumElements() );
}
public void testDiscardFront() {
try {
da.discardFrontElements( 2 );
fail( "Discard front elements should throw an exception");
} catch( Exception e ) {
}
}
}