Author: luc Date: Tue Nov 11 09:50:05 2008 New Revision: 713093 URL: http://svn.apache.org/viewvc?rev=713093&view=rev Log: applied Cyril Briquet's patch adding an observations removal feature to descriptive statistics JIRA: MATH-229
Modified: commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/MessagesResources_fr.java commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/descriptive/DescriptiveStatistics.java commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/util/ResizableDoubleArray.java commons/proper/math/branches/MATH_2_0/src/site/xdoc/changes.xml commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/stat/descriptive/DescriptiveStatisticsTest.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/MessagesResources_fr.java URL: http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/MessagesResources_fr.java?rev=713093&r1=713092&r2=713093&view=diff ============================================================================== --- commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/MessagesResources_fr.java (original) +++ commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/MessagesResources_fr.java Tue Nov 11 09:50:05 2008 @@ -172,10 +172,10 @@ "aucun compartiment s\u00e9lectionn\u00e9" }, // org.apache.commons.math.linear.EigenDecompositionImpl + { "cannot solve degree {0} equation", + "impossible de r\u00e9soudre une \u00e9quation de degr\u00e9 {0}" }, { "negative element on decomposed tridiagonal of {0}x{1} matrix", "\u00e9l\u00e9ment n\u00e9gatif dans la d\u00e9composition tri-diagonale d''une matrice {0}x{1}" }, - { "internal error: please file a bug report at https://issues.apache.org/jira/browse/MATH", - "erreur interne : veuillez enregistrer un rapport de bogue sur https://issues.apache.org/jira/browse/MATH" }, // org.apache.commons.math.linear.NonSquareMatrixException { "a {0}x{1} matrix was provided instead of a square matrix", @@ -238,6 +238,8 @@ "impossible d''extraire un \u00e9l\u00e9ment \u00e0 un index n\u00e9gatif ({0})" }, { "cannot set an element at a negative index {0}", "impossible de mettre un \u00e9l\u00e9ment \u00e0 un index n\u00e9gatif ({0})" }, + { "cannot substitute an element from an empty array", + "impossible de substituer un \u00e9l\u00e9ment dans un tableau vide" }, // org.apache.commons.math.analysis.PolynomialFunctionLagrangeForm { "identical abscissas x[{0}] == x[{1}] == {2} cause division by zero", Modified: commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/descriptive/DescriptiveStatistics.java URL: http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/descriptive/DescriptiveStatistics.java?rev=713093&r1=713092&r2=713093&view=diff ============================================================================== --- commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/descriptive/DescriptiveStatistics.java (original) +++ commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/descriptive/DescriptiveStatistics.java Tue Nov 11 09:50:05 2008 @@ -138,6 +138,24 @@ } } + /** + * Removes the most recent value from the dataset. + */ + public void removeMostRecentValue() { + eDA.discardMostRecentElements(1); + } + + /** + * Replaces the most recently stored value with the given value. + * There must be at least one element stored to call this method. + * + * @param v the value to replace the most recent stored value + * @return replaced value + */ + public double replaceMostRecentValue(double v) { + return eDA.substituteMostRecentElement(v); + } + /** * Returns the <a href="http://www.xycoon.com/arithmetic_mean.htm"> * arithmetic mean </a> of the available values 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=713093&r1=713092&r2=713093&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 Tue Nov 11 09:50:05 2008 @@ -295,6 +295,19 @@ return discarded; } + public synchronized double substituteMostRecentElement(double value) { + if (numElements < 1) { + throw MathRuntimeException.createArrayIndexOutOfBoundsException("cannot substitute an element from an empty array", + null); + } + + double discarded = internalArray[startIndex + (numElements - 1)]; + + internalArray[startIndex + (numElements - 1)] = value; + + return discarded; + } + /** * Checks the expansion factor and the contraction criteria and throws an * IllegalArgumentException if the contractionCriteria is less than the @@ -372,6 +385,46 @@ * @throws IllegalArgumentException if i is greater than numElements. */ public synchronized void discardFrontElements(int i) { + + discardExtremeElements(i,true); + + } + + /** + * Discards the <code>i<code> last elements of the array. For example, + * if the array contains the elements 1,2,3,4, invoking + * <code>discardMostRecentElements(2)</code> will cause the last two elements + * to be discarded, leaving 1,2 in the array. Throws illegalArgumentException + * if i exceeds numElements. + * + * @param i the number of elements to discard from the end of the array + * @throws IllegalArgumentException if i is greater than numElements. + */ + public synchronized void discardMostRecentElements(int i) { + + discardExtremeElements(i,false); + + } + + /** + * Discards the <code>i<code> first or last elements of the array, + * depending on the value of <code>front</code>. + * For example, if the array contains the elements 1,2,3,4, invoking + * <code>discardExtremeElements(2,false)</code> will cause the last two elements + * to be discarded, leaving 1,2 in the array. + * For example, if the array contains the elements 1,2,3,4, invoking + * <code>discardExtremeElements(2,true)</code> 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/end of the array + * @param front true if elements are to be discarded from the front + * of the array, false if elements are to be discarded from the end + * of the array + * @throws IllegalArgumentException if i is greater than numElements. + */ + private synchronized void discardExtremeElements(int i,boolean front) { if (i > numElements) { String msg = "Cannot discard more elements than are" + "contained in this array."; @@ -382,7 +435,7 @@ } else { // "Subtract" this number of discarded from numElements numElements -= i; - startIndex += i; + if (front) startIndex += i; } if (shouldContract()) { contract(); Modified: commons/proper/math/branches/MATH_2_0/src/site/xdoc/changes.xml URL: http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_0/src/site/xdoc/changes.xml?rev=713093&r1=713092&r2=713093&view=diff ============================================================================== --- commons/proper/math/branches/MATH_2_0/src/site/xdoc/changes.xml (original) +++ commons/proper/math/branches/MATH_2_0/src/site/xdoc/changes.xml Tue Nov 11 09:50:05 2008 @@ -39,6 +39,9 @@ </properties> <body> <release version="2.0" date="TBD" description="TBD"> + <action dev="luc" type="add" issue="MATH-229" due-to="Cyril Briquet"> + Added a removal feature for observations in descriptive statistics. + </action> <action dev="luc" type="add" > Added a scalb method in MathUtils. This method is similar to the method with same name added in java.lang.Math as of Java 6. Modified: commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/stat/descriptive/DescriptiveStatisticsTest.java URL: http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/stat/descriptive/DescriptiveStatisticsTest.java?rev=713093&r1=713092&r2=713093&view=diff ============================================================================== --- commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/stat/descriptive/DescriptiveStatisticsTest.java (original) +++ commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/stat/descriptive/DescriptiveStatisticsTest.java Tue Nov 11 09:50:05 2008 @@ -18,6 +18,7 @@ import junit.framework.TestSuite; import org.apache.commons.math.stat.descriptive.rank.Percentile; +import org.apache.commons.math.util.MathUtils; /** * Test cases for the DescriptiveStatistics class. @@ -74,6 +75,35 @@ // expected } } + public void testRemoval() { + + final DescriptiveStatistics dstat = new DescriptiveStatistics(); + + checkremoval(dstat, 1, 6.0, 0.0, Double.NaN); + checkremoval(dstat, 3, 5.0, 3.0, 4.5); + checkremoval(dstat, 6, 3.5, 2.5, 3.0); + checkremoval(dstat, 9, 3.5, 2.5, 3.0); + checkremoval(dstat, DescriptiveStatistics.INFINITE_WINDOW, 3.5, 2.5, 3.0); + + } + + public void checkremoval(DescriptiveStatistics dstat, int wsize, + double mean1, double mean2, double mean3) { + + dstat.setWindowSize(wsize); + dstat.clear(); + + for (int i = 1 ; i <= 6 ; ++i) { + dstat.addValue(i); + } + + assertTrue(MathUtils.equals(mean1, dstat.getMean())); + dstat.replaceMostRecentValue(0); + assertTrue(MathUtils.equals(mean2, dstat.getMean())); + dstat.removeMostRecentValue(); + assertTrue(MathUtils.equals(mean3, dstat.getMean())); + + } // Test UnivariateStatistics impls for setter injection tests 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=713093&r1=713092&r2=713093&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 Tue Nov 11 09:50:05 2008 @@ -313,18 +313,71 @@ ((ResizableDoubleArray)da).discardFrontElements(5); assertEquals( "Number of elements should be 6", 6, da.getNumElements()); + + da.addElement(2.0); + da.addElement(2.0); + da.addElement(2.0); + da.addElement(2.0); + assertEquals( "Number of elements should be 10", 10, da.getNumElements()); + + ((ResizableDoubleArray)da).discardMostRecentElements(2); + assertEquals( "Number of elements should be 8", 8, 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).discardMostRecentElements(-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 ){ } + + try { + ((ResizableDoubleArray)da).discardMostRecentElements( 10000 ); + fail( "You can't discard more elements than the array contains"); + } catch( Exception e ){ + } + + } + + public void testSubstitute() { + + 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).substituteMostRecentElement(24); + + assertEquals( "Number of elements should be 11", 11, da.getNumElements()); + + try { + ((ResizableDoubleArray)da).discardMostRecentElements(10); + } catch( Exception e ){ + fail( "Trying to discard a negative number of element is not allowed"); + } + + ((ResizableDoubleArray)da).substituteMostRecentElement(24); + + assertEquals( "Number of elements should be 1", 1, da.getNumElements()); + } public void testMutators() {