matrix.h

Go to the documentation of this file.
00001 #ifndef MATRIX_H
00002 #define MATRIX_H
00003 
00004 // Standard C and C++ headers
00005 #include <fstream>
00006 #include <cstdio>
00007 #include <cmath>
00008 #include <cstdlib>
00009 #include <cassert>
00010 #include <cstring>
00011 
00012 // Boost uBLAS (linear algebra) headers
00013 #ifndef BOOST_VERSION
00014 #include <boost/version.hpp>
00015 #endif
00016 #if BOOST_VERSION <= 103200
00017 //    Boost 1.32.00 needs explicit includes of "functional.hpp"
00018 //    and "operation.hpp".
00019 //    They are not needed  for Boost 1.34.01, but don't really hurt
00020 //    if we wanted to just include them unconditionally.
00021 #include <boost/numeric/ublas/config.hpp>
00022 #include <boost/numeric/ublas/storage.hpp>
00023 #include <boost/numeric/ublas/functional.hpp>
00024 #include <boost/numeric/ublas/operation.hpp>
00025 #endif
00026 //
00027 #include <boost/numeric/ublas/vector.hpp>
00028 #include <boost/numeric/ublas/matrix.hpp>
00029 #include <boost/numeric/ublas/triangular.hpp>
00030 #include <boost/numeric/ublas/lu.hpp>
00031 #include <boost/numeric/ublas/io.hpp>
00032 
00033 
00034 // Matrix inversion routines optimized for 4 x 4 matrices
00035 double UNorm (const double *A, int n, const int m);
00036 double* M_Cholesky (double *B, double *q, const int n);
00037 double* M_InvertPos (double *B, const int n);
00038 double* M_Invert (double *Ap, double *Bp, const int n);
00039 void RowMult (const double a, double *A, const double b, const double *B, const int n);
00040 double* M_A_times_b (double *y, const double *A, const int n, const int m, const double *b);
00041 double* M_Zero (double *A, const int n);
00042 double* M_Unit (double *A, const int n);
00043 void M_Print (const double *A, const int n);
00044 void M_Print (const double *A, const double *B, const int n);
00045 
00046 double *V_Zero (double *v, const int n);
00047 double *V_Unit (double *v, const int n, int k);
00048 void V_Print (const double *v, const int n);
00049 void V_Print (const double *v, const double *w, const int n);
00050 
00051 
00052 /*------------------------------------------------------------------------*//*!
00053 
00054  The following code inverts the matrix input using LU-decomposition with
00055  backsubstitution of unit vectors.
00056 
00057  References:
00058  Numerical Recipies in C, 2nd ed., by Press, Teukolsky, Vetterling & Flannery.
00059  http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?LU_Matrix_Inversion
00060 
00061  Note:
00062  This function is relatively slow (around 230 usec on my laptop for a 4 x 4 matrix,
00063  compared to less than 10 usec using the functions above), but on a total processing
00064  time per event of 0.1 sec this does not make any difference and greatly improves
00065  maintainability.  If profiling reveals that this matrix inversion is a bottle neck,
00066  we should move back to the optimized functions.
00067 
00068 *//*-------------------------------------------------------------------------*/
00069 
00070 template<class T>
00071 boost::numeric::ublas::matrix<T> invert (boost::numeric::ublas::matrix<T> & input)
00072 {
00073   using namespace boost::numeric::ublas;
00074 
00075   // Initialize the inverse to a zero matrix
00076   matrix<T> inverse(zero_matrix<T>(input.size1()));
00077 
00078   // Create a working copy of the input and inverse
00079   matrix<T> A(input);
00080   // Create a permutation matrix for the LU-factorization
00081   permutation_matrix<std::size_t> pm(A.size1());
00082 
00083   // Perform LU-factorization
00084   int res = lu_factorize(A, pm);
00085   // Return the zero matrix if this fails
00086   if (res != 0) return inverse;
00087 
00088   // Create identity matrix of "inverse"
00089   inverse.assign(identity_matrix<T>(A.size1()));
00090 
00091   // Backsubstitute to get the inverse
00092   lu_substitute(A, pm, inverse);
00093 
00094   return inverse;
00095 }
00096 
00097 
00098 #endif // MATRIX_H

Generated on 19 Feb 2017 for QwAnalysis by  doxygen 1.6.1