/* *
* Title:
* Description:
* Copyright: Copyright (c)
* Company:
* @author
* @version 1.0
*/
package umontreal.iro.lecuyer.stochprocess;
import umontreal.iro.lecuyer.rng.*;
import umontreal.iro.lecuyer.probdist.*;
import umontreal.iro.lecuyer.randvar.*;
/**
* .
*
* This class represents a CIR process
* as in {@link CIRProcess}, but
* the process is generated using the simple Euler scheme
*
*
* where
* Zj∼N(0, 1). This is a good approximation only for small
* time intervals
* tj - tj-1.
*
*/
public class CIRProcessEuler extends StochasticProcess {
protected NormalGen gen;
protected double alpha,
beta,
sigma;
// Precomputed values
protected double[] alphadt,
sigmasqrdt;
/**
* Constructs a new CIRProcessEuler with parameters
* α = alpha, b, σ = sigma and initial value
*
* X(t0) = x0. The normal variates Zj will be
* generated by inversion using the stream stream.
*
*/
public CIRProcessEuler (double x0, double alpha, double b, double sigma,
RandomStream stream) {
this (x0, alpha, b, sigma, new NormalGen (stream, new NormalDist()));
}
/**
* The normal variate generator gen is specified directly
* instead of specifying the stream.
* gen can use another method than inversion.
*
*/
public CIRProcessEuler (double x0, double alpha, double b, double sigma,
NormalGen gen) {
this.alpha = alpha;
this.beta = b;
this.sigma = sigma;
this.x0 = x0;
this.gen = gen;
}
public double nextObservation() {
double xOld = path[observationIndex];
double x;
x = xOld + (beta - xOld) * alphadt[observationIndex]
+ sigmasqrdt[observationIndex] * Math.sqrt(xOld) * gen.nextDouble();
observationIndex++;
if (x >= 0.0)
path[observationIndex] = x;
else
path[observationIndex] = 0.;
return x;
}
/**
* Generates and returns the next observation at time tj+1 =
* nextTime, using the previous observation time tj defined earlier
* (either by this method or by setObservationTimes),
* as well as the value of the previous observation X(tj).
* Warning: This method will reset the observations time tj+1
* for this process to nextTime. The user must make sure that
* the tj+1 supplied is
* >= tj.
*
*/
public double nextObservation (double nextTime) {
double previousTime = t[observationIndex];
double xOld = path[observationIndex];
observationIndex++;
t[observationIndex] = nextTime;
double dt = nextTime - previousTime;
double x = xOld + alpha * (beta - xOld) * dt
+ sigma * Math.sqrt (dt*xOld) * gen.nextDouble();
if (x >= 0.0)
path[observationIndex] = x;
else
path[observationIndex] = 0.;
return x;
}
/**
* Generates an observation of the process in dt time units,
* assuming that the process has value x at the current time.
* Uses the process parameters specified in the constructor.
* Note that this method does not affect the sample path of the process
* stored internally (if any).
*
*
*/
public double nextObservation (double x, double dt) {
x = x + alpha * (beta - x) * dt +
sigma * Math.sqrt (dt*x) * gen.nextDouble();
if (x >= 0.0)
return x;
return 0.0;
}
public double[] generatePath() {
double x;
double xOld = x0;
for (int j = 0; j < d; j++) {
x = xOld + (beta - xOld) * alphadt[j]
+ sigmasqrdt[j] * Math.sqrt(xOld) * gen.nextDouble();
if (x < 0.0)
x = 0.0;
path[j + 1] = x;
xOld = x;
}
observationIndex = d;
return path;
}
public double[] generatePath (RandomStream stream) {
gen.setStream (stream);
return generatePath();
}
/**
* Resets the parameters
* X(t0) = x0, α = alpha,
* b = b and σ = sigma of the process.
* Warning: This method will recompute some quantities stored internally,
* which may be slow if called too frequently.
*
*/
public void setParams (double x0, double alpha, double b, double sigma) {
this.alpha = alpha;
this.beta = b;
this.sigma = sigma;
this.x0 = x0;
if (observationTimesSet) init(); // Otherwise not needed.
}
/**
* Resets the random stream of the normal generator to stream.
*
*/
public void setStream (RandomStream stream) {
gen.setStream (stream);
}
/**
* Returns the random stream of the normal generator.
*
*/
public RandomStream getStream() {
return gen.getStream ();
}
/**
* Returns the value of α.
*
*/
public double getAlpha() { return alpha; }
/**
* Returns the value of b.
*
*/
public double getB() { return beta; }
/**
* Returns the value of σ.
*
*/
public double getSigma() { return sigma; }
/**
* Returns the normal random variate generator used.
* The RandomStream used for that generator can be changed via
* getGen().setStream(stream), for example.
*
*/
public NormalGen getGen() { return gen; }
// This is called by setObservationTimes to precompute constants
// in order to speed up the path generation.
protected void init() {
super.init();
alphadt = new double[d];
sigmasqrdt = new double[d];
double dt;
for (int j = 0; j < d; j++) {
dt = t[j+1] - t[j];
alphadt[j] = alpha * (dt);
sigmasqrdt[j] = sigma * Math.sqrt (dt);
}
}
}
Ads help maintain this website.