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