FilterEx.Kalman (filter_ex v0.2.4)
Kalman filters in pure Elixir with Nx. Supports adaptive feedback to increase responsiveness to external pertubations in the signal.
Examples
Generate example data which jumps up midway from 20 to 30.
iex> %{random_data: random_data} = FilterExTest.generate_data(3)
...> random_data
[20.237325241821775, 19.917010488673977, 20.11041356431258, 29.95666616025292, 30.099203428410778, 30.079518640113378]
Create a Kalman filter with adaptive gain.
iex> %{random_data: random_data} = FilterExTest.generate_data(3)
...> kalman = FilterEx.Kalman.new(dim_x: 1, dim_z: 1, dim_u: 1)
...> kalman = kalman |> FilterEx.Kalman.set(
...> x: 20.0, # initial state (location and velocity)
...> fF: 1.0, # state transition matrix
...> hH: 1.0, # Measurement function
...> rR: 1.0, # state uncertainty
...> qQ: 1.0/10.0 # process uncertainty
...> )
...> kalman = kalman |> Kalman.to_eps_adaptive(
...> q_scale_factor: 3.1, eps_max: 1.0
...> )
...> {_kalman, %{estimates: estimates}} = kalman |> FilterEx.Kalman.filter(random_data)
...> estimates
[20.124313354492188, 20.044675827026367, 20.06612205505371, 23.02187156677246, 25.700191497802734, 28.752626419067383]
Summary
Functions
Set the estimate for the Kalman filter.
Parameters
dim_x : int
Predict next state (prior) using the Kalman filter state propagation equations.
Add a new measurement (z) to the Kalman filter.
Functions
adaptive_eps(self, z)
adaptive_stddev(self, z)
estimate(self)
estimate!(self, value)
Set the estimate for the Kalman filter.
iex> kalman = FilterEx.Kalman.new(dim_x: 1, dim_z: 1, dim_u: 1)
...> kalman = kalman |> FilterEx.Kalman.estimate!(3.3)
...> kalman |> FilterEx.Kalman.estimate()
Nx.tensor([[3.3]])
filter(self, zz, opts \\ [])
new(opts \\ [])
Parameters
dim_x : int
Number of state variables for the Kalman filter. For example, if
you are tracking the position and velocity of an object in two
dimensions, dim_x would be 4.
This is used to set the default size of P, Q, and u
dim_z : int
Number of of measurement inputs. For example, if the sensor
provides you with position in (x,y), dim_z would be 2.
dim_u : int (optional)
size of the control input, if it is being used.
Default value of 0 indicates it is not used.
predict(self, u \\ nil, bB \\ nil, fF \\ nil, qQ \\ nil)
Predict next state (prior) using the Kalman filter state propagation equations.
Parameters
u : np.array, default 0
Optional control vector.
B : np.array(dim_x, dim_u), or None
Optional control transition matrix; a value of None
will cause the filter to use `self.B`.
F : np.array(dim_x, dim_x), or None
Optional state transition matrix; a value of None
will cause the filter to use `self.F`.
Q : np.array(dim_x, dim_x), scalar, or None
Optional process noise matrix; a value of None will cause the
filter to use `self.Q`.
residual(self)
set(self, values)
to_eps_adaptive(self, opts)
to_stddev_adaptive(self, opts)
update(self, z, rR \\ nil, hH \\ nil)
Add a new measurement (z) to the Kalman filter.
If z is None, nothing is computed. However, x_post and P_post are updated with the prior (x_prior, P_prior), and self.z is set to None.
Parameters
z : (dim_z, 1): array_like
measurement for this update. z can be a scalar if dim_z is 1,
otherwise it must be convertible to a column vector.
If you pass in a value of H, z must be a column vector the
of the correct size.
R : np.array, scalar, or None
Optionally provide R to override the measurement noise for this
one call, otherwise self.R will be used.
H : np.array, or None
Optionally provide H to override the measurement function for this
one call, otherwise self.H will be used.