All Downloads are FREE. Search and download functionalities are using the official Maven repository.

umontreal.iro.lecuyer.stochprocess.StochasticProcess Maven / Gradle / Ivy

Go to download

SSJ is a Java library for stochastic simulation, developed under the direction of Pierre L'Ecuyer, in the Département d'Informatique et de Recherche Opérationnelle (DIRO), at the Université de Montréal. It provides facilities for generating uniform and nonuniform random variates, computing different measures related to probability distributions, performing goodness-of-fit tests, applying quasi-Monte Carlo methods, collecting (elementary) statistics, and programming discrete-event simulations with both events and processes.

The newest version!


/*
 * Class:        StochasticProcess
 * Description:  Base class for all stochastic processes
 * Environment:  Java
 * Software:     SSJ 
 * Copyright (C) 2001  Pierre L'Ecuyer and Université de Montréal
 * Organization: DIRO, Université de Montréal
 * @author       
 * @since

 * SSJ is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License (GPL) as published by the
 * Free Software Foundation, either version 3 of the License, or
 * any later version.

 * SSJ is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * A copy of the GNU General Public License is available at
   GPL licence site.
 */

package umontreal.iro.lecuyer.stochprocess;
import umontreal.iro.lecuyer.rng.RandomStream;



/**
 * Abstract base class for a stochastic process 
 * {X(t) : t >= 0}
 * sampled (or observed) at a finite number of time points,
 * 
 * 0 = t0 < t1 <  ...  < td.
 * The observation times are usually all specified before generating a sample path.
 * This can be done via setObservationTimes.
 * The method generatePath generates 
 * X(t1),..., X(td) and memorizes
 * them in a vector, which can be recovered by getPath.
 * 
 * 

* Alternatively, for some types of processes, the observations X(tj) can be * generated sequentially, one at a time, by invoking resetStartProcess * first, and then nextObservation repeatedly. * For some types of processes, the observation times can be specified one by one * as well, when generating the path. This may be convenient or even necessary * if the observation times are random, for example. * *

* WARNING: After having called the constructor for one of the subclass, * one must always set the observation times of the process, * by calling method setObservationTimes for example or otherwise. * */ public abstract class StochasticProcess { // Used in some subclasses to make sure the 'setObservationTimes' // method has already been invoked before calling 'init' protected boolean observationTimesSet = false; protected double x0 = 0.0; // Default Initial Value of the process protected int d = -1; // Num. of observation times protected int observationIndex = 0; // Index of last generated obs time protected int observationCounter = 0; // Counts how many observations have // been generated so far. Useful when they are not generated in // chronological order. protected double[] t; // Observation times protected double[] path; // Observations of the process //protected RandomStream stream; // Random stream used to generate the process protected int[] observationIndexFromCounter; // Links counter# to index# /** * Sets the observation times of the process to a copy of T, * with t0 = T[0] and td = T[d]. * The size of T must be d + 1. * */ public void setObservationTimes (double[] T, int d) { if (d <= 0) throw new IllegalArgumentException ( "Number of observation times d <= 0"); this.d = d; observationTimesSet = true; // Copy of the observation times this.t = new double[d+1]; System.arraycopy (T, 0, this.t, 0, d+1); // Test chronological order for (int i = 0; i < d; i++) { if (T[i+1] < T[i]) throw new IllegalArgumentException ( "Observation times T[] are not time-ordered"); } // Construction of 'path' object // We do not do it in 'init()' because we don't have to change the // path object if the user only calls 'setParams' path = new double[d+1]; /* Process specific initialization; usually precomputes quantities that depend on the observation times. */ init(); } /** * Sets equidistant observation times at * tj = , for * j = 0,..., d, and delta = δ. * */ public void setObservationTimes (double delta, int d) { t = new double[d+1]; for (int i=0; i<=d; i++) t[i] = i*delta; setObservationTimes (t, d); } /** * Returns a reference to the array that contains the observation times * * (t0,..., td). * Warning: This method should only be used to read the observation times. * Changing the values in the array directly may have unexpected consequences. * The method setObservationTimes should be used to modify the observation times. * */ public double[] getObservationTimes() { return t; } /** * Returns the number of observation times excluding the time t0. * */ public int getNbObservationTimes() { return d; } /** * Generates, returns, and saves the sample path * * {X(t0), X(t1),…, X(td)}. It can then be accessed via * getPath, getSubpath, or getObservation. * The generation method depends on the process type. * */ public abstract double[] generatePath(); /** * Same as generatePath(), but first resets the stream to stream. * */ public double[] generatePath (RandomStream stream) { setStream (stream); return generatePath(); } /** * Returns a reference to the last generated sample path * * {X(t0),..., X(td)}. * Warning: The returned array and its size should not be modified, * because this is the one that memorizes the observations (not a copy of it). * To obtain a copy, use getSubpath instead. * */ public double[] getPath() { return path; } /** * Returns in subpath the values of the process at a subset of the observation times, * specified as the times tj whose indices j are in the array pathIndices. * The size of pathIndices should be at least as much as that of subpath. * */ public void getSubpath (double[] subpath, int[] pathIndices) { for (int j=0; jX(tj) from the current sample path. * Warning: If the observation X(tj) for the current path has not yet been * generated, then the value returned is unpredictable. * */ public double getObservation (int j) { return path[j]; } /** * Resets the observation counter to its initial value j = 0, so * that the current observation X(tj) becomes X(t0). This method should * be invoked before generating observations sequentially one by one * via {@link #nextObservation nextObservation}, for a new sample path. * */ public void resetStartProcess() { observationIndex = 0; observationCounter = 0; } /** * Returns true if j < d, where j is the number of observations of the current * sample path generated since the last call to {@link #resetStartProcess resetStartProcess}. * Otherwise returns false. * */ public boolean hasNextObservation() { if (observationCounter < d) return true; else return false; } /** * Generates and returns the next observation X(tj) of the stochastic process. * The processes are usually sampled sequentially, i.e. * if the last observation generated was for time tj-1, the next observation * returned will be for time tj. * In some cases, subclasses extending this abstract class * may use non-sequential sampling algorithms (such as bridge sampling). * The order of generation of the tj's is then specified by the subclass. * All the processes generated using principal components analysis (PCA) do not have * this method. * */ public double nextObservation() { throw new UnsupportedOperationException("Method not defined in this class"); } /** * Returns the value of the index j corresponding to * the time tj of the last generated observation. * */ public int getCurrentObservationIndex() { return observationIndex; } /** * Returns the value of the last generated observation X(tj). * */ public double getCurrentObservation() { return path[observationIndex]; } /** * Returns the initial value X(t0) for this process. * */ public double getX0() { return x0; } /** * Sets the initial value X(t0) for this process to s0, * and reinitializes. * */ public void setX0 (double s0) { x0 = s0; init(); } /** * Resets the random stream of the underlying generator to stream. * */ public abstract void setStream (RandomStream stream); /** * Returns the random stream of the underlying generator. * */ public abstract RandomStream getStream(); /* ** Called by 'setObservationTimes' to initialize arrays and precompute constants to speed up execution. See overriding method 'init' in subclasses for details ***/ protected void init() { if (observationTimesSet) // If observation times are not defined, do nothing. path[0] = x0; // We do this here because the s0 parameter may have changed through // a call to the 'setParams' method. } /** * Returns a reference to an array that maps an integer k * to ik, the index of the observation * S(tik) corresponding * to the k-th observation to be generated for a sample path of this process. * If this process is sampled sequentially, then this map is trivial * (i.e. ik = k). But it can be useful in a more general setting where * the process is not sampled sequentially * (for example, by a Brownian or gamma bridge) and one wants to know which * observations of the current sample path were previously generated * or will be generated next. * */ public int[] getArrayMappingCounterToIndex() { return observationIndexFromCounter; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy