File indexing completed on 2026-08-06 09:20:02
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 #ifndef __EVT_MATRIX_HH__
0022 #define __EVT_MATRIX_HH__
0023
0024 #include <cmath>
0025 #include <sstream>
0026 #include <vector>
0027
0028 template <class T>
0029 class EvtMatrix {
0030 private:
0031 T** _mat;
0032 int _range;
0033
0034 public:
0035 EvtMatrix() : _range( 0 ){};
0036 ~EvtMatrix();
0037 inline void setRange( int range );
0038
0039 T& operator()( int row, int col ) { return _mat[row][col]; }
0040 T* operator[]( int row ) { return _mat[row]; }
0041 T det();
0042 EvtMatrix* min( int row, int col );
0043 EvtMatrix* inverse();
0044 std::string dump();
0045
0046 template <class M>
0047 friend EvtMatrix<M>* operator*( const EvtMatrix<M>& left,
0048 const EvtMatrix<M>& right );
0049 };
0050
0051 template <class T>
0052 inline void EvtMatrix<T>::setRange( int range )
0053 {
0054
0055
0056 if ( _range != range ) {
0057 if ( _range ) {
0058 for ( int row = 0; row < _range; row++ )
0059 delete[] _mat[row];
0060 delete[] _mat;
0061 }
0062
0063 _mat = new T*[range];
0064 for ( int row = 0; row < range; row++ )
0065 _mat[row] = new T[range];
0066
0067
0068 _range = range;
0069 }
0070
0071
0072 for ( int row = 0; row < _range; row++ )
0073 for ( int col = 0; col < _range; col++ )
0074 _mat[row][col] = 0.;
0075 }
0076
0077 template <class T>
0078 EvtMatrix<T>::~EvtMatrix()
0079 {
0080 for ( int row = 0; row < _range; row++ )
0081 delete[] _mat[row];
0082 delete[] _mat;
0083 }
0084
0085 template <class T>
0086 std::string EvtMatrix<T>::dump()
0087 {
0088 std::ostringstream str;
0089
0090 for ( int row = 0; row < _range; row++ ) {
0091 str << "|";
0092 for ( int col = 0; col < _range; col++ )
0093 str << "\t" << _mat[row][col];
0094 str << "\t|" << std::endl;
0095 }
0096
0097 return str.str();
0098 }
0099
0100 template <class T>
0101 T EvtMatrix<T>::det()
0102 {
0103 if ( _range == 1 )
0104 return _mat[0][0];
0105
0106
0107
0108 if ( _range == 2 )
0109 return _mat[0][0] * _mat[1][1] - _mat[0][1] * _mat[1][0];
0110
0111 T sum = 0.;
0112
0113 for ( int col = 0; col < _range; col++ ) {
0114 EvtMatrix<T>* minor = min( 0, col );
0115 sum += std::pow( -1., col ) * _mat[0][col] * minor->det();
0116 delete minor;
0117 }
0118
0119 return sum;
0120 }
0121
0122
0123 template <class T>
0124 EvtMatrix<T>* EvtMatrix<T>::min( int row, int col )
0125 {
0126 EvtMatrix<T>* minor = new EvtMatrix<T>();
0127 minor->setRange( _range - 1 );
0128
0129 int minIndex = 0;
0130
0131 for ( int r = 0; r < _range; r++ )
0132 for ( int c = 0; c < _range; c++ )
0133 if ( ( r != row ) && ( c != col ) ) {
0134 ( *minor )( minIndex / ( _range - 1 ),
0135 minIndex % ( _range - 1 ) ) = _mat[r][c];
0136 minIndex++;
0137 }
0138
0139 return minor;
0140 }
0141
0142 template <class T>
0143 EvtMatrix<T>* EvtMatrix<T>::inverse()
0144 {
0145 EvtMatrix<T>* inv = new EvtMatrix<T>();
0146 inv->setRange( _range );
0147
0148 if ( det() == 0 ) {
0149 std::cerr << "This matrix has a null determinant and cannot be inverted. Returning zero matrix."
0150 << std::endl;
0151 for ( int row = 0; row < _range; row++ )
0152 for ( int col = 0; col < _range; col++ )
0153 ( *inv )( row, col ) = 0.;
0154 return inv;
0155 }
0156
0157 T determinant = det();
0158
0159 for ( int row = 0; row < _range; row++ )
0160 for ( int col = 0; col < _range; col++ ) {
0161 EvtMatrix<T>* minor = min( row, col );
0162 inv->_mat[col][row] = std::pow( -1., row + col ) * minor->det() /
0163 determinant;
0164 delete minor;
0165 }
0166
0167 return inv;
0168 }
0169
0170 template <class T>
0171 EvtMatrix<T>* operator*( const EvtMatrix<T>& left, const EvtMatrix<T>& right )
0172 {
0173
0174 if ( left._range != right._range ) {
0175 std::cerr << "These matrices cannot be multiplied." << std::endl;
0176 return new EvtMatrix<T>();
0177 }
0178
0179 EvtMatrix<T>* mat = new EvtMatrix<T>();
0180 mat->setRange( left._range );
0181
0182
0183 for ( int row = 0; row < left._range; row++ )
0184 for ( int col = 0; col < right._range; col++ )
0185 ( *mat )[row][col] = 0;
0186
0187 for ( int row = 0; row < left._range; row++ )
0188 for ( int col = 0; col < right._range; col++ )
0189 for ( int line = 0; line < right._range; line++ )
0190 ( *mat )[row][col] += left._mat[row][line] *
0191 right._mat[line][col];
0192
0193 return mat;
0194 }
0195
0196 #endif