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
19 import org.hipparchus.util.FastMath;
20
21 /** This class is a Gauss-Markov order 1 autoregressive process generator for scalars.
22 * @since 3.1
23 */
24
25 public class GaussMarkovGenerator {
26
27 /** Correlation time. */
28 private final double tau;
29
30 /** Standard deviation of the stationary process. */
31 private final double stationarySigma;
32
33 /** Underlying generator. */
34 private final RandomGenerator generator;
35
36 /** Last generated value. */
37 private double last;
38
39 /** Create a new generator.
40 * @param tau correlation time
41 * @param stationarySigma standard deviation of the stationary process
42 * @param generator underlying random generator to use
43 */
44 public GaussMarkovGenerator(final double tau, final double stationarySigma,
45 final RandomGenerator generator) {
46 this.tau = tau;
47 this.stationarySigma = stationarySigma;
48 this.generator = generator;
49 this.last = Double.NaN;
50 }
51
52 /** Get the correlation time.
53 * @return correlation time
54 */
55 public double getTau() {
56 return tau;
57 }
58
59 /** Get the standard deviation of the stationary process.
60 * @return standard deviation of the stationary process
61 */
62 public double getStationarySigma() {
63 return stationarySigma;
64 }
65
66 /** Generate next step in the autoregressive process.
67 * @param deltaT time step since previous estimate (unused at first call)
68 * @return a random scalar obeying autoregressive model
69 */
70 public double next(final double deltaT) {
71
72 if (Double.isNaN(last)) {
73 // first generation: use the stationary process
74 last = stationarySigma * generator.nextGaussian();
75 } else {
76 // regular generation: use the autoregressive process
77 final double phi = FastMath.exp(-deltaT / tau);
78 final double sigmaE = FastMath.sqrt(1 - phi * phi) * stationarySigma;
79 last = phi * last + sigmaE * generator.nextGaussian();
80 }
81
82 return last;
83
84 }
85
86 }