Author: psteitz
Date: Sat Nov 22 10:41:40 2008
New Revision: 719894

URL: http://svn.apache.org/viewvc?rev=719894&view=rev
Log:
Added the following methods to ResizableDoubleArray to support MATH-212 
changes to stats classes:
copy constructor
static copy(-,-)
instance copy()
equals and hashcode

JIRA: MATH-212

Modified:
    
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/util/ResizableDoubleArray.java
    
commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/util/ResizableDoubleArrayTest.java

Modified: 
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/util/ResizableDoubleArray.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/util/ResizableDoubleArray.java?rev=719894&r1=719893&r2=719894&view=diff
==============================================================================
--- 
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/util/ResizableDoubleArray.java
 (original)
+++ 
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/util/ResizableDoubleArray.java
 Sat Nov 22 10:41:40 2008
@@ -17,6 +17,7 @@
 package org.apache.commons.math.util;
 
 import java.io.Serializable;
+import java.util.Arrays;
 
 import org.apache.commons.math.MathRuntimeException;
 
@@ -243,6 +244,18 @@
         setExpansionMode(expansionMode);
         internalArray = new double[initialCapacity];
     }
+    
+    /**
+     * Copy constructor.  Creates a new ResizableDoubleArray that is a deep,
+     * fresh copy of the original. Needs to acquire synchronization lock
+     * on original.  Original may not be null; otherwise a NullPointerException
+     * is thrown.
+     * 
+     * @param original
+     */
+    public ResizableDoubleArray(ResizableDoubleArray original) {
+        copy(original, this);
+    }
 
     /**
      * Adds an element to the end of this expandable array.
@@ -294,27 +307,28 @@
         }
         return discarded;
     }
-
+       
     public synchronized double substituteMostRecentElement(double value) {
         if (numElements < 1) {
-               throw 
MathRuntimeException.createArrayIndexOutOfBoundsException("cannot substitute an 
element from an empty array",
-                                                                               
null);
+            throw MathRuntimeException.createArrayIndexOutOfBoundsException(
+                    "cannot substitute an element from an empty array", null);
         }
 
         double discarded = internalArray[startIndex + (numElements - 1)];
 
-       internalArray[startIndex + (numElements - 1)] = value;
+        internalArray[startIndex + (numElements - 1)] = value;
 
-       return discarded;
+        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
+     * @param contractionCritera criteria to be checked
      * @throws IllegalArgumentException if the contractionCriteria is less than
      *         the expansionCriteria.
      */
@@ -386,8 +400,8 @@
      */
     public synchronized void discardFrontElements(int i) {
 
-       discardExtremeElements(i,true);
-       
+        discardExtremeElements(i,true);
+        
     }
 
     /**
@@ -402,10 +416,10 @@
      */
     public synchronized void discardMostRecentElements(int i) {
 
-       discardExtremeElements(i,false);
-       
+        discardExtremeElements(i,false);
+        
     }
-
+    
     /**
      * Discards the <code>i<code> first or last elements of the array,
      * depending on the value of <code>front</code>.
@@ -453,7 +467,7 @@
      */
     protected synchronized void expand() {
 
-        // notice the use of Math.ceil(), this gaurantees that we will always 
+        // notice the use of Math.ceil(), this guarantees 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 
@@ -534,7 +548,7 @@
     }
     
     /**
-     * The expansion factor controls the size of a new aray when an array 
+     * The expansion factor controls the size of a new array when an array 
      * needs to be expanded.  The <code>expansionMode</code>
      * determines whether the size of the array is multiplied by the 
      * <code>expansionFactor</code> (MULTIPLICATIVE_MODE) or if 
@@ -704,7 +718,7 @@
         }
 
         // Test the new num elements, check to see if the array needs to be 
-        // expanded to accomodate this new number of elements
+        // expanded to accommodate this new number of elements
         if ((startIndex + i) > internalArray.length) {
             expandTo(startIndex + i);
         }
@@ -739,5 +753,94 @@
     public synchronized int start() {
         return startIndex;
     }
-
+    
+    /**
+     * <p>Copies source to dest, copying the underlying data, so dest is
+     * a new, independent copy of source.  Does not contract before
+     * the copy.</p>
+     * 
+     * <p>Obtains synchronization locks on both source and dest
+     * (in that order) before performing the copy.</p>
+     * 
+     * <p>Neither source nor dest may be null; otherwise a NullPointerException
+     * is thrown</p>
+     * 
+     */
+    public static void copy(ResizableDoubleArray source, ResizableDoubleArray 
dest) {
+       synchronized(source) {
+           synchronized(dest) {
+               dest.initialCapacity = source.initialCapacity;
+               dest.contractionCriteria = source.contractionCriteria;
+               dest.expansionFactor = source.expansionFactor;
+               dest.expansionMode = source.expansionMode;
+               dest.internalArray = new double[source.internalArray.length];
+               System.arraycopy(source.internalArray, 0, dest.internalArray,
+                       0, dest.internalArray.length);
+               dest.numElements = source.numElements;
+               dest.startIndex = source.startIndex;
+           }
+       }
+    }
+    
+    /**
+     * Returns a copy of the ResizableDoubleArray.  Does not contract before
+     * the copy, so the returned object is an exact copy of this.
+     * 
+     * @return a new ResizableDoubleArray with the same data and configuration
+     * properties as this
+     */
+    public synchronized ResizableDoubleArray copy() {
+        ResizableDoubleArray result = new ResizableDoubleArray();
+        copy(this, result);
+        return result;
+    }
+    
+    /**
+     * Returns true iff object is a ResizableDoubleArray with the same 
properties
+     * as this and an identical internal storage array.
+     * 
+     * @param object object to be compared for equality with this
+     * @return true iff object is a ResizableDoubleArray with the same data and
+     * properties as this
+     *
+     */
+    public boolean equals(Object object) {
+        if (object == this ) {
+            return true;
+        }
+       if (object instanceof ResizableDoubleArray == false) {
+            return false;
+        }
+       boolean result = true;
+       ResizableDoubleArray other = (ResizableDoubleArray) object;
+       result = result && (other.initialCapacity == initialCapacity);
+       result = result && (other.contractionCriteria == contractionCriteria);
+       result = result && (other.expansionFactor == expansionFactor);
+       result = result && (other.expansionMode == expansionMode);
+       result = result && (other.numElements == numElements);
+       result = result && (other.startIndex == startIndex);
+       if (!result) { 
+           return false;
+       } else {
+           return Arrays.equals(internalArray, other.internalArray);
+       }
+    }
+    
+    /**
+     * Returns a hash code consistent with equals.
+     * 
+     * @return hash code representing this ResizableDoubleArray
+     */
+    public int hashCode() {
+        int[] hashData = new int[7];
+        hashData[0] = Arrays.hashCode(internalArray);
+        hashData[1] = new Float(expansionFactor).hashCode();
+        hashData[2] = new Float(contractionCriteria).hashCode();
+        hashData[3] = initialCapacity;
+        hashData[4] = expansionMode;
+        hashData[5] = numElements;
+        hashData[6] = startIndex;
+        return Arrays.hashCode(hashData);
+    }
+         
 }

Modified: 
commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/util/ResizableDoubleArrayTest.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/util/ResizableDoubleArrayTest.java?rev=719894&r1=719893&r2=719894&view=diff
==============================================================================
--- 
commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/util/ResizableDoubleArrayTest.java
 (original)
+++ 
commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/util/ResizableDoubleArrayTest.java
 Sat Nov 22 10:41:40 2008
@@ -106,6 +106,14 @@
             // expected
         }
         
+        // Copy constructor
+        testDa = new ResizableDoubleArray(2, 2.0f, 3.0f, 
+                ResizableDoubleArray.ADDITIVE_MODE);
+        testDa.addElement(2.0);
+        testDa.addElement(3.2);
+        ResizableDoubleArray copyDa = new ResizableDoubleArray(testDa);
+        assertEquals(copyDa, testDa);
+        assertEquals(testDa, copyDa);   
     }
     
     
@@ -402,4 +410,93 @@
             // expected
         }
     }
+    
+    public void testEqualsAndHashCode() throws Exception {
+        
+        // Wrong type
+        ResizableDoubleArray first = new ResizableDoubleArray();
+        Double other = new Double(2);
+        assertFalse(first.equals(other));
+        
+        // Null
+        other = null;
+        assertFalse(first.equals(other));
+        
+        // Reflexive
+        assertTrue(first.equals(first));
+        
+        // Argumentless constructor
+        ResizableDoubleArray second = new ResizableDoubleArray();
+        verifyEquality(first, second);
+        
+        // Equals iff same data, same properties
+        ResizableDoubleArray third = new ResizableDoubleArray(3, 2.0f, 2.0f);
+        verifyInequality(third, first);
+        ResizableDoubleArray fourth = new ResizableDoubleArray(3, 2.0f, 2.0f);
+        ResizableDoubleArray fifth = new ResizableDoubleArray(2, 2.0f, 2.0f);
+        verifyEquality(third, fourth);
+        verifyInequality(third, fifth);
+        third.addElement(4.1);
+        third.addElement(4.2);
+        third.addElement(4.3);
+        fourth.addElement(4.1);
+        fourth.addElement(4.2);
+        fourth.addElement(4.3);
+        verifyEquality(third, fourth);
+        
+        // expand
+        fourth.addElement(4.4);
+        verifyInequality(third, fourth);
+        third.addElement(4.4);
+        verifyEquality(third, fourth);
+        fourth.addElement(4.4);
+        verifyInequality(third, fourth);
+        third.addElement(4.4);
+        verifyEquality(third, fourth);
+        fourth.addElementRolling(4.5);
+        third.addElementRolling(4.5);
+        verifyEquality(third, fourth);
+        
+        // discard
+        third.discardFrontElements(1);
+        verifyInequality(third, fourth);
+        fourth.discardFrontElements(1);
+        verifyEquality(third, fourth);
+        
+        // discard recent
+        third.discardMostRecentElements(2);
+        fourth.discardMostRecentElements(2);
+        verifyEquality(third, fourth);
+        
+        // wrong order
+        third.addElement(18);
+        fourth.addElement(17);
+        third.addElement(17);
+        fourth.addElement(18);
+        verifyInequality(third, fourth);
+        
+        // copy
+        ResizableDoubleArray.copy(fourth, fifth);
+        verifyEquality(fourth, fifth);
+        
+        // Copy constructor
+        verifyEquality(fourth, new ResizableDoubleArray(fourth));
+        
+        // Instance copy
+        verifyEquality(fourth, fourth.copy());   
+             
+    }
+    
+    private void verifyEquality(ResizableDoubleArray a, ResizableDoubleArray 
b) {
+        assertTrue(b.equals(a));
+        assertTrue(a.equals(b));
+        assertEquals(a.hashCode(), b.hashCode());    
+    }
+    
+    private void verifyInequality(ResizableDoubleArray a, ResizableDoubleArray 
b) {
+        assertFalse(b.equals(a));
+        assertFalse(a.equals(b));
+        assertFalse(a.hashCode() == b.hashCode());
+    }
+    
 }


Reply via email to