SSJ API Documentation
Stochastic Simulation in Java
Loading...
Searching...
No Matches
MultivariateBrownianMotionBridge.java
1/*
2 * Class: MultivariateBrownianMotionBridge
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 * @authors 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.probdist.*;
28import umontreal.ssj.randvar.*;
29import cern.colt.matrix.DoubleMatrix2D;
30import cern.colt.matrix.impl.DenseDoubleMatrix2D;
31import cern.colt.matrix.linalg.*;
32
46public class MultivariateBrownianMotionBridge extends MultivariateBrownianMotion {
47
48 protected double[] z, covZCholDecompz; // vector of c*d standard normals.
49 protected int bridgeCounter = -1; // Before 1st observ
50
51 // For precomputations for B Bridge
52 protected double[] wMuDt, wSqrtDt;
53 protected int[] wIndexList, ptIndex;
54
65 public MultivariateBrownianMotionBridge(int c, double[] x0, double[] mu, double[] sigma, double[][] corrZ,
66 RandomStream stream) {
67 setParams(c, x0, mu, sigma, corrZ);
68 this.gen = new NormalGen(stream, new NormalDist());
69 z = new double[c];
70 covZCholDecompz = new double[c];
71 }
72
82 public MultivariateBrownianMotionBridge(int c, double[] x0, double[] mu, double[] sigma, double[][] corrZ,
83 NormalGen gen) {
84 setParams(c, x0, mu, sigma, corrZ);
85 this.gen = gen;
86 z = new double[c];
87 covZCholDecompz = new double[c];
88 }
89
90 public double[] generatePath() {
91 // Generation of Brownian bridge process
92 if (!covZiSCholDecomp) { // the cholesky factorisation must be done to use the matrix covZCholDecomp
93 initCovZCholDecomp();
94 }
95 int oldIndexL, oldIndexR, newIndex, i, j;
96
97 for (i = 0; i < c; i++)
98 z[i] = gen.nextDouble();
99
100 computeAZ(covZCholDecomp, z, covZCholDecompz);
101 for (i = 0; i < c; i++) {
102 path[c * d + i] = x0[i] + mu[i] * (t[d] - t[0]) + wSqrtDt[0] * covZCholDecompz[i];
103
104 }
105 for (j = 0; j < 3 * (d - 1); j += 3) {
106
107 for (i = 0; i < c; i++)
108 z[i] = gen.nextDouble();
109
110 computeAZ(covZCholDecomp, z, covZCholDecompz);
111 oldIndexL = wIndexList[j];
112 newIndex = wIndexList[j + 1];
113 oldIndexR = wIndexList[j + 2];
114 for (i = 0; i < c; i++) {
115 path[c * newIndex + i] = path[c * oldIndexL + i]
116 + (path[c * oldIndexR + i] - path[c * oldIndexL + i]) * wMuDt[newIndex]
117 + wSqrtDt[newIndex] * covZCholDecompz[i];
118// System.out.println("path[0] : " + path[0]);
119// System.out.println("path[" + i + "] : " + path[c * newIndex + i]);
120 }
121 }
122 // resetStartProcess();
123
124 observationIndex = observationCounter = c * d;
125 return path;
126 }
127
128 public void resetStartProcess() {
129 observationIndex = 0;
130 observationCounter = 0;
131 bridgeCounter = -1;
132 }
133
134 public double[] nextObservationVector() {
135 throw new UnsupportedOperationException("nextObservationVector is not implemented ");
136 }
137
138 public void nextObservationVector(double[] obs) {
139 throw new UnsupportedOperationException("nextObservationVector is not implemented ");
140 }
141
142 protected void init() {
143 super.init();
144
145 /* For Brownian Bridge */
146
147 // Quantities for Brownian Bridge process
148 wMuDt = new double[d + 1];
149 wSqrtDt = new double[d + 1];
150 wIndexList = new int[3 * (d)];
151 ptIndex = new int[d + 1];
152
153 int indexCounter = 0;
154 int newIndex, oldLeft, oldRight;
155 int i, j, k, powOfTwo;
156
157 for (i = 0; i < c; i++)
158 path[i] = x0[i];
159
160 ptIndex[0] = 0;
161 ptIndex[1] = d;
162
163 wMuDt[0] = 0.0; // The end point of the Wiener process
164 // w/ Brownian bridge has expectation = 0
165 wSqrtDt[0] = Math.sqrt(t[d] - t[0]);
166 // = sigma*sqrt(Dt) of end point
167
168 for (powOfTwo = 1; powOfTwo <= d / 2; powOfTwo *= 2) {
169 /* Make room in the indexing array "ptIndex" */
170 for (j = powOfTwo; j >= 1; j--) {
171 ptIndex[2 * j] = ptIndex[j];
172 }
173
174 /* Insert new indices and Calculate constants */
175 for (j = 1; j <= powOfTwo; j++) {
176 oldLeft = 2 * j - 2;
177 oldRight = 2 * j;
178 newIndex = (int) (0.5 * (ptIndex[oldLeft] + ptIndex[oldRight]));
179
180 wMuDt[newIndex] = (t[newIndex] - t[ptIndex[oldLeft]]) / (t[ptIndex[oldRight]] - t[ptIndex[oldLeft]]);
181
182 wSqrtDt[newIndex] = Math.sqrt((t[newIndex] - t[ptIndex[oldLeft]]) * (t[ptIndex[oldRight]] - t[newIndex])
183 / (t[ptIndex[oldRight]] - t[ptIndex[oldLeft]]));
184
185 ptIndex[oldLeft + 1] = newIndex;
186 wIndexList[indexCounter] = ptIndex[oldLeft];
187 wIndexList[indexCounter + 1] = newIndex;
188 wIndexList[indexCounter + 2] = ptIndex[oldRight];
189
190 indexCounter += 3;
191 }
192 }
193 /* Check if there are holes remaining and fill them */
194 for (k = 1; k < d; k++) {
195 if (ptIndex[k - 1] + 1 < ptIndex[k]) {
196 // there is a hole between (k-1) and k.
197 wMuDt[ptIndex[k - 1] + 1] = (t[ptIndex[k - 1] + 1] - t[ptIndex[k - 1]])
198 / (t[ptIndex[k]] - t[ptIndex[k - 1]]);
199 wSqrtDt[ptIndex[k - 1] + 1] = Math.sqrt((t[ptIndex[k - 1] + 1] - t[ptIndex[k - 1]])
200 * (t[ptIndex[k]] - t[ptIndex[k - 1] + 1]) / (t[ptIndex[k]] - t[ptIndex[k - 1]]));
201 wIndexList[indexCounter] = ptIndex[k] - 2;
202 wIndexList[indexCounter + 1] = ptIndex[k] - 1;
203 wIndexList[indexCounter + 2] = ptIndex[k];
204 indexCounter += 3;
205 }
206 }
207 }
208
209 // Computes A * z and returns it in vector Az.
210 private void computeAZ(DoubleMatrix2D A, double z[], double Az[]) {
211 for (int i = 0; i < c; i++) {
212 double sum = 0.0;
213 for (int k = 0; k < c; k++)
214 sum += A.getQuick(i, k) * z[k];
215 Az[i] = sum;
216 }
217 }
218
219}
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()
Generates, returns, and saves the sample path.
void nextObservationVector(double[] obs)
Generates and returns in obs the next observation.
double[] nextObservationVector()
Generates and returns the next observation of the multivariate stochastic process in a vector create...
MultivariateBrownianMotionBridge(int c, double[] x0, double[] mu, double[] sigma, double[][] corrZ, RandomStream stream)
Constructs a new MultivariateBrownianMotionBridge with parameters mu,.
MultivariateBrownianMotionBridge(int c, double[] x0, double[] mu, double[] sigma, double[][] corrZ, NormalGen gen)
Constructs a new MultivariateBrownianMotionBridge with parameters mu,.
void resetStartProcess()
Resets the observation counter to its initial value , so that the current observation becomes .
void setParams(int c, double x0[], double mu[], double sigma[], double corrZ[][])
Sets the dimension , the initial value.
This interface defines the basic structures to handle multiple streams of uniform (pseudo)random numb...