QwAnalysis
matrix.h
Go to the documentation of this file.
1 #ifndef MATRIX_H
2 #define MATRIX_H
3 
4 // Standard C and C++ headers
5 #include <fstream>
6 #include <cstdio>
7 #include <cmath>
8 #include <cstdlib>
9 #include <cassert>
10 #include <cstring>
11 
12 // Boost uBLAS (linear algebra) headers
13 #ifndef BOOST_VERSION
14 #include <boost/version.hpp>
15 #endif
16 #if BOOST_VERSION <= 103200
17 // Boost 1.32.00 needs explicit includes of "functional.hpp"
18 // and "operation.hpp".
19 // They are not needed for Boost 1.34.01, but don't really hurt
20 // if we wanted to just include them unconditionally.
21 #include <boost/numeric/ublas/config.hpp>
22 #include <boost/numeric/ublas/storage.hpp>
23 #include <boost/numeric/ublas/functional.hpp>
24 #include <boost/numeric/ublas/operation.hpp>
25 #endif
26 //
27 #include <boost/numeric/ublas/vector.hpp>
28 #include <boost/numeric/ublas/matrix.hpp>
29 #include <boost/numeric/ublas/triangular.hpp>
30 #include <boost/numeric/ublas/lu.hpp>
31 #include <boost/numeric/ublas/io.hpp>
32 
33 
34 // Matrix inversion routines optimized for 4 x 4 matrices
35 double UNorm (const double *A, int n, const int m);
36 double* M_Cholesky (double *B, double *q, const int n);
37 double* M_InvertPos (double *B, const int n);
38 double* M_Invert (double *Ap, double *Bp, const int n);
39 void RowMult (const double a, double *A, const double b, const double *B, const int n);
40 double* M_A_times_b (double *y, const double *A, const int n, const int m, const double *b);
41 double* M_Zero (double *A, const int n);
42 double* M_Unit (double *A, const int n);
43 void M_Print (const double *A, const int n);
44 void M_Print (const double *A, const double *B, const int n);
45 
46 double *V_Zero (double *v, const int n);
47 double *V_Unit (double *v, const int n, int k);
48 void V_Print (const double *v, const int n);
49 void V_Print (const double *v, const double *w, const int n);
50 
51 
52 /*------------------------------------------------------------------------*//*!
53 
54  The following code inverts the matrix input using LU-decomposition with
55  backsubstitution of unit vectors.
56 
57  References:
58  Numerical Recipies in C, 2nd ed., by Press, Teukolsky, Vetterling & Flannery.
59  http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?LU_Matrix_Inversion
60 
61  Note:
62  This function is relatively slow (around 230 usec on my laptop for a 4 x 4 matrix,
63  compared to less than 10 usec using the functions above), but on a total processing
64  time per event of 0.1 sec this does not make any difference and greatly improves
65  maintainability. If profiling reveals that this matrix inversion is a bottle neck,
66  we should move back to the optimized functions.
67 
68 *//*-------------------------------------------------------------------------*/
69 
70 template<class T>
71 boost::numeric::ublas::matrix<T> invert (boost::numeric::ublas::matrix<T> & input)
72 {
73  using namespace boost::numeric::ublas;
74 
75  // Initialize the inverse to a zero matrix
76  matrix<T> inverse(zero_matrix<T>(input.size1()));
77 
78  // Create a working copy of the input and inverse
79  matrix<T> A(input);
80  // Create a permutation matrix for the LU-factorization
81  permutation_matrix<std::size_t> pm(A.size1());
82 
83  // Perform LU-factorization
84  int res = lu_factorize(A, pm);
85  // Return the zero matrix if this fails
86  if (res != 0) return inverse;
87 
88  // Create identity matrix of "inverse"
89  inverse.assign(identity_matrix<T>(A.size1()));
90 
91  // Backsubstitute to get the inverse
92  lu_substitute(A, pm, inverse);
93 
94  return inverse;
95 }
96 
97 
98 #endif // MATRIX_H
double * M_Invert(double *Ap, double *Bp, const int n)
Matrix inversion of Ap will be stored in Bp.
Definition: matrix.cc:240
static const double m
Definition: QwUnits.h:63
double * V_Zero(double *v, const int n)
Definition: matrix.cc:5
double * M_Cholesky(double *B, double *q, const int n)
Calculates the Cholesky decomposition of the positive-definite matrix B.
Definition: matrix.cc:76
double * M_InvertPos(double *B, const int n)
Calculates a*A + b*B, where both A and B are rows of length n.
Definition: matrix.cc:376
double * V_Unit(double *v, const int n, int k)
Definition: matrix.cc:13
double UNorm(const double *A, int n, const int m)
Calculates the least upper bound norm.
Definition: matrix.cc:51
void RowMult(const double a, double *A, const double b, const double *B, const int n)
Calculates a*A + b*B, where both A and B are rows of length n, returns as A.
Definition: matrix.cc:130
void M_Print(const double *A, const int n)
Print matrix A of dimension [n,n] to cout.
Definition: matrix.cc:147
double * M_A_times_b(double *y, const double *A, const int n, const int m, const double *b)
Calculates y[n] = A[n,m] * b[m], with dimensions indicated.
Definition: matrix.cc:443
double * M_Zero(double *A, const int n)
Creates zero matrix A.
Definition: matrix.cc:220
void V_Print(const double *v, const int n)
Definition: matrix.cc:22
double * M_Unit(double *A, const int n)
Creates unit matrix A.
Definition: matrix.cc:199
boost::numeric::ublas::matrix< T > invert(boost::numeric::ublas::matrix< T > &input)
Definition: matrix.h:71