From 15d96cbafda499c3a41203c695bfe314d1db9b74 Mon Sep 17 00:00:00 2001 From: Luc Maisonobe Date: Mon, 26 Feb 2007 22:22:53 +0000 Subject: [PATCH] added support for generation and analysis of random vectors git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/math/trunk@512039 13f79535-47bb-0310-9956-ffa450edef68 --- .../math/random/GaussianRandomGenerator.java | 45 +++ .../random/NormalizedRandomGenerator.java | 16 +- .../NotPositiveDefiniteMatrixException.java} | 34 +-- .../math}/random/RandomVectorGenerator.java | 7 +- .../UncorrelatedRandomVectorGenerator.java | 48 +-- .../math/random/UniformRandomGenerator.java | 50 ++++ .../moment/VectorialCovariance.java | 105 +++++++ .../descriptive/moment/VectorialMean.java | 79 +++++ .../CorrelatedRandomVectorGenerator.java | 281 ------------------ .../random/GaussianRandomGenerator.java | 69 ----- .../NotPositiveDefiniteMatrixException.java | 50 ---- .../random/UniformRandomGenerator.java | 76 ----- .../CorrelatedRandomVectorGeneratorTest.java | 114 ------- .../random/GaussianRandomGeneratorTest.java | 43 --- ...UncorrelatedRandomVectorGeneratorTest.java | 78 ----- .../random/VectorialSampleStatisticsTest.java | 167 ----------- .../random/GaussianRandomGeneratorTest.java | 47 +++ ...UncorrelatedRandomVectorGeneratorTest.java | 86 ++++++ .../random/UniformRandomGeneratorTest.java | 47 +++ .../moment/VectorialCovarianceTest.java | 101 +++++++ .../descriptive/moment/VectorialMeanTest.java | 93 ++++++ 21 files changed, 688 insertions(+), 948 deletions(-) create mode 100644 src/java/org/apache/commons/math/random/GaussianRandomGenerator.java rename src/{mantissa/src/org/spaceroots/mantissa => java/org/apache/commons/math}/random/NormalizedRandomGenerator.java (75%) rename src/{mantissa/tests-src/org/spaceroots/mantissa/random/UniformRandomGeneratorTest.java => java/org/apache/commons/math/random/NotPositiveDefiniteMatrixException.java} (54%) rename src/{mantissa/src/org/spaceroots/mantissa => java/org/apache/commons/math}/random/RandomVectorGenerator.java (80%) rename src/{mantissa/src/org/spaceroots/mantissa => java/org/apache/commons/math}/random/UncorrelatedRandomVectorGenerator.java (68%) create mode 100644 src/java/org/apache/commons/math/random/UniformRandomGenerator.java create mode 100644 src/java/org/apache/commons/math/stat/descriptive/moment/VectorialCovariance.java create mode 100644 src/java/org/apache/commons/math/stat/descriptive/moment/VectorialMean.java delete mode 100644 src/mantissa/src/org/spaceroots/mantissa/random/CorrelatedRandomVectorGenerator.java delete mode 100644 src/mantissa/src/org/spaceroots/mantissa/random/GaussianRandomGenerator.java delete mode 100644 src/mantissa/src/org/spaceroots/mantissa/random/NotPositiveDefiniteMatrixException.java delete mode 100644 src/mantissa/src/org/spaceroots/mantissa/random/UniformRandomGenerator.java delete mode 100644 src/mantissa/tests-src/org/spaceroots/mantissa/random/CorrelatedRandomVectorGeneratorTest.java delete mode 100644 src/mantissa/tests-src/org/spaceroots/mantissa/random/GaussianRandomGeneratorTest.java delete mode 100644 src/mantissa/tests-src/org/spaceroots/mantissa/random/UncorrelatedRandomVectorGeneratorTest.java delete mode 100644 src/mantissa/tests-src/org/spaceroots/mantissa/random/VectorialSampleStatisticsTest.java create mode 100644 src/test/org/apache/commons/math/random/GaussianRandomGeneratorTest.java create mode 100644 src/test/org/apache/commons/math/random/UncorrelatedRandomVectorGeneratorTest.java create mode 100644 src/test/org/apache/commons/math/random/UniformRandomGeneratorTest.java create mode 100644 src/test/org/apache/commons/math/stat/descriptive/moment/VectorialCovarianceTest.java create mode 100644 src/test/org/apache/commons/math/stat/descriptive/moment/VectorialMeanTest.java diff --git a/src/java/org/apache/commons/math/random/GaussianRandomGenerator.java b/src/java/org/apache/commons/math/random/GaussianRandomGenerator.java new file mode 100644 index 000000000..fc88a4d98 --- /dev/null +++ b/src/java/org/apache/commons/math/random/GaussianRandomGenerator.java @@ -0,0 +1,45 @@ +// 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.random; + +/** This class is a gaussian normalized random generator for scalars. + *

This class is a simple wrapper around the {@link + * RandomGenerator#nextGaussian} method.

+ * @version $Revision:$ $Date$ + */ + +public class GaussianRandomGenerator implements NormalizedRandomGenerator { + + /** Create a new generator. + * @param generator underlying random generator to use + */ + public GaussianRandomGenerator(RandomGenerator generator) { + this.generator = generator; + } + + /** Generate a random scalar with null mean and unit standard deviation. + * @return a random scalar with null mean and unit standard deviation + */ + public double nextNormalizedDouble() { + return generator.nextGaussian(); + } + + /** Underlying generator. */ + private RandomGenerator generator; + +} diff --git a/src/mantissa/src/org/spaceroots/mantissa/random/NormalizedRandomGenerator.java b/src/java/org/apache/commons/math/random/NormalizedRandomGenerator.java similarity index 75% rename from src/mantissa/src/org/spaceroots/mantissa/random/NormalizedRandomGenerator.java rename to src/java/org/apache/commons/math/random/NormalizedRandomGenerator.java index 50d3bed04..c61967f86 100644 --- a/src/mantissa/src/org/spaceroots/mantissa/random/NormalizedRandomGenerator.java +++ b/src/java/org/apache/commons/math/random/NormalizedRandomGenerator.java @@ -15,26 +15,22 @@ // specific language governing permissions and limitations // under the License. -package org.spaceroots.mantissa.random; - -import java.io.Serializable; +package org.apache.commons.math.random; /** This interface represent a normalized random generator for * scalars. - * Normalized generator should provide null mean and unit standard - * deviation scalars. - * @version $Id: NormalizedRandomGenerator.java 1705 2006-09-17 19:57:39Z luc $ - * @author L. Maisonobe + * Normalized generator provide null mean and unit standard deviation scalars. + * @version $Revision:$ $Date$ */ -public interface NormalizedRandomGenerator extends Serializable { +public interface NormalizedRandomGenerator { /** Generate a random scalar with null mean and unit standard deviation. *

This method does not specify the shape of the * distribution, it is the implementing class that provides it. The * only contract here is to generate numbers with null mean and unit * standard deviation.

- * @return a random scalar + * @return a random scalar with null mean and unit standard deviation */ - public double nextDouble(); + public double nextNormalizedDouble(); } diff --git a/src/mantissa/tests-src/org/spaceroots/mantissa/random/UniformRandomGeneratorTest.java b/src/java/org/apache/commons/math/random/NotPositiveDefiniteMatrixException.java similarity index 54% rename from src/mantissa/tests-src/org/spaceroots/mantissa/random/UniformRandomGeneratorTest.java rename to src/java/org/apache/commons/math/random/NotPositiveDefiniteMatrixException.java index b48b420ec..3666af219 100644 --- a/src/mantissa/tests-src/org/spaceroots/mantissa/random/UniformRandomGeneratorTest.java +++ b/src/java/org/apache/commons/math/random/NotPositiveDefiniteMatrixException.java @@ -15,29 +15,25 @@ // specific language governing permissions and limitations // under the License. -package org.spaceroots.mantissa.random; +package org.apache.commons.math.random; -import junit.framework.*; +import org.apache.commons.math.MathException; -public class UniformRandomGeneratorTest - extends TestCase { +/** This class represents exceptions thrown by the correlated random + * vector generator. + * @version $Revision:$ $Date$ + */ - public UniformRandomGeneratorTest(String name) { - super(name); - } +public class NotPositiveDefiniteMatrixException extends MathException { - public void testMeanAndStandardDeviation() { - UniformRandomGenerator generator = new UniformRandomGenerator(17399225432l); - ScalarSampleStatistics sample = new ScalarSampleStatistics(); - for (int i = 0; i < 1000; ++i) { - sample.add(generator.nextDouble()); + /** Serializable version identifier */ + private static final long serialVersionUID = 4122929125438624648L; + + /** Simple constructor. + * build an exception with a default message. + */ + public NotPositiveDefiniteMatrixException() { + super("not positive definite matrix", new Object[0]); } - assertEquals(0.0, sample.getMean(), 0.07); - assertEquals(1.0, sample.getStandardDeviation(), 0.02); - } - - public static Test suite() { - return new TestSuite(UniformRandomGeneratorTest.class); - } } diff --git a/src/mantissa/src/org/spaceroots/mantissa/random/RandomVectorGenerator.java b/src/java/org/apache/commons/math/random/RandomVectorGenerator.java similarity index 80% rename from src/mantissa/src/org/spaceroots/mantissa/random/RandomVectorGenerator.java rename to src/java/org/apache/commons/math/random/RandomVectorGenerator.java index c9ea8084a..387961d88 100644 --- a/src/mantissa/src/org/spaceroots/mantissa/random/RandomVectorGenerator.java +++ b/src/java/org/apache/commons/math/random/RandomVectorGenerator.java @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -package org.spaceroots.mantissa.random; +package org.apache.commons.math.random; /** This interface represent a random generator for whole vectors. @@ -27,10 +27,7 @@ package org.spaceroots.mantissa.random; public interface RandomVectorGenerator { /** Generate a random vector. - * @return a random vector as an array of double. The generator - * will reuse the same array for each call, in order to - * save the allocation time, so the user should keep a copy by - * himself if he needs so. + * @return a random vector as an array of double. */ public double[] nextVector(); diff --git a/src/mantissa/src/org/spaceroots/mantissa/random/UncorrelatedRandomVectorGenerator.java b/src/java/org/apache/commons/math/random/UncorrelatedRandomVectorGenerator.java similarity index 68% rename from src/mantissa/src/org/spaceroots/mantissa/random/UncorrelatedRandomVectorGenerator.java rename to src/java/org/apache/commons/math/random/UncorrelatedRandomVectorGenerator.java index 68dc24701..5e02d9c32 100644 --- a/src/mantissa/src/org/spaceroots/mantissa/random/UncorrelatedRandomVectorGenerator.java +++ b/src/java/org/apache/commons/math/random/UncorrelatedRandomVectorGenerator.java @@ -15,42 +15,34 @@ // specific language governing permissions and limitations // under the License. -package org.spaceroots.mantissa.random; +package org.apache.commons.math.random; -import java.io.Serializable; +import java.util.Arrays; /** This class allows to generate random vectors with uncorrelated components. - - * @version $Id: UncorrelatedRandomVectorGenerator.java 1705 2006-09-17 19:57:39Z luc $ - * @author L. Maisonobe - + * @version $Id:$ */ public class UncorrelatedRandomVectorGenerator - implements Serializable, RandomVectorGenerator { + implements RandomVectorGenerator { /** Simple constructor. - *

Build an uncorrelated random vector generator from its mean - * and standard deviation vectors.

- * @param mean expected mean values for all components - * @param standardDeviation standard deviation for all components + *

Build an uncorrelated random vector generator from + * its mean and standard deviation vectors.

+ * @param mean expected mean values for each component + * @param standardDeviation standard deviation for each component * @param generator underlying generator for uncorrelated normalized * components - * @exception IllegalArgumentException if there is a dimension - * mismatch between the mean and standard deviation vectors */ public UncorrelatedRandomVectorGenerator(double[] mean, double[] standardDeviation, NormalizedRandomGenerator generator) { - if (mean.length != standardDeviation.length) { throw new IllegalArgumentException("dimension mismatch"); } this.mean = (double[]) mean.clone(); this.standardDeviation = (double[]) standardDeviation.clone(); - this.generator = generator; - } /** Simple constructor. @@ -62,34 +54,20 @@ public class UncorrelatedRandomVectorGenerator */ public UncorrelatedRandomVectorGenerator(int dimension, NormalizedRandomGenerator generator) { - mean = new double[dimension]; standardDeviation = new double[dimension]; - for (int i = 0; i < dimension; ++i) { - mean[i] = 0; - standardDeviation[i] = 1; - } - + Arrays.fill(standardDeviation, 1.0); this.generator = generator; - - } - - /** Get the underlying normalized components generator. - * @return underlying uncorrelated components generator - */ - public NormalizedRandomGenerator getGenerator() { - return generator; } /** Generate a correlated random vector. - * @return a random vector as an array of double. The returned array - * is created at each call, the caller can do what it wants with it. + * @return a random vector as a newly built array of double */ public double[] nextVector() { double[] random = new double[mean.length]; for (int i = 0; i < random.length; ++i) { - random[i] = mean[i] + standardDeviation[i] * generator.nextDouble(); + random[i] = mean[i] + standardDeviation[i] * generator.nextNormalizedDouble(); } return random; @@ -103,8 +81,6 @@ public class UncorrelatedRandomVectorGenerator private double[] standardDeviation; /** Underlying scalar generator. */ - NormalizedRandomGenerator generator; - - private static final long serialVersionUID = -9094322067568302961L; + private NormalizedRandomGenerator generator; } diff --git a/src/java/org/apache/commons/math/random/UniformRandomGenerator.java b/src/java/org/apache/commons/math/random/UniformRandomGenerator.java new file mode 100644 index 000000000..e072e4ab4 --- /dev/null +++ b/src/java/org/apache/commons/math/random/UniformRandomGenerator.java @@ -0,0 +1,50 @@ +// 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.random; + +/** This class implements a normalized uniform random generator. + *

Since it is a normalized random generator, it has a null mean + * and a unit standard deviation. Being also a uniform + * generator, it produces numbers in the range [-&sqrt;(3) ; +&sqrt;(3)].

+ * @version $Revision:$ $Date$ + */ + +public class UniformRandomGenerator implements NormalizedRandomGenerator { + + /** Create a new generator. + * @param generator underlying random generator to use + */ + public UniformRandomGenerator(RandomGenerator generator) { + this.generator = generator; + } + + /** Generate a random scalar with null mean and unit standard deviation. + *

The number generated is uniformly distributed between -&sqrt;(3) + * and +&sqrt;(3).

+ * @return a random scalar with null mean and unit standard deviation + */ + public double nextNormalizedDouble() { + return SQRT3 * (2 * generator.nextDouble() - 1.0); + } + + /** Underlying generator. */ + private RandomGenerator generator; + + private static final double SQRT3 = Math.sqrt(3.0); + +} diff --git a/src/java/org/apache/commons/math/stat/descriptive/moment/VectorialCovariance.java b/src/java/org/apache/commons/math/stat/descriptive/moment/VectorialCovariance.java new file mode 100644 index 000000000..f76f8cba7 --- /dev/null +++ b/src/java/org/apache/commons/math/stat/descriptive/moment/VectorialCovariance.java @@ -0,0 +1,105 @@ +/* + * 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.moment; + +import java.io.Serializable; + +import org.apache.commons.math.DimensionMismatchException; +import org.apache.commons.math.linear.RealMatrix; +import org.apache.commons.math.linear.RealMatrixImpl; + +/** + * Returns the covariance matrix of the available vectors. + * @version $Revision:$ + */ +public class VectorialCovariance implements Serializable { + + /** Serializable version identifier */ + private static final long serialVersionUID = 4118372414238930270L; + + /** Sums for each component. */ + private double[] sums; + + /** Sums of products for each component. */ + private double[] productsSums; + + /** Number of vectors in the sample. */ + private long n; + + /** Constructs a VectorialMean. + * @param dimension vectors dimension + */ + public VectorialCovariance(int dimension) { + sums = new double[dimension]; + productsSums = new double[dimension * (dimension + 1) / 2]; + n = 0; + } + + /** + * Add a new vector to the sample. + * @param vector vector to add + * @exception DimensionMismatchException if the vector does not have the right dimension + */ + public void increment(double[] v) throws DimensionMismatchException { + if (v.length != sums.length) { + throw new DimensionMismatchException(v.length, sums.length); + } + int k = 0; + for (int i = 0; i < v.length; ++i) { + sums[i] += v[i]; + for (int j = 0; j <= i; ++j) { + productsSums[k++] += v[i] * v[j]; + } + } + n++; + } + + /** + * Get the covariance matrix. + * @return covariance matrix + */ + public RealMatrix getResult() { + + int dimension = sums.length; + RealMatrixImpl result = new RealMatrixImpl(dimension, dimension); + + if (n > 1) { + double[][] resultData = result.getDataRef(); + double c = 1.0 / (n * (n - 1)); + int k = 0; + for (int i = 0; i < dimension; ++i) { + for (int j = 0; j <= i; ++j) { + double e = c * (n * productsSums[k++] - sums[i] * sums[j]); + resultData[i][j] = e; + resultData[j][i] = e; + } + } + } + + return result; + + } + + /** + * Get the number of vectors in the sample. + * @return number of vectors in the sample + */ + public long getN() { + return n; + } + +} \ No newline at end of file diff --git a/src/java/org/apache/commons/math/stat/descriptive/moment/VectorialMean.java b/src/java/org/apache/commons/math/stat/descriptive/moment/VectorialMean.java new file mode 100644 index 000000000..9669c3de7 --- /dev/null +++ b/src/java/org/apache/commons/math/stat/descriptive/moment/VectorialMean.java @@ -0,0 +1,79 @@ +/* + * 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.moment; + +import java.io.Serializable; + +import org.apache.commons.math.DimensionMismatchException; + +/** + * Returns the arithmetic mean of the available vectors. + * @version $Revision:$ + */ +public class VectorialMean implements Serializable { + + /** Serializable version identifier */ + private static final long serialVersionUID = 8223009086481006892L; + + /** Means for each component. */ + private Mean[] means; + + /** Constructs a VectorialMean. + * @param dimension vectors dimension + */ + public VectorialMean(int dimension) { + means = new Mean[dimension]; + for (int i = 0; i < dimension; ++i) { + means[i] = new Mean(); + } + } + + /** + * Add a new vector to the sample. + * @param vector vector to add + * @exception DimensionMismatchException if the vector does not have the right dimension + */ + public void increment(double[] v) throws DimensionMismatchException { + if (v.length != means.length) { + throw new DimensionMismatchException(v.length, means.length); + } + for (int i = 0; i < v.length; ++i) { + means[i].increment(v[i]); + } + } + + /** + * Get the mean vector. + * @return mean vector + */ + public double[] getResult() { + double[] result = new double[means.length]; + for (int i = 0; i < result.length; ++i) { + result[i] = means[i].getResult(); + } + return result; + } + + /** + * Get the number of vectors in the sample. + * @return number of vectors in the sample + */ + public long getN() { + return (means.length == 0) ? 0 : means[0].getN(); + } + +} \ No newline at end of file diff --git a/src/mantissa/src/org/spaceroots/mantissa/random/CorrelatedRandomVectorGenerator.java b/src/mantissa/src/org/spaceroots/mantissa/random/CorrelatedRandomVectorGenerator.java deleted file mode 100644 index e4e81062d..000000000 --- a/src/mantissa/src/org/spaceroots/mantissa/random/CorrelatedRandomVectorGenerator.java +++ /dev/null @@ -1,281 +0,0 @@ -// 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.spaceroots.mantissa.random; - -import org.spaceroots.mantissa.MantissaException; -import org.spaceroots.mantissa.linalg.Matrix; -import org.spaceroots.mantissa.linalg.GeneralMatrix; -import org.spaceroots.mantissa.linalg.SymetricalMatrix; - -import java.io.Serializable; - -/** This class allows to generate random vectors with correlated components. - - *

Random vectors with correlated components are built by combining - * the uncorrelated components of another random vector in such a way - * the resulting correlations are the ones specified by a positive - * definite covariance matrix.

- - *

Sometimes, the covariance matrix for a given simulation is not - * strictly positive definite. This means that the correlations are - * not all independant from each other. In this case, however, the non - * strictly positive elements found during the Cholesky decomposition - * of the covariance matrix should not be negative either, they - * should be null. This implies that rather than computing C = - * L.Lt where C is the covariance matrix and - * L is a lower-triangular matrix, we compute C = - * B.Bt where B is a rectangular matrix having - * more rows than columns. The number of columns of B is - * the rank of the covariance matrix, and it is the dimension of the - * uncorrelated random vector that is needed to compute the component - * of the correlated vector. This class does handle this situation - * automatically.

- - * @version $Id: CorrelatedRandomVectorGenerator.java 1705 2006-09-17 19:57:39Z luc $ - * @author L. Maisonobe - - */ - -public class CorrelatedRandomVectorGenerator - implements Serializable, RandomVectorGenerator { - - /** Simple constructor. - *

Build a correlated random vector generator from its mean - * vector and covariance matrix.

- * @param mean expected mean values for all components - * @param covariance covariance matrix - * @param generator underlying generator for uncorrelated normalized - * components - * @exception IllegalArgumentException if there is a dimension - * mismatch between the mean vector and the covariance matrix - * @exception NotPositiveDefiniteMatrixException if the - * covariance matrix is not strictly positive definite - */ - public CorrelatedRandomVectorGenerator(double[] mean, - SymetricalMatrix covariance, - NormalizedRandomGenerator generator) - throws NotPositiveDefiniteMatrixException { - - int order = covariance.getRows(); - if (mean.length != order) { - String message = - MantissaException.translate("dimension mismatch {0} != {1}", - new String[] { - Integer.toString(mean.length), - Integer.toString(order) - }); - throw new IllegalArgumentException(message); - } - this.mean = (double[]) mean.clone(); - - factorize(covariance); - - this.generator = generator; - normalized = new double[rank]; - - } - - /** Simple constructor. - *

Build a null mean random correlated vector generator from its - * covariance matrix.

- * @param covariance covariance matrix - * @param generator underlying generator for uncorrelated normalized - * components - * @exception NotPositiveDefiniteMatrixException if the - * covariance matrix is not strictly positive definite - */ - public CorrelatedRandomVectorGenerator(SymetricalMatrix covariance, - NormalizedRandomGenerator generator) - throws NotPositiveDefiniteMatrixException { - - int order = covariance.getRows(); - mean = new double[order]; - for (int i = 0; i < order; ++i) { - mean[i] = 0; - } - - factorize(covariance); - - this.generator = generator; - normalized = new double[rank]; - - } - - /** Get the root of the covariance matrix. - * The root is the matrix B such that B.Bt - * is equal to the covariance matrix - * @return root of the square matrix - */ - public Matrix getRootMatrix() { - return root; - } - - /** Get the underlying normalized components generator. - * @return underlying uncorrelated components generator - */ - public NormalizedRandomGenerator getGenerator() { - return generator; - } - - /** Get the rank of the covariance matrix. - * The rank is the number of independant rows in the covariance - * matrix, it is also the number of columns of the rectangular - * matrix of the factorization. - * @return rank of the square matrix. - */ - public int getRank() { - return rank; - } - - /** Factorize the original square matrix. - * @param covariance covariance matrix - * @exception NotPositiveDefiniteMatrixException if the - * covariance matrix is not strictly positive definite - */ - private void factorize(SymetricalMatrix covariance) - throws NotPositiveDefiniteMatrixException { - - int order = covariance.getRows(); - SymetricalMatrix c = (SymetricalMatrix) covariance.duplicate(); - GeneralMatrix b = new GeneralMatrix(order, order); - - int[] swap = new int[order]; - int[] index = new int[order]; - for (int i = 0; i < order; ++i) { - index[i] = i; - } - - rank = 0; - for (boolean loop = true; loop;) { - - // find maximal diagonal element - swap[rank] = rank; - for (int i = rank + 1; i < order; ++i) { - if (c.getElement(index[i], index[i]) - > c.getElement(index[swap[i]], index[swap[i]])) { - swap[rank] = i; - } - } - - - // swap elements - if (swap[rank] != rank) { - int tmp = index[rank]; - index[rank] = index[swap[rank]]; - index[swap[rank]] = tmp; - } - - // check diagonal element - if (c.getElement(index[rank], index[rank]) < 1.0e-12) { - - if (rank == 0) { - throw new NotPositiveDefiniteMatrixException(); - } - - // check remaining diagonal elements - for (int i = rank; i < order; ++i) { - if (c.getElement(index[rank], index[rank]) < -1.0e-12) { - // there is at least one sufficiently negative diagonal element, - // the covariance matrix is wrong - throw new NotPositiveDefiniteMatrixException(); - } - } - - // all remaining diagonal elements are close to zero, - // we consider we have found the rank of the covariance matrix - ++rank; - loop = false; - - } else { - - // transform the matrix - double sqrt = Math.sqrt(c.getElement(index[rank], index[rank])); - b.setElement(rank, rank, sqrt); - double inverse = 1 / sqrt; - for (int i = rank + 1; i < order; ++i) { - double e = inverse * c.getElement(index[i], index[rank]); - b.setElement(i, rank, e); - c.setElement(index[i], index[i], - c.getElement(index[i], index[i]) - e * e); - for (int j = rank + 1; j < i; ++j) { - double f = b.getElement(j, rank); - c.setElementAndSymetricalElement(index[i], index[j], - c.getElement(index[i], index[j]) - - e * f); - } - } - - // prepare next iteration - loop = ++rank < order; - - } - - } - - // build the root matrix - root = new GeneralMatrix(order, rank); - for (int i = 0; i < order; ++i) { - for (int j = 0; j < rank; ++j) { - root.setElement(swap[i], j, b.getElement(i, j)); - } - } - - } - - /** Generate a correlated random vector. - * @return a random vector as an array of double. The returned array - * is created at each call, the caller can do what it wants with it. - */ - public double[] nextVector() { - - // generate uncorrelated vector - for (int i = 0; i < rank; ++i) { - normalized[i] = generator.nextDouble(); - } - - // compute correlated vector - double[] correlated = new double[mean.length]; - for (int i = 0; i < correlated.length; ++i) { - correlated[i] = mean[i]; - for (int j = 0; j < rank; ++j) { - correlated[i] += root.getElement(i, j) * normalized[j]; - } - } - - return correlated; - - } - - /** Mean vector. */ - private double[] mean; - - /** Permutated Cholesky root of the covariance matrix. */ - private Matrix root; - - /** Rank of the covariance matrix. */ - private int rank; - - /** Underlying generator. */ - NormalizedRandomGenerator generator; - - /** Storage for the normalized vector. */ - private double[] normalized; - - private static final long serialVersionUID = -88563624902398453L; - -} diff --git a/src/mantissa/src/org/spaceroots/mantissa/random/GaussianRandomGenerator.java b/src/mantissa/src/org/spaceroots/mantissa/random/GaussianRandomGenerator.java deleted file mode 100644 index a6497bca0..000000000 --- a/src/mantissa/src/org/spaceroots/mantissa/random/GaussianRandomGenerator.java +++ /dev/null @@ -1,69 +0,0 @@ -// 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.spaceroots.mantissa.random; - -import java.util.Random; - -/** This class is a gaussian normalized random generator - * for scalars. - - *

This class is a simple interface adaptor around the {@link - * java.util.Random#nextGaussian nextGaussian} method.

- - * @version $Id: GaussianRandomGenerator.java 1705 2006-09-17 19:57:39Z luc $ - * @author L. Maisonobe - - */ - -public class GaussianRandomGenerator - implements NormalizedRandomGenerator { - - /** Create a new generator. - * The seed of the generator is related to the current time. - */ - public GaussianRandomGenerator() { - generator = new Random(); - } - - /** Creates a new random number generator using a single int seed. - * @param seed the initial seed (32 bits integer) - */ - public GaussianRandomGenerator(int seed) { - generator = new Random(seed); - } - - /** Create a new generator initialized with a single long seed. - * @param seed seed for the generator (64 bits integer) - */ - public GaussianRandomGenerator(long seed) { - generator = new Random(seed); - } - - /** Generate a random scalar with null mean and unit standard deviation. - * @return a random scalar with null mean and unit standard deviation - */ - public double nextDouble() { - return generator.nextGaussian(); - } - - /** Underlying generator. */ - private Random generator; - - private static final long serialVersionUID = 5504568059866195697L; - -} diff --git a/src/mantissa/src/org/spaceroots/mantissa/random/NotPositiveDefiniteMatrixException.java b/src/mantissa/src/org/spaceroots/mantissa/random/NotPositiveDefiniteMatrixException.java deleted file mode 100644 index e79a786f3..000000000 --- a/src/mantissa/src/org/spaceroots/mantissa/random/NotPositiveDefiniteMatrixException.java +++ /dev/null @@ -1,50 +0,0 @@ -// 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.spaceroots.mantissa.random; - -import org.spaceroots.mantissa.MantissaException; - -/** This class represents exceptions thrown by the correlated random - * vector generator. - - * @version $Id: NotPositiveDefiniteMatrixException.java 1705 2006-09-17 19:57:39Z luc $ - * @author L. Maisonobe - - */ - -public class NotPositiveDefiniteMatrixException - extends MantissaException { - - /** Simple constructor. - * build an exception with a default message. - */ - public NotPositiveDefiniteMatrixException() { - super("not positive definite matrix"); - } - - /** Simple constructor. - * build an exception with the specified message. - * @param message message to use to build the exception - */ - public NotPositiveDefiniteMatrixException(String message) { - super(message); - } - - private static final long serialVersionUID = -6801349873804445905L; - -} diff --git a/src/mantissa/src/org/spaceroots/mantissa/random/UniformRandomGenerator.java b/src/mantissa/src/org/spaceroots/mantissa/random/UniformRandomGenerator.java deleted file mode 100644 index 1dc5ea006..000000000 --- a/src/mantissa/src/org/spaceroots/mantissa/random/UniformRandomGenerator.java +++ /dev/null @@ -1,76 +0,0 @@ -// 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.spaceroots.mantissa.random; - -import java.util.Random; - -/** This class implements a normalized uniform random generator. - - *

Since this is a normalized random generator, it has a null mean - * and a unit standard deviation. Being also a uniform - * generator, it produces numbers in the range [-sqrt(3) ; - * sqrt(3)].

- - * @version $Id: UniformRandomGenerator.java 1705 2006-09-17 19:57:39Z luc $ - * @author L. Maisonobe - - */ - -public class UniformRandomGenerator - implements NormalizedRandomGenerator { - - /** Create a new generator. - * The seed of the generator is related to the current time. - */ - public UniformRandomGenerator() { - generator = new Random(); - } - - /** Creates a new random number generator using a single int seed. - * @param seed the initial seed (32 bits integer) - */ - public UniformRandomGenerator(int seed) { - generator = new Random(seed); - } - - /** Create a new generator initialized with a single long seed. - * @param seed seed for the generator (64 bits integer) - */ - public UniformRandomGenerator(long seed) { - generator = new Random(seed); - } - - /** Generate a random scalar with null mean and unit standard deviation. - *

The number generated is uniformly distributed between -sqrt(3) - * and sqrt(3).

- * @return a random scalar with null mean and unit standard deviation - */ - public double nextDouble() { - return TWOSQRT3 * generator.nextDouble() - SQRT3; - } - - /** Underlying generator. */ - private Random generator; - - private static final double SQRT3 = Math.sqrt(3.0); - - private static final double TWOSQRT3 = 2.0 * Math.sqrt(3.0); - - private static final long serialVersionUID = -6913329325753217654L; - -} diff --git a/src/mantissa/tests-src/org/spaceroots/mantissa/random/CorrelatedRandomVectorGeneratorTest.java b/src/mantissa/tests-src/org/spaceroots/mantissa/random/CorrelatedRandomVectorGeneratorTest.java deleted file mode 100644 index 632cc845a..000000000 --- a/src/mantissa/tests-src/org/spaceroots/mantissa/random/CorrelatedRandomVectorGeneratorTest.java +++ /dev/null @@ -1,114 +0,0 @@ -// 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.spaceroots.mantissa.random; - -import org.spaceroots.mantissa.linalg.Matrix; -import org.spaceroots.mantissa.linalg.GeneralMatrix; -import org.spaceroots.mantissa.linalg.SymetricalMatrix; - -import junit.framework.*; - -public class CorrelatedRandomVectorGeneratorTest - extends TestCase { - - public CorrelatedRandomVectorGeneratorTest(String name) { - super(name); - mean = null; - covariance = null; - generator = null; - } - - public void testRank() { - assertEquals(3, generator.getRank()); - } - - public void testRootMatrix() { - Matrix b = generator.getRootMatrix(); - Matrix bbt = b.mul(b.getTranspose()); - for (int i = 0; i < covariance.getRows(); ++i) { - for (int j = 0; j < covariance.getColumns(); ++j) { - assertEquals(covariance.getElement(i, j), - bbt.getElement(i, j), - 1.0e-12); - } - } - } - - public void testMeanAndCovariance() { - - VectorialSampleStatistics sample = new VectorialSampleStatistics(); - for (int i = 0; i < 5000; ++i) { - sample.add(generator.nextVector()); - } - - double[] estimatedMean = sample.getMean(); - SymetricalMatrix estimatedCovariance = sample.getCovarianceMatrix(null); - for (int i = 0; i < estimatedMean.length; ++i) { - assertEquals(mean[i], estimatedMean[i], 0.07); - for (int j = 0; j <= i; ++j) { - assertEquals(covariance.getElement(i, j), - estimatedCovariance.getElement(i, j), - 0.1 * (1.0 + Math.abs(mean[i])) * (1.0 + Math.abs(mean[j]))); - } - } - - } - - public void setUp() { - try { - mean = new double[] { 0.0, 1.0, -3.0, 2.3}; - - GeneralMatrix b = new GeneralMatrix(4, 3); - int counter = 0; - for (int i = 0; i < b.getRows(); ++i) { - for (int j = 0; j < b.getColumns(); ++j) { - b.setElement(i, j, 1.0 + 0.1 * ++counter); - } - } - Matrix bbt = b.mul(b.getTranspose()); - covariance = new SymetricalMatrix(mean.length); - for (int i = 0; i < covariance.getRows(); ++i) { - covariance.setElement(i, i, bbt.getElement(i, i)); - for (int j = 0; j < covariance.getColumns(); ++j) { - covariance.setElementAndSymetricalElement(i, j, - bbt.getElement(i, j)); - } - } - - GaussianRandomGenerator rawGenerator = new GaussianRandomGenerator(17399225432l); - generator = new CorrelatedRandomVectorGenerator(mean, covariance, rawGenerator); - } catch (NotPositiveDefiniteMatrixException e) { - fail("not positive definite matrix"); - } - } - - public void tearDown() { - mean = null; - covariance = null; - generator = null; - } - - public static Test suite() { - return new TestSuite(CorrelatedRandomVectorGeneratorTest.class); - } - - private double[] mean; - private SymetricalMatrix covariance; - private CorrelatedRandomVectorGenerator generator; - -} diff --git a/src/mantissa/tests-src/org/spaceroots/mantissa/random/GaussianRandomGeneratorTest.java b/src/mantissa/tests-src/org/spaceroots/mantissa/random/GaussianRandomGeneratorTest.java deleted file mode 100644 index 2f0156db6..000000000 --- a/src/mantissa/tests-src/org/spaceroots/mantissa/random/GaussianRandomGeneratorTest.java +++ /dev/null @@ -1,43 +0,0 @@ -// 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.spaceroots.mantissa.random; - -import junit.framework.*; - -public class GaussianRandomGeneratorTest - extends TestCase { - - public GaussianRandomGeneratorTest(String name) { - super(name); - } - - public void testMeanAndStandardDeviation() { - GaussianRandomGenerator generator = new GaussianRandomGenerator(17399225432l); - ScalarSampleStatistics sample = new ScalarSampleStatistics(); - for (int i = 0; i < 10000; ++i) { - sample.add(generator.nextDouble()); - } - assertEquals(0.0, sample.getMean(), 0.012); - assertEquals(1.0, sample.getStandardDeviation(), 0.01); - } - - public static Test suite() { - return new TestSuite(GaussianRandomGeneratorTest.class); - } - -} diff --git a/src/mantissa/tests-src/org/spaceroots/mantissa/random/UncorrelatedRandomVectorGeneratorTest.java b/src/mantissa/tests-src/org/spaceroots/mantissa/random/UncorrelatedRandomVectorGeneratorTest.java deleted file mode 100644 index 85624ffc9..000000000 --- a/src/mantissa/tests-src/org/spaceroots/mantissa/random/UncorrelatedRandomVectorGeneratorTest.java +++ /dev/null @@ -1,78 +0,0 @@ -// 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.spaceroots.mantissa.random; - -import org.spaceroots.mantissa.linalg.SymetricalMatrix; - -import junit.framework.*; - -public class UncorrelatedRandomVectorGeneratorTest - extends TestCase { - - public UncorrelatedRandomVectorGeneratorTest(String name) { - super(name); - mean = null; - standardDeviation = null; - generator = null; - } - - public void testMeanAndCorrelation() { - - VectorialSampleStatistics sample = new VectorialSampleStatistics(); - for (int i = 0; i < 10000; ++i) { - sample.add(generator.nextVector()); - } - - double[] estimatedMean = sample.getMean(); - double scale; - SymetricalMatrix estimatedCorrelation = sample.getCovarianceMatrix(null); - for (int i = 0; i < estimatedMean.length; ++i) { - assertEquals(mean[i], estimatedMean[i], 0.07); - for (int j = 0; j < i; ++j) { - scale = standardDeviation[i] * standardDeviation[j]; - assertEquals(0, estimatedCorrelation.getElement(i, j) / scale, 0.03); - } - scale = standardDeviation[i] * standardDeviation[i]; - assertEquals(1, estimatedCorrelation.getElement(i, i) / scale, 0.025); - } - - } - - public void setUp() { - mean = new double[] {0.0, 1.0, -3.0, 2.3}; - standardDeviation = new double[] {1.0, 2.0, 10.0, 0.1}; - generator = - new UncorrelatedRandomVectorGenerator(mean, standardDeviation, - new GaussianRandomGenerator(17399225432l)); - } - - public void tearDown() { - mean = null; - standardDeviation = null; - generator = null; - } - - public static Test suite() { - return new TestSuite(UncorrelatedRandomVectorGeneratorTest.class); - } - - private double[] mean; - private double[] standardDeviation; - private UncorrelatedRandomVectorGenerator generator; - -} diff --git a/src/mantissa/tests-src/org/spaceroots/mantissa/random/VectorialSampleStatisticsTest.java b/src/mantissa/tests-src/org/spaceroots/mantissa/random/VectorialSampleStatisticsTest.java deleted file mode 100644 index 94ce4697b..000000000 --- a/src/mantissa/tests-src/org/spaceroots/mantissa/random/VectorialSampleStatisticsTest.java +++ /dev/null @@ -1,167 +0,0 @@ -// 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.spaceroots.mantissa.random; - -import org.spaceroots.mantissa.linalg.SymetricalMatrix; - -import junit.framework.*; - -public class VectorialSampleStatisticsTest - extends TestCase { - - public VectorialSampleStatisticsTest(String name) { - super(name); - points = null; - } - - public void testSimplistic() { - VectorialSampleStatistics sample = new VectorialSampleStatistics(); - sample.add(new double[] {-1.0, 1.0}); - sample.add(new double[] { 1.0, -1.0}); - SymetricalMatrix c = sample.getCovarianceMatrix(null); - assertEquals( 2.0, c.getElement(0, 0), 1.0e-12); - assertEquals(-2.0, c.getElement(1, 0), 1.0e-12); - assertEquals( 2.0, c.getElement(1, 1), 1.0e-12); - } - - public void testBasicStats() { - - VectorialSampleStatistics sample = new VectorialSampleStatistics(); - for (int i = 0; i < points.length; ++i) { - sample.add(points[i]); - } - - assertEquals(points.length, sample.size()); - - double[] min = sample.getMin(); - double[] max = sample.getMax(); - double[] mean = sample.getMean(); - SymetricalMatrix c = sample.getCovarianceMatrix(null); - - double[] refMin = new double[] {-0.70, 0.00, -3.10}; - double[] refMax = new double[] { 6.00, 2.30, 5.00}; - double[] refMean = new double[] { 1.78, 1.62, 3.12}; - double[][] refC = new double[][] { - { 8.0470, -1.9195, -3.4445}, - {-1.9195, 1.0470, 3.2795}, - {-3.4445, 3.2795, 12.2070} - }; - - for (int i = 0; i < min.length; ++i) { - assertEquals(refMin[i], min[i], 1.0e-12); - assertEquals(refMax[i], max[i], 1.0e-12); - assertEquals(refMean[i], mean[i], 1.0e-12); - for (int j = 0; j <= i; ++j) { - assertEquals(refC[i][j], c.getElement(i, j), 1.0e-12); - } - } - - } - - public void testAddSample() { - - VectorialSampleStatistics all = new VectorialSampleStatistics(); - VectorialSampleStatistics even = new VectorialSampleStatistics(); - VectorialSampleStatistics odd = new VectorialSampleStatistics(); - for (int i = 0; i < points.length; ++i) { - all.add(points[i]); - if (i % 2 == 0) { - even.add(points[i]); - } else { - odd.add(points[i]); - } - } - - even.add(odd); - - assertEquals(all.size(), even.size()); - - double[] min = even.getMin(); - double[] max = even.getMax(); - double[] mean = even.getMean(); - SymetricalMatrix c = even.getCovarianceMatrix(null); - - double[] refMin = all.getMin(); - double[] refMax = all.getMax(); - double[] refMean = all.getMean(); - SymetricalMatrix refC = all.getCovarianceMatrix(null); - - for (int i = 0; i < min.length; ++i) { - assertEquals(refMin[i], min[i], 1.0e-12); - assertEquals(refMax[i], max[i], 1.0e-12); - assertEquals(refMean[i], mean[i], 1.0e-12); - for (int j = 0; j <= i; ++j) { - assertEquals(refC.getElement(i, j), c.getElement(i, j), 1.0e-12); - } - } - - } - - public void testAddArray() { - - VectorialSampleStatistics loop = new VectorialSampleStatistics(); - VectorialSampleStatistics direct = new VectorialSampleStatistics(); - for (int i = 0; i < points.length; ++i) { - loop.add(points[i]); - } - direct.add(points); - - assertEquals(loop.size(), direct.size()); - - double[] min = direct.getMin(); - double[] max = direct.getMax(); - double[] mean = direct.getMean(); - SymetricalMatrix c = direct.getCovarianceMatrix(null); - - double[] refMin = loop.getMin(); - double[] refMax = loop.getMax(); - double[] refMean = loop.getMean(); - SymetricalMatrix refC = loop.getCovarianceMatrix(null); - - for (int i = 0; i < min.length; ++i) { - assertEquals(refMin[i], min[i], 1.0e-12); - assertEquals(refMax[i], max[i], 1.0e-12); - assertEquals(refMean[i], mean[i], 1.0e-12); - for (int j = 0; j <= i; ++j) { - assertEquals(refC.getElement(i, j), c.getElement(i, j), 1.0e-12); - } - } - - } - - public void setUp() { - points = new double[][] { - { 1.2, 2.3, 4.5}, - {-0.7, 2.3, 5.0}, - { 3.1, 0.0, -3.1}, - { 6.0, 1.2, 4.2}, - {-0.7, 2.3, 5.0} - }; - } - - public void tearDown() { - points = null; - } - - public static Test suite() { - return new TestSuite(VectorialSampleStatisticsTest.class); - } - - private double [][] points; - -} diff --git a/src/test/org/apache/commons/math/random/GaussianRandomGeneratorTest.java b/src/test/org/apache/commons/math/random/GaussianRandomGeneratorTest.java new file mode 100644 index 000000000..b5034f5a6 --- /dev/null +++ b/src/test/org/apache/commons/math/random/GaussianRandomGeneratorTest.java @@ -0,0 +1,47 @@ +//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.random; + +import org.apache.commons.math.stat.StatUtils; + +import junit.framework.*; + +public class GaussianRandomGeneratorTest +extends TestCase { + + public GaussianRandomGeneratorTest(String name) { + super(name); + } + + public void testMeanAndStandardDeviation() { + RandomGenerator rg = new JDKRandomGenerator(); + rg.setSeed(17399225432l); + GaussianRandomGenerator generator = new GaussianRandomGenerator(rg); + double[] sample = new double[10000]; + for (int i = 0; i < sample.length; ++i) { + sample[i] = generator.nextNormalizedDouble(); + } + assertEquals(0.0, StatUtils.mean(sample), 0.012); + assertEquals(1.0, StatUtils.variance(sample), 0.01); + } + + public static Test suite() { + return new TestSuite(GaussianRandomGeneratorTest.class); + } + +} diff --git a/src/test/org/apache/commons/math/random/UncorrelatedRandomVectorGeneratorTest.java b/src/test/org/apache/commons/math/random/UncorrelatedRandomVectorGeneratorTest.java new file mode 100644 index 000000000..13bbd69b7 --- /dev/null +++ b/src/test/org/apache/commons/math/random/UncorrelatedRandomVectorGeneratorTest.java @@ -0,0 +1,86 @@ +//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.random; + +import org.apache.commons.math.DimensionMismatchException; +import org.apache.commons.math.linear.RealMatrix; +import org.apache.commons.math.stat.descriptive.moment.VectorialCovariance; +import org.apache.commons.math.stat.descriptive.moment.VectorialMean; + +import junit.framework.*; + +public class UncorrelatedRandomVectorGeneratorTest +extends TestCase { + + public UncorrelatedRandomVectorGeneratorTest(String name) { + super(name); + mean = null; + standardDeviation = null; + generator = null; + } + + public void testMeanAndCorrelation() throws DimensionMismatchException { + + VectorialMean meanStat = new VectorialMean(mean.length); + VectorialCovariance covStat = new VectorialCovariance(mean.length); + for (int i = 0; i < 10000; ++i) { + double[] v = generator.nextVector(); + meanStat.increment(v); + covStat.increment(v); + } + + double[] estimatedMean = meanStat.getResult(); + double scale; + RealMatrix estimatedCorrelation = covStat.getResult(); + for (int i = 0; i < estimatedMean.length; ++i) { + assertEquals(mean[i], estimatedMean[i], 0.07); + for (int j = 0; j < i; ++j) { + scale = standardDeviation[i] * standardDeviation[j]; + assertEquals(0, estimatedCorrelation.getEntry(i, j) / scale, 0.03); + } + scale = standardDeviation[i] * standardDeviation[i]; + assertEquals(1, estimatedCorrelation.getEntry(i, i) / scale, 0.025); + } + + } + + public void setUp() { + mean = new double[] {0.0, 1.0, -3.0, 2.3}; + standardDeviation = new double[] {1.0, 2.0, 10.0, 0.1}; + RandomGenerator rg = new JDKRandomGenerator(); + rg.setSeed(17399225432l); + generator = + new UncorrelatedRandomVectorGenerator(mean, standardDeviation, + new GaussianRandomGenerator(rg)); + } + + public void tearDown() { + mean = null; + standardDeviation = null; + generator = null; + } + + public static Test suite() { + return new TestSuite(UncorrelatedRandomVectorGeneratorTest.class); + } + + private double[] mean; + private double[] standardDeviation; + private UncorrelatedRandomVectorGenerator generator; + +} diff --git a/src/test/org/apache/commons/math/random/UniformRandomGeneratorTest.java b/src/test/org/apache/commons/math/random/UniformRandomGeneratorTest.java new file mode 100644 index 000000000..485cae4eb --- /dev/null +++ b/src/test/org/apache/commons/math/random/UniformRandomGeneratorTest.java @@ -0,0 +1,47 @@ +//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.random; + +import org.apache.commons.math.stat.StatUtils; + +import junit.framework.*; + +public class UniformRandomGeneratorTest +extends TestCase { + + public UniformRandomGeneratorTest(String name) { + super(name); + } + + public void testMeanAndStandardDeviation() { + RandomGenerator rg = new JDKRandomGenerator(); + rg.setSeed(17399225432l); + UniformRandomGenerator generator = new UniformRandomGenerator(rg); + double[] sample = new double[10000]; + for (int i = 0; i < sample.length; ++i) { + sample[i] = generator.nextNormalizedDouble(); + } + assertEquals(0.0, StatUtils.mean(sample), 0.07); + assertEquals(1.0, StatUtils.variance(sample), 0.02); + } + + public static Test suite() { + return new TestSuite(UniformRandomGeneratorTest.class); + } + +} diff --git a/src/test/org/apache/commons/math/stat/descriptive/moment/VectorialCovarianceTest.java b/src/test/org/apache/commons/math/stat/descriptive/moment/VectorialCovarianceTest.java new file mode 100644 index 000000000..2edf84d55 --- /dev/null +++ b/src/test/org/apache/commons/math/stat/descriptive/moment/VectorialCovarianceTest.java @@ -0,0 +1,101 @@ +//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.moment; + +import org.apache.commons.math.DimensionMismatchException; +import org.apache.commons.math.linear.RealMatrix; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +public class VectorialCovarianceTest +extends TestCase { + + public VectorialCovarianceTest(String name) { + super(name); + points = null; + } + + public void testMismatch() { + try { + new VectorialCovariance(8).increment(new double[5]); + fail("an exception should have been thrown"); + } catch (DimensionMismatchException dme) { + assertEquals(5, dme.getDimension1()); + assertEquals(8, dme.getDimension2()); + } catch (Exception e) { + fail("wrong exception type caught: " + e.getClass().getName()); + } + } + + public void testSimplistic() throws DimensionMismatchException { + VectorialCovariance stat = new VectorialCovariance(2); + stat.increment(new double[] {-1.0, 1.0}); + stat.increment(new double[] { 1.0, -1.0}); + RealMatrix c = stat.getResult(); + assertEquals( 2.0, c.getEntry(0, 0), 1.0e-12); + assertEquals(-2.0, c.getEntry(1, 0), 1.0e-12); + assertEquals( 2.0, c.getEntry(1, 1), 1.0e-12); + } + + public void testBasicStats() throws DimensionMismatchException { + + VectorialCovariance stat = new VectorialCovariance(points[0].length); + for (int i = 0; i < points.length; ++i) { + stat.increment(points[i]); + } + + assertEquals(points.length, stat.getN()); + + RealMatrix c = stat.getResult(); + double[][] refC = new double[][] { + { 8.0470, -1.9195, -3.4445}, + {-1.9195, 1.0470, 3.2795}, + {-3.4445, 3.2795, 12.2070} + }; + + for (int i = 0; i < c.getRowDimension(); ++i) { + for (int j = 0; j <= i; ++j) { + assertEquals(refC[i][j], c.getEntry(i, j), 1.0e-12); + } + } + + } + + public void setUp() { + points = new double[][] { + { 1.2, 2.3, 4.5}, + {-0.7, 2.3, 5.0}, + { 3.1, 0.0, -3.1}, + { 6.0, 1.2, 4.2}, + {-0.7, 2.3, 5.0} + }; + } + + public void tearDown() { + points = null; + } + + public static Test suite() { + return new TestSuite(VectorialCovarianceTest.class); + } + + private double [][] points; + +} diff --git a/src/test/org/apache/commons/math/stat/descriptive/moment/VectorialMeanTest.java b/src/test/org/apache/commons/math/stat/descriptive/moment/VectorialMeanTest.java new file mode 100644 index 000000000..295ec174c --- /dev/null +++ b/src/test/org/apache/commons/math/stat/descriptive/moment/VectorialMeanTest.java @@ -0,0 +1,93 @@ +//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.moment; + +import org.apache.commons.math.DimensionMismatchException; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +public class VectorialMeanTest +extends TestCase { + + public VectorialMeanTest(String name) { + super(name); + points = null; + } + + public void testMismatch() { + try { + new VectorialMean(8).increment(new double[5]); + fail("an exception should have been thrown"); + } catch (DimensionMismatchException dme) { + assertEquals(5, dme.getDimension1()); + assertEquals(8, dme.getDimension2()); + } catch (Exception e) { + fail("wrong exception type caught: " + e.getClass().getName()); + } + } + + public void testSimplistic() throws DimensionMismatchException { + VectorialMean stat = new VectorialMean(2); + stat.increment(new double[] {-1.0, 1.0}); + stat.increment(new double[] { 1.0, -1.0}); + double[] mean = stat.getResult(); + assertEquals(0.0, mean[0], 1.0e-12); + assertEquals(0.0, mean[1], 1.0e-12); + } + + public void testBasicStats() throws DimensionMismatchException { + + VectorialMean stat = new VectorialMean(points[0].length); + for (int i = 0; i < points.length; ++i) { + stat.increment(points[i]); + } + + assertEquals(points.length, stat.getN()); + + double[] mean = stat.getResult(); + double[] refMean = new double[] { 1.78, 1.62, 3.12}; + + for (int i = 0; i < mean.length; ++i) { + assertEquals(refMean[i], mean[i], 1.0e-12); + } + + } + + public void setUp() { + points = new double[][] { + { 1.2, 2.3, 4.5}, + {-0.7, 2.3, 5.0}, + { 3.1, 0.0, -3.1}, + { 6.0, 1.2, 4.2}, + {-0.7, 2.3, 5.0} + }; + } + + public void tearDown() { + points = null; + } + + public static Test suite() { + return new TestSuite(VectorialMeanTest.class); + } + + private double [][] points; + +}