GaussMarkovGenerator.java
/*
* Licensed to the Hipparchus project under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The Hipparchus project licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.hipparchus.random;
import org.hipparchus.util.FastMath;
/** This class is a Gauss-Markov order 1 autoregressive process generator for scalars.
* @since 3.1
*/
public class GaussMarkovGenerator {
/** Correlation time. */
private final double tau;
/** Standard deviation of the stationary process. */
private final double stationarySigma;
/** Underlying generator. */
private final RandomGenerator generator;
/** Last generated value. */
private double last;
/** Create a new generator.
* @param tau correlation time
* @param stationarySigma standard deviation of the stationary process
* @param generator underlying random generator to use
*/
public GaussMarkovGenerator(final double tau, final double stationarySigma,
final RandomGenerator generator) {
this.tau = tau;
this.stationarySigma = stationarySigma;
this.generator = generator;
this.last = Double.NaN;
}
/** Get the correlation time.
* @return correlation time
*/
public double getTau() {
return tau;
}
/** Get the standard deviation of the stationary process.
* @return standard deviation of the stationary process
*/
public double getStationarySigma() {
return stationarySigma;
}
/** Generate next step in the autoregressive process.
* @param deltaT time step since previous estimate (unused at first call)
* @return a random scalar obeying autoregressive model
*/
public double next(final double deltaT) {
if (Double.isNaN(last)) {
// first generation: use the stationary process
last = stationarySigma * generator.nextGaussian();
} else {
// regular generation: use the autoregressive process
final double phi = FastMath.exp(-deltaT / tau);
final double sigmaE = FastMath.sqrt(1 - phi * phi) * stationarySigma;
last = phi * last + sigmaE * generator.nextGaussian();
}
return last;
}
}