SSJ API Documentation
Stochastic Simulation in Java
Loading...
Searching...
No Matches
OrnsteinUhlenbeckWithIntegratedProcess.java
1package umontreal.ssj.stochprocess;
2
3import umontreal.ssj.randvar.*;
4import umontreal.ssj.randvarmulti.*;
5// import umontreal.ssj.stochprocess.OrnsteinUhlenbeckProcess;
6import cern.colt.matrix.impl.*;
7
17 double[] integratedPath; // length [d + 1]
18 MultinormalGen[] normalsCorrGen; // length [d]
19 double[] bdt; // length [d]: (beta * dt)
20 double[] oneMExpMADtOverAlpha; // length [d]: (1.0 - exp(-alpha * dt)) / alpha
21 double c22; // sigma * sigma / 2.0 / alpha^3
22
29 public OrnsteinUhlenbeckWithIntegratedProcess(double x0, double alpha, double b, double sigma, NormalGen gen) {
30 super(x0, alpha, b, sigma, gen);
31 }
32
37 @Override
38 protected void initArrays(int d) {
39 super.initArrays(d); // [Not sure why the "d" is there, but was there in super.initArrays...]
40 // this is called by init() which is called in
41 // StochasticProcess.setObservationTimes().
42 integratedPath = new double[d + 1];
43 bdt = new double[d];
44 oneMExpMADtOverAlpha = new double[d];
45 // iTime == d not included
46 for (int iTime = 0; iTime < d; iTime++) {
47 double dt = t[iTime + 1] - t[iTime];
48 bdt[iTime] = beta * dt;
49 double oneMExpMADt = -Math.expm1(-alpha * dt); // (1.0 - exp(-alpha * dt);
50 oneMExpMADtOverAlpha[iTime] = oneMExpMADt / alpha;
51 }
52
53 double c11 = sigma * sigma / 2.0 / alpha;
54 double c12 = c11 / alpha;
55 c22 = c12 / alpha;
56 normalsCorrGen = new MultinormalGen[d];
57 for (int iTime = 0; iTime < d; iTime++) {
58 double dt = t[iTime + 1] - t[iTime];
59 double expMADt = alphadt[iTime];
60 double oneMExpMADt = -Math.expm1(-alpha * dt); // (1.0 - exp(-alpha * dt);
61
62 DenseDoubleMatrix2D covar = new DenseDoubleMatrix2D(2, 2);
63 covar.set(0, 0, c11 * oneMExpMADt * (1.0 + expMADt)); // sigma^2/2/alpha * (1 - exp(-2 * alpha * dt))
64 covar.set(0, 1, c12 * oneMExpMADt * oneMExpMADt); // sigma^2/2/alpha^2 * (1 - exp(-alpha*dt))^2
65 covar.set(1, 0, covar.get(0, 1));
66 covar.set(1, 1, c22 * (-3.0 + 2.0 * alpha * dt + 4.0 * expMADt - expMADt * expMADt));
67
68 double[] mu = { 0.0, 0.0 }; // the expectation terms depend on the previous path values and are added
69 // elsewhere.
70 normalsCorrGen[iTime] = new MultinormalPCAGen(gen, mu, covar);
71 }
72 }
73
86 @Override
87 public double[] generatePath() {
88 path[0] = x0;
89 integratedPath[0] = 0.0;
90 double[] normalsCorr = new double[2];
91 for (int iTime = 1; iTime <= d; iTime++) {
92 normalsCorrGen[iTime - 1].nextPoint(normalsCorr);
93 path[iTime] = badt[iTime - 1] + path[iTime - 1] * alphadt[iTime - 1] + normalsCorr[0];
94
95 integratedPath[iTime] = integratedPath[iTime - 1] + bdt[iTime - 1]
96 + oneMExpMADtOverAlpha[iTime - 1] * (path[iTime - 1] - beta) + normalsCorr[1];
97 }
98 observationIndex = d;
99 return path;
100 }
101
108 public double[] getIntegratedPath() {
109 return integratedPath;
110 }
111
134 public double[] getExpectedFutureDiscount(double[] couponTimes) {
135 double[] analyticNotificationDiscounts = new double[couponTimes.length];
136 for (int iTime = 1; iTime < couponTimes.length; iTime++) {
137 int iTimePath = (iTime < d) ? iTime : d;
138 double dt = couponTimes[iTime] - t[iTimePath]; // noticePeriod
139 double expMADt = Math.exp(-alpha * dt);
140 double mu_2 = beta * dt + (1.0 - expMADt) / alpha * (path[iTimePath] - beta);
141 double sigma22 = c22 * (-3.0 + 2.0 * alpha * dt + 4.0 * expMADt - expMADt * expMADt);
142 analyticNotificationDiscounts[iTime] = Math.exp(-mu_2 + sigma22 / 2.0 - integratedPath[iTimePath]);
143 }
144 return analyticNotificationDiscounts;
145 }
146
158 public double[] getTotalAnalyticDiscount(double[] times) {
159 double[] analyticDiscount = new double[times.length];
160 analyticDiscount[0] = 1.0;
161 for (int iTime = 1; iTime < times.length; iTime++) {
162 double dt = times[iTime] - times[0];
163 double expMADt = Math.exp(-alpha * dt);
164 double mu_2 = beta * dt + (1.0 - expMADt) / alpha * (x0 - beta);
165 double sigma22 = c22 * (-3.0 + 2.0 * alpha * dt + 4.0 * expMADt - expMADt * expMADt);
166 analyticDiscount[iTime] = Math.exp(-mu_2 + sigma22 / 2.0);
167 }
168 return analyticDiscount;
169 }
170}
This class implements methods for generating random variates from the normal distribution .
Extends RandomMultivariateGen for a multivariate normal (or multinormal) distribution tjoh72a .
Extends MultinormalGen for a multivariate normal distribution.
OrnsteinUhlenbeckProcess(double x0, double alpha, double b, double sigma, RandomStream stream)
Constructs a new OrnsteinUhlenbeckProcess with parameters.
double[] getExpectedFutureDiscount(double[] couponTimes)
generatePath must be called before this method is called since it depends on the underlying path.
OrnsteinUhlenbeckWithIntegratedProcess(double x0, double alpha, double b, double sigma, NormalGen gen)
double[] getTotalAnalyticDiscount(double[] times)
This method is independent of the observation times of the object's instance, but it is dependent on ...
double[] getIntegratedPath()
This method must be called after generatePath() or nextObservation().
double[] generatePath()
Same as the method from the parent class, but also generates at each time step a stochastic variable ...
void initArrays(int d)
Sets up various constants and decomposes the correlation matrix at each time step.