/* *
 * 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.*; /** * Same as BrownianMotionPCA, but uses a trick to * speed up the calculation when the time steps * are equidistant. * */ public class BrownianMotionPCAEqualSteps extends BrownianMotion { double dt; protected double[][] A; // sigmaCov = AA' (PCA decomposition). protected double[] z; // vector of standard normals. protected boolean isDecompPCA; protected double[] sortedEigenvalues; /** * Constructs a new BrownianMotionPCAEqualSteps. * */ public BrownianMotionPCAEqualSteps (double x0, double mu, double sigma, RandomStream stream) { super (x0, mu, sigma, stream); isDecompPCA = false; } /** * Constructs a new BrownianMotionPCAEqualSteps. * */ public BrownianMotionPCAEqualSteps (double x0, double mu, double sigma, NormalGen gen) { super (x0, mu, sigma, gen); isDecompPCA = false; } public double nextObservation() { throw new UnsupportedOperationException ("nextObservation() not defined for PCA."); } public double[] generatePath() { if(!isDecompPCA) {init();} // if the decomposition is not done, do it... for (int j = 0; j < d; j++) z[j] = gen.nextDouble (); for (int j = 0; j < d; j++) { double sum = 0.0; for (int k = 0; k < d; k++) sum += A[j][k] * z[k]; path[j+1] = x0 + mu * t[j+1] + sum; } observationIndex = d; observationCounter = d; return path; } public double[] generatePath(double[] QMCpointsBM) { if(!isDecompPCA) {init();} // if the decomposition is not done, do it... for (int j = 0; j < d; j++) z[j] = NormalDist.inverseF01(QMCpointsBM[j]); for (int j = 0; j < d; j++) { double sum = 0.0; for (int k = 0; k < d; k++) sum += A[j][k] * z[k]; path[j+1] = x0 + mu * t[j+1] + sum; } observationIndex = d; observationCounter = d; return path; } public void setObservationTimes(double[] t, int d){ super.setObservationTimes(t,d); this.dt = t[1] - t[0]; for(int i = 1; i < d; i++) if( Math.abs((t[i+1] - t[i])/dt - 1.0) > 1e-7 ) throw new IllegalArgumentException("Not equidistant times"); } public void setObservationTimes(double dt, int d){ this.dt = dt; super.setObservationTimes(dt,d); } protected void init() { super.init(); if(observationTimesSet){ final double twoOverSqrt2dP1 = 2.0/Math.sqrt(2.0*d+1.0); final double piOver2dP1 = Math.PI/(2.0*d+1.0); z = new double[d]; // A contains the eigenvectors (as columns), times sqrt(eigenvalues). A = new double[d][d]; sortedEigenvalues = new double[d]; for(int ic = 1; ic <= d; ic++){ final double tempSin = Math.sin( (2*ic-1)*piOver2dP1/2.0 ); sortedEigenvalues[ic-1] = dt/4.0/tempSin/tempSin * sigma*sigma; for(int ir = 1; ir <= d; ir++){ A[ir-1][ic-1] = twoOverSqrt2dP1 * Math.sin( (2*ic-1)*piOver2dP1*ir ); A[ir-1][ic-1] *= Math.sqrt( sortedEigenvalues[ic-1] ); } } double[][] AA = new double[d][d]; for(int ic = 0; ic < d; ic++){ for(int ir = 0; ir < d; ir++){ double sum = 0.0; for(int k = 0; k < d; k++) sum += A[ir][k]*A[ic][k]; AA[ir][ic] = sum; } } isDecompPCA = true; } } public double[] getSortedEigenvalues(){ return sortedEigenvalues; } }

Ads help maintain this website.