/* @file KalmanFilterSpec.hpp */ #pragma once #include "filter/KalmanFilterStep.hpp" namespace xo { namespace kalman { /* full specification for a kalman filter. * * For a textbook linear filter, expect a KalmanFilterStep * instance to be independent of KalmanFilterState/KalmanFilterInput. * * Relaxing this requirement for two reasons: * 1. (proper) want to allow filter with variable timing between observations, * expecially if observations are event-driven. * In that case it's likely that state transition matrices are a function * of elapsed time between observations. Providing filter state sk * allows MkStepFn to use sk.tm() * 2. (sketchy) when observations represent market data, * desirable to treat an observation as giving one-sided information * about true value. For example treat a bid price as evidence * true value is higher than that bid, but don't want to constrain * "how much higher". Certainly no reason to think that * bid price is normally distributed around fair value. * Allow for hack in which we * and modulate error distribution "as if it were normal" to assess * a non-gaussian error distribution */ class KalmanFilterSpec { public: /* typical implementation will look something like: * mk_step(KalmanFilterState const & sk, * KalmanFilterInputPtr const & zkp1) * { * KalmanFilterTransition model = ...; * KalmanFilterObservable obs = ...; * * return KalmanFilterStep(sk, model, obs, zkp1); * } */ using MkStepFn = std::function const & sk, KalmanFilterInputPtr const & zkp1)>; public: explicit KalmanFilterSpec(ref::rp s0, MkStepFn mkstepfn) : start_ext_{std::move(s0)}, mk_step_fn_{std::move(mkstepfn)} {} ref::rp const & start_ext() const { return start_ext_; } /* get step parameters (i.e. matrices F, Q, H, R) * for step t(k) -> t(k+1). * * We supply t(k) state s and t(k+1) observation z(k+1): * - to allow time stepping to be observation-driven * - to allow for selective outlier removal */ KalmanFilterStep make_step(ref::rp const & sk, ref::rp const & zkp1) { return this->mk_step_fn_(sk, zkp1); } /*make_step*/ void display(std::ostream & os) const; std::string display_string() const; private: /* starting state */ ref::rp start_ext_; /* creates kalman filter step object on demand; * step object specifies inputs to 1 step in discrete * linear kalman filter */ MkStepFn mk_step_fn_; }; /*KalmanFilterSpec*/ inline std::ostream & operator<<(std::ostream & os, KalmanFilterSpec const & x) { x.display(os); return os; } /*operator<<*/ } /*namespace kalman*/ } /*namespace xo*/ /* end KalmanFilterSpec.hpp */