Package umontreal.iro.lecuyer.rng

Source Code of umontreal.iro.lecuyer.rng.RandomStreamWithCache


/*
* Class:        RandomStreamWithCache
* Description:  random stream whose uniforms are cached for more efficiency
* 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
   <a href="http://www.gnu.org/licenses">GPL licence site</a>.
*/

package umontreal.iro.lecuyer.rng;

import cern.colt.list.DoubleArrayList;


/**
* This class represents a random stream whose uniforms
* are cached for more efficiency when using
* common random numbers.  An object
* from this class is constructed with a reference to a
* {@link RandomStream} instance used to
* get the random numbers.  These numbers
* are stored in an internal array to be retrieved later.
* The dimension of the array increases as the values
* are generated.
* If the {@link #nextDouble(()) nextDouble} method is called after
* the object is reset, it gives back the cached
* values instead of computing new ones.
* If the cache is exhausted before the stream is reset,
* new values are computed, and added to the cache.
*
* <P>
* Such caching allows for a better performance with
* common random numbers, when
* generating uniforms is time-consuming.
* It can also help with restoring the simulation to a
* certain state without setting stream-specific
* seeds.
* However, using such caching may lead to memory problems if
* a large quantity of random numbers are needed.
*
*/
public class RandomStreamWithCache implements RandomStream {
   private RandomStream stream;
   private DoubleArrayList values;
   private int index = 0;
   private boolean caching = true;



   /**
    * Constructs a new cached random stream with
    *  internal stream <TT>stream</TT>.
    *
    * @param stream the random stream whose uniforms are cached.
    *
    *    @exception NullPointerException if <TT>stream</TT> is <TT>null</TT>.
    *
    *
    */
   public RandomStreamWithCache (RandomStream stream) {
      if (stream == null)
         throw new NullPointerException
            ("The given random stream cannot be null");
      this.stream = stream;
      values = new DoubleArrayList();
   }


   /**
    * Constructs a new cached random stream
    *  with internal stream <TT>stream</TT>.
    *  The <TT>initialCapacity</TT>
    *  parameter is used to set the initial capacity of the internal array
    *  which can grow as needed; it does not
    *  limit the total size of the cache.
    *
    * @param stream the random stream whose values are cached.
    *
    *    @param initialCapacity the initial capacity of the cache.
    *
    *    @exception NullPointerException if <TT>stream</TT> is <TT>null</TT>.
    *
    */
   public RandomStreamWithCache (RandomStream stream, int initialCapacity) {
      if (stream == null)
         throw new NullPointerException
            ("The given random stream cannot be null");
      this.stream = stream;
      values = new DoubleArrayList (initialCapacity);
   }


   /**
    * Determines if the random stream is caching values,
    *  default being <TT>true</TT>.
    *  When caching is turned OFF, the {@link #nextDouble(()) nextDouble}
    *  method simply calls the corresponding method on the internal
    *  random stream, without storing the generated uniforms.
    *
    * @return the caching indicator.
    *
    */
   public boolean isCaching() {
      return caching;
   }


   /**
    * Sets the caching indicator to <TT>caching</TT>.
    *  If caching is turned OFF, this method calls {@link #clearCache(()) clearCache}
    *  to clear the cached values.
    *
    * @param caching the new value of the caching indicator.
    *
    *
    */
   public void setCaching (boolean caching) {
      if (this.caching && !caching)
         clearCache();
      this.caching = caching;
   }


   /**
    * Returns a reference to the random stream
    *  whose values are cached.
    *
    * @return a reference to the random stream whose values are cached.
    *
    */
   public RandomStream getCachedStream() {
      return stream;
   }


   /**
    * Sets the random stream whose values are cached to
    *  <TT>stream</TT>.  If the stream is changed, the {@link #clearCache(()) clearCache}
    *  method is called to clear the cache.
    *
    * @param stream the new random stream whose values will be cached.
    *
    *    @exception NullPointerException if <TT>stream</TT> is <TT>null</TT>.
    *
    *
    */
   public void setCachedStream (RandomStream stream) {
      if (stream == null)
         throw new NullPointerException
            ("The given random stream cannot be null");
      if (stream == this.stream)
         return;
      this.stream = stream;
      clearCache();
   }


   /**
    * Clears the cached values for this random stream.
    *  Any subsequent call will then obtain new values
    *  from the internal stream.
    *
    */
   public void clearCache() {
      //values.clear();
      // Keep the array previously returned by getCachedValues
      // intact to allow caching values for several
      // replications.
      values = new DoubleArrayList();
      index = 0;
   }


   /**
    * Resets this random stream to recover values from the cache.
    *  Subsequent calls
    *  to {@link #nextDouble(()) nextDouble} will return the cached uniforms
    *  until all the values are returned.  When the array
    *  of cached values is exhausted, the internal random stream
    *  is used to generate new values which are added
    *  to the internal array as well.
    *  This method is equivalent to calling {@link #setCacheIndex((int)) setCacheIndex}.
    *
    */
   public void initCache() {
      index = 0;
   }


   /**
    * Returns the total number of values cached by this random stream.
    *
    * @return the total number of cached values.
    *
    */
   public int getNumCachedValues() {
      return values.size();
   }


   /**
    * Return the index of the next cached value that will be
    *  returned by the stream.
    *  If the cache is exhausted, the
    *  returned value corresponds to the value returned by
    *  {@link #getNumCachedValues(()) getNumCachedValues}, and a subsequent call to
    *  {@link #nextDouble(()) nextDouble} will generate a new variate rather than
    *  reading a previous one from the cache.
    *  If caching is disabled, this always returns 0.
    *
    * @return the index of the next cached value.
    *
    */
   public int getCacheIndex() {
      return index;
   }


   /**
    * Sets the index, in the cache, of the next value returned
    *  by {@link #nextDouble(()) nextDouble}.
    *  If <TT>newIndex</TT> is 0, this is equivalent to
    *  calling {@link #initCache(()) initCache}.
    *  If <TT>newIndex</TT> is {@link #getNumCachedValues(()) getNumCachedValues},
    *  subsequent calls to {@link #nextDouble(()) nextDouble} will add
    *  new values to the cache.
    *
    * @param newIndex the new index.
    *
    *    @exception IllegalArgumentException if <TT>newIndex</TT>
    *  is negative or greater than or equal to the cache size.
    *
    *
    */
   public void setCacheIndex (int newIndex) {
      if (newIndex < 0 || newIndex > values.size())
         throw new IllegalArgumentException
         ("newIndex must not be negative or greater than the cache size");
      index = newIndex;
   }


   /**
    * Returns an array list containing the values
    *  cached by this random stream.
    *
    * @return the array of cached values.
    *
    */
   public DoubleArrayList getCachedValues() {
      return values;
   }


   /**
    * Sets the array list containing the cached
    *  values to <TT>values</TT>.
    *  This resets the cache index to
    *  the size of the given array.
    *
    * @param values the array list of cached values.
    *
    *    @exception NullPointerException if <TT>values</TT> is <TT>null</TT>.
    *
    *
    */
   public void setCachedValues (DoubleArrayList values) {
      if (values == null)
         throw new NullPointerException();
      this.values = values;
      index = values.size();
   }


   public void resetStartStream () {
      stream.resetStartStream();
   }

   public void resetStartSubstream () {
      stream.resetStartSubstream();
   }

   public void resetNextSubstream () {
      stream.resetNextSubstream();
   }

   public double nextDouble () {
      if (!caching)
         return stream.nextDouble();
      else if (index >= values.size()) {
         double v = stream.nextDouble();
         values.add (v);
         ++index;
         return v;
      }
      else
         return values.getQuick (index++);
   }

   public void nextArrayOfDouble (double[] u, int start, int n) {
      if (!caching) {
         stream.nextArrayOfDouble (u, start, n);
         return;
      }
      int remainingValues = values.size() - index;
      if (remainingValues < 0)
         remainingValues = 0;
      int ncpy = Math.min (n, remainingValues);
      if (ncpy > 0) {
         System.arraycopy (values.elements(), index, u, start, ncpy);
         index += ncpy;
      }
      int ngen = n - ncpy;
      if (ngen > 0) {
         stream.nextArrayOfDouble (u, start + ncpy, ngen);
         for (int i = ncpy; i < n; i++) {
            values.add (u[start + i]);
            ++index;
         }
      }
   }

   public int nextInt (int i, int j) {
      return i + (int) (nextDouble () * (j - i + 1));
   }

   public void nextArrayOfInt (int i, int j, int[] u, int start, int n) {
      for (int x = start; x < start + n; x++)
         u[x] = nextInt (i, j);
   }
}
TOP

Related Classes of umontreal.iro.lecuyer.rng.RandomStreamWithCache

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.