BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
EvtMatrix.hh
Go to the documentation of this file.
1/*****************************************************************************
2 * Project: BaBar detector at the SLAC PEP-II B-factory
3 * Package: EvtGenBase
4 * File: $Id: EvtMatrix.hh,v 1.1 2009/05/08 01:59:56 pingrg Exp $
5 *
6 * Description:
7 * Class to make simple computations with matrices: assignment, product,
8 * determinant, inverse... Still many functions could be implemented.
9 *
10 * Modification history:
11 * Jordi Garra Ticó 2008/07/03 File created
12 *****************************************************************************/
13
14#ifndef __EVT_MATRIX_HH__
15#define __EVT_MATRIX_HH__
16
17#include <sstream>
18#include <vector>
19
20template <class T> class EvtMatrix {
21private:
22 T** _mat;
23 int _range;
24
25public:
26 EvtMatrix() : _range( 0 ){};
27 ~EvtMatrix();
28 inline void setRange( int range );
29
30 T& operator()( int row, int col ) { return _mat[row][col]; }
31 T* operator[]( int row ) { return _mat[row]; }
32 T det();
33 EvtMatrix* min( int row, int col );
35 std::string dump();
36
37 template <class M>
38 friend EvtMatrix<M>* operator*( const EvtMatrix<M>& left, const EvtMatrix<M>& right );
39};
40
41template <class T> inline void EvtMatrix<T>::setRange( int range ) {
42 // If the range is changed, delete any previous matrix stored
43 // and allocate elements with the newly specified range.
44 if ( _range != range )
45 {
46 if ( _range )
47 {
48 for ( int row = 0; row < _range; row++ ) delete[] _mat[row];
49 delete[] _mat;
50 }
51
52 _mat = new T*[range];
53 for ( int row = 0; row < range; row++ ) _mat[row] = new T[range];
54
55 // Set the new range.
56 _range = range;
57 }
58
59 // Since user is willing to change the range, reset the matrix elements.
60 for ( int row = 0; row < _range; row++ )
61 for ( int col = 0; col < _range; col++ ) _mat[row][col] = 0.;
62}
63
64template <class T> EvtMatrix<T>::~EvtMatrix() {
65 for ( int row = 0; row < _range; row++ ) delete[] _mat[row];
66 delete[] _mat;
67}
68
69template <class T> std::string EvtMatrix<T>::dump() {
70 std::ostringstream str;
71
72 for ( int row = 0; row < _range; row++ )
73 {
74 str << "|";
75 for ( int col = 0; col < _range; col++ ) str << "\t" << _mat[row][col];
76 str << "\t|" << std::endl;
77 }
78
79 return str.str();
80}
81
82template <class T> T EvtMatrix<T>::det() {
83 if ( _range == 1 ) return _mat[0][0];
84
85 // There's no need to define the range 2 determinant manually, but it may
86 // speed up the calculation.
87 if ( _range == 2 ) return _mat[0][0] * _mat[1][1] - _mat[0][1] * _mat[1][0];
88
89 T sum = 0.;
90
91 for ( int col = 0; col < _range; col++ )
92 {
93 EvtMatrix<T>* minor = min( 0, col );
94 sum += std::pow( -1., col ) * _mat[0][col] * minor->det();
95 delete minor;
96 }
97
98 return sum;
99}
100
101// Returns the minor at (i, j).
102template <class T> EvtMatrix<T>* EvtMatrix<T>::min( int row, int col ) {
103 EvtMatrix<T>* minor = new EvtMatrix<T>();
104 minor->setRange( _range - 1 );
105
106 int minIndex = 0;
107
108 for ( int r = 0; r < _range; r++ )
109 for ( int c = 0; c < _range; c++ )
110 if ( ( r != row ) && ( c != col ) )
111 {
112 ( *minor )( minIndex / ( _range - 1 ), minIndex % ( _range - 1 ) ) = _mat[r][c];
113 minIndex++;
114 }
115
116 return minor;
117}
118
119template <class T> EvtMatrix<T>* EvtMatrix<T>::inverse() {
120 EvtMatrix<T>* inv = new EvtMatrix<T>();
121 inv->setRange( _range );
122
123 if ( det() == 0 )
124 {
125 std::cerr
126 << "This matrix has a null determinant and cannot be inverted. Returning zero matrix."
127 << std::endl;
128 for ( int row = 0; row < _range; row++ )
129 for ( int col = 0; col < _range; col++ ) ( *inv )( row, col ) = 0.;
130 return inv;
131 }
132
133 T determinant = det();
134
135 for ( int row = 0; row < _range; row++ )
136 for ( int col = 0; col < _range; col++ )
137 {
138 EvtMatrix<T>* minor = min( row, col );
139 inv->_mat[col][row] = std::pow( -1., row + col ) * minor->det() / determinant;
140 delete minor;
141 }
142
143 return inv;
144}
145
146template <class T>
147EvtMatrix<T>* operator*( const EvtMatrix<T>& left, const EvtMatrix<T>& right ) {
148 // Chech that the matrices have the correct range.
149 if ( left._range != right._range )
150 {
151 std::cerr << "These matrices cannot be multiplied." << std::endl;
152 return new EvtMatrix<T>();
153 }
154
155 EvtMatrix<T>* mat = new EvtMatrix<T>();
156 mat->setRange( left._range );
157
158 // Initialize the elements of the matrix.
159 for ( int row = 0; row < left._range; row++ )
160 for ( int col = 0; col < right._range; col++ ) ( *mat )[row][col] = 0;
161
162 for ( int row = 0; row < left._range; row++ )
163 for ( int col = 0; col < right._range; col++ )
164 for ( int line = 0; line < right._range; line++ )
165 ( *mat )[row][col] += left._mat[row][line] * right._mat[line][col];
166
167 return mat;
168}
169
170#endif
#define min(a, b)
EvtMatrix< T > * operator*(const EvtMatrix< T > &left, const EvtMatrix< T > &right)
Definition EvtMatrix.hh:147
friend EvtMatrix< M > * operator*(const EvtMatrix< M > &left, const EvtMatrix< M > &right)
std::string dump()
Definition EvtMatrix.hh:69
EvtMatrix * min(int row, int col)
Definition EvtMatrix.hh:102
T & operator()(int row, int col)
Definition EvtMatrix.hh:30
void setRange(int range)
Definition EvtMatrix.hh:41
EvtMatrix * inverse()
Definition EvtMatrix.hh:119
T * operator[](int row)
Definition EvtMatrix.hh:31