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