1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.hipparchus.random;
19
20 import java.util.Arrays;
21
22 import org.hipparchus.UnitTestUtils;
23 import org.hipparchus.linear.Array2DRowRealMatrix;
24 import org.hipparchus.linear.MatrixUtils;
25 import org.hipparchus.linear.RealMatrix;
26 import org.hipparchus.util.FastMath;
27 import org.junit.Assert;
28 import org.junit.Test;
29
30 public class CorrelatedRandomVectorGeneratorTest {
31 private double[] mean;
32 private RealMatrix covariance;
33 private CorrelatedRandomVectorGenerator generator;
34
35 public CorrelatedRandomVectorGeneratorTest() {
36 mean = new double[] { 0.0, 1.0, -3.0, 2.3 };
37
38 RealMatrix b = MatrixUtils.createRealMatrix(4, 3);
39 int counter = 0;
40 for (int i = 0; i < b.getRowDimension(); ++i) {
41 for (int j = 0; j < b.getColumnDimension(); ++j) {
42 b.setEntry(i, j, 1.0 + 0.1 * ++counter);
43 }
44 }
45 RealMatrix bbt = b.multiplyTransposed(b);
46 covariance = MatrixUtils.createRealMatrix(mean.length, mean.length);
47 for (int i = 0; i < covariance.getRowDimension(); ++i) {
48 covariance.setEntry(i, i, bbt.getEntry(i, i));
49 for (int j = 0; j < covariance.getColumnDimension(); ++j) {
50 double s = bbt.getEntry(i, j);
51 covariance.setEntry(i, j, s);
52 covariance.setEntry(j, i, s);
53 }
54 }
55
56 RandomGenerator rg = new JDKRandomGenerator();
57 rg.setSeed(17399225432l);
58 GaussianRandomGenerator rawGenerator = new GaussianRandomGenerator(rg);
59 generator = new CorrelatedRandomVectorGenerator(mean,
60 covariance,
61 1.0e-12 * covariance.getNorm1(),
62 rawGenerator);
63 }
64
65 @Test
66 public void testRank() {
67 Assert.assertEquals(2, generator.getRank());
68 }
69
70 @Test
71 public void testMath226() {
72 double[] mean = { 1, 1, 10, 1 };
73 double[][] cov = {
74 { 1, 3, 2, 6 },
75 { 3, 13, 16, 2 },
76 { 2, 16, 38, -1 },
77 { 6, 2, -1, 197 }
78 };
79 RealMatrix covRM = MatrixUtils.createRealMatrix(cov);
80 JDKRandomGenerator jg = new JDKRandomGenerator();
81 jg.setSeed(5322145245211l);
82 NormalizedRandomGenerator rg = new GaussianRandomGenerator(jg);
83 CorrelatedRandomVectorGenerator sg =
84 new CorrelatedRandomVectorGenerator(mean, covRM, 0.00001, rg);
85
86 double[] min = new double[mean.length];
87 Arrays.fill(min, Double.POSITIVE_INFINITY);
88 double[] max = new double[mean.length];
89 Arrays.fill(max, Double.NEGATIVE_INFINITY);
90 for (int i = 0; i < 10; i++) {
91 double[] generated = sg.nextVector();
92 for (int j = 0; j < generated.length; ++j) {
93 min[j] = FastMath.min(min[j], generated[j]);
94 max[j] = FastMath.max(max[j], generated[j]);
95 }
96 }
97 for (int j = 0; j < min.length; ++j) {
98 Assert.assertTrue(max[j] - min[j] > 2.0);
99 }
100
101 }
102
103 @Test
104 public void testRootMatrix() {
105 RealMatrix b = generator.getRootMatrix();
106 RealMatrix bbt = b.multiplyTransposed(b);
107 for (int i = 0; i < covariance.getRowDimension(); ++i) {
108 for (int j = 0; j < covariance.getColumnDimension(); ++j) {
109 Assert.assertEquals(covariance.getEntry(i, j), bbt.getEntry(i, j), 1.0e-12);
110 }
111 }
112 }
113
114 @Test
115 public void testMeanAndCovariance() {
116
117 final double[] meanStat = new double[mean.length];
118 final RealMatrix matrix = new Array2DRowRealMatrix(5000, mean.length);
119 for (int i = 0; i < 5000; ++i) {
120 double[] v = generator.nextVector();
121 matrix.setRow(i, v);
122 }
123
124 for (int i = 0; i < mean.length; i++) {
125 meanStat[i] = UnitTestUtils.mean(matrix.getColumn(i));
126 }
127
128 RealMatrix estimatedCovariance = UnitTestUtils.covarianceMatrix(matrix);
129 for (int i = 0; i < meanStat.length; ++i) {
130 Assert.assertEquals(mean[i], meanStat[i], 0.07);
131 for (int j = 0; j <= i; ++j) {
132 Assert.assertEquals(covariance.getEntry(i, j),
133 estimatedCovariance.getEntry(i, j),
134 0.1 * (1.0 + FastMath.abs(mean[i])) * (1.0 + FastMath.abs(mean[j])));
135 }
136 }
137
138 }
139
140 @Test
141 public void testSampleWithZeroCovariance() {
142 final double[][] covMatrix1 = new double[][]{
143 {0.013445532, 0.010394690, 0.009881156, 0.010499559},
144 {0.010394690, 0.023006616, 0.008196856, 0.010732709},
145 {0.009881156, 0.008196856, 0.019023866, 0.009210099},
146 {0.010499559, 0.010732709, 0.009210099, 0.019107243}
147 };
148
149 final double[][] covMatrix2 = new double[][]{
150 {0.0, 0.0, 0.0, 0.0, 0.0},
151 {0.0, 0.013445532, 0.010394690, 0.009881156, 0.010499559},
152 {0.0, 0.010394690, 0.023006616, 0.008196856, 0.010732709},
153 {0.0, 0.009881156, 0.008196856, 0.019023866, 0.009210099},
154 {0.0, 0.010499559, 0.010732709, 0.009210099, 0.019107243}
155 };
156
157 final double[][] covMatrix3 = new double[][]{
158 {0.013445532, 0.010394690, 0.0, 0.009881156, 0.010499559},
159 {0.010394690, 0.023006616, 0.0, 0.008196856, 0.010732709},
160 {0.0, 0.0, 0.0, 0.0, 0.0},
161 {0.009881156, 0.008196856, 0.0, 0.019023866, 0.009210099},
162 {0.010499559, 0.010732709, 0.0, 0.009210099, 0.019107243}
163 };
164
165 testSampler(covMatrix1, 10000, 0.001);
166 testSampler(covMatrix2, 10000, 0.001);
167 testSampler(covMatrix3, 10000, 0.001);
168
169 }
170
171 private CorrelatedRandomVectorGenerator createSampler(double[][] cov) {
172 RealMatrix matrix = new Array2DRowRealMatrix(cov);
173 double small = 10e-12 * matrix.getNorm1();
174 return new CorrelatedRandomVectorGenerator(
175 new double[cov.length],
176 matrix,
177 small,
178 new GaussianRandomGenerator(new Well1024a(0x366a26b94e520f41l)));
179 }
180
181 private void testSampler(final double[][] covMatrix, int samples, double epsilon) {
182 CorrelatedRandomVectorGenerator sampler = createSampler(covMatrix);
183 RealMatrix matrix = new Array2DRowRealMatrix(samples, covMatrix.length);
184
185 for (int i = 0; i < samples; ++i) {
186 matrix.setRow(i, sampler.nextVector());
187 }
188
189 RealMatrix sampleCov = UnitTestUtils.covarianceMatrix(matrix);
190 for (int r = 0; r < covMatrix.length; ++r) {
191 UnitTestUtils.assertEquals(covMatrix[r], sampleCov.getColumn(r), epsilon);
192 }
193
194 }
195
196 }