You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by to...@apache.org on 2003/05/21 07:48:25 UTC

cvs commit: jakarta-commons-sandbox/math/src/java/org/apache/commons/math DoubleArray.java ExpandableDoubleArray.java FixedDoubleArray.java

tobrien     2003/05/20 22:48:25

  Modified:    math/src/java/org/apache/commons/math DoubleArray.java
                        ExpandableDoubleArray.java FixedDoubleArray.java
  Log:
  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.
  
  Revision  Changes    Path
  1.4       +9 -9      jakarta-commons-sandbox/math/src/java/org/apache/commons/math/DoubleArray.java
  
  Index: DoubleArray.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/math/src/java/org/apache/commons/math/DoubleArray.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- DoubleArray.java	20 May 2003 18:15:29 -0000	1.3
  +++ DoubleArray.java	21 May 2003 05:48:25 -0000	1.4
  @@ -56,8 +56,11 @@
   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 @@
        */
       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 
  
  
  
  1.9       +6 -6      jakarta-commons-sandbox/math/src/java/org/apache/commons/math/ExpandableDoubleArray.java
  
  Index: ExpandableDoubleArray.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/math/src/java/org/apache/commons/math/ExpandableDoubleArray.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- ExpandableDoubleArray.java	20 May 2003 18:15:29 -0000	1.8
  +++ ExpandableDoubleArray.java	21 May 2003 05:48:25 -0000	1.9
  @@ -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 @@
   
           // 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 @@
        * @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 @@
   		
   		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) {
  
  
  
  1.3       +178 -22   jakarta-commons-sandbox/math/src/java/org/apache/commons/math/FixedDoubleArray.java
  
  Index: FixedDoubleArray.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/math/src/java/org/apache/commons/math/FixedDoubleArray.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- FixedDoubleArray.java	20 May 2003 18:15:29 -0000	1.2
  +++ FixedDoubleArray.java	21 May 2003 05:48:25 -0000	1.3
  @@ -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 @@
           }
       }
   
  -    /* (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 @@
   
               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++;
  -        } 
  -
  -        double discarded = internalArray[nextAdd];
  +        } 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;	
   
  @@ -147,16 +273,27 @@
           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 @@
           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 @@
           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 @@
           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() {
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org