SSJ API Documentation
Stochastic Simulation in Java
Loading...
Searching...
No Matches
InverseGaussianProcessBridge.java
1/*
2 * The conditional bridge distribution is known @cite fWEB03a,
3 * but is not integrable, therefore there can be no bridge method
4 * using simply inversion, with a single
5 * \externalclass{umontreal.ssj.rng}{RandomStream}.
6 */
7
8/*
9 * Class: InverseGaussianProcessBridge
10 * Description:
11 * Environment: Java
12 * Software: SSJ
13 * Copyright (C) 2001 Pierre L'Ecuyer and Universite de Montreal
14 * Organization: DIRO, Universite de Montreal
15 * @author
16 * @since
17 *
18 *
19 * Licensed under the Apache License, Version 2.0 (the "License");
20 * you may not use this file except in compliance with the License.
21 * You may obtain a copy of the License at
22 *
23 * http://www.apache.org/licenses/LICENSE-2.0
24 *
25 * Unless required by applicable law or agreed to in writing, software
26 * distributed under the License is distributed on an "AS IS" BASIS,
27 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
28 * See the License for the specific language governing permissions and
29 * limitations under the License.
30 *
31 */
32package umontreal.ssj.stochprocess;
33
34import umontreal.ssj.rng.*;
35import umontreal.ssj.probdist.*;
36import umontreal.ssj.randvar.*;
37
47
48 // Careful: mu and lambda are completely different from parent class.
49 protected double[] imu2;
50 protected double[] imuLambdaZ;
51 protected double[] imuOver2LambdaZ;
52
53 protected int[] wIndexList;
54 protected int bridgeCounter = -1; // Before 1st observ
55
60 public InverseGaussianProcessBridge(double s0, double delta, double gamma, RandomStream stream,
61 RandomStream otherStream) {
62 super(s0, delta, gamma, stream, otherStream);
63 numberOfRandomStreams = 2;
64 }
65
71 public double[] generatePath() {
72 bridgeCounter = -1;
73 observationIndex = 0;
74 path[0] = x0;
75 for (int j = 0; j < d; j++)
77 return path;
78 }
79
85 public double[] generatePath(double[] unifNorm, double[] unifOther) {
86 double s = x0;
87 RandomStream cacheStreamNormal = stream;
88 RandomStream cacheStreamOther = otherStream;
89 stream = new NonRandomStream(unifNorm);
90 normalGen.setStream(stream);
91 otherStream = new NonRandomStream(unifOther);
92
93 bridgeCounter = -1;
94 observationIndex = 0;
95 path[0] = x0;
96 for (int j = 0; j < d; j++)
98
99 stream = cacheStreamNormal;
100 normalGen.setStream(stream);
101 otherStream = cacheStreamOther;
102 return path;
103 }
104
108 public double nextObservation() {
109 double s;
110 if (bridgeCounter == -1) {
111 double temp = delta * (t[d] - t[0]);
112 s = x0 + InverseGaussianMSHGen.nextDouble(otherStream, normalGen, temp / gamma, temp * temp);
113 bridgeCounter = 0;
114 observationIndex = d;
115 } else {
116 int j = bridgeCounter * 3;
117 int oldIndexL = wIndexList[j];
118 int newIndex = wIndexList[j + 1];
119 int oldIndexR = wIndexList[j + 2];
120
121 // Use the fact that \chi^2_1 is equivalent to a normal squared.
122 double q = normalGen.nextDouble();
123 q *= q;
124
125 double z = path[oldIndexR];
126 double mu = imu[newIndex];
127 double muLambda = imuLambdaZ[newIndex] / z;
128 double mu2 = imu2[newIndex];
129 double muOver2Lambda = imuOver2LambdaZ[newIndex] * z;
130
131 double root = mu + muOver2Lambda * mu * q - muOver2Lambda * Math.sqrt(4. * muLambda * q + mu2 * q * q);
132 double probabilityRoot1 = mu * (1. + root) / (1. + mu) / (root + mu);
133 // Check if reject first root for 2nd one: root2=mu^2/root1.
134 if (otherStream.nextDouble() > probabilityRoot1)
135 root = mu2 / root;
136 s = path[oldIndexL] + (path[oldIndexR] - path[oldIndexL]) / (1.0 + root);
137 bridgeCounter++;
138 observationIndex = newIndex;
139 }
140 observationCounter = bridgeCounter + 1;
141 path[observationIndex] = s;
142 return s;
143 }
144
145 public void resetStartProcess() {
146 observationIndex = 0;
147 observationCounter = 0;
148 bridgeCounter = -1;
149 }
150
151 protected void init() {
152 // imu[] etc. in super.init() will be overriden here.
153 // Necessary nonetheless.
154 super.init();
155
156 double tauX;
157 double tauY;
158 double mu;
159 double lambdaZ;
160 if (observationTimesSet) {
161 wIndexList = new int[3 * d];
162
163 int[] ptIndex = new int[d + 1];
164 int indexCounter = 0;
165 int newIndex, oldIndexL, oldIndexR;
166
167 ptIndex[0] = 0;
168 ptIndex[1] = d;
169
170 // Careful: mu and lambda are completely different from parent class.
171 imu = new double[d + 1];
172 ilam = new double[d + 1];
173 imu2 = new double[d + 1];
174 imuLambdaZ = new double[d + 1];
175 imuOver2LambdaZ = new double[d + 1];
176
177 for (int powOfTwo = 1; powOfTwo <= d / 2; powOfTwo *= 2) {
178 /* Make room in the indexing array "ptIndex" */
179 for (int j = powOfTwo; j >= 1; j--)
180 ptIndex[2 * j] = ptIndex[j];
181
182 /* Insert new indices and Calculate constants */
183 for (int j = 1; j <= powOfTwo; j++) {
184 oldIndexL = 2 * j - 2;
185 oldIndexR = 2 * j;
186 newIndex = (int) (0.5 * (ptIndex[oldIndexL] + ptIndex[oldIndexR]));
187
188 tauX = t[newIndex] - t[ptIndex[oldIndexL]];
189 tauY = t[ptIndex[oldIndexR]] - t[newIndex];
190 mu = tauY / tauX;
191 lambdaZ = delta * delta * tauY * tauY;
192 imu[newIndex] = mu;
193 ilam[newIndex] = lambdaZ;
194 imu2[newIndex] = mu * mu;
195 imuLambdaZ[newIndex] = mu * lambdaZ;
196 imuOver2LambdaZ[newIndex] = mu / 2. / lambdaZ;
197
198 ptIndex[oldIndexL + 1] = newIndex;
199 wIndexList[indexCounter] = ptIndex[oldIndexL];
200 wIndexList[indexCounter + 1] = newIndex;
201 wIndexList[indexCounter + 2] = ptIndex[oldIndexR];
202
203 indexCounter += 3;
204 }
205 }
206
207 /* Check if there are holes remaining and fill them */
208 for (int k = 1; k < d; k++) {
209 if (ptIndex[k - 1] + 1 < ptIndex[k]) {
210 // there is a hole between (k-1) and k.
211
212 tauX = t[ptIndex[k - 1] + 1] - t[ptIndex[k - 1]];
213 tauY = t[ptIndex[k]] - t[ptIndex[k - 1] + 1];
214 mu = tauY / tauX;
215 lambdaZ = delta * delta * tauY * tauY;
216 imu[ptIndex[k - 1] + 1] = mu;
217 ilam[ptIndex[k - 1] + 1] = lambdaZ;
218 imu2[ptIndex[k - 1] + 1] = mu * mu;
219 imuLambdaZ[ptIndex[k - 1] + 1] = mu * lambdaZ;
220 imuOver2LambdaZ[ptIndex[k - 1] + 1] = mu / 2. / lambdaZ;
221
222 wIndexList[indexCounter] = ptIndex[k] - 2;
223 wIndexList[indexCounter + 1] = ptIndex[k] - 1;
224 wIndexList[indexCounter + 2] = ptIndex[k];
225 indexCounter += 3;
226 }
227 }
228 }
229 }
230
235 if (stream != otherStream)
236 throw new IllegalStateException("Two different streams or more are present");
237 return stream;
238 }
239
243 public void setStream(RandomStream stream, RandomStream otherStream) {
244 this.stream = stream;
245 this.otherStream = otherStream;
246 normalGen.setStream(stream);
247 }
248
252 public void setStream(RandomStream stream) {
253 setStream(stream, stream);
254 }
255
256}
This class implements inverse gaussian random variate generators using the many-to-one transformation...
static double nextDouble(RandomStream s, NormalGen sn, double mu, double lambda)
Generates a new variate from the inverse gaussian distribution with parameters mu and lambda,...
void setStream(RandomStream stream, RandomStream otherStream)
Sets the streams.
RandomStream getStream()
Only returns a stream if both inner streams are the same.
double[] generatePath(double[] unifNorm, double[] unifOther)
Instead of using the internal streams to generate the path, it uses two arrays of uniforms .
double nextObservation()
Returns the next observation in the bridge order, not the sequential order.
void resetStartProcess()
Resets the observation counter to its initial value , so that the current observation becomes .
InverseGaussianProcessBridge(double s0, double delta, double gamma, RandomStream stream, RandomStream otherStream)
Constructs a new InverseGaussianProcessBridge.
void setStream(RandomStream stream)
Sets both inner streams to the same stream.
NonRandomStream: Given a double array, this class will return those values as if it where a random st...
InverseGaussianProcessMSH(double s0, double delta, double gamma, RandomStream stream, RandomStream otherStream)
Constructs a new InverseGaussianProcessMSH.
This interface defines the basic structures to handle multiple streams of uniform (pseudo)random numb...