Added javadoc to FixedDA and altered exceptions in DoubleArray

* One should be able to use a DoubleArray in a similar way to a
regular double[], to this effect methods for accessing element
values will no longer throw NoSuchElementExceptions when an
index is outside of the element set.  These method all throw
ArrayIndexOutOfBoundException if a bad index is supplied.

* Filled out javadoc in FixedDoubleArray.


git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/math/trunk@140845 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Tim O'Brien 2003-05-21 05:48:25 +00:00
parent 7d540cfa99
commit 5d9efdbcd4
3 changed files with 192 additions and 36 deletions

View File

@ -56,8 +56,11 @@ package org.apache.commons.math;
import java.util.NoSuchElementException;
/**
* Provides an interface to implemntations which function as an array
* of double primitives.
* 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
* such as automatic expansion, contraction, and array "rolling".
*
* @author <a href="mailto:tobrien@apache.org">Tim O'Brien</a>
*/
@ -70,19 +73,16 @@ public interface DoubleArray {
*/
int getNumElements();
//TODO: Throwing a NoSuchElementException might not be the right
//thing to do, it may be more helpful to just throw ArrayOutOfBounds...
/**
* Returns the element at the specified index
* Returns the element at the specified index. Note that if an
* out of bounds index is supplied a ArrayIndexOutOfBoundsException
* will be thrown.
*
* @param index index to fetch a value from
* @return value stored at the specified index
* @throws NoSuchElementException exception thrown if the array index
* exceeds the known boundaries of this array.
*
*/
double getElement(int index) throws NoSuchElementException;
double getElement(int index);
/**
* Sets the element at the specified index. This method will expand the

View File

@ -54,7 +54,7 @@
package org.apache.commons.math;
import java.io.Serializable;
import java.util.NoSuchElementException;
/**
* An array of double primitives which can expand as needed.
@ -137,7 +137,7 @@ public class ExpandableDoubleArray implements Serializable, DoubleArray {
// 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 ArrayOutOfBound exceptions.
// will lead to ArrayIndexOutOfBound exceptions.
if (expansionFactor > 1.0) {
this.expansionFactor = expansionFactor;
} else {
@ -214,18 +214,18 @@ public class ExpandableDoubleArray implements Serializable, DoubleArray {
* @param index index to fetch a value from
* @return value stored at the specified index
*/
public double getElement(int index) throws NoSuchElementException {
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 NoSuchElementException(msg);
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 IllegalArgumentException(msg);
throw new ArrayIndexOutOfBoundsException(msg);
}
return value;
}
@ -242,7 +242,7 @@ public class ExpandableDoubleArray implements Serializable, DoubleArray {
if (index < 0) {
String msg = "Cannot set an element at a negative index";
throw new IllegalArgumentException(msg);
throw new ArrayIndexOutOfBoundsException(msg);
}
if ((startIndex + index) >= internalArray.length) {

View File

@ -53,50 +53,128 @@
*/
package org.apache.commons.math;
import java.util.NoSuchElementException;
/**
* Provides a fixed size implementation of the DoubleArray with
* support to true "rolling" functionality. If a program attempts to add
* a value to a fixed array which has reach a maximum number of
* elements a ArrayIndexOutOfBoundsException will be thrown.
* <p>
* 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.
* </p>
*
* <p>
* 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.
* </p>
*
* <p>
* 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.
* </p>
*
* @author <a href="mailto:tobrien@apache.org">Tim O'Brien</a>
*/
public class FixedDoubleArray implements DoubleArray {
// This is the internal storage array. This array is assigned
// a known fixed size in the constructor.
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.
int size = 0;
// This index points to the location of the next update. Next
// add, cycles from 0 to (maxElement-1)
int nextAdd = 0;
// The maximum number of elements in the FixedDoubleArray
int maxElements = 0;
/**
* Create a fixed array for double primitives which can hold up to
* <code>maxElements</codec> 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];
}
/* (non-Javadoc)
/**
* Retrieves the current size of the array.
* @see org.apache.commons.math.DoubleArray#getNumElements()
*/
public int getNumElements() {
return size;
}
/* (non-Javadoc)
/**
* 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.DoubleArray#getElement(int)
*/
public double getElement(int index) throws NoSuchElementException {
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];
}
}
/* (non-Javadoc)
/**
* <p>
* Sets the element at the specified index to the value supplied.
* </p>
*
* <p>Implementation Notes:
* <ul>
* 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.
* </ul>
* <ul>
* 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.
* </ul>
* </p>
*
* @see org.apache.commons.math.DoubleArray#setElement(int, double)
*/
public void setElement(int index, double value) {
@ -109,7 +187,11 @@ public class FixedDoubleArray implements DoubleArray {
}
}
/* (non-Javadoc)
/**
* 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.DoubleArray#addElement(double)
*/
public void addElement(double value) {
@ -118,28 +200,72 @@ public class FixedDoubleArray implements DoubleArray {
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);
}
}
}
/* (non-Javadoc)
/**
* <p>
* Adds an element by "rolling" the new value into the current array
* while discarding the element which was added <code>maxElement</code>
* 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.
* </p>
*
* <p>
* <b>Note:</b> This function will return <code>Double.NaN</code> 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.
* </p>
*
* @return Returns the value which a has been "removed" from the
* database. <b>Important:</b> 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 <code>Double.NaN</code> value.
*
* @see org.apache.commons.math.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.
double discarded = internalArray[nextAdd];
// Obtain the value discarded by this overwrite
discarded = internalArray[nextAdd];
}
internalArray[nextAdd] = value;
// nextAdd cycles between 0 and (maxElements-1).
nextAdd++;
nextAdd = nextAdd % maxElements;
@ -147,16 +273,27 @@ public class FixedDoubleArray implements DoubleArray {
return (discarded);
}
/* (non-Javadoc)
/**
* 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.DoubleArray#getElements()
*/
public double[] getElements() {
double[] copy = new double[internalArray.length];
System.arraycopy(internalArray, 0, copy, 0, internalArray.length);
double[] copy = new double[size];
System.arraycopy(internalArray, 0, copy, 0, size);
return copy;
}
/* (non-Javadoc)
/**
* 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.DoubleArray#clear()
*/
public void clear() {
@ -165,7 +302,18 @@ public class FixedDoubleArray implements DoubleArray {
internalArray = new double[maxElements];
}
/* (non-Javadoc)
/**
* This method is not implemented in this implemetnation of
* DoubleArray. Until the size of the element array meets the
* maxElements condition introduced in the constructor this is
* a regular array. When the size of the array is at a maximum
* this array starts to function more as a circular list of
* double primitives. In a circular "rolling" data structure it
* make little sense to allow people to "drop" objects from the
* "front".
*
* @param number of elements to discard.
*
* @see org.apache.commons.math.DoubleArray#discardFrontElements(int)
*/
public void discardFrontElements(int i) {
@ -176,7 +324,11 @@ public class FixedDoubleArray implements DoubleArray {
throw new RuntimeException(msg);
}
/* (non-Javadoc)
/**
* Retrieves the minimum double value contained in this array.
*
* @return The number less than all other numbers in this
* array.
* @see org.apache.commons.math.DoubleArray#getMin()
*/
public double getMin() {
@ -189,7 +341,11 @@ public class FixedDoubleArray implements DoubleArray {
return min;
}
/* (non-Javadoc)
/**
* Retrieves the maximum double value contained in this array.
*
* @return The number greater than all other numbers in this
* array.
* @see org.apache.commons.math.DoubleArray#getMax()
*/
public double getMax() {