File: GaussMarkovProcess.hh

package info (click to toggle)
ignition-math 6.7.0%2Bds-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 2,396 kB
  • sloc: cpp: 22,476; python: 2,730; ansic: 1,152; ruby: 844; sh: 168; makefile: 14
file content (153 lines) | stat: -rw-r--r-- 5,646 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*
 * Copyright (C) 2020 Open Source Robotics Foundation
 *
 * Licensed 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
 *
 *     http://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.
 *
*/
#ifndef IGNITION_MATH_GAUSSMARKOVPROCESS_HH_
#define IGNITION_MATH_GAUSSMARKOVPROCESS_HH_

#include <chrono>
#include <memory>
#include <ignition/math/Export.hh>
#include <ignition/math/config.hh>

namespace ignition
{
  namespace math
  {
    // Use a steady clock
    using clock = std::chrono::steady_clock;

    // Inline bracket to help doxygen filtering.
    inline namespace IGNITION_MATH_VERSION_NAMESPACE {
    //
    // Forward declarations.
    class GaussMarkovProcessPrivate;

    /** \class GaussMarkovProcess GaussMarkovProcess.hh\
     * ignition/math/GaussMarkovProcess.hh
     **/
    /// \brief Implementation of a stationary gauss-markov process, also
    /// known as a Ornstein Ulenbeck process.
    ///
    /// See the Update(const clock::duration &) for details on the forumla
    /// used to update the process.
    ///
    /// ## Example usage
    ///
    /// \snippet examples/gauss_markov_process_example.cc complete
    class IGNITION_MATH_VISIBLE GaussMarkovProcess
    {
      // Default constructor. This sets all the parameters to zero.
      public: GaussMarkovProcess();

      /// \brief Create a process with the provided process parameters.
      /// This will also call Set(), and in turn Reset().
      /// \param[in] _start The start value of the process.
      /// \param[in] _theta The theta (\f$\theta\f$) parameter. A value of
      /// zero will be used if this parameter is negative.
      /// \param[in] _mu The mu (\f$\mu\f$) parameter.
      /// \param[in] _sigma The sigma (\f$\sigma\f$) parameter. A value of
      /// zero will be used if this parameter is negative.
      /// \sa Update(const clock::duration &)
      public: GaussMarkovProcess(double _start, double _theta, double _mu,
                  double _sigma);

      /// \brief Destructor.
      public: ~GaussMarkovProcess();

      /// \brief Set the process parameters. This will also call Reset().
      /// \param[in] _start The start value of the process.
      /// \param[in] _theta The theta (\f$\theta\f$) parameter.
      /// \param[in] _mu The mu (\f$\mu\f$) parameter.
      /// \param[in] _sigma The sigma (\f$\sigma\f$) parameter.
      /// \sa Update(const clock::duration &)
      public: void Set(double _start, double _theta, double _mu, double _sigma);

      /// \brief Get the start value.
      /// \return The start value.
      /// \sa Set(double, double, double, double)
      public: double Start() const;

      /// \brief Get the current process value.
      /// \return The value of the process.
      public: double Value() const;

      /// \brief Get the theta (\f$\theta\f$) value.
      /// \return The theta value.
      /// \sa Set(double, double, double, double)
      public: double Theta() const;

      /// \brief Get the mu (\f$\mu\f$) value.
      /// \return The mu value.
      /// \sa Set(double, double, double, double)
      public: double Mu() const;

      /// \brief Get the sigma (\f$\sigma\f$) value.
      /// \return The sigma value.
      /// \sa Set(double, double, double, double)
      public: double Sigma() const;

      /// \brief Reset the process. This will set the current process value
      /// to the start value.
      public: void Reset();

      /// \brief Update the process and get the new value.
      ///
      /// The following equation is computed:
      ///
      /// \f$x_{t+1} += \theta * (\mu - x_t) * dt + \sigma * dW_t\f$
      ///
      /// where
      ///
      ///   * \f$\theta, \mu, \sigma\f$ are parameters specified by the
      ///     user. In order, the parameters are theta, mu, and sigma. Theta
      ///     and sigma must be greater than or equal to zero. You can think
      ///     of mu as representing the mean or equilibrium value, sigma as the
      ///     degree of volatility, and theta as the rate by which changes
      ///     dissipate and revert towards the mean.
      ///   * \f$dt\f$ is the time step in seconds.
      ///   * \f$dW_t\f$ is a random number drawm from a normal distribution
      ///     with mean of zero and variance of 1.
      ///   * \f$x_t\f$ is the current value of the Gauss-Markov process
      ///   * \f$x_{t+1}\f$ is the new value of the Gauss-Markvov process
      ///
      /// See also: https://en.wikipedia.org/wiki/Ornstein%E2%80%93Uhlenbeck_process
      ///
      /// This implementation include a drift parameter, mu. In financial
      /// mathematics, this is known as a Vasicek model.
      ///
      /// \param[in] _dt Length of the timestep after which a new sample
      /// should be taken.
      /// \return The new value of this process.
      public: double Update(const clock::duration &_dt);

      public: double Update(double _dt);

#ifdef _WIN32
// Disable warning C4251 which is triggered by
// std::unique_ptr
#pragma warning(push)
#pragma warning(disable: 4251)
#endif
      /// \brief Private data pointer.
      private: std::unique_ptr<GaussMarkovProcessPrivate> dataPtr;
#ifdef _WIN32
#pragma warning(pop)
#endif
    };
    }
  }
}
#endif