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 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 }