| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

Gaudi::Math::SymPosDefMatrixInverter::inverterForAllN< T > Struct Template Reference

invert symmetric positive definite matrix (dimension n, general, implementation) More...

#include <SymPosDefMatrixInverter.h>

List of all members.


Public Types

typedef T::value_type F

Public Member Functions

bool operator() (T &m, int N) const

Detailed Description

template<class T>
struct Gaudi::Math::SymPosDefMatrixInverter::inverterForAllN< T >

invert symmetric positive definite matrix (dimension n, general, implementation)

Definition at line 21 of file SymPosDefMatrixInverter.h.


Member Typedef Documentation

template<class T>
typedef T::value_type Gaudi::Math::SymPosDefMatrixInverter::inverterForAllN< T >::F

Definition at line 23 of file SymPosDefMatrixInverter.h.


Member Function Documentation

template<class T>
bool Gaudi::Math::SymPosDefMatrixInverter::inverterForAllN< T >::operator() ( T &  m,
int  N 
) const [inline]

Definition at line 24 of file SymPosDefMatrixInverter.h.

00025         {
00026           // perform Cholesky decomposition of matrix: M = L L^T
00027           // only thing that can go wrong: trying to take square root of negative
00028           // number or zero (matrix is ill-conditioned or singular in these cases)
00029 
00030           // we only need N * (N + 1) / 2 elements to store L
00031           // element L(i,j) is at array position (i * (i + 1)) / 2 + j
00032           F l[(N * (N + 1)) / 2];
00033 
00034           // quirk: we need to invert L later anyway, so we can invert elements
00035           // on diagonale straight away (we only ever need their reciprocals!)
00036 
00037           // cache starting address of rows of L for speed reasons
00038           F *base1 = &l[0];
00039           for (int i = 0; i < N; base1 += ++i) {
00040             F tmpdiag = F(0);   // for element on diagonale
00041             // calculate off-diagonal elements
00042             F *base2 = &l[0];
00043             for (int j = 0; j < i; base2 += ++j) {
00044               F tmp = m(i, j);
00045               for (int k = j; k--; )
00046                 tmp -= base1[k] * base2[k];
00047               base1[j] = tmp *= base2[j];
00048               // keep track of contribution to element on diagonale
00049               tmpdiag += tmp * tmp;
00050             }
00051             // keep truncation error small
00052             tmpdiag = m(i, i) - tmpdiag;
00053             // check if positive definite
00054             if (tmpdiag <= F(0)) return false;
00055             else base1[i] = std::sqrt(F(1) / tmpdiag);
00056           }
00057 
00058           // ok, next step: invert off-diagonal part of matrix
00059           base1 = &l[1];
00060           for (int i = 1; i < N; base1 += ++i) {
00061             for (int j = 0; j < i; ++j) {
00062               F tmp = F(0);
00063               F *base2 = &l[(i * (i - 1)) / 2];
00064               for (int k = i; k-- > j; base2 -= k)
00065                 tmp -= base1[k] * base2[j];
00066               base1[j] = tmp * base1[i];
00067             }
00068           }
00069 
00070           // Li = L^(-1) formed, now calculate M^(-1) = Li^T Li
00071           for (int i = N; i--; ) {
00072             for (int j = i + 1; j--; ) {
00073               F tmp = F(0);
00074               base1 = &l[(N * (N - 1)) / 2];
00075               for (int k = N; k-- > i; base1 -= k)
00076                 tmp += base1[i] * base1[j];
00077               m(i,j) = tmp;
00078             }
00079           }
00080 
00081           return true;
00082         }


The documentation for this struct was generated from the following file:
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Mon Apr 11 20:02:59 2011 for LHCbMath by doxygen 1.4.7