SSJ API Documentation
Stochastic Simulation in Java
Loading...
Searching...
No Matches
MultivariateBrownianMotion.java
1/*
2 * Class: MultivariateBrownianMotion
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 Pierre L'Écuyer, Jean-Sébastien Parent & Clément Teule
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.util.DMatrix;
28import umontreal.ssj.probdist.*;
29import umontreal.ssj.randvar.*;
30import cern.colt.matrix.DoubleMatrix2D;
31import cern.colt.matrix.impl.DenseDoubleMatrix2D;
32import cern.colt.matrix.linalg.CholeskyDecomposition;
33
60public class MultivariateBrownianMotion extends MultivariateStochasticProcess {
61 protected NormalGen gen;
62 protected double[] mu;
63 protected double[] sigma;
64 protected double[][] corrZ; // Correlation matrix for Z.
65 protected DoubleMatrix2D covZ; // Covariance Matrix
66 protected DoubleMatrix2D covZCholDecomp; // Matrix obtained using the cholesky decomposition on covZ
67 protected CholeskyDecomposition decomp;
68 protected boolean covZiSCholDecomp;
69
70 // Precomputed values for standard BM
71 protected double[] dt, sqrdt;
72
73 protected MultivariateBrownianMotion() {
74 };
75
86 public MultivariateBrownianMotion(int c, double[] x0, double[] mu, double[] sigma, double[][] corrZ,
87 RandomStream stream) {
88 setParams(c, x0, mu, sigma, corrZ);
89 this.gen = new NormalGen(stream, new NormalDist());
90 }
91
101 public MultivariateBrownianMotion(int c, double[] x0, double[] mu, double[] sigma, double[][] corrZ, NormalGen gen) {
102 setParams(c, x0, mu, sigma, corrZ);
103 this.gen = gen;
104 }
105
114 public void nextObservationVector(double[] obs) {
115 if (!covZiSCholDecomp)
116 // the cholesky factorisation must be done to use the matrix covZCholDecomp
117 initCovZCholDecomp();
118 double z;
119 for (int i = 0; i < c; i++) {
120 z = 0.0;
121 for (int k = 0; k < c; k++)
122 z += covZCholDecomp.getQuick(i, k) * gen.nextDouble();
123 obs[i] = path[c * observationIndex + i] + mu[i] * dt[observationIndex] + sqrdt[observationIndex] * z;
124 path[c * (observationIndex + 1) + i] = obs[i];
125 }
126 observationIndex++;
127 }
128
136 public double[] nextObservationVector() {
137 double[] obs = new double[c];
139 return obs;
140 }
141
151 public double[] nextObservationVector(double nextTime, double[] obs) {
152 if (!covZiSCholDecomp) // the cholesky factorisation must be done to use the matrix covZCholDecomp
153 initCovZCholDecomp();
154 t[observationIndex + 1] = nextTime;
155 double z;
156 for (int i = 0; i < c; i++) {
157 z = 0.0;
158 for (int k = 0; k < c; k++)
159 z += covZCholDecomp.getQuick(i, k) * gen.nextDouble();
160 obs[i] = path[c * observationIndex + i] + mu[i] * (t[observationIndex + 1] - t[observationIndex])
161 + Math.sqrt(t[observationIndex + 1] - t[observationIndex]) * z;
162 path[c * (observationIndex + 1) + i] = obs[i];
163 }
164 observationIndex++;
165 return obs;
166 }
167
174 public double[] nextObservationVector(double x[], double dt) {
175 double[] obs = new double[c];
176 double z;
177 if (!covZiSCholDecomp) // the cholesky factorisation must be done to use the matrix covZCholDecomp
178 initCovZCholDecomp();
179
180 for (int i = 0; i < c; i++) {
181 z = 0.0;
182 for (int k = 0; k < c; k++)
183 z += covZCholDecomp.getQuick(i, k) * gen.nextDouble();
184 obs[i] = x[i] + mu[i] * dt + Math.sqrt(dt) * z;
185 }
186 observationIndex++;
187 return obs;
188 }
189
190 public double[] generatePath() {
191 double[] u = new double[c * d];
192 for (int i = 0; i < c * d; i++)
193 u[i] = gen.nextDouble();
194 return generatePath(u);
195 }
196
201 public double[] generatePath(double[] uniform01) {
202 if (!covZiSCholDecomp) {
203 // the cholesky factorisation must be done to use the matrix covZCholDecomp
204 initCovZCholDecomp();
205 }
206 double z;
207 double[] QMCpointsPart = new double[c];
208 for (int i = 0; i < c; i++)
209 path[i] = x0[i];
210 for (int j = 0; j < d; j++) {
211 for (int i = 0; i < c; i++)
212 QMCpointsPart[i] = uniform01[j * c + i];
213 for (int i = 0; i < c; i++) {
214 z = 0.0;
215 for (int k = 0; k < c; k++)
216 z += covZCholDecomp.getQuick(i, k) * QMCpointsPart[k];
217 path[c * (j + 1) + i] = path[c * j + i] + mu[i] * dt[j] + sqrdt[j] * z;
218 }
219 }
220 observationIndex = d;
221 return path;
222 }
223
224 public double[] generatePath(RandomStream stream) {
225 gen.setStream(stream);
226 return generatePath();
227 }
228
240 public void setParams(int c, double x0[], double mu[], double sigma[], double corrZ[][]) {
241 this.c = c;
242 this.x0 = x0;
243 this.mu = mu;
244 this.sigma = sigma;
245 this.corrZ = corrZ;
246
247 if (x0.length < c)
248 throw new IllegalArgumentException(
249 "x0 dimension : " + x0.length + " is smaller than the process dimension : " + c);
250 if (mu.length < c)
251 throw new IllegalArgumentException(
252 "mu dimension : " + mu.length + " is smaller than the process dimension : " + c);
253 if (sigma.length < c)
254 throw new IllegalArgumentException(
255 "sigma dimension : " + sigma.length + " is smaller than the process dimension : " + c);
256 if ((corrZ.length < c) || (corrZ[0].length < c))
257 throw new IllegalArgumentException("corrZ dimensions : " + corrZ.length + "x" + corrZ[0].length
258 + " are smaller than the process dimension : " + c);
259 covZ = new DenseDoubleMatrix2D(c, c);
260 initCovZ();
261 covZiSCholDecomp = false;
262
263 if (observationTimesSet)
264 init(); // Otherwise not needed.
265 }
266
275 public void setParams(double x0[], double mu[], double sigma[]) {
276 this.x0 = x0;
277 this.mu = mu;
278 this.sigma = sigma;
279 covZ = new DenseDoubleMatrix2D(c, c);
280 initCovZ();
281 covZiSCholDecomp = false;
282
283 if (observationTimesSet)
284 init(); // Otherwise not needed.
285 }
286
290 public void setStream(RandomStream stream) {
291 gen.setStream(stream);
292 }
293
298 return gen.getStream();
299 }
300
305 public NormalGen getGen() {
306 return gen;
307 }
308
309 // This is called by setObservationTimes to precompute constants
310 // in order to speed up the path generation.
311 protected void init() {
312 super.init();
313 dt = new double[d + 1];
314 sqrdt = new double[d + 1];
315 for (int j = 0; j < d; j++) {
316 dt[j] = t[j + 1] - t[j];
317 sqrdt[j] = Math.sqrt(dt[j]);
318 }
319 }
320
321 protected void initCovZCholDecomp() {
322 covZCholDecomp = new DenseDoubleMatrix2D(c, c);
323 covZCholDecomp = DMatrix.CholeskyDecompose(covZ);
324 covZiSCholDecomp = true;
325 }
326
327 protected void initCovZ() {
328 for (int i = 0; i < c; i++)
329 for (int j = 0; j < c; j++)
330 covZ.setQuick(i, j, corrZ[i][j] * sigma[i] * sigma[j]);
331 }
332
336 public double[] getMu() {
337 return mu;
338 }
339
340}
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 .
RandomStream getStream()
Returns the random stream of the normal generator.
double[] generatePath(RandomStream stream)
Same as generatePath(), but first resets the stream to stream.
void setParams(double x0[], double mu[], double sigma[])
Sets the dimension , the initial value.
void setStream(RandomStream stream)
Resets the random stream of the normal generator to stream.
void nextObservationVector(double[] obs)
Generates and returns in obs the next observation.
double[] generatePath()
Generates, returns, and saves the sample path.
double[] generatePath(double[] uniform01)
Same as generatePath() but requires a vector of uniform random numbers which are used to generate the...
NormalGen getGen()
Returns the normal random variate generator used.
double[] nextObservationVector(double nextTime, double[] obs)
Generates and returns the vector of next observations, at time , using the previous observation time...
MultivariateBrownianMotion(int c, double[] x0, double[] mu, double[] sigma, double[][] corrZ, RandomStream stream)
Constructs a new MultivariateBrownianMotion with parameters.
void setParams(int c, double x0[], double mu[], double sigma[], double corrZ[][])
Sets the dimension , the initial value.
double[] nextObservationVector(double x[], double dt)
Generates an observation (vector) of the process in dt time units, assuming that the process has (vec...
double[] nextObservationVector()
Generates and returns the next observation of the multivariate stochastic process in a vector create...
MultivariateBrownianMotion(int c, double[] x0, double[] mu, double[] sigma, double[][] corrZ, NormalGen gen)
Constructs a new MultivariateBrownianMotion with parameters.
This class is a multivariate version of StochasticProcess where the process evolves in the -dimension...
This interface defines the basic structures to handle multiple streams of uniform (pseudo)random numb...