SSJ API Documentation
Stochastic Simulation in Java
Loading...
Searching...
No Matches
MultivariateBrownianMotionPCA.java
1/*
2 * Class: MultivariateBrownianMotionPCA
3 * Description:
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 Jean-Sébastien Parent
9 * @since 2008
10
11 * SSJ is free software: you can redistribute it and/or modify it under
12 * the terms of the GNU General Public License (GPL) as published by the
13 * Free Software Foundation, either version 3 of the License, or
14 * any later version.
15
16 * SSJ is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20
21 * A copy of the GNU General Public License is available at
22 <a href="http://www.gnu.org/licenses">GPL licence site</a>.
23 */
24package umontreal.ssj.stochprocess;
25
26import umontreal.ssj.rng.*;
27import umontreal.ssj.probdist.*;
28import umontreal.ssj.randvar.*;
29import cern.colt.matrix.DoubleMatrix2D;
30import cern.colt.matrix.impl.*;
31import cern.colt.matrix.linalg.*;
32import cern.colt.matrix.doublealgo.*;
33
52public class MultivariateBrownianMotionPCA extends MultivariateBrownianMotion {
53
54 // protected double[][] covX; // Matrice de covariance du vecteur des observ.
55 // covX [i*c+k][j*c+l] = Cov[X_k(t_{i+1}),X_l(t_{j+1})].
56 // --> We will not store this one explicitly!
57 protected DoubleMatrix2D C; // C[i,j] = \min(t_{i+1},t_{j+1}).
58 protected DoubleMatrix2D BC, sortedBC, copyBC;
59 protected DoubleMatrix2D PcovZ, PC; // C = AA' (PCA decomposition).
60 protected double[] z, zz, zzz; // vector of c*d standard normals.
61 protected int[] eigenIndex; // The (j+1)-th generated normal, j>=1, should be placed
62 // at position vector eigenIndex[j] in vector z.
63 // eigenIndex[0..cd-1] should be a permutation of 0,...,cd-1.
64 protected boolean decompPCA;
65
76 public MultivariateBrownianMotionPCA(int c, double[] x0, double[] mu, double[] sigma, double[][] corrZ,
77 RandomStream stream) {
78 this.gen = new NormalGen(stream, new NormalDist());
79 setParams(c, x0, mu, sigma, corrZ);
80 }
81
91 public MultivariateBrownianMotionPCA(int c, double[] x0, double[] mu, double[] sigma, double[][] corrZ,
92 NormalGen gen) {
93 this.gen = gen;
94 setParams(c, x0, mu, sigma, corrZ);
95 }
96
97 public void setParams(int c, double[] x0, double[] mu, double[] sigma, double[][] corrZ) {
98 decompPCA = false;
99 super.setParams(c, x0, mu, sigma, corrZ);
100 }
101
102 public double[] generatePath() {
103 double[] u = new double[c * d];
104 for (int i = 0; i < c * d; i++)
105 u[i] = gen.nextDouble();
106 return generatePath(u);
107 }
108
112 public double[] generatePath(double[] uniform01) {
113 double sum;
114 int i, j, k;
115 if (!decompPCA) {
116 init();
117 }
118 for (j = 0; j < c * d; j++) // the first components are multiplied by the biggest eigenvalues
119 z[j] = uniform01[j] * BC.getQuick(j, 0);
120// System.out.println("PCA");
121 // now we need to permute the vector z in the right order
122 for (j = 0; j < c * d; j++) {
123 zz[j] = z[(int) BC.getQuick(j, 1)];
124 }
125 for (j = 0; j < d; j++) {
126 for (i = 0; i < c; i++) {
127 sum = 0.0;
128 for (k = 0; k < c; k++)
129 sum += PcovZ.getQuick(i, k) * zz[j * c + k];
130 zzz[j * c + i] = sum; // chaque bloc de z multiplié par \Sigma (i.e. B)
131 }
132 }
133 // multiplication of zz (zz = Id(\Sigma) * z) by the matrix \tilde C (\tilde C
134 // is the matrix C with all its components multiplied by the Identity matrix of
135 // size c x c to obtain a matrix of size cd x cd.
136
137 for (j = 0; j < d; j++) {
138 for (i = 0; i < c; i++) {
139 sum = 0.0;
140 for (k = 0; k < d; k++) {
141 sum += PC.getQuick(j, k) * zzz[c * k + i];
142 }
143 path[(j + 1) * c + i] = sum + mu[i] * (t[j + 1] - t[0]) + x0[i];
144 }
145 }
146
147 observationIndex = observationCounter = d;
148 return path;
149 }
150
151 protected DoubleMatrix2D decompPCA(DoubleMatrix2D Sigma, double[] eigenValues) {
152 // L'objet SingularValueDecomposition permet de recuperer la matrice
153 // des valeurs propres en ordre decroissant et celle des vecteurs propres de
154 // sigma (pour une matrice symetrique et definie-positive seulement).
155 SingularValueDecomposition sv = new SingularValueDecomposition(Sigma);
156 DoubleMatrix2D D = sv.getS(); // diagonal
157 // Calculer la racine carree des valeurs propres
158 for (int i = 0; i < D.rows(); i++) {
159 D.setQuick(i, i, Math.sqrt(D.getQuick(i, i)));
160 eigenValues[i] = D.getQuick(i, i);
161 }
162 DoubleMatrix2D P = sv.getV(); // right factor matrix
163 return P; // returns the matrix of eigenvectors associate with the eigenValues
164 // in the vector eigenValue. The values in eigenValue are the square root
165 // of the eigenvalues
166 }
167
168 protected void init() {
169 super.init();
170 int i, j;
171 z = new double[c * d];
172 zz = new double[c * d];
173 zzz = new double[c * d];
174 double[] lambdaC = new double[d];
175 double[] etaB = new double[c];
176// BC stocks the product of eigenvalues in column 0 and the associated rank in the products in column 1
177 BC = new DenseDoubleMatrix2D(c * d, 2);
178// sortedBC stocks the product of eigenvalues in decreasing order in column 0 and their initial rank in the product in column 1, so column 1 becomes the eigenIndex.
179 sortedBC = new DenseDoubleMatrix2D(c * d, 2);
180 PC = new DenseDoubleMatrix2D(d, d); // the matrix P (unit eigenVectors) of PCA decomp for matrix C
181 PcovZ = new DenseDoubleMatrix2D(c, c); // the matrix P (unit eigenVectors) of PCA decomp for matrix covZ
182
183 // Initialize C, based on the observation times.
184 C = new DenseDoubleMatrix2D(d, d);
185 for (j = 0; j < d; j++) {
186 for (i = j; i < d; i++) {
187 C.setQuick(j, i, t[j + 1]);
188 C.setQuick(i, j, t[j + 1]);
189 }
190 }
191
192 PC = decompPCA(C, lambdaC); // v_j and \lambda_j
193 PcovZ = decompPCA(covZ, etaB); // w_i \eta_i
194
195 for (j = 0; j < d; j++)
196 for (i = 0; i < c; i++) {
197 BC.setQuick(c * j + i, 0, lambdaC[j] * etaB[i]);
198 BC.setQuick(c * j + i, 1, (double) (c * j + i));
199 }
200 sortedBC = Sorting.quickSort.sort(BC, 0); // sort in ascending order... we need to reverse to
201 // have descending order
202 // the matrix returned by sort (sortedBC) is still linked to BC so we need a
203 // deep copy in order to be able to inverse the order
204 DoubleMatrix2D copyBC = sortedBC.copy();
205
206 for (i = 0; i < c * d; i++) {
207 BC.setQuick(i, 0, copyBC.getQuick(c * d - 1 - i, 0)); // to obtain the eigenvalues in increasing order
208 BC.setQuick(i, 1, copyBC.getQuick(c * d - 1 - i, 1)); // reverse the index...
209 }
210 decompPCA = true;
211 }
212}
Extends the class ContinuousDistribution for the normal distribution (e.g., tjoh95a  (page 80)).
This class implements methods for generating random variates from the normal distribution .
double[] generatePath(double[] uniform01)
Sets the parameters.
MultivariateBrownianMotionPCA(int c, double[] x0, double[] mu, double[] sigma, double[][] corrZ, NormalGen gen)
Constructs a new MultivariateBrownianMotionPCA with parameters.
void setParams(int c, double[] x0, double[] mu, double[] sigma, double[][] corrZ)
Sets the dimension , the initial value.
MultivariateBrownianMotionPCA(int c, double[] x0, double[] mu, double[] sigma, double[][] corrZ, RandomStream stream)
Constructs a new MultivariateBrownianMotionPCA with parameters.
double[] generatePath()
Generates, returns, and saves the sample path.
This interface defines the basic structures to handle multiple streams of uniform (pseudo)random numb...