Skip to content

Commit e7b43fc

Browse files
committed
Switch Kálmán filters to use Joseph form
This commit switches the Kálmán filters to use the Joseph form covariance update which is known to be usable for any gain matrix $K$ even if the gain matrix is distorted by numerical imprecision. Empirically, this seems to resolve quite a few issues with our filtering algorithms.
1 parent d668f0f commit e7b43fc

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed

core/include/traccc/fitting/kalman_filter/gain_matrix_updater.hpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,13 +121,22 @@ struct gain_matrix_updater {
121121
// Calculate the filtered track parameters
122122
const matrix_type<6, 1> filtered_vec =
123123
predicted_vec + K * (meas_local - H * predicted_vec);
124-
const matrix_type<6, 6> filtered_cov = (I66 - K * H) * predicted_cov;
124+
const matrix_type<6, 6> i_minus_kh = I66 - K * H;
125+
const matrix_type<6, 6> filtered_cov =
126+
i_minus_kh * predicted_cov * matrix::transpose(i_minus_kh) +
127+
K * V * matrix::transpose(K);
125128

126129
// Residual between measurement and (projected) filtered vector
127130
const matrix_type<D, 1> residual = meas_local - H * filtered_vec;
128131

129132
// Calculate the chi square
130-
const matrix_type<D, D> R = (I_m - H * K) * V;
133+
const matrix_type<D, D> i_minus_hk = I_m - H * K;
134+
// See
135+
// https://indico.cern.ch/event/1564924/contributions/6629447/attachments/3113201/5519076/asami_250731_acts.pdf
136+
const matrix_type<D, D> R =
137+
i_minus_hk * V * matrix::transpose(i_minus_hk) +
138+
H * i_minus_kh * predicted_cov * matrix::transpose(i_minus_kh) *
139+
matrix::transpose(H);
131140
const matrix_type<1, 1> chi2 =
132141
algebra::matrix::transposed_product<true, false>(
133142
residual, matrix::inverse(R)) *

core/include/traccc/fitting/kalman_filter/two_filters_smoother.hpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,13 +178,22 @@ struct two_filters_smoother {
178178
// Calculate the filtered track parameters
179179
const matrix_type<6, 1> filtered_vec =
180180
predicted_vec + K * (meas_local - H * predicted_vec);
181-
const matrix_type<6, 6> filtered_cov = (I66 - K * H) * predicted_cov;
181+
const matrix_type<6, 6> i_minus_kh = I66 - K * H;
182+
const matrix_type<6, 6> filtered_cov =
183+
i_minus_kh * predicted_cov * matrix::transpose(i_minus_kh) +
184+
K * V * matrix::transpose(K);
182185

183186
// Residual between measurement and (projected) filtered vector
184187
const matrix_type<D, 1> residual = meas_local - H * filtered_vec;
185188

186189
// Calculate backward chi2
187-
const matrix_type<D, D> R = (I_m - H * K) * V;
190+
const matrix_type<D, D> i_minus_hk = I_m - H * K;
191+
// See
192+
// https://indico.cern.ch/event/1564924/contributions/6629447/attachments/3113201/5519076/asami_250731_acts.pdf
193+
const matrix_type<D, D> R =
194+
i_minus_hk * V * matrix::transpose(i_minus_hk) +
195+
H * i_minus_kh * predicted_cov * matrix::transpose(i_minus_kh) *
196+
matrix::transpose(H);
188197
// assert(matrix::determinant(R) != 0.f);
189198
assert(std::isfinite(matrix::determinant(R)));
190199
const matrix_type<1, 1> chi2 =

0 commit comments

Comments
 (0)