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:
parent
71dfdabde1
commit
d6f7028269
11
project.xml
11
project.xml
|
@ -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>
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 ){
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 ) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue