LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
infer_lqn_ekf.h File Reference

Extended Kalman Filter for LQN parameter identification. More...

#include <cmath>
#include <cstddef>
#include <functional>
#include <vector>
#include "line/api/infer/infer_lqn_jacobian.h"
#include "line/num/number.h"
#include "line/util/error.h"
#include "line/util/lu.h"
#include "line/util/matrix.h"
Include dependency graph for infer_lqn_ekf.h:

Go to the source code of this file.

Classes

struct  line::infer::EkfOptions< T >
 MATLAB's OPTIONS struct, with the same defaults infer_lqn_optget supplies. More...
struct  line::infer::EkfResult< T >
 MATLAB's [ahat, info] return list. More...

Namespaces

namespace  line
namespace  line::infer

Functions

template<class T>
EkfResult< T > line::infer::infer_lqn_ekf (const std::function< std::vector< T >(const std::vector< T > &)> &hfun, const std::vector< T > &a0, const Matrix< T > &P0, const Matrix< T > &Z, const Matrix< T > &Q, const Matrix< T > &R, const EkfOptions< T > &opts=EkfOptions< T >())
 Extended Kalman Filter for LQN parameter identification.

Detailed Description

Extended Kalman Filter for LQN parameter identification.

Templated port of matlab/src/api/infer/infer_lqn_ekf.m. The JAR carries the same recursion inside jline/api/infer/InferLqn.java.

Tracks a hidden parameter vector across a measurement sequence, following Zheng, Yang, Woodside, Litoiu, Iszlai, "Tracking Time-Varying Parameters in Software Systems with Extended Kalman Filters", CASCON 2005, equations 1-9. The parameter follows a zero-mean random walk a_k = a_{k-1} + w and the measurement is z_k = h(a_k) + v, with h the nonlinear performance model. Per step:

a_pred = a, P_pred = P + Q (prediction, eq 5) H, zpred = jacobian of h at a_pred (eq 4) e = z_k - zpred (innovation) S = H P_pred H' + R, K = P_pred H' S^-1 (gain, eq 6) a = a_pred + K e, P = (I - K H) P_pred (update, eq 7)

h enters as a std::function, exactly as in infer_lqn_jacobian, so the model layer that evaluates an LQN stays outside this header: any caller that can produce z = h(a) can run the filter. That is the whole reason the MATLAB splits infer_lqn into infer_lqn_ekf plus a model-evaluating closure.

MATLAB forms the gain as (Ppred*H')/S, a right division, i.e. it SOLVES K S = Ppred H' rather than inverting S. The port does the same, row by row through one LU factorization of S', which matters: S is the innovation covariance and is ill-conditioned exactly when a parameter is unobservable, which is the regime the filter is used in. The covariance is symmetrized after the update, as in MATLAB, because (I - K H) P_pred is symmetric only up to roundoff and an asymmetric P feeds back into every later gain.

MATLAB's OPTIONS struct is read through infer_lqn_optget, a field-present-and-non-empty default helper. That helper has no counterpart here and needs none: EkfOptions below carries the same five defaults as member initializers, which is what a struct with defaulted fields IS in C++. The one option not carried is 'verbose', a console trace: the port writes nothing to any stream (an API-layer invariant), and the caller has the same information in the returned per-step innovations.

ARITHMETIC: the recursion itself is rational, but Er and Ea are root mean squares, so the routine is gated on transcendental arithmetic and registered for Double and Real only. That gate is not merely about the two summary numbers: the filter is a fixed number of steps of a linear-algebraic recursion, so in exact arithmetic the numerators of P would grow without bound while the estimate it produces stays an approximation of a nonlinear problem, and the finite differences inside H carry a truncation error that exact arithmetic cannot remove.

Definition in file infer_lqn_ekf.h.