Skip to content

Commit c0d2faf

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 e393122 commit c0d2faf

File tree

2 files changed

+15
-3
lines changed

2 files changed

+15
-3
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
@@ -112,13 +112,22 @@ struct gain_matrix_updater {
112112
// Calculate the filtered track parameters
113113
const matrix_type<6, 1> filtered_vec =
114114
predicted_vec + K * (meas_local - H * predicted_vec);
115-
const matrix_type<6, 6> filtered_cov = (I66 - K * H) * predicted_cov;
115+
const matrix_type<6, 6> i_minus_kh = I66 - K * H;
116+
const matrix_type<6, 6> filtered_cov =
117+
i_minus_kh * predicted_cov * matrix::transpose(i_minus_kh) +
118+
K * V * matrix::transpose(K);
116119

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

120123
// Calculate the chi square
121-
const matrix_type<D, D> R = (I_m - H * K) * V;
124+
const matrix_type<D, D> i_minus_hk = I_m - H * K;
125+
// See
126+
// https://indico.cern.ch/event/1564924/contributions/6629447/attachments/3113201/5519076/asami_250731_acts.pdf
127+
const matrix_type<D, D> R =
128+
i_minus_hk * V * matrix::transpose(i_minus_hk) +
129+
H * i_minus_kh * predicted_cov * matrix::transpose(i_minus_kh) *
130+
matrix::transpose(H);
122131
const matrix_type<1, 1> chi2 =
123132
algebra::matrix::transposed_product<true, false>(
124133
residual, matrix::inverse(R)) *

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,10 @@ struct two_filters_smoother {
171171
// Calculate the filtered track parameters
172172
const matrix_type<6, 1> filtered_vec =
173173
predicted_vec + K * (meas_local - H * predicted_vec);
174-
const matrix_type<6, 6> filtered_cov = (I66 - K * H) * predicted_cov;
174+
const matrix_type<6, 6> i_minus_kh = I66 - K * H;
175+
const matrix_type<6, 6> filtered_cov =
176+
i_minus_kh * predicted_cov * matrix::transpose(i_minus_kh) +
177+
K * V * matrix::transpose(K);
175178

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

0 commit comments

Comments
 (0)