View Javadoc
1   //Licensed to the Apache Software Foundation (ASF) under one
2   //or more contributor license agreements.  See the NOTICE file
3   //distributed with this work for additional information
4   //regarding copyright ownership.  The ASF licenses this file
5   //to you under the Apache License, Version 2.0 (the
6   //"License"); you may not use this file except in compliance
7   //with the License.  You may obtain a copy of the License at
8   
9   //https://www.apache.org/licenses/LICENSE-2.0
10  
11  //Unless required by applicable law or agreed to in writing,
12  //software distributed under the License is distributed on an
13  //"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14  //KIND, either express or implied.  See the License for the
15  //specific language governing permissions and limitations
16  //under the License.
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 }