/* *
 * 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 * obtained as a subordinate of the Brownian motion process * B(t;θ, σ) * using the operational time * G(t;1, ν) (see): *

*

*
* X(t;θ, σ, ν) : = B(G(t;1, ν), θ, σ). *

* See also for applications to modelling * asset returns and option pricing. * *

* The process is sampled as follows: when generatePath() is called, the method * generatePath() of the inner {@link GammaProcess} is called; * its path is then used to set the observation times of the * {@link BrownianMotion}. Finally, the method generatePath() of * the {@link BrownianMotion} is called. * Warning: If one wants to reduced the variance as much as possible * in a QMC simulation, this way of proceeding is not optimal. Use * the method generatePath(uniform01) instead. * *

* If one calls the nextObservation method, the operational * time is generated first, followed by the corresponding * brownian motion increment, which is then returned. * *

* Note that if one wishes to use bridge sampling with the * nextObservation method, both the gamma process G * and the Brownian motion process B should use bridge sampling so that * their observations are synchronized. * */ public class VarianceGammaProcess extends StochasticProcess { protected GammaProcess randomTime; // For the transformed time method protected BrownianMotion BM; protected double theta, sigma, nu; public VarianceGammaProcess() {} /** * Constructs a new VarianceGammaProcess with parameters * * θ = theta, * σ = sigma, * ν = nu * and initial value * S(t0) = s0. * stream is used to generate both the {@link BrownianMotion} B and the * {@link GammaProcess} G in. * */ public VarianceGammaProcess (double s0, double theta, double sigma, double nu, RandomStream stream) { this (s0, new BrownianMotion (s0, theta, sigma, stream), new GammaProcess (0.0, 1.0, nu, stream)); } /** * Constructs a new VarianceGammaProcess. * The parameters θ and σ are set to the parameters μ and * σ, respectively, of the {@link BrownianMotion} BM and * the parameter ν is set to the parameter ν of the {@link GammaProcess} * Gamma. The parameters μ and x0 of the {@link GammaProcess} are * overwritten to equal 1 and 0 respectively. * The initial value of the process is * S(t0) = $ \tt s0$. * */ public VarianceGammaProcess (double s0, BrownianMotion BM, GammaProcess Gamma) { this.BM = BM; Gamma.setParams(0.0, 1.0, Gamma.getNu()); // forces the average of the GammaProcess randomTime = Gamma; // to be 1.0 and the initial value to be 0.0 setParams (s0, BM.getMu(), BM.getSigma(), Gamma.getNu()); } /** * Generates the observation for the next time. * It also works with bridge sampling; however both * {@link BrownianMotionBridge} and {@link GammaProcessBridge} * must be used in the constructor in that case. Furthermore, for bridge * sampling, the order of the observations is that of the bridge, * not sequential order. * */ public double nextObservation() { // We first generate w, then verify what its new counter value is // This is necessary to be general enough to handle bridge sampling double nextBM = BM.nextObservation (randomTime.nextObservation ()); observationIndex = BM.getCurrentObservationIndex(); path[observationIndex] = nextBM; observationCounter++; return nextBM; } /** * Generates and returns the path. To do so, it * first generates the complete path of the inner {@link GammaProcess} * and sets the observation times of the inner {@link BrownianMotion} * to this path. This method is not optimal to reduce the variance in * QMC simulations; use generatePath(double[] uniform01) for that. * */ public double[] generatePath() { BM.setObservationTimes(randomTime.generatePath(), d); path = BM.generatePath(); observationIndex = d; observationCounter = d; return path; } /** * Similar to the usual generatePath(), 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 which are used to generate the path of the inner * {@link GammaProcess}, and the even indices (in the second table) are used to * generate the path of the inner {@link BrownianMotion}. This way of proceeding * reduces the variance as much as possible 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[] QMCpointsGP = new double[d]; double[] QMCpointsBM = new double[d]; for(int i = 0; i < d; i++){ QMCpointsGP[i] = uniform01[2 * i]; // the odd numbers for the gamma process QMCpointsBM[i] = uniform01[2 * i + 1]; // and the even for the BM process } BM.setObservationTimes(randomTime.generatePath(QMCpointsGP), d); path = BM.generatePath(QMCpointsBM); observationIndex = d; observationCounter = d; return path; } /** * Resets the observation index and counter to 0 and * applies the resetStartProcess method to the * {@link BrownianMotion} and the {@link GammaProcess} objects * used to generate this process. * */ public void resetStartProcess() { observationIndex = 0; observationCounter = 0; BM.resetStartProcess(); randomTime.resetStartProcess(); } /** * Sets the parameters * * S(t0) = s0, θ = theta, σ = sigma * and ν = nu of the process. * Warning: This method will recompute some quantities stored internally, * which may be slow if called repeatedly. * */ public void setParams (double s0, double theta, double sigma, double nu) { this.x0 = s0; this.theta = theta; this.sigma = sigma; this.nu = nu; if (observationTimesSet) init(); // Otherwise no need to. } /** * Returns the value of the parameter θ. * */ public double getTheta() { return theta; } /** * Returns the value of the parameter σ. * */ public double getSigma() { return sigma; } /** * Returns the value of the parameter ν. * */ public double getNu() { return nu; } protected void init() { super.init(); if(observationTimesSet){ randomTime.setObservationTimes(t, d); randomTime.x0 = t[0]; } } /** * Sets the observation times on the VarianceGammaProcess as * usual, but also sets the observation times of the underlying * {@link GammaProcess}. It furthermore sets the starting value * of the {@link GammaProcess} to t[0]. * */ public void setObservationTimes (double t[], int d) { super.setObservationTimes(t, d); //sets the observation times of the GammaProcess by } //calling init() /** * Resets the {@link umontreal.iro.lecuyer.rng.RandomStream RandomStream}'s. * Warning: this method sets both the * {@link umontreal.iro.lecuyer.rng.RandomStream RandomStream} of the * {@link BrownianMotion} and of the {@link GammaProcess} to * the same {@link umontreal.iro.lecuyer.rng.RandomStream RandomStream}. * */ public void setStream (RandomStream stream) { BM.setStream (stream); } /** * Returns the random stream of the {@link BrownianMotion} process, which should * be the same as for the {@link GammaProcess}. * */ public RandomStream getStream() { return BM.getStream(); } /** * Returns a reference to the inner {@link BrownianMotion}. * */ public BrownianMotion getBrownianMotion() { return BM; } /** * Returns a reference to the inner {@link GammaProcess}. * */ public GammaProcess getGammaProcess() { return randomTime; } }

Ads help maintain this website.