SSJ API Documentation
Stochastic Simulation in Java
Loading...
Searching...
No Matches
MultinormalPCAGen.java
1/*
2 * Class: MultinormalPCAGen
3 * Description: multivariate normal random variable generator
4 * Environment: Java
5 * Software: SSJ
6 * Copyright (C) 2001 Pierre L'Ecuyer and Universite de Montreal
7 * Organization: DIRO, Universite de Montreal
8 * @author
9 * @since
10 *
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 *
24 */
25package umontreal.ssj.randvarmulti;
26
27import cern.colt.matrix.DoubleMatrix2D;
28import cern.colt.matrix.linalg.SingularValueDecomposition;
29import umontreal.ssj.probdist.NormalDist;
30import umontreal.ssj.randvar.NormalGen;
31import umontreal.ssj.rng.RandomStream;
32import cern.colt.matrix.impl.DenseDoubleMatrix2D;
33
58public class MultinormalPCAGen extends MultinormalGen {
59 private double[] lambda;
60
61 private static SingularValueDecomposition getSvd(DoubleMatrix2D sigma) {
62 return (new SingularValueDecomposition(sigma));
63 }
64
65 private DoubleMatrix2D decompPCA(SingularValueDecomposition svd) {
66 DoubleMatrix2D D = svd.getS();
67 // Calculer la racine carree des valeurs propres
68 for (int i = 0; i < D.rows(); ++i) {
69 lambda[i] = D.getQuick(i, i);
70 D.setQuick(i, i, Math.sqrt(D.getQuick(i, i)));
71 }
72 DoubleMatrix2D P = svd.getV();
73 return P.zMult(D, null);
74 }
75
76 private void initL() {
77 if (mu.length != sigma.rows() || mu.length != sigma.columns())
78 throw new IllegalArgumentException("Incompatible mean vector and covariance matrix");
79 lambda = new double[mu.length];
80 sqrtSigma = decompPCA(getSvd(sigma));
81 }
82
87 public MultinormalPCAGen(NormalGen gen1, double[] mu, double[][] sigma) {
88 super(gen1, mu, sigma);
89 initL();
90 }
91
108 public MultinormalPCAGen(NormalGen gen1, double[] mu, DoubleMatrix2D sigma) {
109 super(gen1, mu, sigma);
110 initL();
111 }
112
119 public static DoubleMatrix2D decompPCA(double[][] sigma) {
120 return decompPCA(new DenseDoubleMatrix2D(sigma));
121 }
122
129 public static DoubleMatrix2D decompPCA(DoubleMatrix2D sigma) {
130 // L'objet SingularValueDecomposition permet de recuperer la matrice
131 // des valeurs propres en ordre decroissant et celle des vecteurs propres de
132 // sigma (pour une matrice symetrique et definie-positive seulement).
133
134 SingularValueDecomposition sv = getSvd(sigma);
135 // D contient les valeurs propres sur la diagonale
136 DoubleMatrix2D D = sv.getS();
137 // Calculer la racine carree des valeurs propres
138 for (int i = 0; i < D.rows(); ++i)
139 D.setQuick(i, i, Math.sqrt(D.getQuick(i, i)));
140 DoubleMatrix2D P = sv.getV();
141 // Multiplier par la matrice orthogonale (ici P)
142 return P.zMult(D, null);
143 }
144
151 public DoubleMatrix2D getPCADecompSigma() {
152 return sqrtSigma.copy();
153 }
154
158 public static double[] getLambda(DoubleMatrix2D sigma) {
159 SingularValueDecomposition sv = getSvd(sigma);
160 DoubleMatrix2D D = sv.getS();
161 double[] lambd = new double[D.rows()];
162 for (int i = 0; i < D.rows(); ++i)
163 lambd[i] = D.getQuick(i, i);
164 return lambd;
165 }
166
170 public double[] getLambda() {
171 return lambda;
172 }
173
181 public void setSigma(DoubleMatrix2D sigma) {
182 if (sigma.rows() != mu.length || sigma.columns() != mu.length)
183 throw new IllegalArgumentException("Invalid dimensions of covariance matrix");
184 this.sigma.assign(sigma);
185 this.sqrtSigma = decompPCA(getSvd(sigma));
186 }
187
213 public static void nextPoint(NormalGen gen1, double[] mu, DoubleMatrix2D sigma, double[] p) {
214 if (gen1 == null)
215 throw new NullPointerException("gen1 is null");
216
217 NormalDist dist = (NormalDist) gen1.getDistribution();
218 if (dist.getMu() != 0.0)
219 throw new IllegalArgumentException("mu != 0");
220 if (dist.getSigma() != 1.0)
221 throw new IllegalArgumentException("sigma != 1");
222
223 if (mu.length != sigma.rows() || mu.length != sigma.columns())
224 throw new IllegalArgumentException("Incompatible mean vector and covariance matrix dimensions");
225 double[] temp = new double[mu.length];
226 DoubleMatrix2D sqrtSigma = decompPCA(sigma);
227 for (int i = 0; i < temp.length; i++) {
228 temp[i] = gen1.nextDouble();
229 if (temp[i] == Double.NEGATIVE_INFINITY)
230 temp[i] = -MYINF;
231 if (temp[i] == Double.POSITIVE_INFINITY)
232 temp[i] = MYINF;
233 }
234 for (int i = 0; i < temp.length; i++) {
235 p[i] = 0;
236 for (int c = 0; c < temp.length; c++)
237 p[i] += sqrtSigma.getQuick(i, c) * temp[c];
238 p[i] += mu[i];
239 }
240 }
241
246 public static void nextPoint(NormalGen gen1, double[] mu, double[][] sigma, double[] p) {
247 nextPoint(gen1, mu, new DenseDoubleMatrix2D(sigma), p);
248 }
249
257 public void nextPoint(double[] p) {
258 int n = mu.length;
259 for (int i = 0; i < n; i++) {
260 temp[i] = gen1.nextDouble();
261 if (temp[i] == Double.NEGATIVE_INFINITY)
262 temp[i] = -MYINF;
263 if (temp[i] == Double.POSITIVE_INFINITY)
264 temp[i] = MYINF;
265 }
266 for (int i = 0; i < n; i++) {
267 p[i] = 0;
268 for (int c = 0; c < n; c++)
269 p[i] += sqrtSigma.getQuick(i, c) * temp[c];
270 p[i] += mu[i];
271 }
272 }
273}
Extends the class ContinuousDistribution for the normal distribution (e.g., tjoh95a  (page 80)).
double getMu()
Returns the parameter .
double getSigma()
Returns the parameter .
This class implements methods for generating random variates from the normal distribution .
MultinormalGen(NormalGen gen1, int d)
Constructs a generator with the standard multinormal distribution (with and.
static double[] getLambda(DoubleMatrix2D sigma)
Computes and returns the eigenvalues of sigma in decreasing order.
void nextPoint(double[] p)
Generates a point from this multinormal distribution.
DoubleMatrix2D getPCADecompSigma()
Returns the matrix of this object.
MultinormalPCAGen(NormalGen gen1, double[] mu, double[][] sigma)
Equivalent to MultinormalPCAGen(gen1, mu, new DenseDoubleMatrix2D(sigma)).
double[] getLambda()
Returns the eigenvalues of in decreasing order.
MultinormalPCAGen(NormalGen gen1, double[] mu, DoubleMatrix2D sigma)
Constructs a multinormal generator with mean vector mu and covariance matrix sigma.
static DoubleMatrix2D decompPCA(double[][] sigma)
Computes the decomposition sigma = .
void setSigma(DoubleMatrix2D sigma)
Sets the covariance matrix of this multinormal generator to sigma (and recomputes ).
static void nextPoint(NormalGen gen1, double[] mu, DoubleMatrix2D sigma, double[] p)
Generates a -dimensional vector from the multinormal distribution with mean vector mu and covariance ...
static void nextPoint(NormalGen gen1, double[] mu, double[][] sigma, double[] p)
Equivalent to nextPoint(gen1, mu, new DenseDoubleMatrix2D(sigma), p).
static DoubleMatrix2D decompPCA(DoubleMatrix2D sigma)
Computes the decomposition sigma = .