/* *
 * 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 variance gamma (VG) process * * {S(t) = X(t;θ, σ, ν) : t >= 0}. * This process is generated using difference of gamma sampling * (see), which uses the representation of the VG process * as the difference of two independent {@link GammaProcess}'es (see): *

*

*
* X(t;θ, σ, ν) : = X(0) + Γ+(t;μp, νp) - Γ-(t;μn, νn) *

* where X(0) is a constant corresponding to the initial value of the process * and *

*

*
* * * * * * * * * * * * * * * * * *
μp=(( &thetas;^2 + 2σ^2/ν)1/2 + θ)/2
μn=(( &thetas;^2 + 2σ^2/ν)1/2 - θ)/2
νp=νμp2
νn=νμn2
*

* */ public class VarianceGammaProcessDiff extends VarianceGammaProcess { protected GammaProcess gpos; protected GammaProcess gneg; protected double mup, mun, nup, nun; /** * Constructs a new VarianceGammaProcessDiff with parameters * * θ = theta, * σ = sigma, * ν = nu * and initial value * S(t0) = s0. stream is * used by two instances of {@link GammaProcess}, * Γ+ and * Γ-, * respectively. The other parameters are * as in the class {@link VarianceGammaProcess}. * The {@link GammaProcess} objects for * Γ+ and * Γ- are * constructed using the parameters from and their * initial values * Γ+(t0) and * Γ-(t0) are set to 0. * */ public VarianceGammaProcessDiff (double s0, double theta, double sigma, double nu, RandomStream stream) { this (s0, theta, sigma, nu, new GammaProcess (0.0, 1.0, 1.0, stream), new GammaProcess (0.0, 1.0, 1.0, stream)); // Params mu, nu of the 2 gamma processes are redefined in init() // which will be called after a call to 'setObservTimes' } /** * The parameters of the {@link GammaProcess} * objects for * Γ+ and * Γ- are * set to those of and their * initial values * Γ+(t0) and * Γ-(t0) are set to t0. * The RandomStream of the * Γ- process is overwritten with the * RandomStream of the * Γ+ process. * */ public VarianceGammaProcessDiff (double s0, double theta, double sigma, double nu, GammaProcess gpos, GammaProcess gneg) { this.gpos = gpos; this.gneg = gneg; setParams (s0, theta, sigma, nu); gneg.setStream(gpos.getStream()); // to avoid confusion with stream because there is only // one stream in the other constructor } public double nextObservation() { // This implementation takes possible bridge sampling into account double s = x0 + gpos.nextObservation() - gneg.nextObservation(); observationIndex = gpos.getCurrentObservationIndex(); path[observationIndex] = s; observationCounter++; return s; } // no longer useful, this method was created to automaticaly alternate // between the two processes the uniform random variables used in the // in the simulation. However, this method does not work if the two // GammaProcess are PCA... // public double[] generatePath() { // gpos.resetStartProcess(); // gneg.resetStartProcess(); // double s; // for (int i=1; i<=d; i++) { // s = x0 + gpos.nextObservation() - gneg.nextObservation(); // path[gpos.getCurrentObservationIndex()] = s; // // Note: we must get the observCounter from gpos in the case that // // the process is generated by a Gamma bridge // // The observCounter of gneg should be the same because both // // gamma processes should be generated the same way // } // observationIndex = d; // observationCounter = d; // return path; // } /** * Generates, returns and saves the path. To do so, the * path of * Γ+ is first generated and then the path * of * Γ-. This is not the optimal way of proceeding * in order to reduce the variance in QMC simulations; for that, * use generatePath(double[] uniform01) instead. * */ public double[] generatePath() { double[] pathUP = gpos.generatePath(); double[] pathDOWN = gneg.generatePath(); for (int i=0; igeneratePath(), but here the uniform * random numbers used for the simulation must be provided to the method. This * allows to properly use the uniform random variates in QMC simulations. * This method divides the table of uniform random * numbers uniform01 in two smaller tables, the first one containing * the odd indices of uniform01 are used to generate the path of * Γ+ * and the even indices are used to generate the path of * Γ-. * This way of proceeding further reduces the * variance for QMC simulations. * */ public double[] generatePath (double[] uniform01) { int dd = uniform01.length; int d = dd / 2; if (dd % 2 != 0) { throw new IllegalArgumentException ( "The Array uniform01 must have a even length"); } double[] QMCpointsUP = new double[d]; double[] QMCpointsDW = new double[d]; for(int i = 0; i < d; i++){ QMCpointsUP[i] = uniform01[2*i]; // keeps the odd numbers for the gamma process QMCpointsDW[i] = uniform01[2*i + 1]; // and the even for the BM process } gpos.resetStartProcess(); gneg.resetStartProcess(); double[] pathUP = gpos.generatePath(QMCpointsUP); double[] pathDOWN = gneg.generatePath(QMCpointsDW); for (int i=0; iVarianceGammaProcessDiff * as usual, but also applies the resetStartProcess method to the two * {@link GammaProcess} objects used to generate this process. * */ public void resetStartProcess() { observationIndex = 0; observationCounter = 0; gpos.resetStartProcess(); gneg.resetStartProcess(); } /** * Returns a reference to the {@link GammaProcess} object gpos * used to generate the * Γ+ component of the process. * */ public GammaProcess getGpos() { return gpos; } /** * Returns a reference to the {@link GammaProcess} object gneg * used to generate the * Γ- component of the process. * */ public GammaProcess getGneg() { return gneg; } protected void init() { // super.init() is not called because the init() in VarianceGammaProcess // is very different. mup = 0.5 * (Math.sqrt (theta*theta + 2*sigma*sigma/nu) + theta); mun = 0.5 * (Math.sqrt (theta*theta + 2*sigma*sigma/nu) - theta); nup = mup * mup * nu; nun = mun * mun * nu; if (observationTimesSet) { path[0] = x0; gpos.setParams(t[0], mup, nup); gneg.setParams(t[0], mun, nun); } } /** * Sets the observation times on the VarianceGammaProcesDiff * as usual, but also sets the observation times of the underlying * {@link GammaProcess}'es. * */ public void setObservationTimes (double t[], int d) { gpos.setObservationTimes(t, d); gneg.setObservationTimes(t, d); super.setObservationTimes(t, d); // the initial value is set to t[0] in the init, which is called in // super.setObservationTimes(t, d). } /** * Returns the RandomStream of the * Γ+ process. * */ public RandomStream getStream() { return gpos.getStream (); } /** * Sets the {@link umontreal.iro.lecuyer.rng.RandomStream RandomStream} * of the two {@link GammaProcess}'es to stream. * */ public void setStream (RandomStream stream) { gpos.setStream(stream); gneg.setStream(stream); } }

Ads help maintain this website.