diff --git a/src/java/org/apache/commons/math/stat/univariate/DescriptiveStatisticsImpl.java b/src/java/org/apache/commons/math/stat/univariate/DescriptiveStatisticsImpl.java index d3962d2c4..5520a8410 100644 --- a/src/java/org/apache/commons/math/stat/univariate/DescriptiveStatisticsImpl.java +++ b/src/java/org/apache/commons/math/stat/univariate/DescriptiveStatisticsImpl.java @@ -17,13 +17,13 @@ package org.apache.commons.math.stat.univariate; import java.io.Serializable; -import org.apache.commons.math.util.ContractableDoubleArray; +import org.apache.commons.math.util.ResizableDoubleArray; /** * Default implementation of * {@link org.apache.commons.math.stat.univariate.DescriptiveStatistics}. * - * @version $Revision: 1.6 $ $Date: 2004/06/01 21:34:35 $ + * @version $Revision: 1.7 $ $Date: 2004/06/14 21:41:33 $ */ public class DescriptiveStatisticsImpl extends DescriptiveStatistics implements Serializable { @@ -36,7 +36,7 @@ public class DescriptiveStatisticsImpl extends DescriptiveStatistics implements /** * Stored data values */ - protected ContractableDoubleArray eDA; + protected ResizableDoubleArray eDA; /** * Construct a DescriptiveStatisticsImpl with infinite window @@ -51,7 +51,7 @@ public class DescriptiveStatisticsImpl extends DescriptiveStatistics implements */ public DescriptiveStatisticsImpl(int window) { super(); - eDA = new ContractableDoubleArray(); + eDA = new ResizableDoubleArray(); setWindowSize(window); } diff --git a/src/java/org/apache/commons/math/util/ContractableDoubleArray.java b/src/java/org/apache/commons/math/util/ContractableDoubleArray.java deleted file mode 100644 index c19017cff..000000000 --- a/src/java/org/apache/commons/math/util/ContractableDoubleArray.java +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Copyright 2003-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.commons.math.util; - -import java.io.Serializable; - -/** - *
- * A variable length double array implementation and extension of - * ExpandableDoubleArray which automatically handles expanding and - * contracting double arrays. - *
- * - *
- * This class extends the functionality of ExpandableDoubleArray and
- * inherits the expansion parameters from that class. If a developer
- * instantiates a ContractableDoubleArray and only adds values to
- * that instance, the behavior of this class is no different from
- * the behavior of the super-class ExpandableDoubleArray. If, on the
- * other hand, elements are removed from the array, this implementation
- * tests an additional parameter contractionCriteria
. The
- * contractionCriteria
dictates when this implementation
- * will contract the size of the internal storage array to
- * the number of elements + 1. This check is performed after every
- * operation that alters the number of elements in the array.
- *
- * Note that the contractionCriteria must always be greater than the - * expansionFactor. If this were not the case (assume a - * contractionCriteria of 1.5f and a expansionFactor of 2.0f) an - * endless series of expansions and contractions would occur. If the - * length of this array is highly varied over time it is a good idea - * to trade efficient memory usage for performance. Each time an array - * is expanded or contracted the meaningful portions of the internal - * storage array are copied to a new array and the reference to the - * internal storage array is swapped. - *
- * - * @version $Revision: 1.14 $ $Date: 2004/05/19 14:16:32 $ - */ -public class ContractableDoubleArray extends ExpandableDoubleArray implements Serializable { - - /** Serializable version identifier */ - static final long serialVersionUID = -3485529955529426875L; - - /** The contraction criteria defines the conditions under which this - * object will "resize" the internal array to the number of elements - * contained in the element array + 1 - */ - private float contractionCriteria = 2.5f; - - /** - * Create an expandable double array with the default initial capacity of - * 16, an expansion factor of 2.00, and a contractionCriteria of 2.5 - */ - public ContractableDoubleArray() { - super(); - } - - /** - * Create an expandable double array with the specified initial capacity, - * the defult expansion factor of 2.00, and a contractionCriteria of 2.5 - * - * @param initialCapacity The initial size of the internal storage array - */ - public ContractableDoubleArray(int initialCapacity) { - super(initialCapacity); - } - - /** - * Create an expandable double array with the specificed initial capacity - * and expand factor, with a contractionCriteria of 2.5 - * - * @param initialCapacity The initial size of the internal storage array - * @param expansionFactor the array will be expanded based on this - * parameter - */ - public ContractableDoubleArray( - int initialCapacity, - float expansionFactor) { - this.expansionFactor = expansionFactor; - setInitialCapacity(initialCapacity); - internalArray = new double[initialCapacity]; - checkContractExpand(getContractionCriteria(), expansionFactor); - } - - /** - * Create an expandable double array with the - * specificed initial capacity, expand factor, and contractionCriteria - * - * @param initialCapacity The initial size of the internal storage array - * @param expansionFactor the array will be expanded based on this - * parameter - * @param contractionCriteria The contraction Criteria. - */ - public ContractableDoubleArray( - int initialCapacity, - float expansionFactor, - float contractionCriteria) { - this.contractionCriteria = contractionCriteria; - this.expansionFactor = expansionFactor; - setInitialCapacity(initialCapacity); - internalArray = new double[initialCapacity]; - checkContractExpand(contractionCriteria, expansionFactor); - } - - /** - * Contracts the storage array to the (size of the element set) + 1 - to - * avoid a zero length array. This function also resets the startIndex to - * zero. - */ - public synchronized void contract() { - double[] tempArray = new double[numElements + 1]; - - // Copy and swap - copy only the element array from the src array. - System.arraycopy(internalArray, startIndex, tempArray, 0, numElements); - internalArray = tempArray; - - // Reset the start index to zero - startIndex = 0; - } - - /** - * Adds an element to the end of this expandable array - * - * @param value to be added to end of array - */ - public synchronized void addElement(double value) { - super.addElement(value); - if (shouldContract()) { - contract(); - } - } - - /** - *- * Adds an element to the end of this expandable array and - * discards a value from the front of the array. This method - * has the effect of adding a value to the end of the list - * and discarded an element from the front of the list. - *
- * - *- * When an array rolls it actually "scrolls" the element array in - * the internal storage array. An element is added to the end of the - * array, and the first element of the array is discard by incrementing - * the starting index of the element array within the internal - * storage array. Over time this will create an orphaned prefix - * to the element array within the internal storage array. If this - * function is called frequently, this orphaned prefix list will - * gradually push the internal storage vs. element storage to - * the contractionCriteria. - *
- * @param value to be added to end of array - * @return value added - */ - public synchronized double addElementRolling(double value) { - double discarded = super.addElementRolling(value); - // Check the contraction criteria - if (shouldContract()) { - contract(); - } - return discarded; - } - - /** - * Should contract returns true if the ratio of (internal storage length) - * to (number of elements) is larger than the contractionCriteria value. - * In other words, using the default value of 2.5, if the internal storage - * array provides more than 2.5x the space needed to store numElements, - * then this function returns true - * - * @return true if array satisfies the contraction criteria - */ - private synchronized boolean shouldContract() { - boolean shouldContract = false; - if ((internalArray.length / numElements) > contractionCriteria) { - shouldContract = true; - } - return shouldContract; - } - - /** - * @see org.apache.commons.math.util.DoubleArray#setElement(int, double) - */ - public synchronized void setElement(int index, double value) { - super.setElement(index, value); - if (shouldContract()) { - contract(); - } - } - - /** - * Method invokes the super class' setExpansionFactor but first it - * must validate the combination of expansionFactor and - * contractionCriteria. - * - * @see org.apache.commons.math.util.ExpandableDoubleArray#setExpansionFactor(float) - */ - public void setExpansionFactor(float expansionFactor) { - checkContractExpand(getContractionCriteria(), expansionFactor); - super.setExpansionFactor(expansionFactor); - } - - /** - * The contraction criteria defines when the internal array will contract - * to store only the number of elements in the element array. This - * contractionCriteria gaurantees that the internal storage array will - * never exceed this factor more than the space needed to store - * numElements. - * - * @return the contraction criteria used to reclaim memory when array is - * empty - */ - public float getContractionCriteria() { - return contractionCriteria; - } - - /** - * Sets the contraction criteria for this ExpandContractDoubleArray. - * - * @param contractionCriteria contraction criteria - */ - public void setContractionCriteria(float contractionCriteria) { - checkContractExpand(contractionCriteria, getExpansionFactor()); - - this.contractionCriteria = contractionCriteria; - } - - /** - * Checks the expansion factor and the contraction criteria and throws an - * IllegalArgumentException if the contractionCriteria is less than the - * expansionCriteria - * - * @param expansionFactor factor to be checked - * @param contractionCritera critera to be checked - * @throws IllegalArgumentException if the contractionCriteria is less than - * the expansionCriteria. - */ - protected void checkContractExpand( - float contractionCritera, - float expansionFactor) { - - if (contractionCritera < expansionFactor) { - String msg = - "Contraction criteria can never be smaller than " + - "the expansion factor. This would lead to a never " + - "ending loop of expansion and contraction as a newly " + - "expanded internal storage array would immediately " + - "satisfy the criteria for contraction"; - throw new IllegalArgumentException(msg); - } - - if (contractionCriteria <= 1.0) { - String msg = - "The contraction criteria must be a number larger " + - "than one. If the contractionCriteria is less than or " + - "equal to one an endless loop of contraction and " + - "expansion would ensue as an internalArray.length " + - "== numElements would satisfy the contraction criteria"; - throw new IllegalArgumentException(msg); - } - - if (expansionFactor < 1.0) { - String msg = - "The expansion factor must be a number greater than 1.0"; - throw new IllegalArgumentException(msg); - } - } - - /** - * @see org.apache.commons.math.util.ExpandableDoubleArray#discardFrontElements(int) - */ - public synchronized void discardFrontElements(int i) { - super.discardFrontElements(i); - if (shouldContract()) { - contract(); - } - } -} diff --git a/src/java/org/apache/commons/math/util/DoubleArray.java b/src/java/org/apache/commons/math/util/DoubleArray.java index 371e9ae5e..e70b98bf1 100644 --- a/src/java/org/apache/commons/math/util/DoubleArray.java +++ b/src/java/org/apache/commons/math/util/DoubleArray.java @@ -17,19 +17,18 @@ package org.apache.commons.math.util; /** - * Provides a single interface for dealing with various flavors - * of double arrays. This arrays framework follows the model of the - * Collections API by allowing a user to select from a number of - * array implementations with support for various storage mechanisms + * Provides a standard interface for double arrays. Allows different + * array implementations to support various storage mechanisms * such as automatic expansion, contraction, and array "rolling". * - * @version $Revision: 1.11 $ $Date: 2004/06/08 14:19:40 $ + * @version $Revision: 1.12 $ $Date: 2004/06/14 21:41:33 $ */ 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. + * that this may be different from the length of the internal storage array. + * * @return number of elements */ int getNumElements(); @@ -47,9 +46,11 @@ public interface DoubleArray { double getElement(int index); /** - * Sets the element at the specified index. This method may expand the - * internal storage array to accomodate the insertion of a value at an - * index beyond the current capacity. + * Sets the element at the specified index. If the specified index is greater than + *getNumElements() - 1
, the numElements
property
+ * is increased to index +1
and additional storage is allocated
+ * (if necessary) for the new element and all (uninitialized) elements
+ * between the new element and the previous end of the array).
*
* @param index index to store a value in
* @param value value to store at the specified index
@@ -66,23 +67,29 @@ public interface DoubleArray {
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 may be
- * removed from the array. In this case, the return value of this function is the
- * discarded double. In some implementations, removal will only occur when
- * the array has reached a capacity threshold.
* - * When removal does occur, the effect is to add an element to the end of the - * array and to discard the element at the beginning of the array. + * Adds an element to the end of the array and removes the first + * element in the array. Returns the discarded first element. + * The effect is similar to a push operation in a FIFO queue. + *
+ *+ * Example: If the array contains the elements 1, 2, 3, 4 (in that order) + * and addElementRolling(5) is invoked, the result is an array containing + * the entries 2, 3, 4, 5 and the value returned is 1. + *
* * @param value the value to be added to the array * @return the value which has been discarded or "pushed" out of the array - * by this rolling insert or null if no value has been discarded + * by this rolling insert */ double addElementRolling(double value); /** - * Returns a double[] of elements + * Returns a double[] array containing the elements of this + *DoubleArray
. If the underlying implementation is
+ * array-based, this method should always return a copy, rather than a
+ * reference to the underlying array so that changes made to the returned
+ * array have no effect on the DoubleArray.
*
* @return all elements added to the array
*/
diff --git a/src/java/org/apache/commons/math/util/ExpandableDoubleArray.java b/src/java/org/apache/commons/math/util/ExpandableDoubleArray.java
deleted file mode 100644
index cbb0f25d8..000000000
--- a/src/java/org/apache/commons/math/util/ExpandableDoubleArray.java
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * Copyright 2003-2004 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.math.util;
-
-import java.io.Serializable;
-
-/**
- *
- * A DoubleArray implementation which automatically expands
- * an internal double array to handle an array of arbitrary length. This
- * implementation of DoubleArray is provided to support scenarios in
- * which the ultimate length of an array is unknown, and the
- * developer can control the expansion process through the
- * initialCapacity
and expansionFactor
- * parameters.
- *
- * This implementation also allows a developer to: - *
setNumElements(int)
discardFrontElements(int)
- * The initialCapacity parameter sets the capacity of the initial - * storage array, and the expansionFactor is the factor by which - * the current storage capacity is multiplied each time the internal - * array needs to be expanded. Please note that the length of the - * internal storage array has nothing to do with the number of elements - * currently stored in this array. If one creates an instance of this - * class with an initialCapacity of "2" and an expansion factor of "2", and - * then adds 3546 elements to the array, this implementation will need to - * expand the array 10 times - first from 2 -> 4. then 4 -> 8, 8 -> 16, - * and so on until we reach 4096 which is sufficient to hold 3546 elements. - *
- * @version $Revision: 1.15 $ $Date: 2004/05/19 14:16:32 $ - */ -public class ExpandableDoubleArray implements Serializable, DoubleArray { - - /** Serializable version identifier */ - static final long serialVersionUID = -5697417774251632284L; - - // TODO: expansionFactor is valuable, by if I only need storage - // for 1025 items and I use the default settings, I'll end up - // with enough storage for 2048 elements. Maybe this implementation - // should have flags for incremental growth - (i.e. when expanding, only - // increase storage by a constant size - 100, 200 ) ? - - /** - * This is the internal storage array. - */ - protected double[] internalArray; - - /** - * Number of elements in the array - */ - protected int numElements = 0; - - /** - * Keeps track of a starting index - */ - protected int startIndex = 0; - - /**The initial capacity of the array. - * Initial capacity is not exposed as a property as it is only meaningful - * when passed to a constructor. - */ - protected int initialCapacity = 16; - - /** The expand factor of the array. When the array need to be expanded, - * the new array size will be internalArray.length * expandFactor - */ - protected float expansionFactor = 2.0f; - - /** - * Create an expandable double array with the - * default initial capactiy of 16 and an expansion factor of 2.00 - */ - public ExpandableDoubleArray() { - internalArray = new double[initialCapacity]; - } - - /** - * Create an expandable double array with the - * specified initial capacity and the defult expansion factor of 2.00 - * - * @param initialCapacity The initial size of the internal storage array - */ - public ExpandableDoubleArray(int initialCapacity) { - setInitialCapacity(initialCapacity); - internalArray = new double[this.initialCapacity]; - } - - /** - * Create an expandable double array with the - * specificed initial capacity and expand factor. - * - * @param initialCapacity The initial size of the internal storage array - * @param expansionFactor the array will be expanded based on this - * parameter - */ - public ExpandableDoubleArray(int initialCapacity, float expansionFactor) { - setInitialCapacity(initialCapacity); - setExpansionFactor(expansionFactor); - this.initialCapacity = initialCapacity; - internalArray = new double[initialCapacity]; - } - - /** - * The expansion factor controls the size of a new aray when an array - * needs to be expanded. When a value is inserted into a full array, the - * new array size is calculated as the current array size times this - * expansion factor. The default expansion factor is 2.0 - * - * @return the expansion factor of this expandable double array - */ - public float getExpansionFactor() { - return expansionFactor; - } - - /** - * Sets the expansion factor for this expandable double array. - * The expansion factor will affect the next expansion of this array. - * - * @param expansionFactor the expansion factor of this array - * @throws IllegalArgumentException ifexpansionFactor
is less
- * than or equal to 1.0
- */
- public void setExpansionFactor(float expansionFactor) {
-
- // The expansion factor *must* be larger than 1.0, otherwise we'll
- // have an inconsistency upon expansion we'll start shrinking which
- // will lead to ArrayIndexOutOfBound exceptions.
- if (expansionFactor > 1.0) {
- this.expansionFactor = expansionFactor;
- } else {
- String msg =
- "The expansion factor must be a number greater " + "than 1.0";
- throw new IllegalArgumentException(msg);
- }
- }
-
- /**
- * Sets the initial capacity
- * @param initialCapacity of the array
- * @throws IllegalArgumentException if initialCapacity
is not
- * positive.
- */
- public void setInitialCapacity(int initialCapacity) {
- if (initialCapacity > 0) {
- this.initialCapacity = initialCapacity;
- } else {
- String msg =
- "The initial capacity supplied: " + initialCapacity +
- "must be a positive integer";
- throw new IllegalArgumentException(msg);
- }
- }
-
- /**
- * Returns the internal storage array
- *
- * @return the internal storage array used by this object
- */
- public double[] getValues() {
- return (internalArray);
- }
-
- /**
- * Returns the starting index of the internal array.
- * @return starting index
- */
- public int start() {
- return startIndex;
- }
-
- /**
- * 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 int getNumElements() {
- return (numElements);
- }
-
- /**
- * This function allows you to control the number of elements contained
- * in this array, and can be used to "throw" out the last n values in an
- * array. This feature is mainly targetted at the subclasses of this
- * array class. Note that this function will also expand the internal
- * array as needed.
- *
- * @param i a new number of elements
- * @throws IllegalArgumentException if i
is negative.
- */
- public synchronized void setNumElements(int i) {
-
- // If index is negative thrown an error
- if (i < 0) {
- String msg =
- "Number of elements must be zero or a positive " + "integer";
- throw new IllegalArgumentException(msg);
- }
-
- // Test the new num elements, check to see if the array needs to be
- // expanded to accomodate this new number of elements
- if ((startIndex + i) > internalArray.length) {
- expandTo(startIndex + i);
- }
-
- // Set the new number of elements to new value
- numElements = i;
- }
-
- /**
- * Returns the element at the specified index
- *
- * @param index index to fetch a value from
- * @return value stored at the specified index
- * @throws ArrayIndexOutOfBoundsException if index
is less than
- * zero or is greater than getNumElements() - 1
.
- */
- public double getElement(int index) {
- double value = Double.NaN;
- if (index >= numElements) {
- String msg =
- "The index specified: " + index +
- " is larger than the current number of elements";
- throw new ArrayIndexOutOfBoundsException(msg);
- } else if (index >= 0) {
- value = internalArray[startIndex + index];
- } else {
- String msg =
- "Elements cannot be retrieved from a negative array index";
- throw new ArrayIndexOutOfBoundsException(msg);
- }
- return value;
- }
-
- /**
- * 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
- * @throws ArrayIndexOutOfBoundsException if index
is less than
- * zero.
- */
- public synchronized void setElement(int index, double value) {
-
- if (index < 0) {
- String msg = "Cannot set an element at a negative index";
- throw new ArrayIndexOutOfBoundsException(msg);
- }
-
- if ((startIndex + index) >= internalArray.length) {
- expandTo(startIndex + (index + 1));
- numElements = index + 1;
- }
- internalArray[startIndex + index] = value;
- }
-
- /**
- * Expands the internal storage array to the specified size.
- *
- * @param size Size of the new internal storage array
- */
- private synchronized void expandTo(int size) {
- double[] tempArray = new double[size];
- // Copy and swap
- System.arraycopy(internalArray, 0, tempArray, 0, internalArray.length);
- internalArray = tempArray;
- }
-
- /**
- * Expands the internal storage array using the expansion factor
- */
- protected synchronized void expand() {
-
- // notice the use of Math.ceil(), this gaurantees that we will always
- // have an array of at least currentSize + 1. Assume that the
- // current initial capacity is 1 and the expansion factor
- // is 1.000000000000000001. The newly calculated size will be
- // rounded up to 2 after the multiplication is performed.
- int newSize = (int) Math.ceil(internalArray.length * expansionFactor);
- double[] tempArray = new double[newSize];
-
- // Copy and swap
- System.arraycopy(internalArray, 0, tempArray, 0, internalArray.length);
- internalArray = tempArray;
- }
-
- /**
- * Adds an element to the end of this expandable array
- *
- * @param value value to be added to end of array
- */
- public synchronized void addElement(double value) {
- numElements++;
- if ((startIndex + numElements) > internalArray.length) {
- expand();
- }
- internalArray[startIndex + (numElements - 1)] = 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.
- * @param value the value to add
- * @return the value which has been discarded or "pushed" out of the array
- * by this rolling insert.
- */
- public synchronized double addElementRolling(double value) {
- double discarded = internalArray[startIndex];
-
- if ((startIndex + (numElements + 1)) > internalArray.length) {
- expand();
- }
- // Increment the start index
- startIndex += 1;
-
- // Add the new value
- internalArray[startIndex + (numElements - 1)] = value;
-
- return discarded;
- }
-
- /**
- * Notice the package scope on this method. This method is simply here
- * for the JUnit test, it allows us check if the expansion is working
- * properly after a number of expansions. This is not meant to be a part
- * of the public interface of this class.
- *
- * @return the length of the internal storage array.
- */
- int getInternalLength() {
- return (internalArray.length);
- }
-
- /**
- * Clear the array, reset the size to the initialCapacity and the number
- * of elements to zero.
- */
- public synchronized void clear() {
- numElements = 0;
- internalArray = new double[initialCapacity];
- }
-
- /**
- * 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.
- * @throws IllegalArgumentException if i
is negative of is
- * greater than getNumElements()
.
- */
- public synchronized void discardFrontElements(int i) {
-
- if (i > numElements) {
- String msg = "Cannot discard more elements than are" +
- "contained in this array.";
- throw new IllegalArgumentException(msg);
- } else if (i < 0) {
- String msg = "Cannot discard a negative number of elements.";
- throw new IllegalArgumentException(msg);
- } else {
- // "Subtract" this number of discarded from numElements
- numElements -= i;
- startIndex += i;
- }
- }
-
- /**
- * @see org.apache.commons.math.util.DoubleArray#getElements()
- */
- public double[] getElements() {
- double[] elementArray = new double[numElements];
- System.arraycopy(
- internalArray,
- startIndex,
- elementArray,
- 0,
- numElements);
- return elementArray;
- }
-
-}
diff --git a/src/java/org/apache/commons/math/util/FixedDoubleArray.java b/src/java/org/apache/commons/math/util/FixedDoubleArray.java
deleted file mode 100644
index 70dd7a868..000000000
--- a/src/java/org/apache/commons/math/util/FixedDoubleArray.java
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * Copyright 2003-2004 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.math.util;
-
-import java.io.Serializable;
-
-/**
- * - * Provides an implementation of the DoubleArray with a maximum number of - * elements. Creating an array implementation with an upper limit on the - * number of elements allows us to support a more efficient "rolling" - * mechanism to support addElementRoling(double). Please note that this - * implementation will not preserve the order of the values supplied to - * this array, calling getValues() will return an array of indeterminate - * order. - *
- * - *- * Values are added to this array by calling addElement(double) or - * addElementRolling(double). If addElement(double) is called on - * an array that already contains the maximum number of elements, an - * ArrayIndexOutOfBoundsException will be thrown to reflect an attempt to - * add a value beyond the boundaries of the fixed length array - in this - * respect a FixedDoubleArray can be considered "full". Calling - * addElementRolling(double) on an array which contains the maximum - * number of elements will cause the array to overwrite the "oldest" - * value in the array. - *
- * - *- * This class is called FixedDoubleArray not because it is of a fixed size. - * The name is appropriate because the internal storage array remains - * "fixed" in memory, this implementation will never allocate, or copy - * the internal storage array to a new array instance. - *
- * @version $Revision: 1.16 $ $Date: 2004/05/19 14:16:32 $ - */ -public class FixedDoubleArray implements DoubleArray, Serializable { - - /** Serializable version identifier */ - static final long serialVersionUID = 1247853239629842963L; - - /** - * This is the internal storage array. This array is assigned - * a known fixed size in the constructor - */ - private double[] internalArray; - - /** - * Size determined the number of elements in the array at - * any given time. When an array is created is maxElements - * of 100, it is of size 0, and size increases as values are - * added. - */ - private int size = 0; - - /** - * This index points to the location of the next update. Next - * add, cycles from 0 to (maxElement-1) - */ - private int nextAdd = 0; - - /** - * The maximum number of elements in the FixedDoubleArray - */ - private int maxElements = 0; - - /** - * Create a fixed array for double primitives which can hold up to - *maxElements doubles. This implementation of
- * DoubleArray was created to provide a more "performance-oriented"
- * in-place rolling mechanism for calculations which need to
- * operate on a rolling window of values.
- *
- * @param maxElements the maximum number of elements this
- * FixeddoubleArray may contain.
- */
- public FixedDoubleArray(int maxElements) {
- this.maxElements = maxElements;
- internalArray = new double[maxElements];
- }
-
- /**
- * Create a fixed array backed by the provided double[] implementation.
- * the array should have all the elements occupied. the size and maxElements
- * are drawn from the array's length.
- *
- * This implementation of DoubleArray was created to provide a more
- * "performance-oriented" in-place rolling mechanism for calculations
- * which need to operate on a rolling window of values.
- * @param array the backing array
- */
- public FixedDoubleArray(double[] array) {
- this.maxElements = array.length;
- this.size = array.length;
- internalArray = array;
- }
-
- /**
- * Retrieves the current size of the array.
- * @see org.apache.commons.math.util.DoubleArray#getNumElements()
- */
- public int getNumElements() {
- return size;
- }
-
- /**
- * Returns the element value at the specified index. Please note that
- * the size of the element array is not directly related to the
- * maximum number of elements which this array can contain. One can
- * create an instance of FixedDoubleArray with a maximum of
- * ten elements, add three items, and get any items from index 0 to index
- * 2 - trying to retrieve an element outside of the current element
- * array will throw an ArrayIndexOutOfBoundsException.
- *
- * @see org.apache.commons.math.util.DoubleArray#getElement(int)
- * @throws ArrayIndexOutOfBoundsException if index
is less than
- * zero or is greater than getNumElements() - 1
.
- */
- public double getElement(int index) {
- if (index > (size - 1)) {
- String msg =
- "Attempted to retrieve an element outside of " +
- "the element array";
- throw new ArrayIndexOutOfBoundsException(msg);
- } else {
- // Return the element requested, if the index supplied
- // is negative this statement may also throw an
- // ArrayIndexOutOfBoundException.
- return internalArray[index];
- }
- }
-
- /**
- *
- * Sets the element at the specified index to the value supplied.
- *
- *
- * Implementation Notes:
- *
- * This implementation will not expand the array to the specified
- * size. Unlike the expandable double array implementation calling
- * setElement(10, 3.0) on an array with 5 elements will throw an
- * ArrayIndexOutOfBoundsException.
- *
- *
- * The number of elements in an array corresponds to the number
- * of elements that have been added to this FixedDoubleArray. This
- * is not the same as the maximum number of elements which can be
- * contained in this array. A FixedDoubleArray instance can be
- * created with a maximum upper limit of 10 elements, until 10
- * elements have been added to this array, the size of the array
- * reflects the number of elements added.
- *
- *
- *
- * @see org.apache.commons.math.util.DoubleArray#setElement(int, double)
- * @throws ArrayIndexOutOfBoundsException if index
is less than
- * zero or is greater than getNumElements() - 1
.
- */
- public void setElement(int index, double value) {
- if (index > (size - 1)) {
- String msg =
- "Attempted to set an element outside of" + "the element array";
- throw new ArrayIndexOutOfBoundsException(msg);
- } else {
- internalArray[index] = value;
- }
- }
-
- /**
- * Add an element to the current array, testing to see if
- * this array has already met or exceeded the maximum number
- * of elements
- *
- * @see org.apache.commons.math.util.DoubleArray#addElement(double)
- * @throws ArrayIndexOutOfBoundsException if array is already at capacity.
- */
- public void addElement(double value) {
- if (size < internalArray.length) {
- size++;
-
- internalArray[nextAdd] = value;
-
- // Incremenet nextAdd and then modulo it against maxElements
- // this has the effect of repeatedly "cycling" nextAdd
- // between 0 and (maxElements-1) endlessly.
- nextAdd++;
- nextAdd = nextAdd % (maxElements);
-
- } else {
- // If the array has ALREADY reached the maximum size allowable,
- // we throw an ArrayIndexOutOfBoundsException - the end-user
- // is trying to add an element beyond the boundaries of the
- // fixed array.
- String msg =
- "Attempted to add a value to an array of fixed " +
- "size, please use addElementRolling " +
- "to avoid this exception";
- throw new ArrayIndexOutOfBoundsException(msg);
- }
- }
-
- /**
- *
- * Adds an element by "rolling" the new value into the current array
- * while discarding the element which was added maxElement
- * add operations ago. The value replaced is returned from this
- * method. Until an array contains the maximum number of element, this
- * method has the same result as the addElement(double) operation. Once
- * the maximum number of elements has been reached this implementation
- * inserts the new values starting at index 0 of the internal storage
- * array. This allows for efficient rolling, but prevents us from
- * preserving the order of the added values.
- *
- *
- *
- * Note: This function will return Double.NaN
if
- * no value has been discarded in this roll. This can happen when
- * the array has not met the size limitation introduced in the
- * constructor.
- *
- * @param value the value to be added to the array
- * @return Returns the value which a has been "removed" from the
- * database. Important: If the element array has
- * not reached the maximum size, then it is possible that
- * no element will be discarded from a given roll. In this
- * case this method will return a Double.NaN
value.
- *
- * @see org.apache.commons.math.util.DoubleArray#addElementRolling(double)
- */
- public double addElementRolling(double value) {
-
- // Create the discarded primitive. If no element is
- // discarded by this roll, this method will return a
- // Double.NaN value.
- double discarded = Double.NaN;
-
- if (size < internalArray.length) {
- size++;
- } else {
- // If we've reached the length of the internal
- // storage array, we have to start "discarding"
- // values from the original array.
-
- // Obtain the value discarded by this overwrite
- discarded = internalArray[nextAdd];
- }
-
- internalArray[nextAdd] = value;
-
- // nextAdd cycles between 0 and (maxElements-1).
- nextAdd++;
- nextAdd = nextAdd % maxElements;
-
- // but we return the value which was "replaced"
- return (discarded);
- }
-
- /**
- * Provides an array of double[] which contain the
- * number of elements added to this array. This
- * method will return an array from zero to maxElements in length.
- *
- * @return The array of elements added to this DoubleArray
- * implementation.
- * @see org.apache.commons.math.util.DoubleArray#getElements()
- */
- public double[] getElements() {
- double[] copy = new double[size];
- System.arraycopy(internalArray, 0, copy, 0, size);
- return copy;
- }
-
- /**
- * Returns the internal storage array
- *
- * @return the internal storage array used by this object
- */
- public double[] getValues() {
- return (internalArray);
- }
-
- /**
- * The starting index in the InternalArray.
- * @return starting index.
- */
- public int start() {
- return 0;
- }
-
- /**
- * Clear the array - drop all the data and start with a blank
- * internal array. This implementation takes care of
- * setting the size of the array back to zero, and reinitializing
- * the internal storage array.
- *
- * @see org.apache.commons.math.util.DoubleArray#clear()
- */
- public void clear() {
- size = 0;
- nextAdd = 0;
- internalArray = new double[maxElements];
- }
-
-}
diff --git a/src/java/org/apache/commons/math/util/ResizableDoubleArray.java b/src/java/org/apache/commons/math/util/ResizableDoubleArray.java
new file mode 100644
index 000000000..16e7b087d
--- /dev/null
+++ b/src/java/org/apache/commons/math/util/ResizableDoubleArray.java
@@ -0,0 +1,689 @@
+/*
+ * Copyright 2003-2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math.util;
+
+import java.io.Serializable;
+
+/**
+ *
+ * A variable length {@link DoubleArray} implementation that automatically
+ * handles expanding and contracting its internal storage array as elements
+ * are added and removed.
+ *
+ *
+ * The internal storage array starts with capacity determined by the
+ * initialCapacity
property, which can be set by the constructor.
+ * The default initial capacity is 16. Adding elements using
+ * {@link #addElement(double)} appends elements to the end of the array. When
+ * there are no open entries at the end of the internal storage array, the
+ * array is expanded. The size of the expanded array depends on the
+ * expansionMode
and expansionFactor
properties.
+ * The expansionMode
determines whether the size of the array is
+ * multiplied by the expansionFactor
(MULTIPLICATIVE_MODE) or if
+ * the expansion is additive (ADDITIVE_MODE -- expansionFactor
+ * storage locations added). The default expansionMode
is
+ * MULTIPLICATIVE_MODE and the default expansionFactor
+ * is 2.0.
+ *
+ *
+ * The {@link #addElementRolling(double)} method adds a new element to the end
+ * of the internal storage array and adjusts the "usable window" of the
+ * internal array forward by one position (effectively making what was the
+ * second element the first, and so on). Repeated activations of this method
+ * (or activation of {@link #discardFrontElements(int)}) will effectively orphan
+ * the storage locations at the beginning of the internal storage array. To
+ * reclaim this storage, each time one of these methods is activated, the size
+ * of the internal storage array is compared to the number of addressable
+ * elements (the numElements
property) and if the difference
+ * is too large, the internal array is contracted to size
+ * numElements + 1.
The determination of when the internal
+ * storage array is "too large" depends on the expansionMode
and
+ * contractionFactor
properties. If the expansionMode
+ * is MULTIPLICATIVE_MODE
, contraction is triggered when the
+ * ratio between storage array length and numElements
exceeds
+ * contractionFactor.
If the expansionMode
+ * is ADDITIVE_MODE,
the number of excess storage locations
+ * is compared to contractionFactor.
+ *
+ *
+ * To avoid cycles of expansions and contractions, the
+ * expansionFactor
must not exceed the
+ * contractionFactor.
Constructors and mutators for both of these
+ * properties enforce this requirement, throwing IllegalArgumentException if it
+ * is violated.
+ *
+ *
+ * @version $Revision: 1.1 $ $Date: 2004/06/14 21:41:33 $
+ */
+public class ResizableDoubleArray implements DoubleArray, Serializable {
+
+ /** Serializable version identifier */
+ static final long serialVersionUID = -3485529955529426875L;
+
+ /** additive expansion mode */
+ public static final int ADDITIVE_MODE = 1;
+
+ /** multiplicative expansion mode */
+ public static final int MULTIPLICATIVE_MODE = 0;
+
+ /**
+ * The contraction criteria determines when the internal array will be
+ * contracted to fit the number of elements contained in the element
+ * array + 1.
+ */
+ protected float contractionCriteria = 2.5f;
+
+ /**
+ * The expansion factor of the array. When the array needs to be expanded,
+ * the new array size will be
+ * internalArray.length * expansionFactor
+ * if expansionMode
is set to MULTIPLICATIVE_MODE, or
+ * internalArray.length + expansionFactor
if
+ * expansionMode
is set to ADDITIVE_MODE.
+ */
+ protected float expansionFactor = 2.0f;
+
+ /**
+ * Determines whether array expansion by expansionFactor
+ * is additive or multiplicative.
+ */
+ protected int expansionMode = MULTIPLICATIVE_MODE;
+
+ /**
+ * The initial capacity of the array. Initial capacity is not exposed as a
+ * property as it is only meaningful when passed to a constructor.
+ */
+ protected int initialCapacity = 16;
+
+ /**
+ * The internal storage array.
+ */
+ protected double[] internalArray;
+
+ /**
+ * The number of addressable elements in the array. Note that this
+ * has nothing to do with the length of the internal storage array.
+ */
+ protected int numElements = 0;
+
+ /**
+ * The position of the first addressable element in the internal storage
+ * array. The addressable elements in the array are
+ * internalArray[startIndex],...,internalArray[startIndex + numElements -1]
+ *
+ */
+ protected int startIndex = 0;
+
+ /**
+ * Create a ResizableArray with default properties.
+ *
+ * initialCapacity = 16
+ * expansionMode = MULTIPLICATIVE_MODE
+ * expansionFactor = 2.5
+ * contractionFactor = 2.0
+ *
+ */
+ public ResizableDoubleArray() {
+ internalArray = new double[initialCapacity];
+ }
+
+ /**
+ * Create a ResizableArray with the specified initial capacity. Other
+ * properties take default values:
+ *
+ * expansionMode = MULTIPLICATIVE_MODE
+ * expansionFactor = 2.5
+ * contractionFactor = 2.0
+ *
+ * @param initialCapacity The initial size of the internal storage array
+ * @throws IllegalArgumentException if initialCapacity is not > 0
+ */
+ public ResizableDoubleArray(int initialCapacity) {
+ setInitialCapacity(initialCapacity);
+ internalArray = new double[this.initialCapacity];
+ }
+
+ /**
+ *
+ * Create a ResizableArray with the specified initial capacity
+ * and expansion factor. The remaining properties take default
+ * values:
+ *
+ * expansionMode = MULTIPLICATIVE_MODE
+ * contractionFactor = 0.5 + expansionFactor
+ *
+ *
+ * Throws IllegalArgumentException if the following conditions are
+ * not met:
+ *
+ * initialCapacity > 0
+ * expansionFactor > 1
+ *
+ *
+ * @param initialCapacity The initial size of the internal storage array
+ * @param expansionFactor the array will be expanded based on this
+ * parameter
+ * @throws IllegalArgumentException if parameters are not valid
+ */
+ public ResizableDoubleArray(int initialCapacity, float expansionFactor) {
+ this.expansionFactor = expansionFactor;
+ setInitialCapacity(initialCapacity);
+ internalArray = new double[initialCapacity];
+ setContractionCriteria(expansionFactor +0.5f);
+ }
+
+ /**
+ *
+ * Create a ResizableArray with the specified initialCapacity,
+ * expansionFactor, and contractionCriteria. The expansionMode
+ * will default to MULTIPLICATIVE_MODE.
+ *
+ * Throws IllegalArgumentException if the following conditions are
+ * not met:
+ *
+ * initialCapacity > 0
+ * expansionFactor > 1
+ * contractionFactor >= expansionFactor
+ *
+ * @param initialCapacity The initial size of the internal storage array
+ * @param expansionFactor the array will be expanded based on this
+ * parameter
+ * @param contractionCriteria The contraction Criteria.
+ * @throws IllegalArgumentException if parameters are not valid
+ */
+ public ResizableDoubleArray(int initialCapacity, float expansionFactor,
+ float contractionCriteria) {
+ this.expansionFactor = expansionFactor;
+ setContractionCriteria(contractionCriteria);
+ setInitialCapacity(initialCapacity);
+ internalArray = new double[initialCapacity];
+ }
+
+ /**
+ *
+ * Create a ResizableArray with the specified properties.
+ *
+ * Throws IllegalArgumentException if the following conditions are
+ * not met:
+ *
+ * initialCapacity > 0
+ * expansionFactor > 1
+ * contractionFactor >= expansionFactor
+ * expansionMode in {MULTIPLICATIVE_MODE, ADDITIVE_MODE}
+ *
+ *
+ *
+ * @param initialCapacity the initial size of the internal storage array
+ * @param expansionFactor the array will be expanded based on this
+ * parameter
+ * @param contractionCriteria the contraction Criteria
+ * @param expansionMode the expansion mode
+ * @throws IllegalArgumentException if parameters are not valid
+ */
+ public ResizableDoubleArray(int initialCapacity, float expansionFactor,
+ float contractionCriteria, int expansionMode) {
+ this.expansionFactor = expansionFactor;
+ setContractionCriteria(contractionCriteria);
+ setInitialCapacity(initialCapacity);
+ setExpansionMode(expansionMode);
+ internalArray = new double[initialCapacity];
+ }
+
+ /**
+ * Adds an element to the end of this expandable array.
+ *
+ * @param value to be added to end of array
+ */
+ public synchronized void addElement(double value) {
+ numElements++;
+ if ((startIndex + numElements) > internalArray.length) {
+ expand();
+ }
+ internalArray[startIndex + (numElements - 1)] = value;
+ if (shouldContract()) {
+ contract();
+ }
+ }
+
+ /**
+ *
+ * Adds an element to the end of the array and removes the first
+ * element in the array. Returns the discarded first element.
+ * The effect is similar to a push operation in a FIFO queue.
+ *
+ *
+ * Example: If the array contains the elements 1, 2, 3, 4 (in that order)
+ * and addElementRolling(5) is invoked, the result is an array containing
+ * the entries 2, 3, 4, 5 and the value returned is 1.
+ *
+ *
+ * @param value the value to be added to the array
+ * @return the value which has been discarded or "pushed" out of the array
+ * by this rolling insert
+ */
+ public synchronized double addElementRolling(double value) {
+ double discarded = internalArray[startIndex];
+
+ if ((startIndex + (numElements + 1)) > internalArray.length) {
+ expand();
+ }
+ // Increment the start index
+ startIndex += 1;
+
+ // Add the new value
+ internalArray[startIndex + (numElements - 1)] = value;
+
+ // Check the contraction criteria
+ if (shouldContract()) {
+ contract();
+ }
+ return discarded;
+ }
+
+ /**
+ * Checks the expansion factor and the contraction criteria and throws an
+ * IllegalArgumentException if the contractionCriteria is less than the
+ * expansionCriteria
+ *
+ * @param expansionFactor factor to be checked
+ * @param contractionCritera critera to be checked
+ * @throws IllegalArgumentException if the contractionCriteria is less than
+ * the expansionCriteria.
+ */
+ protected void checkContractExpand(
+ float contractionCritera,
+ float expansionFactor) {
+
+ if (contractionCritera < expansionFactor) {
+ String msg =
+ "Contraction criteria can never be smaller than " +
+ "the expansion factor. This would lead to a never " +
+ "ending loop of expansion and contraction as a newly " +
+ "expanded internal storage array would immediately " +
+ "satisfy the criteria for contraction";
+ throw new IllegalArgumentException(msg);
+ }
+
+ if (contractionCriteria <= 1.0) {
+ String msg =
+ "The contraction criteria must be a number larger " +
+ "than one. If the contractionCriteria is less than or " +
+ "equal to one an endless loop of contraction and " +
+ "expansion would ensue as an internalArray.length " +
+ "== numElements would satisfy the contraction criteria";
+ throw new IllegalArgumentException(msg);
+ }
+
+ if (expansionFactor <= 1.0) {
+ String msg =
+ "The expansion factor must be a number greater than 1.0";
+ throw new IllegalArgumentException(msg);
+ }
+ }
+
+ /**
+ * Clear the array, reset the size to the initialCapacity and the number
+ * of elements to zero.
+ */
+ public synchronized void clear() {
+ numElements = 0;
+ internalArray = new double[initialCapacity];
+ }
+
+ /**
+ * Contracts the storage array to the (size of the element set) + 1 - to
+ * avoid a zero length array. This function also resets the startIndex to
+ * zero.
+ */
+ public synchronized void contract() {
+ double[] tempArray = new double[numElements + 1];
+
+ // Copy and swap - copy only the element array from the src array.
+ System.arraycopy(internalArray, startIndex, tempArray, 0, numElements);
+ internalArray = tempArray;
+
+ // Reset the start index to zero
+ startIndex = 0;
+ }
+
+ /**
+ * Discards the i initial elements of the array. For example,
+ * if the array contains the elements 1,2,3,4, invoking
+ * discardFrontElements(2)
will cause the first two elements
+ * to be discarded, leaving 3,4 in the array. Throws illegalArgumentException
+ * if i exceeds numElements.
+ *
+ * @param i the number of elements to discard from the front of the array
+ * @throws IllegalArgumentException if i is greater than numElements.
+ */
+ public synchronized void discardFrontElements(int i) {
+ if (i > numElements) {
+ String msg = "Cannot discard more elements than are" +
+ "contained in this array.";
+ throw new IllegalArgumentException(msg);
+ } else if (i < 0) {
+ String msg = "Cannot discard a negative number of elements.";
+ throw new IllegalArgumentException(msg);
+ } else {
+ // "Subtract" this number of discarded from numElements
+ numElements -= i;
+ startIndex += i;
+ }
+ if (shouldContract()) {
+ contract();
+ }
+ }
+
+ /**
+ * Expands the internal storage array using the expansion factor.
+ *
+ * if expansionMode
is set to MULTIPLICATIVE_MODE,
+ * the new array size will be internalArray.length * expansionFactor.
+ * If expansionMode
is set to ADDITIVE_MODE, the length
+ * after expansion will be internalArray.length + expansionFactor
+ */
+ protected synchronized void expand() {
+
+ // notice the use of Math.ceil(), this gaurantees that we will always
+ // have an array of at least currentSize + 1. Assume that the
+ // current initial capacity is 1 and the expansion factor
+ // is 1.000000000000000001. The newly calculated size will be
+ // rounded up to 2 after the multiplication is performed.
+ int newSize = 0;
+ if (expansionMode == MULTIPLICATIVE_MODE) {
+ newSize = (int) Math.ceil(internalArray.length * expansionFactor);
+ } else {
+ newSize = internalArray.length + Math.round(expansionFactor);
+ }
+ double[] tempArray = new double[newSize];
+
+ // Copy and swap
+ System.arraycopy(internalArray, 0, tempArray, 0, internalArray.length);
+ internalArray = tempArray;
+ }
+
+ /**
+ * Expands the internal storage array to the specified size.
+ *
+ * @param size Size of the new internal storage array
+ */
+ private synchronized void expandTo(int size) {
+ double[] tempArray = new double[size];
+ // Copy and swap
+ System.arraycopy(internalArray, 0, tempArray, 0, internalArray.length);
+ internalArray = tempArray;
+ }
+
+ /**
+ * The contraction criteria defines when the internal array will contract
+ * to store only the number of elements in the element array.
+ * If the expansionMode
is MULTIPLICATIVE_MODE
,
+ * contraction is triggered when the ratio between storage array length
+ * and numElements
exceeds contractionFactor
.
+ * If the expansionMode
is ADDITIVE_MODE
, the
+ * number of excess storage locations is compared to
+ * contractionFactor.
+ *
+ * @return the contraction criteria used to reclaim memory.
+ */
+ public float getContractionCriteria() {
+ return contractionCriteria;
+ }
+
+ /**
+ * Returns the element at the specified index
+ *
+ * @param index index to fetch a value from
+ * @return value stored at the specified index
+ * @throws ArrayIndexOutOfBoundsException if index
is less than
+ * zero or is greater than getNumElements() - 1
.
+ */
+ public double getElement(int index) {
+ double value = Double.NaN;
+ if (index >= numElements) {
+ String msg =
+ "The index specified: " + index +
+ " is larger than the current number of elements";
+ throw new ArrayIndexOutOfBoundsException(msg);
+ } else if (index >= 0) {
+ value = internalArray[startIndex + index];
+ } else {
+ String msg =
+ "Elements cannot be retrieved from a negative array index";
+ throw new ArrayIndexOutOfBoundsException(msg);
+ }
+ return value;
+ }
+
+ /**
+ * Returns a double[] array containing the elements of this
+ * ResizableArray
. This method returns a copy, not a
+ * reference to the underlying array, so that changes made to the returned
+ * array have no effect on this ResizableArray.
+ */
+ public double[] getElements() {
+ double[] elementArray = new double[numElements];
+ System.arraycopy( internalArray, startIndex, elementArray, 0,
+ numElements);
+ return elementArray;
+ }
+
+ /**
+ * The expansion factor controls the size of a new aray when an array
+ * needs to be expanded. The expansionMode
+ * determines whether the size of the array is multiplied by the
+ * expansionFactor
(MULTIPLICATIVE_MODE) or if
+ * the expansion is additive (ADDITIVE_MODE -- expansionFactor
+ * storage locations added). The default expansionMode
is
+ * MULTIPLICATIVE_MODE and the default expansionFactor
+ * is 2.0.
+ *
+ * @return the expansion factor of this expandable double array
+ */
+ public float getExpansionFactor() {
+ return expansionFactor;
+ }
+
+ /**
+ * The expansionMode
determines whether the internal storage
+ * array grows additively (ADDITIVE_MODE) or multiplicatively
+ * (MULTIPLICATIVE_MODE) when it is expanded.
+ *
+ * @return Returns the expansionMode.
+ */
+ public int getExpansionMode() {
+ return expansionMode;
+ }
+
+ /**
+ * Notice the package scope on this method. This method is simply here
+ * for the JUnit test, it allows us check if the expansion is working
+ * properly after a number of expansions. This is not meant to be a part
+ * of the public interface of this class.
+ *
+ * @return the length of the internal storage array.
+ */
+ int getInternalLength() {
+ return (internalArray.length);
+ }
+
+ /**
+ * 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 int getNumElements() {
+ return (numElements);
+ }
+
+ /**
+ * Returns the internal storage array. Note that this method returns
+ * a reference to the internal storage array, not a copy, and to correctly
+ * address elements of the array, the startIndex
is
+ * required (available via the {@link #start} method). This method should
+ * only be used in cases where copying the internal array is not practical.
+ * The {@link #getElements} method should be used in all other cases.
+ *
+ *
+ * @return the internal storage array used by this object
+ */
+ public double[] getValues() {
+ return (internalArray);
+ }
+
+ /**
+ * Sets the contraction criteria for this ExpandContractDoubleArray.
+ *
+ * @param contractionCriteria contraction criteria
+ */
+ public void setContractionCriteria(float contractionCriteria) {
+ checkContractExpand(contractionCriteria, getExpansionFactor());
+ this.contractionCriteria = contractionCriteria;
+ }
+
+
+ /**
+ * Sets the element at the specified index. If the specified index is greater than
+ * getNumElements() - 1
, the numElements
property
+ * is increased to index +1
and additional storage is allocated
+ * (if necessary) for the new element and all (uninitialized) elements
+ * between the new element and the previous end of the array).
+ *
+ * @param index index to store a value in
+ * @param value value to store at the specified index
+ * @throws ArrayIndexOutOfBoundsException if index
is less than
+ * zero.
+ */
+ public synchronized void setElement(int index, double value) {
+ if (index < 0) {
+ String msg = "Cannot set an element at a negative index";
+ throw new ArrayIndexOutOfBoundsException(msg);
+ }
+ if (index + 1 > numElements) {
+ numElements = index + 1;
+ }
+ if ((startIndex + index) >= internalArray.length) {
+ expandTo(startIndex + (index + 1));
+ }
+ internalArray[startIndex + index] = value;
+ }
+
+ /**
+ * Sets the expansionFactor. Throws IllegalArgumentException if the
+ * the following conditions are not met:
+ *
+ * expansionFactor > 1
+ * contractionFactor >= expansionFactor
+ *
+ *
+ * @throws IllegalArgumentException if expansionFactor is <= 1 or greater
+ * than contractionFactor
+ */
+ public void setExpansionFactor(float expansionFactor) {
+ checkContractExpand(getContractionCriteria(), expansionFactor);
+ // The check above verifies that the expansion factor is > 1.0;
+ this.expansionFactor = expansionFactor;
+ }
+
+ /**
+ * Sets the expansionMode
. The specified value must be one of
+ * ADDITIVE_MODE, MULTIPLICATIVE_MODE.
+ *
+ * @param expansionMode The expansionMode to set.
+ * @throws IllegalArgumentException if the specified mode value is not valid
+ */
+ public void setExpansionMode(int expansionMode) {
+ if (expansionMode != MULTIPLICATIVE_MODE &&
+ expansionMode != ADDITIVE_MODE) {
+ throw new IllegalArgumentException("Illegal expansionMode setting.");
+ }
+ this.expansionMode = expansionMode;
+ }
+
+ /**
+ * Sets the initial capacity. Should only be invoked by constructors.
+ *
+ * @param initialCapacity of the array
+ * @throws IllegalArgumentException if initialCapacity
is not
+ * positive.
+ */
+ protected void setInitialCapacity(int initialCapacity) {
+ if (initialCapacity > 0) {
+ this.initialCapacity = initialCapacity;
+ } else {
+ String msg =
+ "The initial capacity supplied: " + initialCapacity +
+ "must be a positive integer";
+ throw new IllegalArgumentException(msg);
+ }
+ }
+
+ /**
+ * This function allows you to control the number of elements contained
+ * in this array, and can be used to "throw out" the last n values in an
+ * array. This function will also expand the internal array as needed.
+ *
+ * @param i a new number of elements
+ * @throws IllegalArgumentException if i
is negative.
+ */
+ public synchronized void setNumElements(int i) {
+
+ // If index is negative thrown an error
+ if (i < 0) {
+ String msg =
+ "Number of elements must be zero or a positive " + "integer";
+ throw new IllegalArgumentException(msg);
+ }
+
+ // Test the new num elements, check to see if the array needs to be
+ // expanded to accomodate this new number of elements
+ if ((startIndex + i) > internalArray.length) {
+ expandTo(startIndex + i);
+ }
+
+ // Set the new number of elements to new value
+ numElements = i;
+ }
+
+ /**
+ * Returns true if the internal storage array has too many unused
+ * storage positions.
+ *
+ * @return true if array satisfies the contraction criteria
+ */
+ private synchronized boolean shouldContract() {
+ if (expansionMode == MULTIPLICATIVE_MODE) {
+ return (internalArray.length / numElements) > contractionCriteria;
+ } else {
+ return (internalArray.length - numElements) > contractionCriteria;
+ }
+ }
+
+ /**
+ * Returns the starting index of the internal array. The starting index is
+ * the position of the first addressable element in the internal storage
+ * array. The addressable elements in the array are
+ * internalArray[startIndex],...,internalArray[startIndex + numElements -1]
+ *
+ *
+ * @return starting index
+ */
+ public int start() {
+ return startIndex;
+ }
+
+}
diff --git a/src/test/org/apache/commons/math/util/ContractableDoubleArrayTest.java b/src/test/org/apache/commons/math/util/ContractableDoubleArrayTest.java
deleted file mode 100644
index daf4f0e99..000000000
--- a/src/test/org/apache/commons/math/util/ContractableDoubleArrayTest.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2003-2004 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.math.util;
-
-
-/**
- * This class contains test cases for the ExpandableDoubleArray.
- *
- * @version $Revision: 1.9 $ $Date: 2004/05/04 13:15:47 $
- */
-public class ContractableDoubleArrayTest extends ExpandableDoubleArrayTest {
-
- public ContractableDoubleArrayTest(String name) {
- super( name );
- }
-
- /* (non-Javadoc)
- * @see junit.framework.TestCase#setUp()
- */
- protected void setUp() throws Exception {
- da = new ContractableDoubleArray();
- ra = new ContractableDoubleArray();
- }
-
- protected ExpandableDoubleArray newInstance(int initialCapacity) {
- return new ContractableDoubleArray(initialCapacity);
- }
-
- protected ExpandableDoubleArray newInstance() {
- return new ContractableDoubleArray();
- }
-
- protected ExpandableDoubleArray newInstance(int initialCapacity, float expansionFactor) {
- if (expansionFactor < 2.5f) {
- return new ContractableDoubleArray(initialCapacity, expansionFactor);
- } else {
- return newInstance(initialCapacity, expansionFactor, expansionFactor + 1.0f);
- }
- }
-
- protected ExpandableDoubleArray newInstance(int initialCapacity, float expansionFactor, float contractionFactor) {
- return new ContractableDoubleArray(initialCapacity, expansionFactor, contractionFactor);
- }
-}
diff --git a/src/test/org/apache/commons/math/util/ExpandableDoubleArrayTest.java b/src/test/org/apache/commons/math/util/ExpandableDoubleArrayTest.java
deleted file mode 100644
index 39bd1e09e..000000000
--- a/src/test/org/apache/commons/math/util/ExpandableDoubleArrayTest.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Copyright 2003-2004 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.math.util;
-
-
-/**
- * This class contains test cases for the ExpandableDoubleArray.
- *
- * @version $Revision: 1.10 $ $Date: 2004/05/04 13:15:47 $
- */
-public class ExpandableDoubleArrayTest extends DoubleArrayAbstractTest {
-
- public ExpandableDoubleArrayTest(String name) {
- super( name );
- }
-
- /* (non-Javadoc)
- * @see junit.framework.TestCase#setUp()
- */
- protected void setUp() throws Exception {
- da = newInstance();
- ra = newInstance();
- }
-
- /* (non-Javadoc)
- * @see junit.framework.TestCase#tearDown()
- */
- 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 " +
- "16 and an expansion factor of 2.0",
- 1024, ((ExpandableDoubleArray) da).getInternalLength());
- }
-
- public void testAddElementRolling() {
- super.testAddElementRolling();
- }
-
- 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 */
-
- public void testWithInitialCapacity() {
-
- ExpandableDoubleArray eDA2 = newInstance(2);
- assertEquals("Initial number of elements should be 0", 0, eDA2.getNumElements());
-
- int iterations = (int) Math.pow(2.0, 15.0);
-
- for( int i = 0; i < iterations; i++) {
- eDA2.addElement( i );
- }
-
- assertEquals("Number of elements should be equal to 2^15", (int) Math.pow(2.0, 15.0), eDA2.getNumElements());
-
- 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() );
- }
-
- public void testWithInitialCapacityAndExpansionFactor() {
-
- ExpandableDoubleArray eDA3 = newInstance(3, 3.0f);
- assertEquals("Initial number of elements should be 0", 0, eDA3.getNumElements() );
-
- int iterations = (int) Math.pow(3.0, 7.0);
-
- for( int i = 0; i < iterations; i++) {
- eDA3.addElement( i );
- }
-
- assertEquals("Number of elements should be equal to 3^7", (int) Math.pow(3.0, 7.0), eDA3.getNumElements());
-
- 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("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());
-
- ((ExpandableDoubleArray)da).discardFrontElements(5);
- assertEquals( "Number of elements should be 6", 6, da.getNumElements());
-
- try {
- ((ExpandableDoubleArray)da).discardFrontElements(-1);
- fail( "Trying to discard a negative number of element is not allowed");
- } catch( Exception e ){
- }
-
- try {
- ((ExpandableDoubleArray)da).discardFrontElements( 10000 );
- fail( "You can't discard more elements than the array contains");
- } catch( Exception e ){
- }
-
- }
-
- /** TEST ERROR CONDITIONS **/
-
- public void testIllegalInitialCapacity() {
- try {
- ExpandableDoubleArray eDA = newInstance(-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 {
- ExpandableDoubleArray eDA = newInstance(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 {
- ExpandableDoubleArray eDA = newInstance(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 {
- ExpandableDoubleArray eDA = newInstance(3, 0.0f);
- fail( "That constructor should have thrown an IllegalArgumentException because " +
- "the expansionFactor for 0.0");
- } catch( IllegalArgumentException iae) {
- }
-
- try {
- ExpandableDoubleArray eDA = newInstance(3, -4.35f);
- fail( "That constructor should have thrown an IllegalArgumentException because " +
- "the expansionFactor for -4.35");
- } catch( IllegalArgumentException iae) {
- }
- }
-
- 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 ){
- }
- }
-
- protected ExpandableDoubleArray newInstance(int initialCapacity) {
- return new ExpandableDoubleArray(initialCapacity);
- }
-
- protected ExpandableDoubleArray newInstance() {
- return new ExpandableDoubleArray();
- }
-
- protected ExpandableDoubleArray newInstance(int initialCapacity, float expansionFactor) {
- return new ExpandableDoubleArray(initialCapacity, expansionFactor);
- }
-}
diff --git a/src/test/org/apache/commons/math/util/FixedDoubleArrayTest.java b/src/test/org/apache/commons/math/util/FixedDoubleArrayTest.java
deleted file mode 100644
index 4917a854b..000000000
--- a/src/test/org/apache/commons/math/util/FixedDoubleArrayTest.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright 2003-2004 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.math.util;
-
-
-/**
- * This class contains test cases for the ExpandableDoubleArray.
- *
- * @version $Revision: 1.10 $ $Date: 2004/02/21 21:35:18 $
- */
-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).getValues().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() );
-
- }
-
-
-}
diff --git a/src/test/org/apache/commons/math/util/ResizableDoubleArrayTest.java b/src/test/org/apache/commons/math/util/ResizableDoubleArrayTest.java
new file mode 100644
index 000000000..8d9737580
--- /dev/null
+++ b/src/test/org/apache/commons/math/util/ResizableDoubleArrayTest.java
@@ -0,0 +1,351 @@
+/*
+ * Copyright 2003-2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math.util;
+import org.apache.commons.math.random.RandomDataImpl;
+import org.apache.commons.math.random.RandomData;
+
+
+/**
+ * This class contains test cases for the ResizableDoubleArray.
+ *
+ * @version $Revision: 1.1 $ $Date: 2004/06/14 21:41:33 $
+ */
+public class ResizableDoubleArrayTest extends DoubleArrayAbstractTest {
+
+ public ResizableDoubleArrayTest(String name) {
+ super( name );
+ }
+
+ protected void tearDown() throws Exception {
+ da = null;
+ ra = null;
+ }
+
+ protected void setUp() throws Exception {
+ da = new ResizableDoubleArray();
+ ra = new ResizableDoubleArray();
+ }
+
+ public void testConstructors() {
+ float defaultExpansionFactor = 2.0f;
+ float defaultContractionCriteria = 2.5f;
+ int defaultMode = ResizableDoubleArray.MULTIPLICATIVE_MODE;
+
+ ResizableDoubleArray testDa = new ResizableDoubleArray(2);
+ assertEquals(0, testDa.getNumElements());
+ assertEquals(2, testDa.getInternalLength());
+ assertEquals(defaultExpansionFactor, testDa.getExpansionFactor(), 0);
+ assertEquals(defaultContractionCriteria, testDa.getContractionCriteria(), 0);
+ assertEquals(defaultMode, testDa.getExpansionMode());
+ try {
+ da = new ResizableDoubleArray(-1);
+ fail("Expecting IllegalArgumentException");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+
+ testDa = new ResizableDoubleArray(2, 2.0f);
+ assertEquals(0, testDa.getNumElements());
+ assertEquals(2, testDa.getInternalLength());
+ assertEquals(defaultExpansionFactor, testDa.getExpansionFactor(), 0);
+ assertEquals(defaultContractionCriteria, testDa.getContractionCriteria(), 0);
+ assertEquals(defaultMode, testDa.getExpansionMode());
+
+ try {
+ da = new ResizableDoubleArray(2, 0.5f);
+ fail("Expecting IllegalArgumentException");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+
+ testDa = new ResizableDoubleArray(2, 3.0f);
+ assertEquals(3.0f, testDa.getExpansionFactor(), 0);
+ assertEquals(3.5f, testDa.getContractionCriteria(), 0);
+
+ testDa = new ResizableDoubleArray(2, 2.0f, 3.0f);
+ assertEquals(0, testDa.getNumElements());
+ assertEquals(2, testDa.getInternalLength());
+ assertEquals(defaultExpansionFactor, testDa.getExpansionFactor(), 0);
+ assertEquals(3.0f, testDa.getContractionCriteria(), 0);
+ assertEquals(defaultMode, testDa.getExpansionMode());
+
+ try {
+ da = new ResizableDoubleArray(2, 2.0f, 1.5f);
+ fail("Expecting IllegalArgumentException");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+
+ testDa = new ResizableDoubleArray(2, 2.0f, 3.0f,
+ ResizableDoubleArray.ADDITIVE_MODE);
+ assertEquals(0, testDa.getNumElements());
+ assertEquals(2, testDa.getInternalLength());
+ assertEquals(defaultExpansionFactor, testDa.getExpansionFactor(), 0);
+ assertEquals(3.0f, testDa.getContractionCriteria(), 0);
+ assertEquals(ResizableDoubleArray.ADDITIVE_MODE,
+ testDa.getExpansionMode());
+
+ try {
+ da = new ResizableDoubleArray(2, 2.0f, 2.5f, -1);
+ fail("Expecting IllegalArgumentException");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+
+ }
+
+
+ public void testSetElementArbitraryExpansion() {
+
+ // MULTIPLICATIVE_MODE
+ 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);
+
+ // Make sure numElements and expansion work correctly for expansion boundary cases
+ da.clear();
+ da.addElement(2.0);
+ da.addElement(4.0);
+ da.addElement(6.0);
+ assertEquals(4, ((ResizableDoubleArray) da).getInternalLength());
+ assertEquals(3, da.getNumElements());
+ da.setElement(3, 7.0);
+ assertEquals(4, ((ResizableDoubleArray) da).getInternalLength());
+ assertEquals(4, da.getNumElements());
+ da.setElement(10, 10.0);
+ assertEquals(11, ((ResizableDoubleArray) da).getInternalLength());
+ assertEquals(11, da.getNumElements());
+ da.setElement(9, 10.0);
+ assertEquals(11, ((ResizableDoubleArray) da).getInternalLength());
+ assertEquals(11, da.getNumElements());
+
+ try {
+ da.setElement(-2, 3);
+ fail("Expecting ArrayIndexOutOfBoundsException for negative index");
+ } catch (ArrayIndexOutOfBoundsException ex) {
+ // expected
+ }
+
+ // ADDITIVE_MODE
+
+ ResizableDoubleArray testDa = new ResizableDoubleArray(2, 2.0f, 3.0f,
+ ResizableDoubleArray.ADDITIVE_MODE);
+ assertEquals(2, testDa.getInternalLength());
+ testDa.addElement(1d);
+ testDa.addElement(1d);
+ assertEquals(2, testDa.getInternalLength());
+ testDa.addElement(1d);
+ assertEquals(4, testDa.getInternalLength());
+ }
+
+ 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, ((ResizableDoubleArray) da).getInternalLength());
+ }
+
+ public void testAddElementRolling() {
+ super.testAddElementRolling();
+
+ // MULTIPLICATIVE_MODE
+ da.clear();
+ da.addElement(1);
+ da.addElement(2);
+ da.addElementRolling(3);
+ assertEquals(3, da.getElement(1), 0);
+ da.addElementRolling(4);
+ assertEquals(3, da.getElement(0), 0);
+ assertEquals(4, da.getElement(1), 0);
+ da.addElement(5);
+ assertEquals(5, da.getElement(2), 0);
+ da.addElementRolling(6);
+ assertEquals(4, da.getElement(0), 0);
+ assertEquals(5, da.getElement(1), 0);
+ assertEquals(6, da.getElement(2), 0);
+
+ // ADDITIVE_MODE (x's are occupied storage locations, 0's are open)
+ ResizableDoubleArray testDa = new ResizableDoubleArray(2, 2.0f, 2.5f,
+ ResizableDoubleArray.ADDITIVE_MODE);
+ assertEquals(2, testDa.getInternalLength());
+ testDa.addElement(1d); // x,0
+ testDa.addElement(2d); // x,x
+ testDa.addElement(3d); // x,x,x,0 -- expanded
+ assertEquals(1d, testDa.getElement(0), 0);
+ assertEquals(2d, testDa.getElement(1), 0);
+ assertEquals(3d, testDa.getElement(2), 0);
+ assertEquals(4, testDa.getInternalLength()); // x,x,x,0
+ assertEquals(3, testDa.getNumElements());
+ testDa.addElementRolling(4d);
+ assertEquals(2d, testDa.getElement(0), 0);
+ assertEquals(3d, testDa.getElement(1), 0);
+ assertEquals(4d, testDa.getElement(2), 0);
+ assertEquals(4, testDa.getInternalLength()); // 0,x,x,x
+ assertEquals(3, testDa.getNumElements());
+ testDa.addElementRolling(5d); // 0,0,x,x,x,0 -- time to contract
+ assertEquals(3d, testDa.getElement(0), 0);
+ assertEquals(4d, testDa.getElement(1), 0);
+ assertEquals(5d, testDa.getElement(2), 0);
+ assertEquals(4, testDa.getInternalLength()); // contracted -- x,x,x,0
+ assertEquals(3, testDa.getNumElements());
+ try {
+ testDa.getElement(4);
+ fail("Expecting ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException ex) {
+ // expected
+ }
+ try {
+ testDa.getElement(-1);
+ fail("Expecting ArrayIndexOutOfBoundsException");
+ } catch (ArrayIndexOutOfBoundsException ex) {
+ // expected
+ }
+ }
+
+ 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);
+
+ ((ResizableDoubleArray) da).setNumElements( 3 );
+ assertEquals( "Number of elements should equal 3", da.getNumElements(), 3);
+
+ try {
+ ((ResizableDoubleArray) da).setNumElements( -3 );
+ fail( "Setting number of elements to negative should've thrown an exception");
+ } catch( IllegalArgumentException iae ) {
+ }
+
+ ((ResizableDoubleArray) 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 testWithInitialCapacity() {
+
+ ResizableDoubleArray eDA2 = new ResizableDoubleArray(2);
+ assertEquals("Initial number of elements should be 0", 0, eDA2.getNumElements());
+
+ RandomData randomData = new RandomDataImpl();
+ int iterations = randomData.nextInt(100, 1000);
+
+ for( int i = 0; i < iterations; i++) {
+ eDA2.addElement( i );
+ }
+
+ assertEquals("Number of elements should be equal to " + iterations, iterations, eDA2.getNumElements());
+
+ eDA2.addElement( 2.0 );
+
+ assertEquals("Number of elements should be equals to " + (iterations +1),
+ iterations + 1 , eDA2.getNumElements() );
+ }
+
+ public void testWithInitialCapacityAndExpansionFactor() {
+
+ ResizableDoubleArray eDA3 = new ResizableDoubleArray(3, 3.0f, 3.5f);
+ assertEquals("Initial number of elements should be 0", 0, eDA3.getNumElements() );
+
+ RandomData randomData = new RandomDataImpl();
+ int iterations = randomData.nextInt(100, 3000);
+
+ for( int i = 0; i < iterations; i++) {
+ eDA3.addElement( i );
+ }
+
+ assertEquals("Number of elements should be equal to " + iterations, iterations,eDA3.getNumElements());
+
+ eDA3.addElement( 2.0 );
+
+ assertEquals("Number of elements should be equals to " + (iterations +1),
+ iterations +1, eDA3.getNumElements() );
+
+ 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());
+
+ ((ResizableDoubleArray)da).discardFrontElements(5);
+ assertEquals( "Number of elements should be 6", 6, da.getNumElements());
+
+ try {
+ ((ResizableDoubleArray)da).discardFrontElements(-1);
+ fail( "Trying to discard a negative number of element is not allowed");
+ } catch( Exception e ){
+ }
+
+ try {
+ ((ResizableDoubleArray)da).discardFrontElements( 10000 );
+ fail( "You can't discard more elements than the array contains");
+ } catch( Exception e ){
+ }
+ }
+
+ public void testMutators() {
+ ((ResizableDoubleArray)da).setContractionCriteria(10f);
+ assertEquals(10f, ((ResizableDoubleArray)da).getContractionCriteria(), 0);
+ ((ResizableDoubleArray)da).setExpansionFactor(8f);
+ assertEquals(8f, ((ResizableDoubleArray)da).getExpansionFactor(), 0);
+ try {
+ ((ResizableDoubleArray)da).setExpansionFactor(11f); // greater than contractionCriteria
+ fail("Expecting IllegalArgumentException");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+ ((ResizableDoubleArray)da).setExpansionMode(
+ ResizableDoubleArray.ADDITIVE_MODE);
+ assertEquals(ResizableDoubleArray.ADDITIVE_MODE,
+ ((ResizableDoubleArray)da).getExpansionMode());
+ try {
+ ((ResizableDoubleArray)da).setExpansionMode(-1);
+ fail ("Expecting IllegalArgumentException");
+ } catch (IllegalArgumentException ex) {
+ // expected
+ }
+ }
+}