GaussMarkovGenerator.java

  1. /*
  2.  * Licensed to the Hipparchus project under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The Hipparchus project licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      https://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.hipparchus.random;

  18. import org.hipparchus.util.FastMath;

  19. /** This class is a Gauss-Markov order 1 autoregressive process generator for scalars.
  20.  * @since 3.1
  21.  */

  22. public class GaussMarkovGenerator {

  23.     /** Correlation time. */
  24.     private final double tau;

  25.     /** Standard deviation of the stationary process. */
  26.     private final double stationarySigma;

  27.     /** Underlying generator. */
  28.     private final RandomGenerator generator;

  29.     /** Last generated value. */
  30.     private double last;

  31.     /** Create a new generator.
  32.      * @param tau correlation time
  33.      * @param stationarySigma standard deviation of the stationary process
  34.      * @param generator underlying random generator to use
  35.      */
  36.     public GaussMarkovGenerator(final double tau, final double stationarySigma,
  37.                                 final RandomGenerator generator) {
  38.         this.tau             = tau;
  39.         this.stationarySigma = stationarySigma;
  40.         this.generator       = generator;
  41.         this.last            = Double.NaN;
  42.     }

  43.     /** Get the correlation time.
  44.      * @return correlation time
  45.      */
  46.     public double getTau() {
  47.         return tau;
  48.     }

  49.     /** Get the standard deviation of the stationary process.
  50.      * @return standard deviation of the stationary process
  51.      */
  52.     public double getStationarySigma() {
  53.         return stationarySigma;
  54.     }

  55.     /** Generate next step in the autoregressive process.
  56.      * @param deltaT time step since previous estimate (unused at first call)
  57.      * @return a random scalar obeying autoregressive model
  58.      */
  59.     public double next(final double deltaT) {

  60.         if (Double.isNaN(last)) {
  61.             // first generation: use the stationary process
  62.             last = stationarySigma * generator.nextGaussian();
  63.         } else {
  64.             // regular generation: use the autoregressive process
  65.             final double phi    = FastMath.exp(-deltaT / tau);
  66.             final double sigmaE = FastMath.sqrt(1 - phi * phi) * stationarySigma;
  67.             last = phi * last + sigmaE * generator.nextGaussian();
  68.         }

  69.         return last;

  70.     }

  71. }