commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pste...@apache.org
Subject svn commit: r894472 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math/stat/descriptive/ main/java/org/apache/commons/math/stat/descriptive/moment/ main/java/org/apache/commons/math/stat/descriptive/summary/ test/java/org/apache/com...
Date Tue, 29 Dec 2009 19:57:50 GMT
Author: psteitz
Date: Tue Dec 29 19:57:49 2009
New Revision: 894472

URL: http://svn.apache.org/viewvc?rev=894472&view=rev
Log:
Added WeightedEvaluation interface and added evaluate(values, weights) to weighted statistics
implementations. JIRA: MATH-287.

Added:
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/stat/descriptive/WeightedEvaluation.java
  (with props)
Modified:
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/stat/descriptive/moment/Mean.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/stat/descriptive/moment/Variance.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/stat/descriptive/summary/Product.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/stat/descriptive/summary/Sum.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math/stat/descriptive/UnivariateStatisticAbstractTest.java

Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math/stat/descriptive/WeightedEvaluation.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/stat/descriptive/WeightedEvaluation.java?rev=894472&view=auto
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/stat/descriptive/WeightedEvaluation.java
(added)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/stat/descriptive/WeightedEvaluation.java
Tue Dec 29 19:57:49 2009
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.stat.descriptive;
+
+/**
+ * Weighted evaluation for statistics.
+ *
+ * @since 2.1
+ * @version $Revision$ $Date$
+ */
+public interface WeightedEvaluation {
+
+    /**
+     * Returns the result of evaluating the statistic over the input array,
+     * using the supplied weights.
+     *
+     * @param values input array
+     * @param weights array of weights
+     * @return the value of the statistic applied to the input array
+     */
+    double evaluate(double[] values, double[] weights);
+
+    /**
+     * Returns the result of evaluating the statistic over the specified entries
+     * in the input array, using corresponding entries in the supplied weights array.
+     *
+     * @param values the input array
+     * @param weights array of weights
+     * @param begin the index of the first element to include
+     * @param length the number of elements to include
+     * @return the value of the statistic applied to the included array entries
+     */
+    double evaluate(double[] values, double[] weights, int begin, int length);
+
+}

Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math/stat/descriptive/WeightedEvaluation.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math/stat/descriptive/WeightedEvaluation.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math/stat/descriptive/WeightedEvaluation.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/stat/descriptive/moment/Mean.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/stat/descriptive/moment/Mean.java?rev=894472&r1=894471&r2=894472&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/stat/descriptive/moment/Mean.java
(original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/stat/descriptive/moment/Mean.java
Tue Dec 29 19:57:49 2009
@@ -19,6 +19,7 @@
 import java.io.Serializable;
 
 import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic;
+import org.apache.commons.math.stat.descriptive.WeightedEvaluation;
 import org.apache.commons.math.stat.descriptive.summary.Sum;
 
 /**
@@ -56,7 +57,7 @@
  * @version $Revision$ $Date$
  */
 public class Mean extends AbstractStorelessUnivariateStatistic
-    implements Serializable {
+    implements Serializable, WeightedEvaluation {
 
     /** Serializable version identifier */
     private static final long serialVersionUID = -1296043746617791564L;
@@ -214,6 +215,33 @@
         }
         return Double.NaN;
     }
+    
+    /**
+     * Returns the weighted arithmetic mean of the entries in the input array.
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if either array is null.</p>
+     * <p>
+     * See {@link Mean} for details on the computing algorithm. The two-pass algorithm
+     * described above is used here, with weights applied in computing both the original
+     * estimate and the correction factor.</p>
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if any of the following are
true:
+     * <ul><li>the values array is null</li>
+     *     <li>the weights array is null</li>
+     *     <li>the weights array does not have the same length as the values array</li>
+     *     <li>the weights array contains one or more infinite values</li>
+     *     <li>the weights array contains one or more NaN values</li>
+     *     <li>the weights array contains negative values</li>
+     * </ul></p>
+     *
+     * @param values the input array
+     * @param weights the weights array
+     * @return the mean of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the parameters are not valid
+     */
+    public double evaluate(final double[] values, final double[] weights) {
+        return evaluate(values, weights, 0, values.length);
+    }
 
     /**
      * {@inheritDoc}

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/stat/descriptive/moment/Variance.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/stat/descriptive/moment/Variance.java?rev=894472&r1=894471&r2=894472&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/stat/descriptive/moment/Variance.java
(original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/stat/descriptive/moment/Variance.java
Tue Dec 29 19:57:49 2009
@@ -19,6 +19,7 @@
 import java.io.Serializable;
 
 import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.stat.descriptive.WeightedEvaluation;
 import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic;
 
 /**
@@ -63,7 +64,7 @@
  *
  * @version $Revision$ $Date$
  */
-public class Variance extends AbstractStorelessUnivariateStatistic implements Serializable
{
+public class Variance extends AbstractStorelessUnivariateStatistic implements Serializable,
WeightedEvaluation {
 
     /** Serializable version identifier */
     private static final long serialVersionUID = -9111962718267217978L;
@@ -293,7 +294,7 @@
      * @param weights the weights array
      * @param begin index of the first array element to include
      * @param length the number of elements to include
-     * @return the variance of the values or Double.NaN if length = 0
+     * @return the weighted variance of the values or Double.NaN if length = 0
      * @throws IllegalArgumentException if the parameters are not valid
      */
     public double evaluate(final double[] values, final double[] weights,
@@ -313,6 +314,47 @@
         }
         return var;
     }
+    
+    /**
+     * <p>
+     * Returns the weighted variance of the entries in the the input array.</p>
+     * <p>
+     * Uses the formula <pre>
+     *   &Sigma;(weights[i]*(values[i] - weightedMean)<sup>2</sup>)/(&Sigma;(weights[i])
- 1)
+     * </pre>
+     * where weightedMean is the weighted mean</p>
+     * <p>
+     * This formula will not return the same result as the unweighted variance when all
+     * weights are equal, unless all weights are equal to 1. The formula assumes that
+     * weights are to be treated as "expansion values," as will be the case if for example
+     * the weights represent frequency counts. To normalize weights so that the denominator
+     * in the variance computation equals the length of the input vector minus one, use <pre>
+     *   <code>evaluate(values, MathUtils.normalizeArray(weights, values.length));
</code>
+     * </pre>
+     * <p>
+     * Returns 0 for a single-value (i.e. length = 1) sample.</p>
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if any of the following are
true:
+     * <ul><li>the values array is null</li>
+     *     <li>the weights array is null</li>
+     *     <li>the weights array does not have the same length as the values array</li>
+     *     <li>the weights array contains one or more infinite values</li>
+     *     <li>the weights array contains one or more NaN values</li>
+     *     <li>the weights array contains negative values</li>
+     * </ul></p>
+     * <p>
+     * Does not change the internal state of the statistic.</p>
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if either array is null.</p>
+     *
+     * @param values the input array
+     * @param weights the weights array
+     * @return the weighted variance of the values
+     * @throws IllegalArgumentException if the parameters are not valid
+     */
+    public double evaluate(final double[] values, final double[] weights) {
+        return evaluate(values, weights, 0, values.length);
+    }
 
     /**
      * Returns the variance of the entries in the specified portion of
@@ -367,6 +409,35 @@
         }
         return var;
     }
+    
+    /**
+     * Returns the variance of the entries in the input array, using the
+     * precomputed mean value.  Returns <code>Double.NaN</code> if the array
+     * is empty.
+     * <p>
+     * See {@link Variance} for details on the computing algorithm.</p>
+     * <p>
+     * If <code>isBiasCorrected</code> is <code>true</code> the formula
used
+     * assumes that the supplied mean value is the arithmetic mean of the
+     * sample data, not a known population parameter.  If the mean is a known
+     * population parameter, or if the "population" version of the variance is
+     * desired, set <code>isBiasCorrected</code> to <code>false</code>
before
+     * invoking this method.</p>
+     * <p>
+     * Returns 0 for a single-value (i.e. length = 1) sample.</p>
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     * <p>
+     * Does not change the internal state of the statistic.</p>
+     *
+     * @param values the input array
+     * @param mean the precomputed mean value
+     * @return the variance of the values or Double.NaN if the array is empty
+     * @throws IllegalArgumentException if the array is null
+     */
+    public double evaluate(final double[] values, final double mean) {
+        return evaluate(values, mean, 0, values.length);
+    }
 
     /**
      * Returns the weighted variance of the entries in the specified portion of
@@ -387,7 +458,7 @@
      * weights are to be treated as "expansion values," as will be the case if for example
      * the weights represent frequency counts. To normalize weights so that the denominator
      * in the variance computation equals the length of the input vector minus one, use <pre>
-     *   <code>evaluate(values, MathUtils.normalizeArray(weights, values.length));
</code>
+     *   <code>evaluate(values, MathUtils.normalizeArray(weights, values.length), mean);
</code>
      * </pre>
      * <p>
      * Returns 0 for a single-value (i.e. length = 1) sample.</p>
@@ -442,34 +513,49 @@
         }
         return var;
     }
-
+    
     /**
-     * Returns the variance of the entries in the input array, using the
-     * precomputed mean value.  Returns <code>Double.NaN</code> if the array
-     * is empty.
+     * <p>Returns the weighted variance of the values in the input array, using
+     * the precomputed weighted mean value.</p>
      * <p>
-     * See {@link Variance} for details on the computing algorithm.</p>
+     * Uses the formula <pre>
+     *   &Sigma;(weights[i]*(values[i] - mean)<sup>2</sup>)/(&Sigma;(weights[i])
- 1)
+     * </pre></p>
      * <p>
-     * If <code>isBiasCorrected</code> is <code>true</code> the formula
used
-     * assumes that the supplied mean value is the arithmetic mean of the
-     * sample data, not a known population parameter.  If the mean is a known
-     * population parameter, or if the "population" version of the variance is
-     * desired, set <code>isBiasCorrected</code> to <code>false</code>
before
-     * invoking this method.</p>
+     * The formula used assumes that the supplied mean value is the weighted arithmetic
+     * mean of the sample data, not a known population parameter. This method
+     * is supplied only to save computation when the mean has already been
+     * computed.</p>
+     * <p>
+     * This formula will not return the same result as the unweighted variance when all
+     * weights are equal, unless all weights are equal to 1. The formula assumes that
+     * weights are to be treated as "expansion values," as will be the case if for example
+     * the weights represent frequency counts. To normalize weights so that the denominator
+     * in the variance computation equals the length of the input vector minus one, use <pre>
+     *   <code>evaluate(values, MathUtils.normalizeArray(weights, values.length), mean);
</code>
+     * </pre>
      * <p>
      * Returns 0 for a single-value (i.e. length = 1) sample.</p>
      * <p>
-     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     * Throws <code>IllegalArgumentException</code> if any of the following are
true:
+     * <ul><li>the values array is null</li>
+     *     <li>the weights array is null</li>
+     *     <li>the weights array does not have the same length as the values array</li>
+     *     <li>the weights array contains one or more infinite values</li>
+     *     <li>the weights array contains one or more NaN values</li>
+     *     <li>the weights array contains negative values</li>
+     * </ul></p>
      * <p>
      * Does not change the internal state of the statistic.</p>
      *
      * @param values the input array
-     * @param mean the precomputed mean value
-     * @return the variance of the values or Double.NaN if the array is empty
-     * @throws IllegalArgumentException if the array is null
+     * @param weights the weights array
+     * @param mean the precomputed weighted mean value
+     * @return the variance of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the parameters are not valid
      */
-    public double evaluate(final double[] values, final double mean) {
-        return evaluate(values, mean, 0, values.length);
+    public double evaluate(final double[] values, final double[] weights, final double mean)
{
+        return evaluate(values, weights, mean, 0, values.length);
     }
 
     /**

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/stat/descriptive/summary/Product.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/stat/descriptive/summary/Product.java?rev=894472&r1=894471&r2=894472&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/stat/descriptive/summary/Product.java
(original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/stat/descriptive/summary/Product.java
Tue Dec 29 19:57:49 2009
@@ -19,6 +19,7 @@
 import java.io.Serializable;
 
 import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic;
+import org.apache.commons.math.stat.descriptive.WeightedEvaluation;
 
 /**
  * Returns the product of the available values.
@@ -33,7 +34,7 @@
  *
  * @version $Revision$ $Date$
  */
-public class Product extends AbstractStorelessUnivariateStatistic implements Serializable
{
+public class Product extends AbstractStorelessUnivariateStatistic implements Serializable,
WeightedEvaluation {
 
     /** Serializable version identifier */
     private static final long serialVersionUID = 2824226005990582538L;
@@ -165,6 +166,33 @@
         }
         return product;
     }
+    
+    /**
+     * <p>Returns the weighted product of the entries in the input array.</p>
+     *
+     * <p>Throws <code>IllegalArgumentException</code> if any of the following
are true:
+     * <ul><li>the values array is null</li>
+     *     <li>the weights array is null</li>
+     *     <li>the weights array does not have the same length as the values array</li>
+     *     <li>the weights array contains one or more infinite values</li>
+     *     <li>the weights array contains one or more NaN values</li>
+     *     <li>the weights array contains negative values</li>
+     * </ul></p>
+     *
+     * <p>Uses the formula, <pre>
+     *    weighted product = &prod;values[i]<sup>weights[i]</sup>
+     * </pre>
+     * that is, the weights are applied as exponents when computing the weighted product.</p>
+     *
+     * @param values the input array
+     * @param weights the weights array
+     * @return the product of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the parameters are not valid
+     */
+    public double evaluate(final double[] values, final double[] weights) {
+        return evaluate(values, weights, 0, values.length);
+    }
+
 
     /**
      * {@inheritDoc}

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/stat/descriptive/summary/Sum.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/stat/descriptive/summary/Sum.java?rev=894472&r1=894471&r2=894472&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/stat/descriptive/summary/Sum.java
(original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/stat/descriptive/summary/Sum.java
Tue Dec 29 19:57:49 2009
@@ -19,6 +19,8 @@
 import java.io.Serializable;
 
 import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic;
+import org.apache.commons.math.stat.descriptive.WeightedEvaluation;
+
 
 /**
   * Returns the sum of the available values.
@@ -164,6 +166,31 @@
         }
         return sum;
     }
+    
+    /**
+     * The weighted sum of the entries in the the input array.
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if any of the following are
true:
+     * <ul><li>the values array is null</li>
+     *     <li>the weights array is null</li>
+     *     <li>the weights array does not have the same length as the values array</li>
+     *     <li>the weights array contains one or more infinite values</li>
+     *     <li>the weights array contains one or more NaN values</li>
+     *     <li>the weights array contains negative values</li>
+     * </ul></p>
+     * <p>
+     * Uses the formula, <pre>
+     *    weighted sum = &Sigma;(values[i] * weights[i])
+     * </pre></p>
+     *
+     * @param values the input array
+     * @param weights the weights array
+     * @return the sum of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the parameters are not valid
+     */
+    public double evaluate(final double[] values, final double[] weights) {
+        return evaluate(values, weights, 0, values.length);
+    }
 
     /**
      * {@inheritDoc}

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math/stat/descriptive/UnivariateStatisticAbstractTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/stat/descriptive/UnivariateStatisticAbstractTest.java?rev=894472&r1=894471&r2=894472&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math/stat/descriptive/UnivariateStatisticAbstractTest.java
(original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/stat/descriptive/UnivariateStatisticAbstractTest.java
Tue Dec 29 19:57:49 2009
@@ -126,12 +126,8 @@
         // See if this statistic computes weighted statistics
         // If not, skip this test
         UnivariateStatistic statistic = getUnivariateStatistic();
-        Method evaluateMethod = null;
-        try {
-            evaluateMethod = statistic.getClass().getDeclaredMethod("evaluate",
-                double[].class, double[].class, int.class, int.class);
-        } catch (NoSuchMethodException ex) {
-            return;  // skip test
+        if (!(statistic instanceof WeightedEvaluation)) {
+            return;
         }
 
         // Create arrays of values and corresponding integral weights
@@ -171,10 +167,14 @@
 
         // Compare result of weighted statistic computation with direct computation
         // on array of repeated values
-        double weightedResult = (Double) evaluateMethod.invoke(
-                statistic, values, weights, 0, values.length);
-        TestUtils.assertRelativelyEquals(
-                statistic.evaluate(repeatedValues), weightedResult, 10E-14);
+        WeightedEvaluation weightedStatistic = (WeightedEvaluation) statistic;
+        TestUtils.assertRelativelyEquals(statistic.evaluate(repeatedValues),
+                weightedStatistic.evaluate(values, weights, 0, values.length),
+                10E-14);
+        
+        // Check consistency of weighted evaluation methods
+        assertEquals(weightedStatistic.evaluate(values, weights, 0, values.length),
+                weightedStatistic.evaluate(values, weights), Double.MIN_VALUE);       
 
     }
 



Mime
View raw message