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
This commit is contained in:
parent
2a4219105e
commit
15d96cbafd
|
@ -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.
|
||||
* <p>This class is a simple wrapper around the {@link
|
||||
* RandomGenerator#nextGaussian} method.</p>
|
||||
* @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;
|
||||
|
||||
}
|
|
@ -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.
|
||||
* <p>This method does <strong>not</strong> 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.</p>
|
||||
* @return a random scalar
|
||||
* @return a random scalar with null mean and unit standard deviation
|
||||
*/
|
||||
public double nextDouble();
|
||||
public double nextNormalizedDouble();
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
* <em>will</em> 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();
|
||||
|
|
@ -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.
|
||||
* <p>Build an uncorrelated random vector generator from its mean
|
||||
* and standard deviation vectors.</p>
|
||||
* @param mean expected mean values for all components
|
||||
* @param standardDeviation standard deviation for all components
|
||||
* <p>Build an uncorrelated random vector generator from
|
||||
* its mean and standard deviation vectors.</p>
|
||||
* @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;
|
||||
|
||||
}
|
|
@ -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.
|
||||
* <p>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)].</p>
|
||||
* @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.
|
||||
* <p>The number generated is uniformly distributed between -&sqrt;(3)
|
||||
* and +&sqrt;(3).</p>
|
||||
* @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);
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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.
|
||||
|
||||
* <p>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.</p>
|
||||
|
||||
* <p>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 <code>C =
|
||||
* L.Lt</code> where <code>C</code> is the covariance matrix and
|
||||
* <code>L</code> is a lower-triangular matrix, we compute <code>C =
|
||||
* B.Bt</code> where <code>B</code> is a rectangular matrix having
|
||||
* more rows than columns. The number of columns of <code>B</code> 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.</p>
|
||||
|
||||
* @version $Id: CorrelatedRandomVectorGenerator.java 1705 2006-09-17 19:57:39Z luc $
|
||||
* @author L. Maisonobe
|
||||
|
||||
*/
|
||||
|
||||
public class CorrelatedRandomVectorGenerator
|
||||
implements Serializable, RandomVectorGenerator {
|
||||
|
||||
/** Simple constructor.
|
||||
* <p>Build a correlated random vector generator from its mean
|
||||
* vector and covariance matrix.</p>
|
||||
* @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.
|
||||
* <p>Build a null mean random correlated vector generator from its
|
||||
* covariance matrix.</p>
|
||||
* @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 <code>B</code> such that <code>B.Bt</code>
|
||||
* 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;
|
||||
|
||||
}
|
|
@ -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.
|
||||
|
||||
* <p>This class is a simple interface adaptor around the {@link
|
||||
* java.util.Random#nextGaussian nextGaussian} method.</p>
|
||||
|
||||
* @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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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.
|
||||
|
||||
* <p>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)].</p>
|
||||
|
||||
* @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.
|
||||
* <p>The number generated is uniformly distributed between -sqrt(3)
|
||||
* and sqrt(3).</p>
|
||||
* @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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
Loading…
Reference in New Issue