You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by lu...@apache.org on 2008/02/08 17:42:37 UTC
svn commit: r619934 - in /commons/proper/math/trunk/src:
java/org/apache/commons/math/stat/descriptive/ site/xdoc/
test/org/apache/commons/math/stat/descriptive/
Author: luc
Date: Fri Feb 8 08:42:34 2008
New Revision: 619934
URL: http://svn.apache.org/viewvc?rev=619934&view=rev
Log:
added multivariate summary statistics
Added:
commons/proper/math/trunk/src/java/org/apache/commons/math/stat/descriptive/MultivariateSummaryStatistics.java (with props)
commons/proper/math/trunk/src/java/org/apache/commons/math/stat/descriptive/StatisticalMultivariateSummary.java (with props)
commons/proper/math/trunk/src/java/org/apache/commons/math/stat/descriptive/StatisticalMultivariateSummaryValues.java (with props)
commons/proper/math/trunk/src/java/org/apache/commons/math/stat/descriptive/SynchronizedMultivariateSummaryStatistics.java (with props)
commons/proper/math/trunk/src/test/org/apache/commons/math/stat/descriptive/MultivariateSummaryStatisticsTest.java (with props)
Modified:
commons/proper/math/trunk/src/site/xdoc/changes.xml
Added: commons/proper/math/trunk/src/java/org/apache/commons/math/stat/descriptive/MultivariateSummaryStatistics.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/stat/descriptive/MultivariateSummaryStatistics.java?rev=619934&view=auto
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/stat/descriptive/MultivariateSummaryStatistics.java (added)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/stat/descriptive/MultivariateSummaryStatistics.java Fri Feb 8 08:42:34 2008
@@ -0,0 +1,592 @@
+/*
+ * 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;
+
+import java.io.Serializable;
+import java.util.Arrays;
+
+import org.apache.commons.math.DimensionMismatchException;
+import org.apache.commons.math.linear.RealMatrix;
+import org.apache.commons.math.stat.descriptive.moment.GeometricMean;
+import org.apache.commons.math.stat.descriptive.moment.Mean;
+import org.apache.commons.math.stat.descriptive.moment.VectorialCovariance;
+import org.apache.commons.math.stat.descriptive.rank.Max;
+import org.apache.commons.math.stat.descriptive.rank.Min;
+import org.apache.commons.math.stat.descriptive.summary.Sum;
+import org.apache.commons.math.stat.descriptive.summary.SumOfLogs;
+import org.apache.commons.math.stat.descriptive.summary.SumOfSquares;
+import org.apache.commons.math.util.MathUtils;
+
+/**
+ * <p>Computes summary statistics for a stream of data values added using the
+ * {@link #addValue(double[]) addValue} method. The data values are not stored in
+ * memory, so this class can be used to compute statistics for very large
+ * data streams.</p>
+ *
+ * <p>The {@link StorelessUnivariateStatistic} array instances used to maintain
+ * summary state and compute statistics are configurable via setters.
+ * For example, the default implementation for the mean can be overridden by
+ * calling {@link #setMeanImpl(StorelessUnivariateStatistic[])}. Actual
+ * parameters to these methods must implement the
+ * {@link StorelessUnivariateStatistic} interface and configuration must be
+ * completed before <code>addValue</code> is called. No configuration is
+ * necessary to use the default, commons-math provided implementations.</p>
+ *
+ * <p>Note: This class is not thread-safe. Use
+ * {@link SynchronizedMultivariateSummaryStatistics} if concurrent access from multiple
+ * threads is required.</p>
+ *
+ * @since 1.2
+ * @version $Revision: 618097 $ $Date: 2008-02-03 22:39:08 +0100 (dim., 03 févr. 2008) $
+ */
+public class MultivariateSummaryStatistics
+ implements StatisticalMultivariateSummary, Serializable {
+
+ /** Serialization UID */
+ private static final long serialVersionUID = 2271900808994826718L;
+
+ /**
+ * Construct a MultivariateSummaryStatistics instance
+ * @param k dimension of the data
+ * @param isCovarianceBiasCorrected if true, the unbiased sample
+ * covariance is computed, otherwise the biased population covariance
+ * is computed
+ */
+ public MultivariateSummaryStatistics(int k, boolean isCovarianceBiasCorrected) {
+ this.k = k;
+
+ sumImpl = new StorelessUnivariateStatistic[k];
+ sumSqImpl = new StorelessUnivariateStatistic[k];
+ minImpl = new StorelessUnivariateStatistic[k];
+ maxImpl = new StorelessUnivariateStatistic[k];
+ sumLogImpl = new StorelessUnivariateStatistic[k];
+ geoMeanImpl = new StorelessUnivariateStatistic[k];
+ meanImpl = new StorelessUnivariateStatistic[k];
+
+ for (int i = 0; i < k; ++i) {
+ sumImpl[i] = new Sum();
+ sumSqImpl[i] = new SumOfSquares();
+ minImpl[i] = new Min();
+ maxImpl[i] = new Max();
+ sumLogImpl[i] = new SumOfLogs();
+ geoMeanImpl[i] = new GeometricMean();
+ meanImpl[i] = new Mean();
+ }
+
+ covarianceImpl =
+ new VectorialCovariance(k, isCovarianceBiasCorrected);
+
+ }
+
+ /** Dimension of the data. */
+ private int k;
+
+ /** Count of values that have been added */
+ private long n = 0;
+
+ /** Sum statistic implementation - can be reset by setter. */
+ private StorelessUnivariateStatistic[] sumImpl;
+
+ /** Sum of squares statistic implementation - can be reset by setter. */
+ private StorelessUnivariateStatistic[] sumSqImpl;
+
+ /** Minimum statistic implementation - can be reset by setter. */
+ private StorelessUnivariateStatistic[] minImpl;
+
+ /** Maximum statistic implementation - can be reset by setter. */
+ private StorelessUnivariateStatistic[] maxImpl;
+
+ /** Sum of log statistic implementation - can be reset by setter. */
+ private StorelessUnivariateStatistic[] sumLogImpl;
+
+ /** Geometric mean statistic implementation - can be reset by setter. */
+ private StorelessUnivariateStatistic[] geoMeanImpl;
+
+ /** Mean statistic implementation - can be reset by setter. */
+ private StorelessUnivariateStatistic[] meanImpl;
+
+ /** Covariance statistic implementation - cannot be reset. */
+ private VectorialCovariance covarianceImpl;
+
+ /**
+ * Return a {@link StatisticalMultivariateSummary} instance reporting current
+ * statistics.
+ *
+ * @return Current values of statistics
+ */
+ public StatisticalMultivariateSummary getSummary() {
+ return new StatisticalMultivariateSummaryValues(getDimension(), getMean(),
+ getCovariance(), getStandardDeviation(),
+ getN(), getMax(), getMin(),
+ getSum(), getSumSq(), getSumLog());
+ }
+
+ /**
+ * Add a value to the data
+ *
+ * @param value the value to add
+ * @throws DimensionMismatchException if the value dimension
+ * does not match the one used at construction
+ */
+ public void addValue(double[] value)
+ throws DimensionMismatchException {
+ if (value.length != k) {
+ throw new DimensionMismatchException(value.length, k);
+ }
+
+ for (int i = 0; i < k; ++i) {
+ double v = value[i];
+ sumImpl[i].increment(v);
+ sumSqImpl[i].increment(v);
+ minImpl[i].increment(v);
+ maxImpl[i].increment(v);
+ sumLogImpl[i].increment(v);
+ geoMeanImpl[i].increment(v);
+ meanImpl[i].increment(v);
+ }
+ covarianceImpl.increment(value);
+ n++;
+ }
+
+ /**
+ * Returns the dimension of the data
+ * @return The dimension of the data
+ */
+ public int getDimension() {
+ return k;
+ }
+
+ /**
+ * Returns the number of available values
+ * @return The number of available values
+ */
+ public long getN() {
+ return n;
+ }
+
+ /**
+ * Returns an array of the results of a statistic.
+ * @param stats univariate statistic array
+ * @return results array
+ */
+ private double[] getResults(StorelessUnivariateStatistic[] stats) {
+ double[] results = new double[stats.length];
+ for (int i = 0; i < results.length; ++i) {
+ results[i] = stats[i].getResult();
+ }
+ return results;
+ }
+
+ /**
+ * Returns the sum of the values that have been added
+ * @return The sum or <code>Double.NaN</code> if no values have been added
+ */
+ public double[] getSum() {
+ return getResults(sumImpl);
+ }
+
+ /**
+ * Returns the sum of the squares of the values that have been added.
+ * <p>
+ * Double.NaN is returned if no values have been added.</p>
+ *
+ * @return The sum of squares
+ */
+ public double[] getSumSq() {
+ return getResults(sumSqImpl);
+ }
+
+ /**
+ * Returns the sum of the logarithms of the values that have been added.
+ * <p>
+ * Double.NaN is returned if no values have been added.</p>
+ *
+ * @return The sum of logarithms
+ */
+ public double[] getSumLog() {
+ return getResults(sumLogImpl);
+ }
+
+ /**
+ * Returns the mean of the values that have been added.
+ * <p>
+ * Double.NaN is returned if no values have been added.</p>
+ *
+ * @return the mean
+ */
+ public double[] getMean() {
+ return getResults(meanImpl);
+ }
+
+ /**
+ * Returns the standard deviation of the values that have been added.
+ * <p>
+ * Double.NaN is returned if no values have been added.</p>
+ *
+ * @return the standard deviation
+ */
+ public double[] getStandardDeviation() {
+ double[] stdDev = new double[k];
+ if (getN() < 1) {
+ Arrays.fill(stdDev, Double.NaN);
+ } else if (getN() < 2) {
+ Arrays.fill(stdDev, 0.0);
+ } else {
+ RealMatrix matrix = covarianceImpl.getResult();
+ for (int i = 0; i < k; ++i) {
+ stdDev[i] = Math.sqrt(matrix.getEntry(i, i));
+ }
+ }
+ return stdDev;
+ }
+
+ /**
+ * Returns the covariance of the values that have been added.
+ * <p>
+ * Double.NaN is returned if no values have been added.</p>
+ *
+ * @return the variance
+ */
+ public RealMatrix getCovariance() {
+ return covarianceImpl.getResult();
+ }
+
+ /**
+ * Returns the maximum of the values that have been added.
+ * <p>
+ * Double.NaN is returned if no values have been added.</p>
+ *
+ * @return the maximum
+ */
+ public double[] getMax() {
+ return getResults(maxImpl);
+ }
+
+ /**
+ * Returns the minimum of the values that have been added.
+ * <p>
+ * Double.NaN is returned if no values have been added.</p>
+ *
+ * @return the minimum
+ */
+ public double[] getMin() {
+ return getResults(minImpl);
+ }
+
+ /**
+ * Returns the geometric mean of the values that have been added.
+ * <p>
+ * Double.NaN is returned if no values have been added.</p>
+ *
+ * @return the geometric mean
+ */
+ public double[] getGeometricMean() {
+ return getResults(geoMeanImpl);
+ }
+
+ /**
+ * Generates a text report displaying
+ * summary statistics from values that
+ * have been added.
+ * @return String with line feeds displaying statistics
+ */
+ public String toString() {
+ StringBuffer outBuffer = new StringBuffer();
+ outBuffer.append("MultivariateSummaryStatistics:\n");
+ outBuffer.append("n: " + getN() + "\n");
+ append(outBuffer, getMin(), "min: ", ", ", "\n");
+ append(outBuffer, getMax(), "max: ", ", ", "\n");
+ append(outBuffer, getMean(), "mean: ", ", ", "\n");
+ append(outBuffer, getGeometricMean(), "geometric mean: ", ", ", "\n");
+ append(outBuffer, getSumSq(), "sum of squares: ", ", ", "\n");
+ append(outBuffer, getSumLog(), "sum of logarithms: ", ", ", "\n");
+ append(outBuffer, getStandardDeviation(), "standard deviation: ", ", ", "\n");
+ outBuffer.append("covariance: " + getCovariance().toString() + "\n");
+ return outBuffer.toString();
+ }
+
+ /**
+ * Append a text representation of an array to a buffer.
+ * @param buffer buffer to fill
+ * @param data data array
+ * @param prefix text prefix
+ * @param separator elements separator
+ * @param suffix text suffix
+ */
+ private void append(StringBuffer buffer, double[] data,
+ String prefix, String separator, String suffix) {
+ buffer.append(prefix);
+ for (int i = 0; i < data.length; ++i) {
+ if (i > 0) {
+ buffer.append(separator);
+ }
+ buffer.append(data[i]);
+ }
+ buffer.append(suffix);
+ }
+
+ /**
+ * Resets all statistics and storage
+ */
+ public void clear() {
+ this.n = 0;
+ for (int i = 0; i < k; ++i) {
+ minImpl[i].clear();
+ maxImpl[i].clear();
+ sumImpl[i].clear();
+ sumLogImpl[i].clear();
+ sumSqImpl[i].clear();
+ geoMeanImpl[i].clear();
+ meanImpl[i].clear();
+ }
+ covarianceImpl.clear();
+ }
+
+ /**
+ * Returns true iff <code>object</code> is a <code>SummaryStatistics</code>
+ * instance and all statistics have the same values as this.
+ * @param object the object to test equality against.
+ * @return true if object equals this
+ */
+ public boolean equals(Object object) {
+ if (object == this ) {
+ return true;
+ }
+ if (object instanceof MultivariateSummaryStatistics == false) {
+ return false;
+ }
+ MultivariateSummaryStatistics stat = (MultivariateSummaryStatistics) object;
+ return (MathUtils.equals(stat.getGeometricMean(),
+ this.getGeometricMean()) &&
+ MathUtils.equals(stat.getMax(), this.getMax()) &&
+ MathUtils.equals(stat.getMean(),this.getMean()) &&
+ MathUtils.equals(stat.getMin(),this.getMin()) &&
+ MathUtils.equals(stat.getN(), this.getN()) &&
+ MathUtils.equals(stat.getSum(), this.getSum()) &&
+ MathUtils.equals(stat.getSumSq(),this.getSumSq()) &&
+ MathUtils.equals(stat.getSumLog(),this.getSumLog()) &&
+ stat.getCovariance().equals(this.getCovariance()));
+ }
+
+ /**
+ * Returns hash code based on values of statistics
+ *
+ * @return hash code
+ */
+ public int hashCode() {
+ int result = 31 + MathUtils.hash(getGeometricMean());
+ result = result * 31 + MathUtils.hash(getGeometricMean());
+ result = result * 31 + MathUtils.hash(getMax());
+ result = result * 31 + MathUtils.hash(getMean());
+ result = result * 31 + MathUtils.hash(getMin());
+ result = result * 31 + MathUtils.hash(getN());
+ result = result * 31 + MathUtils.hash(getSum());
+ result = result * 31 + MathUtils.hash(getSumSq());
+ result = result * 31 + MathUtils.hash(getSumLog());
+ result = result * 31 + getCovariance().hashCode();
+ return result;
+ }
+
+ // Getters and setters for statistics implementations
+ /**
+ * Returns the currently configured Sum implementation
+ *
+ * @return the StorelessUnivariateStatistic implementing the sum
+ */
+ public StorelessUnivariateStatistic[] getSumImpl() {
+ return sumImpl;
+ }
+
+ /**
+ * <p>Sets the implementation for the Sum.</p>
+ * <p>This method must be activated before any data has been added - i.e.,
+ * before {@link #addValue(double[]) addValue} has been used to add data;
+ * otherwise an IllegalStateException will be thrown.</p>
+ *
+ * @param sumImpl the StorelessUnivariateStatistic instance to use
+ * for computing the Sum
+ * @throws IllegalArgumentException if the array dimension
+ * does not match the one used at construction
+ * @throws IllegalStateException if data has already been added
+ * (i.e if n > 0)
+ */
+ public void setSumImpl(StorelessUnivariateStatistic[] sumImpl) {
+ checkEmpty();
+ this.sumImpl = sumImpl;
+ }
+
+ /**
+ * Returns the currently configured sum of squares implementation
+ *
+ * @return the StorelessUnivariateStatistic implementing the sum of squares
+ */
+ public StorelessUnivariateStatistic[] getSumsqImpl() {
+ return sumSqImpl;
+ }
+
+ /**
+ * <p>Sets the implementation for the sum of squares.</p>
+ * <p>This method must be activated before any data has been added - i.e.,
+ * before {@link #addValue(double[]) addValue} has been used to add data;
+ * otherwise an IllegalStateException will be thrown.</p>
+ *
+ * @param sumsqImpl the StorelessUnivariateStatistic instance to use
+ * for computing the sum of squares
+ * @throws IllegalStateException if data has already been added
+ * (i.e if n > 0)
+ */
+ public void setSumsqImpl(StorelessUnivariateStatistic[] sumsqImpl) {
+ checkEmpty();
+ this.sumSqImpl = sumsqImpl;
+ }
+
+ /**
+ * Returns the currently configured minimum implementation
+ *
+ * @return the StorelessUnivariateStatistic implementing the minimum
+ */
+ public StorelessUnivariateStatistic[] getMinImpl() {
+ return minImpl;
+ }
+
+ /**
+ * <p>Sets the implementation for the minimum.</p>
+ * <p>This method must be activated before any data has been added - i.e.,
+ * before {@link #addValue(double[]) addValue} has been used to add data;
+ * otherwise an IllegalStateException will be thrown.</p>
+ *
+ * @param minImpl the StorelessUnivariateStatistic instance to use
+ * for computing the minimum
+ * @throws IllegalStateException if data has already been added
+ * (i.e if n > 0)
+ */
+ public void setMinImpl(StorelessUnivariateStatistic[] minImpl) {
+ checkEmpty();
+ this.minImpl = minImpl;
+ }
+
+ /**
+ * Returns the currently configured maximum implementation
+ *
+ * @return the StorelessUnivariateStatistic implementing the maximum
+ */
+ public StorelessUnivariateStatistic[] getMaxImpl() {
+ return maxImpl;
+ }
+
+ /**
+ * <p>Sets the implementation for the maximum.</p>
+ * <p>This method must be activated before any data has been added - i.e.,
+ * before {@link #addValue(double[]) addValue} has been used to add data;
+ * otherwise an IllegalStateException will be thrown.</p>
+ *
+ * @param maxImpl the StorelessUnivariateStatistic instance to use
+ * for computing the maximum
+ * @throws IllegalStateException if data has already been added
+ * (i.e if n > 0)
+ */
+ public void setMaxImpl(StorelessUnivariateStatistic[] maxImpl) {
+ checkEmpty();
+ this.maxImpl = maxImpl;
+ }
+
+ /**
+ * Returns the currently configured sum of logs implementation
+ *
+ * @return the StorelessUnivariateStatistic implementing the log sum
+ */
+ public StorelessUnivariateStatistic[] getSumLogImpl() {
+ return sumLogImpl;
+ }
+
+ /**
+ * <p>Sets the implementation for the sum of logs.</p>
+ * <p>This method must be activated before any data has been added - i.e.,
+ * before {@link #addValue(double[]) addValue} has been used to add data;
+ * otherwise an IllegalStateException will be thrown.</p>
+ *
+ * @param sumLogImpl the StorelessUnivariateStatistic instance to use
+ * for computing the log sum
+ * @throws IllegalStateException if data has already been added
+ * (i.e if n > 0)
+ */
+ public void setSumLogImpl(StorelessUnivariateStatistic[] sumLogImpl) {
+ checkEmpty();
+ this.sumLogImpl = sumLogImpl;
+ }
+
+ /**
+ * Returns the currently configured geometric mean implementation
+ *
+ * @return the StorelessUnivariateStatistic implementing the geometric mean
+ */
+ public StorelessUnivariateStatistic[] getGeoMeanImpl() {
+ return geoMeanImpl;
+ }
+
+ /**
+ * <p>Sets the implementation for the geometric mean.</p>
+ * <p>This method must be activated before any data has been added - i.e.,
+ * before {@link #addValue(double[]) addValue} has been used to add data;
+ * otherwise an IllegalStateException will be thrown.</p>
+ *
+ * @param geoMeanImpl the StorelessUnivariateStatistic instance to use
+ * for computing the geometric mean
+ * @throws IllegalStateException if data has already been added
+ * (i.e if n > 0)
+ */
+ public void setGeoMeanImpl(StorelessUnivariateStatistic[] geoMeanImpl) {
+ checkEmpty();
+ this.geoMeanImpl = geoMeanImpl;
+ }
+
+ /**
+ * Returns the currently configured mean implementation
+ *
+ * @return the StorelessUnivariateStatistic implementing the mean
+ */
+ public StorelessUnivariateStatistic[] getMeanImpl() {
+ return meanImpl;
+ }
+
+ /**
+ * <p>Sets the implementation for the mean.</p>
+ * <p>This method must be activated before any data has been added - i.e.,
+ * before {@link #addValue(double[]) addValue} has been used to add data;
+ * otherwise an IllegalStateException will be thrown.</p>
+ *
+ * @param meanImpl the StorelessUnivariateStatistic instance to use
+ * for computing the mean
+ * @throws IllegalStateException if data has already been added
+ * (i.e if n > 0)
+ */
+ public void setMeanImpl(StorelessUnivariateStatistic[] meanImpl) {
+ checkEmpty();
+ this.meanImpl = meanImpl;
+ }
+
+ /**
+ * Throws IllegalStateException if n > 0.
+ */
+ private void checkEmpty() {
+ if (n > 0) {
+ throw new IllegalStateException(
+ "Implementations must be configured before values are added.");
+ }
+ }
+
+}
Propchange: commons/proper/math/trunk/src/java/org/apache/commons/math/stat/descriptive/MultivariateSummaryStatistics.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/proper/math/trunk/src/java/org/apache/commons/math/stat/descriptive/StatisticalMultivariateSummary.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/stat/descriptive/StatisticalMultivariateSummary.java?rev=619934&view=auto
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/stat/descriptive/StatisticalMultivariateSummary.java (added)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/stat/descriptive/StatisticalMultivariateSummary.java Fri Feb 8 08:42:34 2008
@@ -0,0 +1,81 @@
+/*
+ * 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;
+
+import org.apache.commons.math.linear.RealMatrix;
+
+/**
+ * Reporting interface for basic multivariate statistics.
+ *
+ * @since 1.2
+ * @version $Revision: 480440 $ $Date: 2006-11-29 08:14:12 +0100 (mer., 29 nov. 2006) $
+ */
+public interface StatisticalMultivariateSummary {
+ /**
+ * Returns the dimension of the data
+ * @return The dimension of the data
+ */
+ public int getDimension();
+ /**
+ * Returns the <a href="http://www.xycoon.com/arithmetic_mean.htm">
+ * arithmetic mean </a> of the available values
+ * @return The mean or null if no values have been added.
+ */
+ public abstract double[] getMean();
+ /**
+ * Returns the covariance of the available values.
+ * @return The covariance, null if no values have been added
+ * or a zeroed matrix for a single value set.
+ */
+ public abstract RealMatrix getCovariance();
+ /**
+ * Returns the standard deviation of the available values.
+ * @return The standard deviation, null if no values have been added
+ * or a zeroed array for a single value set.
+ */
+ public abstract double[] getStandardDeviation();
+ /**
+ * Returns the maximum of the available values
+ * @return The max or null if no values have been added.
+ */
+ public abstract double[] getMax();
+ /**
+ * Returns the minimum of the available values
+ * @return The min or null if no values have been added.
+ */
+ public abstract double[] getMin();
+ /**
+ * Returns the number of available values
+ * @return The number of available values
+ */
+ public abstract long getN();
+ /**
+ * Returns the sum of the values that have been added.
+ * @return The sum or null if no values have been added
+ */
+ public abstract double[] getSum();
+ /**
+ * Returns the sum of the squares of the values that have been added.
+ * @return The sum or null if no values have been added
+ */
+ public abstract double[] getSumSq();
+ /**
+ * Returns the sum of the logarithms of the values that have been added.
+ * @return The sum or null if no values have been added
+ */
+ public abstract double[] getSumLog();
+}
\ No newline at end of file
Propchange: commons/proper/math/trunk/src/java/org/apache/commons/math/stat/descriptive/StatisticalMultivariateSummary.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/proper/math/trunk/src/java/org/apache/commons/math/stat/descriptive/StatisticalMultivariateSummaryValues.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/stat/descriptive/StatisticalMultivariateSummaryValues.java?rev=619934&view=auto
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/stat/descriptive/StatisticalMultivariateSummaryValues.java (added)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/stat/descriptive/StatisticalMultivariateSummaryValues.java Fri Feb 8 08:42:34 2008
@@ -0,0 +1,215 @@
+/*
+ * 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;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.linear.RealMatrix;
+import org.apache.commons.math.util.MathUtils;
+
+/**
+ * Value object representing the results of a statistical multivariate summary.
+ *
+ * @since 1.2
+ * @version $Revision: 480440 $ $Date: 2006-11-29 08:14:12 +0100 (mer., 29 nov. 2006) $
+ */
+public class StatisticalMultivariateSummaryValues
+ implements Serializable, StatisticalMultivariateSummary {
+
+ /** Serialization id */
+ private static final long serialVersionUID = 8152538650791979064L;
+
+ /** Dimension of the data. */
+ private final int k;
+
+ /** The sample mean */
+ private final double[] mean;
+
+ /** The sample covariance */
+ private final RealMatrix covariance;
+
+ /** The sample standard deviation. */
+ private double[] stdev;
+
+ /** The number of observations in the sample */
+ private final long n;
+
+ /** The maximum value */
+ private final double[] max;
+
+ /** The minimum value */
+ private final double[] min;
+
+ /** The sum of the sample values */
+ private final double[] sum;
+
+ /** The sum of the squares of the sample values */
+ private final double[] sumSq;
+
+ /** The sum of the logarithms of the sample values */
+ private final double[] sumLog;
+
+ /**
+ * Constructor
+ *
+ * @param mean the sample mean
+ * @param covariance the sample covariance
+ * @param stdev the sample standard deviation
+ * @param k dimension of the data
+ * @param n the number of observations in the sample
+ * @param max the maximum value
+ * @param min the minimum value
+ * @param sum the sum of the values
+ * @param sumSq the sum of the squares of the values
+ * @param sumLog the sum of the logarithms of the values
+ */
+ public StatisticalMultivariateSummaryValues(int k, double[] mean,
+ RealMatrix covariance, double[] stdev,
+ long n, double[] max, double[] min,
+ double[] sum, double[] sumSq, double[] sumLog) {
+ super();
+ this.k = k;
+ this.mean = mean;
+ this.covariance = covariance;
+ this.stdev = stdev;
+ this.n = n;
+ this.max = max;
+ this.min = min;
+ this.sum = sum;
+ this.sumSq = sumSq;
+ this.sumLog = sumLog;
+ }
+
+ /**
+ * Returns the dimension of the data
+ * @return The dimension of the data
+ */
+ public int getDimension() {
+ return k;
+ }
+
+ /**
+ * @return Returns the max.
+ */
+ public double[] getMax() {
+ return max;
+ }
+
+ /**
+ * @return Returns the mean.
+ */
+ public double[] getMean() {
+ return mean;
+ }
+
+ /**
+ * @return Returns the min.
+ */
+ public double[] getMin() {
+ return min;
+ }
+
+ /**
+ * @return Returns the number of values.
+ */
+ public long getN() {
+ return n;
+ }
+
+ /**
+ * @return Returns the sum.
+ */
+ public double[] getSum() {
+ return sum;
+ }
+
+ /**
+ * @return Returns the sum of the squares.
+ */
+ public double[] getSumSq() {
+ return sumSq;
+ }
+
+ /**
+ * @return Returns the sum of the logarithms.
+ */
+ public double[] getSumLog() {
+ return sumLog;
+ }
+
+ /**
+ * @return Returns the standard deviation (roots of the diagonal elements)
+ */
+ public double[] getStandardDeviation() {
+ return stdev;
+ }
+
+ /**
+ * @return Returns the covariance.
+ */
+ public RealMatrix getCovariance() {
+ return covariance;
+ }
+
+ /**
+ * Returns true iff <code>object</code> is a
+ * <code>StatisticalSummaryValues</code> instance and all statistics have
+ * the same values as this.
+ *
+ * @param object the object to test equality against.
+ * @return true if object equals this
+ */
+ public boolean equals(Object object) {
+ if (object == this ) {
+ return true;
+ }
+ if (object instanceof StatisticalMultivariateSummaryValues == false) {
+ return false;
+ }
+ StatisticalMultivariateSummaryValues stat = (StatisticalMultivariateSummaryValues) object;
+ return ((stat.getDimension() == this.getDimension()) &&
+ MathUtils.equals(stat.getMax(), this.getMax()) &&
+ MathUtils.equals(stat.getMean(),this.getMean()) &&
+ MathUtils.equals(stat.getMin(),this.getMin()) &&
+ MathUtils.equals(stat.getN(), this.getN()) &&
+ MathUtils.equals(stat.getSum(), this.getSum()) &&
+ MathUtils.equals(stat.getSumSq(), this.getSumSq()) &&
+ MathUtils.equals(stat.getSumLog(), this.getSumLog()) &&
+ MathUtils.equals(stat.getStandardDeviation(), this.getStandardDeviation()) &&
+ stat.getCovariance().equals(this.getCovariance()));
+ }
+
+ /**
+ * Returns hash code based on values of statistics
+ *
+ * @return hash code
+ */
+ public int hashCode() {
+ int result = getDimension();
+ result = result * 31 + MathUtils.hash(getMax());
+ result = result * 31 + MathUtils.hash(getMean());
+ result = result * 31 + MathUtils.hash(getMin());
+ result = result * 31 + MathUtils.hash(getN());
+ result = result * 31 + MathUtils.hash(getSum());
+ result = result * 31 + MathUtils.hash(getSumSq());
+ result = result * 31 + MathUtils.hash(getSumLog());
+ result = result * 31 + getCovariance().hashCode();
+ result = result * 31 + MathUtils.hash(getStandardDeviation());
+ return result;
+ }
+
+}
Propchange: commons/proper/math/trunk/src/java/org/apache/commons/math/stat/descriptive/StatisticalMultivariateSummaryValues.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/proper/math/trunk/src/java/org/apache/commons/math/stat/descriptive/SynchronizedMultivariateSummaryStatistics.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/stat/descriptive/SynchronizedMultivariateSummaryStatistics.java?rev=619934&view=auto
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/stat/descriptive/SynchronizedMultivariateSummaryStatistics.java (added)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/stat/descriptive/SynchronizedMultivariateSummaryStatistics.java Fri Feb 8 08:42:34 2008
@@ -0,0 +1,269 @@
+/*
+ * 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;
+
+import org.apache.commons.math.DimensionMismatchException;
+import org.apache.commons.math.linear.RealMatrix;
+
+/**
+ * Implementation of
+ * {@link org.apache.commons.math.stat.descriptive.MultivariateSummaryStatistics} that
+ * is safe to use in a multithreaded environment. Multiple threads can safely
+ * operate on a single instance without causing runtime exceptions due to race
+ * conditions. In effect, this implementation makes modification and access
+ * methods atomic operations for a single instance. That is to say, as one
+ * thread is computing a statistic from the instance, no other thread can modify
+ * the instance nor compute another statistic.
+ * @since 1.2
+ * @version $Revision: 618097 $ $Date: 2008-02-03 22:39:08 +0100 (dim., 03 févr. 2008) $
+ */
+public class SynchronizedMultivariateSummaryStatistics
+ extends MultivariateSummaryStatistics {
+
+ /** Serialization UID */
+ private static final long serialVersionUID = 7099834153347155363L;
+
+ /**
+ * Construct a SynchronizedMultivariateSummaryStatistics instance
+ * @param k dimension of the data
+ * @param isCovarianceBiasCorrected if true, the unbiased sample
+ * covariance is computed, otherwise the biased population covariance
+ * is computed
+ */
+ public SynchronizedMultivariateSummaryStatistics(int k, boolean isCovarianceBiasCorrected) {
+ super(k, isCovarianceBiasCorrected);
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#getSummary()
+ */
+ public synchronized StatisticalMultivariateSummary getSummary() {
+ return super.getSummary();
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#addValue(double[])
+ */
+ public synchronized void addValue(double[] value)
+ throws DimensionMismatchException {
+ super.addValue(value);
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#getDimension()
+ */
+ public synchronized int getDimension() {
+ return super.getDimension();
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#getN()
+ */
+ public synchronized long getN() {
+ return super.getN();
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#getSum()
+ */
+ public synchronized double[] getSum() {
+ return super.getSum();
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#getSummSq()
+ */
+ public synchronized double[] getSumSq() {
+ return super.getSumSq();
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#getSumLog()
+ */
+ public synchronized double[] getSumLog() {
+ return super.getSumLog();
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#getMean()
+ */
+ public synchronized double[] getMean() {
+ return super.getMean();
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#getStandardDeviation()
+ */
+ public synchronized double[] getStandardDeviation() {
+ return super.getStandardDeviation();
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#getCovariance()
+ */
+ public synchronized RealMatrix getCovariance() {
+ return super.getCovariance();
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#getMax()
+ */
+ public synchronized double[] getMax() {
+ return super.getMax();
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#getMin()
+ */
+ public synchronized double[] getMin() {
+ return super.getMin();
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#getGeometricMean()
+ */
+ public synchronized double[] getGeometricMean() {
+ return super.getGeometricMean();
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#toString()
+ */
+ public synchronized String toString() {
+ return super.toString();
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#clear()
+ */
+ public synchronized void clear() {
+ super.clear();
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#equals()
+ */
+ public synchronized boolean equals(Object object) {
+ return super.equals(object);
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#hashCode()
+ */
+ public synchronized int hashCode() {
+ return super.hashCode();
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#getSumImpl()
+ */
+ public synchronized StorelessUnivariateStatistic[] getSumImpl() {
+ return super.getSumImpl();
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#setSumImpl(StorelessUnivariateStatistic[])
+ */
+ public synchronized void setSumImpl(StorelessUnivariateStatistic[] sumImpl) {
+ super.setSumImpl(sumImpl);
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#getSumsqImpl()
+ */
+ public synchronized StorelessUnivariateStatistic[] getSumsqImpl() {
+ return super.getSumsqImpl();
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#setSumsqImpl(StorelessUnivariateStatistic[])
+ */
+ public synchronized void setSumsqImpl(StorelessUnivariateStatistic[] sumsqImpl) {
+ super.setSumsqImpl(sumsqImpl);
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#getMinImpl()
+ */
+ public synchronized StorelessUnivariateStatistic[] getMinImpl() {
+ return super.getMinImpl();
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#setMinImpl(StorelessUnivariateStatistic[])
+ */
+ public synchronized void setMinImpl(StorelessUnivariateStatistic[] minImpl) {
+ super.setMinImpl(minImpl);
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#getMaxImpl()
+ */
+ public synchronized StorelessUnivariateStatistic[] getMaxImpl() {
+ return super.getMaxImpl();
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#setMaxImpl(StorelessUnivariateStatistic[])
+ */
+ public synchronized void setMaxImpl(StorelessUnivariateStatistic[] maxImpl) {
+ super.setMaxImpl(maxImpl);
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#getSumLogImpl()
+ */
+ public synchronized StorelessUnivariateStatistic[] getSumLogImpl() {
+ return super.getSumLogImpl();
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#setSumLogImpl(StorelessUnivariateStatistic[])
+ */
+ public synchronized void setSumLogImpl(StorelessUnivariateStatistic[] sumLogImpl) {
+ super.setSumLogImpl(sumLogImpl);
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#getGeoMeanImpl()
+ */
+ public synchronized StorelessUnivariateStatistic[] getGeoMeanImpl() {
+ return super.getGeoMeanImpl();
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#setGeoMeanImpl(StorelessUnivariateStatistic[])
+ */
+ public synchronized void setGeoMeanImpl(StorelessUnivariateStatistic[] geoMeanImpl) {
+ super.setGeoMeanImpl(geoMeanImpl);
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#getMeanImpl()
+ */
+ public synchronized StorelessUnivariateStatistic[] getMeanImpl() {
+ return super.getMeanImpl();
+ }
+
+ /**
+ * @see org.apache.commons.math.stat.descriptive.MultivariateSummary#setMeanImpl(StorelessUnivariateStatistic[])
+ */
+ public synchronized void setMeanImpl(StorelessUnivariateStatistic[] meanImpl) {
+ super.setMeanImpl(meanImpl);
+ }
+
+}
Propchange: commons/proper/math/trunk/src/java/org/apache/commons/math/stat/descriptive/SynchronizedMultivariateSummaryStatistics.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: commons/proper/math/trunk/src/site/xdoc/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/site/xdoc/changes.xml?rev=619934&r1=619933&r2=619934&view=diff
==============================================================================
--- commons/proper/math/trunk/src/site/xdoc/changes.xml (original)
+++ commons/proper/math/trunk/src/site/xdoc/changes.xml Fri Feb 8 08:42:34 2008
@@ -154,6 +154,9 @@
Added vectorial covariance computation (either sample or population
covariance)
</action>
+ <action dev="luc" type="update" >
+ Added multivariate summary statistics
+ </action>
</release>
<release version="1.1" date="2005-12-17"
description="This is a maintenance release containing bug fixes and enhancements.
Added: commons/proper/math/trunk/src/test/org/apache/commons/math/stat/descriptive/MultivariateSummaryStatisticsTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/org/apache/commons/math/stat/descriptive/MultivariateSummaryStatisticsTest.java?rev=619934&view=auto
==============================================================================
--- commons/proper/math/trunk/src/test/org/apache/commons/math/stat/descriptive/MultivariateSummaryStatisticsTest.java (added)
+++ commons/proper/math/trunk/src/test/org/apache/commons/math/stat/descriptive/MultivariateSummaryStatisticsTest.java Fri Feb 8 08:42:34 2008
@@ -0,0 +1,294 @@
+/*
+ * 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;
+
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.apache.commons.math.DimensionMismatchException;
+import org.apache.commons.math.TestUtils;
+import org.apache.commons.math.stat.descriptive.moment.Mean;
+
+/**
+ * Test cases for the {@link MultivariateSummaryStatistics} class.
+ *
+ * @version $Revision: 566833 $ $Date: 2007-08-16 13:36:33 -0700 (Thu, 16 Aug 2007) $
+ */
+
+public class MultivariateSummaryStatisticsTest extends TestCase {
+
+ public MultivariateSummaryStatisticsTest(String name) {
+ super(name);
+ }
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite(MultivariateSummaryStatisticsTest.class);
+ suite.setName("MultivariateSummaryStatistics tests");
+ return suite;
+ }
+
+ public void testSetterInjection() throws Exception {
+ MultivariateSummaryStatistics u = new MultivariateSummaryStatistics(2, true);
+ u.setMeanImpl(new StorelessUnivariateStatistic[] {
+ new sumMean(), new sumMean()
+ });
+ u.addValue(new double[] { 1, 2 });
+ u.addValue(new double[] { 3, 4 });
+ assertEquals(4, u.getMean()[0], 1E-14);
+ assertEquals(6, u.getMean()[1], 1E-14);
+ u.clear();
+ u.addValue(new double[] { 1, 2 });
+ u.addValue(new double[] { 3, 4 });
+ assertEquals(4, u.getMean()[0], 1E-14);
+ assertEquals(6, u.getMean()[1], 1E-14);
+ u.clear();
+ u.setMeanImpl(new StorelessUnivariateStatistic[] {
+ new Mean(), new Mean()
+ }); // OK after clear
+ u.addValue(new double[] { 1, 2 });
+ u.addValue(new double[] { 3, 4 });
+ assertEquals(2, u.getMean()[0], 1E-14);
+ assertEquals(3, u.getMean()[1], 1E-14);
+ }
+
+ public void testSetterIllegalState() throws Exception {
+ MultivariateSummaryStatistics u = new MultivariateSummaryStatistics(2, true);
+ u.addValue(new double[] { 1, 2 });
+ u.addValue(new double[] { 3, 4 });
+ try {
+ u.setMeanImpl(new StorelessUnivariateStatistic[] {
+ new sumMean(), new sumMean()
+ });
+ fail("Expecting IllegalStateException");
+ } catch (IllegalStateException ex) {
+ // expected
+ }
+ }
+
+ /**
+ * Bogus mean implementation to test setter injection.
+ * Returns the sum instead of the mean.
+ */
+ static class sumMean implements StorelessUnivariateStatistic {
+ private static final long serialVersionUID = 6492471391340853423L;
+ private double sum = 0;
+ private long n = 0;
+ public double evaluate(double[] values, int begin, int length) {
+ return 0;
+ }
+ public double evaluate(double[] values) {
+ return 0;
+ }
+ public void clear() {
+ sum = 0;
+ n = 0;
+ }
+ public long getN() {
+ return n;
+ }
+ public double getResult() {
+ return sum;
+ }
+ public void increment(double d) {
+ sum += d;
+ n++;
+ }
+ public void incrementAll(double[] values, int start, int length) {
+ }
+ public void incrementAll(double[] values) {
+ }
+ }
+
+ public void testDimension() {
+ try {
+ new MultivariateSummaryStatistics(2, true).addValue(new double[3]);
+ } catch (DimensionMismatchException dme) {
+ // expected behavior
+ } catch (Exception e) {
+ fail("wrong exception caught");
+ }
+ }
+
+ /** test stats */
+ public void testStats() throws DimensionMismatchException {
+ MultivariateSummaryStatistics u = new MultivariateSummaryStatistics(2, true);
+ assertEquals(0, u.getN());
+ u.addValue(new double[] { 1, 2 });
+ u.addValue(new double[] { 2, 3 });
+ u.addValue(new double[] { 2, 3 });
+ u.addValue(new double[] { 3, 4 });
+ assertEquals( 4, u.getN());
+ assertEquals( 8, u.getSum()[0], 1.0e-10);
+ assertEquals(12, u.getSum()[1], 1.0e-10);
+ assertEquals(18, u.getSumSq()[0], 1.0e-10);
+ assertEquals(38, u.getSumSq()[1], 1.0e-10);
+ assertEquals( 1, u.getMin()[0], 1.0e-10);
+ assertEquals( 2, u.getMin()[1], 1.0e-10);
+ assertEquals( 3, u.getMax()[0], 1.0e-10);
+ assertEquals( 4, u.getMax()[1], 1.0e-10);
+ assertEquals(2.4849066497880003102, u.getSumLog()[0], 1.0e-10);
+ assertEquals( 4.276666119016055311, u.getSumLog()[1], 1.0e-10);
+ assertEquals( 1.8612097182041991979, u.getGeometricMean()[0], 1.0e-10);
+ assertEquals( 2.9129506302439405217, u.getGeometricMean()[1], 1.0e-10);
+ assertEquals( 2, u.getMean()[0], 1.0e-10);
+ assertEquals( 3, u.getMean()[1], 1.0e-10);
+ assertEquals(Math.sqrt(2.0 / 3.0), u.getStandardDeviation()[0], 1.0e-10);
+ assertEquals(Math.sqrt(2.0 / 3.0), u.getStandardDeviation()[1], 1.0e-10);
+ assertEquals(2.0 / 3.0, u.getCovariance().getEntry(0, 0), 1.0e-10);
+ assertEquals(2.0 / 3.0, u.getCovariance().getEntry(0, 1), 1.0e-10);
+ assertEquals(2.0 / 3.0, u.getCovariance().getEntry(1, 0), 1.0e-10);
+ assertEquals(2.0 / 3.0, u.getCovariance().getEntry(1, 1), 1.0e-10);
+ u.clear();
+ assertEquals(0, u.getN());
+ }
+
+ public void testN0andN1Conditions() throws Exception {
+ MultivariateSummaryStatistics u = new MultivariateSummaryStatistics(1, true);
+ assertTrue(Double.isNaN(u.getMean()[0]));
+ assertTrue(Double.isNaN(u.getStandardDeviation()[0]));
+
+ /* n=1 */
+ u.addValue(new double[] { 1 });
+ assertEquals(1.0, u.getMean()[0], 1.0e-10);
+ assertEquals(1.0, u.getGeometricMean()[0], 1.0e-10);
+ assertEquals(0.0, u.getStandardDeviation()[0], 1.0e-10);
+
+ /* n=2 */
+ u.addValue(new double[] { 2 });
+ assertTrue(u.getStandardDeviation()[0] > 0);
+
+ }
+
+ public void testNaNContracts() throws DimensionMismatchException {
+ MultivariateSummaryStatistics u = new MultivariateSummaryStatistics(1, true);
+ assertTrue(Double.isNaN(u.getMean()[0]));
+ assertTrue(Double.isNaN(u.getMin()[0]));
+ assertTrue(Double.isNaN(u.getStandardDeviation()[0]));
+ assertTrue(Double.isNaN(u.getGeometricMean()[0]));
+
+ u.addValue(new double[] { 1.0 });
+ assertFalse(Double.isNaN(u.getMean()[0]));
+ assertFalse(Double.isNaN(u.getMin()[0]));
+ assertFalse(Double.isNaN(u.getStandardDeviation()[0]));
+ assertFalse(Double.isNaN(u.getGeometricMean()[0]));
+
+ }
+
+ public void testGetSummary() throws DimensionMismatchException {
+ MultivariateSummaryStatistics u = new MultivariateSummaryStatistics(2, true);
+ StatisticalMultivariateSummary summary = u.getSummary();
+ verifySummary(u, summary);
+ u.addValue(new double[] { 1, 2 });
+ summary = u.getSummary();
+ verifySummary(u, summary);
+ u.addValue(new double[] { 2, 5 });
+ summary = u.getSummary();
+ verifySummary(u, summary);
+ u.addValue(new double[] { 2, 2 });
+ summary = u.getSummary();
+ verifySummary(u, summary);
+ }
+
+ public void testSerialization() throws DimensionMismatchException {
+ MultivariateSummaryStatistics u = new MultivariateSummaryStatistics(2, true);
+ // Empty test
+ TestUtils.checkSerializedEquality(u);
+ MultivariateSummaryStatistics s = (MultivariateSummaryStatistics) TestUtils.serializeAndRecover(u);
+ StatisticalMultivariateSummary summary = s.getSummary();
+ verifySummary(u, summary);
+
+ // Add some data
+ u.addValue(new double[] { 2d, 1d });
+ u.addValue(new double[] { 1d, 1d });
+ u.addValue(new double[] { 3d, 1d });
+ u.addValue(new double[] { 4d, 1d });
+ u.addValue(new double[] { 5d, 1d });
+
+ // Test again
+ TestUtils.checkSerializedEquality(u);
+ s = (MultivariateSummaryStatistics) TestUtils.serializeAndRecover(u);
+ summary = s.getSummary();
+ verifySummary(u, summary);
+
+ }
+
+ public void testEqualsAndHashCode() throws DimensionMismatchException {
+ MultivariateSummaryStatistics u = new MultivariateSummaryStatistics(2, true);
+ MultivariateSummaryStatistics t = null;
+ int emptyHash = u.hashCode();
+ assertTrue(u.equals(u));
+ assertFalse(u.equals(t));
+ assertFalse(u.equals(new Double(0)));
+ t = new MultivariateSummaryStatistics(2, true);
+ assertTrue(t.equals(u));
+ assertTrue(u.equals(t));
+ assertEquals(emptyHash, t.hashCode());
+
+ // Add some data to u
+ u.addValue(new double[] { 2d, 1d });
+ u.addValue(new double[] { 1d, 1d });
+ u.addValue(new double[] { 3d, 1d });
+ u.addValue(new double[] { 4d, 1d });
+ u.addValue(new double[] { 5d, 1d });
+ assertFalse(t.equals(u));
+ assertFalse(u.equals(t));
+ assertTrue(u.hashCode() != t.hashCode());
+
+ //Add data in same order to t
+ t.addValue(new double[] { 2d, 1d });
+ t.addValue(new double[] { 1d, 1d });
+ t.addValue(new double[] { 3d, 1d });
+ t.addValue(new double[] { 4d, 1d });
+ t.addValue(new double[] { 5d, 1d });
+ assertTrue(t.equals(u));
+ assertTrue(u.equals(t));
+ assertEquals(u.hashCode(), t.hashCode());
+
+ // Clear and make sure summaries are indistinguishable from empty summary
+ u.clear();
+ t.clear();
+ assertTrue(t.equals(u));
+ assertTrue(u.equals(t));
+ assertEquals(emptyHash, t.hashCode());
+ assertEquals(emptyHash, u.hashCode());
+ }
+
+ private void verifySummary(MultivariateSummaryStatistics u, StatisticalMultivariateSummary s) {
+ assertEquals(s.getN(), u.getN());
+ for (int i = 0; i < u.getDimension(); ++i) {
+ checkValue(s.getSum()[i], u.getSum()[i], 1.0e-10);
+ checkValue(s.getStandardDeviation()[i], u.getStandardDeviation()[i], 1.0e-10);
+ checkValue(s.getMean()[i], u.getMean()[i], 1.0e-10);
+ checkValue(s.getMin()[i], u.getMin()[i], 1.0e-10);
+ checkValue(s.getMax()[i], u.getMax()[i], 1.0e-10);
+ checkValue(s.getSumSq()[i], u.getSumSq()[i], 1.0e-10);
+ checkValue(s.getSumLog()[i], u.getSumLog()[i], 1.0e-10);
+ checkValue(s.getMax()[i], u.getMax()[i], 1.0e-10);
+ }
+ }
+
+ private void checkValue(double expected, double actual, double tolerance) {
+ if (Double.isNaN(expected)) {
+ assertTrue(Double.isNaN(actual));
+ } else {
+ assertEquals(expected, actual, tolerance);
+ }
+ }
+
+}
Propchange: commons/proper/math/trunk/src/test/org/apache/commons/math/stat/descriptive/MultivariateSummaryStatisticsTest.java
------------------------------------------------------------------------------
svn:eol-style = native