* DoubleArray is now an interface which is implemented by
ExpandableDoubleArray. The interface provides a public interface which does not hint at any of the storage parameters of Expandable or Contractable. * DoubleArrayTest now operates on the DoubleArray interface, casting to Expandable when we need to call the package scopes getInternalLength method. * While we should not provide access to the internal storage array, it should be possible to obtain a double[] of elements stored in this DoubleArray - double[] getElements() was added to the DoubleArray interface, it will return the element array. git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/math/trunk@140834 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
7651a6b14d
commit
0700b0f482
|
@ -145,12 +145,13 @@ public class ContractableDoubleArray extends ExpandableDoubleArray implements Se
|
|||
*
|
||||
* @return value to be added to end of array
|
||||
*/
|
||||
public synchronized void addElementRolling(double value) {
|
||||
super.addElementRolling(value);
|
||||
public synchronized double addElementRolling(double value) {
|
||||
double discarded = super.addElementRolling(value);
|
||||
// Check the contraction criteria
|
||||
if( shouldContract() ) {
|
||||
contract();
|
||||
}
|
||||
return discarded;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
/* ====================================================================
|
||||
* 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 an interface to implemntations which function as an array
|
||||
* of double primitives.
|
||||
*
|
||||
* @author <a href="mailto:tobrien@apache.org">Tim O'Brien</a>
|
||||
*/
|
||||
public interface DoubleArray {
|
||||
|
||||
/**
|
||||
* Returns the number of elements currently in the array. Please note
|
||||
* that this is different from the length of the internal storage array.
|
||||
* @return number of elements
|
||||
*/
|
||||
public abstract int getNumElements();
|
||||
|
||||
/**
|
||||
* Returns the element at the specified index
|
||||
*
|
||||
* @param index index to fetch a value from
|
||||
* @return value stored at the specified index
|
||||
*/
|
||||
public abstract double getElement(int index) throws NoSuchElementException;
|
||||
|
||||
/**
|
||||
* Sets the element at the specified index. This method will expand the internal storage array to
|
||||
* accomodate the insertion of a value at an index beyond the current capacity.
|
||||
* @param index index to store a value in
|
||||
* @param value value to store at the specified index
|
||||
*/
|
||||
public abstract void setElement(int index, double value);
|
||||
|
||||
/**
|
||||
* Adds an element to the end of this expandable array
|
||||
*
|
||||
* @return value to be added to end of array
|
||||
*/
|
||||
public abstract void addElement(double value);
|
||||
|
||||
/**
|
||||
* Adds an element and moves the window of elements up one. This
|
||||
* has the effect of a FIFO. when you "roll" the array an element is removed
|
||||
* from the array. The return value of this function is the discarded double.
|
||||
*
|
||||
* @return the value which has been discarded or "pushed" out of the array
|
||||
* by this rolling insert.
|
||||
*/
|
||||
public abstract double addElementRolling(double value);
|
||||
|
||||
/**
|
||||
* Returns a double[] of elements
|
||||
*/
|
||||
public abstract double[] getElements();
|
||||
|
||||
/**
|
||||
* Clear the double array
|
||||
*/
|
||||
public abstract void clear();
|
||||
|
||||
/**
|
||||
* Discards values from the front of the list. This function removes n elements from
|
||||
* the front of the array.
|
||||
*
|
||||
* @param i number of elements to discard from the front of the array.
|
||||
*/
|
||||
public abstract void discardFrontElements(int i);
|
||||
}
|
|
@ -61,7 +61,7 @@ import java.util.NoSuchElementException;
|
|||
*
|
||||
* @author <a href="mailto:tobrien@apache.org">Tim O'Brien</a>
|
||||
*/
|
||||
public class ExpandableDoubleArray implements Serializable {
|
||||
public class ExpandableDoubleArray implements Serializable, DoubleArray {
|
||||
|
||||
// This is the internal storage array.
|
||||
protected double[] internalArray;
|
||||
|
@ -290,9 +290,15 @@ public class ExpandableDoubleArray implements Serializable {
|
|||
|
||||
/**
|
||||
* Adds an element and moves the window of elements up one. This
|
||||
* has the effect of a FIFO
|
||||
* has the effect of a FIFO. when you "roll" the array an element is removed
|
||||
* from the array. The return value of this function is the discarded double.
|
||||
*
|
||||
* @return the value which has been discarded or "pushed" out of the array
|
||||
* by this rolling insert.
|
||||
*/
|
||||
public synchronized void addElementRolling(double value) {
|
||||
public synchronized double addElementRolling(double value) {
|
||||
double discarded = internalArray[startIndex];
|
||||
|
||||
if ( (startIndex + (numElements+1) ) > internalArray.length) {
|
||||
expand();
|
||||
}
|
||||
|
@ -301,6 +307,8 @@ public class ExpandableDoubleArray implements Serializable {
|
|||
|
||||
// Add the new value
|
||||
internalArray[startIndex + (numElements -1)] = value;
|
||||
|
||||
return discarded;
|
||||
}
|
||||
|
||||
|
||||
|
@ -342,4 +350,13 @@ public class ExpandableDoubleArray implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.commons.math.DoubleArray#getElements()
|
||||
*/
|
||||
public double[] getElements() {
|
||||
double[] elementArray = new double[numElements];
|
||||
System.arraycopy(internalArray, startIndex, elementArray, 0, numElements);
|
||||
return elementArray;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ public class ContractableDoubleArrayTest extends DoubleArrayAbstractTest {
|
|||
* @see junit.framework.TestCase#setUp()
|
||||
*/
|
||||
protected void setUp() throws Exception {
|
||||
eDA = new ContractableDoubleArray();
|
||||
da = new ContractableDoubleArray();
|
||||
}
|
||||
|
||||
/** Test normal operations and then test internal storage */
|
||||
|
@ -77,18 +77,18 @@ public class ContractableDoubleArrayTest extends DoubleArrayAbstractTest {
|
|||
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, eDA.getInternalLength());
|
||||
1024, ((ExpandableDoubleArray) da).getInternalLength());
|
||||
}
|
||||
|
||||
public void testSetElementArbitraryExpansion() {
|
||||
super.testSetElementArbitraryExpansion();
|
||||
assertEquals( "The length of the internal array should now be 1001, it isn't", eDA.getInternalLength(), 1001);
|
||||
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",
|
||||
eDA.getInternalLength() < ((int) 6 * 2.5) );
|
||||
((ExpandableDoubleArray) da).getInternalLength() < ((int) 6 * 2.5) );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ import junit.framework.TestCase;
|
|||
*/
|
||||
public abstract class DoubleArrayAbstractTest extends TestCase {
|
||||
|
||||
protected ExpandableDoubleArray eDA = null;
|
||||
protected DoubleArray da = null;
|
||||
|
||||
public DoubleArrayAbstractTest(String name) {
|
||||
super( name );
|
||||
|
@ -75,15 +75,15 @@ public abstract class DoubleArrayAbstractTest extends TestCase {
|
|||
public void testAdd1000() {
|
||||
|
||||
for( int i = 0; i < 1000; i++) {
|
||||
eDA.addElement( i );
|
||||
da.addElement( i );
|
||||
}
|
||||
|
||||
assertEquals("Number of elements should be equal to 1000 after adding 1000 values",
|
||||
1000, eDA.getNumElements() );
|
||||
1000, da.getNumElements() );
|
||||
|
||||
|
||||
assertEquals("The element at the 56th index should be 56",
|
||||
56.0, eDA.getElement(56), Double.MIN_VALUE );
|
||||
56.0, da.getElement(56), Double.MIN_VALUE );
|
||||
|
||||
}
|
||||
|
||||
|
@ -91,12 +91,12 @@ public abstract class DoubleArrayAbstractTest extends TestCase {
|
|||
public void testGetValues() {
|
||||
double[] controlArray = {2.0, 4.0, 6.0};
|
||||
|
||||
eDA.addElement(2.0);
|
||||
eDA.addElement(4.0);
|
||||
eDA.addElement(6.0);
|
||||
double[] testArray = eDA.getValues();
|
||||
da.addElement(2.0);
|
||||
da.addElement(4.0);
|
||||
da.addElement(6.0);
|
||||
double[] testArray = da.getElements();
|
||||
|
||||
for( int i = 0; i < eDA.getNumElements(); i++) {
|
||||
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);
|
||||
}
|
||||
|
@ -106,65 +106,65 @@ public abstract class DoubleArrayAbstractTest extends TestCase {
|
|||
public void testSetElementArbitraryExpansion() {
|
||||
double[] controlArray = {2.0, 4.0, 6.0};
|
||||
|
||||
eDA.addElement(2.0);
|
||||
eDA.addElement(4.0);
|
||||
eDA.addElement(6.0);
|
||||
eDA.setElement(1, 3.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
|
||||
eDA.setElement(1000, 3.4);
|
||||
da.setElement(1000, 3.4);
|
||||
|
||||
assertEquals( "The number of elements should now be 1001, it isn't", eDA.getNumElements(), 1001);
|
||||
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,
|
||||
eDA.getElement( 760 ), Double.MIN_VALUE );
|
||||
da.getElement( 760 ), Double.MIN_VALUE );
|
||||
|
||||
assertEquals( "The 1000th index should be 3.4, it isn't", 3.4, eDA.getElement(1000), Double.MIN_VALUE );
|
||||
assertEquals( "The 0th index should be 2.0, it isn't", 2.0, eDA.getElement(0), 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() {
|
||||
eDA.addElement( 1.0 );
|
||||
eDA.addElement( 1.0 );
|
||||
eDA.addElement( 1.0 );
|
||||
eDA.addElement( 1.0 );
|
||||
eDA.addElement( 1.0 );
|
||||
eDA.addElement( 1.0 );
|
||||
assertEquals( "Number of elements should equal 6", eDA.getNumElements(), 6);
|
||||
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);
|
||||
|
||||
eDA.setNumElements( 3 );
|
||||
assertEquals( "Number of elements should equal 3", eDA.getNumElements(), 3);
|
||||
((ExpandableDoubleArray) da).setNumElements( 3 );
|
||||
assertEquals( "Number of elements should equal 3", da.getNumElements(), 3);
|
||||
|
||||
try {
|
||||
eDA.setNumElements( -3 );
|
||||
((ExpandableDoubleArray) da).setNumElements( -3 );
|
||||
fail( "Setting number of elements to negative should've thrown an exception");
|
||||
} catch( IllegalArgumentException iae ) {
|
||||
}
|
||||
|
||||
eDA.setNumElements(1024);
|
||||
assertEquals( "Number of elements should now be 1024", eDA.getNumElements(), 1024);
|
||||
assertEquals( "Element 453 should be a default double", eDA.getElement( 453 ), 0.0, 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() {
|
||||
eDA.addElement( 1.0 );
|
||||
eDA.addElement( 1.0 );
|
||||
eDA.addElement( 1.0 );
|
||||
eDA.addElement( 1.0 );
|
||||
eDA.addElement( 1.0 );
|
||||
eDA.addElement( 1.0 );
|
||||
eDA.addElementRolling( 2.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.addElementRolling( 2.0 );
|
||||
|
||||
assertEquals( "There should be 6 elements in the eda", eDA.getNumElements(), 6);
|
||||
assertEquals( "The last element should be 2.0", eDA.getElement( eDA.getNumElements() -1 ), 2.0, Double.MIN_VALUE);
|
||||
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++ ) {
|
||||
eDA.addElementRolling( i );
|
||||
da.addElementRolling( i );
|
||||
}
|
||||
|
||||
assertEquals( "We just inserted 1024 rolling elements, num elements should still be 6", eDA.getNumElements(), 6);
|
||||
assertEquals( "We just inserted 1024 rolling elements, num elements should still be 6", da.getNumElements(), 6);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -69,14 +69,14 @@ public class ExpandableDoubleArrayTest extends DoubleArrayAbstractTest {
|
|||
* @see junit.framework.TestCase#setUp()
|
||||
*/
|
||||
protected void setUp() throws Exception {
|
||||
eDA = new ExpandableDoubleArray();
|
||||
da = new ExpandableDoubleArray();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see junit.framework.TestCase#tearDown()
|
||||
*/
|
||||
protected void tearDown() throws Exception {
|
||||
eDA = null;
|
||||
da = null;
|
||||
}
|
||||
|
||||
|
||||
|
@ -87,17 +87,17 @@ public class ExpandableDoubleArrayTest extends DoubleArrayAbstractTest {
|
|||
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, eDA.getInternalLength());
|
||||
1024, ((ExpandableDoubleArray) da).getInternalLength());
|
||||
}
|
||||
|
||||
public void testSetElementArbitraryExpansion() {
|
||||
super.testSetElementArbitraryExpansion();
|
||||
assertEquals( "The length of the internal array should now be 1001, it isn't", eDA.getInternalLength(), 1001);
|
||||
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", eDA.getInternalLength(), 2048);
|
||||
assertEquals( "Even though there are only 6 element, internal storage should be 2048", ((ExpandableDoubleArray) da).getInternalLength(), 2048);
|
||||
}
|
||||
|
||||
/** TESTS WHICH FOCUS ON ExpandableSpecific internal storage */
|
||||
|
|
Loading…
Reference in New Issue