Added append method to StorelessCovariance, making this class map/reducible.

JIRA: MATH-978
Contributed by Ajo Fod

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1488337 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Phil Steitz 2013-05-31 17:47:53 +00:00
parent 94c9d2e023
commit 33809e031d
5 changed files with 74 additions and 0 deletions

View File

@ -183,6 +183,9 @@
<contributor>
<name>Ted Dunning</name>
</contributor>
<contributor>
<name>Ajo Fod</name>
</contributor>
<contributor>
<name>John Gant</name>
</contributor>

View File

@ -51,6 +51,9 @@ If the output is not quite correct, check for invisible trailing spaces!
</properties>
<body>
<release version="x.y" date="TBD" description="TBD">
<action dev="psteitz" type="update" issue="MATH-978" due-to="Ajo Fod">
Added append method to StorelessCovariance, making this class map/reducible.
</action>
<action dev="tn" type="add" issue="MATH-851" due-to="Clemens Novak">
Added method "MathArrays#convolve(double[], double[])" to compute the
discrete, linear convolution of two sequences.

View File

@ -90,6 +90,24 @@ class StorelessBivariateCovariance {
covarianceNumerator += ((n - 1.0) / n) * deltaX * deltaY;
}
/**
* Appends another bivariate covariance calculation to this.
* After this operation, statistics returned should be close to what would
* have been obtained by by performing all of the {@link #increment(double, double)}
* operations in {@code cov} directly on this.
*
* @param cov StorelessBivariateCovariance instance to append.
*/
public void append(StorelessBivariateCovariance cov) {
double oldN = n;
n += cov.n;
final double deltaX = cov.meanX - meanX;
final double deltaY = cov.meanY - meanY;
meanX += deltaX * cov.n / n;
meanY += deltaY * cov.n / n;
covarianceNumerator += cov.covarianceNumerator + oldN * cov.n / n * deltaX * deltaY;
}
/**
* Returns the number of observations.
*

View File

@ -162,6 +162,29 @@ public class StorelessCovariance extends Covariance {
}
/**
* Appends {@code sc} to this, effectively aggregating the computations in {@code sc}
* with this. After invoking this method, covariances returned should be close
* to what would have been obtained by performing all of the {@link #increment(double[])}
* operations in {@code sc} directly on this.
*
* @param sc externally computed StorelessCovariance to add to this
* @throws DimensionMismatchException if the dimension of sc does not match this
*/
public void append(StorelessCovariance sc) throws DimensionMismatchException {
if (sc.dimension != dimension) {
throw new DimensionMismatchException(sc.dimension, dimension);
}
// only update the upper triangular part of the covariance matrix
// as only these parts are actually stored
for (int i = 0; i < dimension; i++) {
for (int j = i; j < dimension; j++) {
getElement(i, j).append(sc.getElement(i, j));
}
}
}
/**
* {@inheritDoc}
* @throws NumberIsTooSmallException if the number of observations

View File

@ -19,6 +19,7 @@ package org.apache.commons.math3.stat.correlation;
import org.apache.commons.math3.TestUtils;
import org.apache.commons.math3.linear.Array2DRowRealMatrix;
import org.apache.commons.math3.linear.RealMatrix;
import org.apache.commons.math3.random.ISAACRandom;
import org.junit.Assert;
import org.junit.Test;
@ -221,6 +222,32 @@ public class StorelessCovarianceTest {
}
}
/**
* Test equality of covariance. chk: covariance of two
* samples separately and adds them together. cov: computes
* covariance of the combined sample showing both are equal.
*/
@Test
public void testEquivalence() {
int num_sets = 2;
StorelessBivariateCovariance cov = new StorelessBivariateCovariance();// covariance of the superset
StorelessBivariateCovariance chk = new StorelessBivariateCovariance();// check covariance made by appending covariance of subsets
ISAACRandom rand = new ISAACRandom(10L);// Seed can be changed
for (int s = 0; s < num_sets; s++) {// loop through sets of samlpes
StorelessBivariateCovariance covs = new StorelessBivariateCovariance();
for (int i = 0; i < 5; i++) { // loop through individual samlpes.
double x = rand.nextDouble();
double y = rand.nextDouble();
covs.increment(x, y);// add sample to the subset
cov.increment(x, y);// add sample to the superset
}
chk.append(covs);
}
TestUtils.assertEquals("covariance subset test", chk.getResult(), cov.getResult(), 10E-7);
}
protected RealMatrix createRealMatrix(double[] data, int nRows, int nCols) {
double[][] matrixData = new double[nRows][nCols];
int ptr = 0;