LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
KalmanLinearAlgebra.h
Go to the documentation of this file.
1 
39 #ifndef KALMANLINEARALGEBRA_H
40 #define KALMANLINEARALGEBRA_H
41 
42 #include "boost/numeric/ublas/lu.hpp"
43 #include "boost/numeric/ublas/matrix.hpp"
44 #include "boost/numeric/ublas/symmetric.hpp"
45 #include "boost/numeric/ublas/vector.hpp"
46 #include "boost/serialization/array_wrapper.hpp" // workaround for deficiency in boost 1.64
47 #include <cmath>
48 
49 namespace trkf {
50 
52  namespace ublas = boost::numeric::ublas;
53 
55  template <int N>
56  struct KVector {
57  typedef ublas::vector<double, ublas::bounded_array<double, N>> type;
58  };
59 
61  template <int N>
62  struct KSymMatrix {
63  typedef ublas::symmetric_matrix<double,
64  ublas::lower,
65  ublas::row_major,
66  ublas::bounded_array<double, N*(N + 1) / 2>>
68  };
69 
71  template <int N, int M>
72  struct KMatrix {
73  typedef ublas::matrix<double, ublas::row_major, ublas::bounded_array<double, N * M>> type;
74  };
75 
77  template <int N>
78  struct KHMatrix {
79  typedef typename KMatrix<N, 5>::type type;
80  };
81 
83  template <int N>
84  struct KGMatrix {
85  typedef typename KMatrix<5, N>::type type;
86  };
87 
89  typedef typename KVector<5>::type TrackVector;
90 
92  typedef typename KSymMatrix<5>::type TrackError;
93 
95  typedef typename KMatrix<5, 5>::type TrackMatrix;
96 
107  template <class T, class TRI, class L, class A>
108  bool syminvert(ublas::symmetric_matrix<T, TRI, L, A>& m)
109  {
110  typedef typename ublas::symmetric_matrix<T, TRI, L, A>::size_type size_type;
111  typedef typename ublas::symmetric_matrix<T, TRI, L, A>::value_type value_type;
112 
113  // In situ Cholesky decomposition m = LDL^T.
114  // D is diagonal matrix.
115  // L is lower triangular with ones on the diagonal (ones not stored).
116 
117  for (size_type i = 0; i < m.size1(); ++i) {
118  for (size_type j = 0; j <= i; ++j) {
119 
120  value_type ele = m(i, j);
121 
122  for (size_type k = 0; k < j; ++k)
123  ele -= m(k, k) * m(i, k) * m(j, k);
124 
125  // Diagonal elements (can't have zeroes).
126 
127  if (i == j) {
128  if (ele == 0.) return false;
129  }
130 
131  // Off-diagonal elements.
132 
133  else
134  ele = ele / m(j, j);
135 
136  // Replace element.
137 
138  m(i, j) = ele;
139  }
140  }
141 
142  // In situ inversion of D by simple division.
143  // In situ inversion of L by back-substitution.
144 
145  for (size_type i = 0; i < m.size1(); ++i) {
146  for (size_type j = 0; j <= i; ++j) {
147 
148  value_type ele = m(i, j);
149 
150  // Diagonal elements.
151 
152  if (i == j) m(i, i) = 1. / ele;
153 
154  // Off diagonal elements.
155 
156  else {
157  value_type sum = -ele;
158  for (size_type k = j + 1; k < i; ++k)
159  sum -= m(i, k) * m(k, j);
160  m(i, j) = sum;
161  }
162  }
163  }
164 
165  // Recompose the inverse matrix in situ by matrix multiplication m = L^T DL.
166 
167  for (size_type i = 0; i < m.size1(); ++i) {
168  for (size_type j = 0; j <= i; ++j) {
169 
170  value_type sum = m(i, i);
171  if (i != j) sum *= m(i, j);
172 
173  for (size_type k = i + 1; k < m.size1(); ++k)
174  sum += m(k, k) * m(k, i) * m(k, j);
175 
176  m(i, j) = sum;
177  }
178  }
179 
180  // Done (success).
181 
182  return true;
183  }
184 
188  template <class T, class L, class A>
189  bool invert(ublas::matrix<T, L, A>& m)
190  {
191  // Make sure matrix is square.
192 
193  if (m.size1() != m.size2()) return false;
194 
195  // Create permutation matrix for pivoting.
196 
197  ublas::permutation_matrix<std::size_t> pm(m.size1());
198 
199  // Make temp copy of input matrix.
200 
201  ublas::matrix<T, L, A> mcopy(m);
202 
203  // Do LU factorization with partial pivoting.
204  // This step will fail if matrix is singular.
205 
206  int res = lu_factorize(mcopy, pm);
207  if (res != 0) return false;
208 
209  // Set original matrix to the identity matrix.
210 
211  m.assign(ublas::identity_matrix<T>(m.size1()));
212 
213  // Do backsubstitution.
214 
215  lu_substitute(mcopy, pm, m);
216 
217  // Done (success).
218 
219  return true;
220  }
221 
224  template <class M>
225  typename M::value_type trace(const M& m)
226  {
227  typename M::size_type n = std::min(m.size1(), m.size2());
228  typename M::value_type result = 0.;
229 
230  for (typename M::size_type i = 0; i < n; ++i)
231  result += m(i, i);
232 
233  return result;
234  }
235 }
236 
237 #endif
Kalman gain matrix, dimension 5xN.
KSymMatrix< 5 >::type TrackError
Track error matrix, dimension 5x5.
Define a shortened alias for ublas namespace.
M::value_type trace(const M &m)
KMatrix< 5, 5 >::type TrackMatrix
General 5x5 matrix.
KMatrix< 5, N >::type type
ublas::vector< double, ublas::bounded_array< double, N > > type
bool syminvert(ublas::symmetric_matrix< T, TRI, L, A > &m)
General matrix, dimension NxM.
bool invert(ublas::matrix< T, L, A > &m)
KVector< 5 >::type TrackVector
Track state vector, dimension 5.
Kalman H-matrix, dimension Nx5.
KMatrix< N, 5 >::type type
ublas::matrix< double, ublas::row_major, ublas::bounded_array< double, N *M > > type
Char_t n[5]
Double_t sum
Definition: plot.C:31
Symmetric matrix, dimension NxN.