/* *
* 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 an Ornstein-Uhlenbeck process
* as in {@link OrnsteinUhlenbeckProcess}, 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 OrnsteinUhlenbeckProcessEuler extends OrnsteinUhlenbeckProcess {
/**
* Constructor 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 OrnsteinUhlenbeckProcessEuler (double x0, double alpha, double b,
double sigma, RandomStream stream)
{
this (x0, alpha, b, sigma, new NormalGen (stream));
}
/**
* Here, the normal variate generator is specified directly
* instead of specifying the stream.
* The normal generator gen can use another method than inversion.
*
*/
public OrnsteinUhlenbeckProcessEuler (double x0, double alpha, double b,
double sigma, NormalGen gen) {
super (x0, alpha, b, sigma, gen);
}
/**
* Generates and returns the next observation at time tj+1 =
* nextTime. Assumes the previous observation time is 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 xOld = path[observationIndex];
double x = xOld + (beta - xOld) * alphadt[observationIndex]
+ sigmasqrdt[observationIndex] * gen.nextDouble();
observationIndex++;
path[observationIndex] = x;
return x;
}
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) * gen.nextDouble();
path[observationIndex] = x;
return x;
}
/**
* Generates and returns 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) * gen.nextDouble();
return x;
}
/**
* Generates a sample path of the process at all observation times,
* which are provided in array t.
* Note that t[0] should be the observation time of x0,
* the initial value of the process, and t[] should have at least d + 1
* elements (see the setObservationTimes method).
*
*/
public double[] generatePath() {
double x;
double xOld = x0;
for (int j = 0; j < d; j++) {
x = xOld + (beta - xOld)*alphadt[j] + sigmasqrdt[j]*gen.nextDouble();
path[j + 1] = x;
xOld = x;
}
observationIndex = d;
return path;
}
protected void initArrays(int 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.