18 #ifndef KALMAN_FILTER__SRCF_CORE_HPP_
19 #define KALMAN_FILTER__SRCF_CORE_HPP_
37 namespace kalman_filter
46 template<
int32_t NumStates,
int32_t ProcessNoiseDim>
51 using square_mat_t = Eigen::Matrix<float32_t, NumStates, NumStates>;
69 template<
int32_t ColN1,
int32_t ColN2>
71 Eigen::Matrix<float32_t, NumStates, ColN1> & A,
72 Eigen::Matrix<float32_t, NumStates, ColN2> & B,
79 for (
index_t j = col_start; j < col_end; ++j) {
82 if (fabsf(g) <=
FEPS) {
85 }
else if (fabsf(A(row, row)) <=
FEPS) {
87 for (
index_t k = row; k < NumStates; ++k) {
88 const float32_t tau = std::copysign(A(k, row), g);
89 A(k, row) = std::copysign(B(k, j), g);
94 const float32_t ir = 1.0F / std::copysign(sqrtf((
f *
f) + (g * g)),
f);
99 for (
index_t k = row; k < NumStates; ++k) {
100 const float32_t tau = (c * B(k, j)) - (s * A(k, row));
101 A(k, row) = (s * B(k, j)) + (c * A(k, row));
117 template<
int32_t NCols2>
120 Eigen::Matrix<float32_t, NumStates, NCols2> & B,
126 zero_row(A, A, i, i + 1, NumStates);
141 template<
typename Derived>
145 const Eigen::MatrixBase<Derived> & h,
156 throw std::domain_error(
"ScrfCore: measurement noise variance must be positive");
160 for (
index_t idx = NumStates - 1; idx < NumStates && idx >= 0; --idx) {
161 const index_t jdx = NumStates - idx;
162 Eigen::Block<square_mat_t> col = C.block(idx, idx, jdx, 1);
165 (h.block(0, idx, 1, jdx) * col)(0, 0);
169 alpha += (sigma * sigma);
170 m_tau.block(0, 0, jdx, 1) = col;
173 col += zetap * m_k.block(idx, 0, jdx, 1);
178 m_k.block(idx, 0, jdx, 1) += sigma * m_tau.block(0, 0, jdx, 1);
185 throw std::runtime_error(
"ScrfCore: invariant broken, kalman gain must be positive");
189 x += del_alpha * m_k;
192 constexpr
float32_t logf2pi = 1.83787706641F;
195 return -0.5F * (logf2pi + logf(alpha) + (del * del_alpha));
201 static_assert(NumStates > 0U,
"must have positive number of states");
202 static_assert(ProcessNoiseDim > 0U,
"must have positive number of process noise dimensions");
208 #endif // KALMAN_FILTER__SRCF_CORE_HPP_