// @(#)root/smatrix:$Id$ // Author: L. Moneta, J. Palacios 2006 #ifndef ROOT_Math_MatrixRepresentationsStatic #define ROOT_Math_MatrixRepresentationsStatic 1 // Include files /** @defgroup MatRep SMatrix Storage Representation @ingroup SMatrixGroup @author Juan Palacios @date 2006-01-15 Classes MatRepStd and MatRepSym for generic and symmetric matrix data storage and manipulation. Define data storage and access, plus operators =, +=, -=, ==. */ #ifndef ROOT_Math_StaticCheck #include "Math/StaticCheck.h" #endif namespace ROOT { namespace Math { //________________________________________________________________________________ /** MatRepStd Standard Matrix representation for a general D1 x D2 matrix. This class is itself a template on the contained type T, the number of rows and the number of columns. Its data member is an array T[nrows*ncols] containing the matrix data. The data are stored in the row-major C convention. For example, for a matrix, M, of size 3x3, the data \f$ \left[a_0,a_1,a_2,.......,a_7,a_8 \right] \f$d are stored in the following order: \f[ M = \left( \begin{array}{ccc} a_0 & a_1 & a_2 \\ a_3 & a_4 & a_5 \\ a_6 & a_7 & a_8 \end{array} \right) \f] @ingroup MatRep */ template class MatRepStd { public: typedef T value_type; inline const T& operator()(unsigned int i, unsigned int j) const { return fArray[i*D2+j]; } inline T& operator()(unsigned int i, unsigned int j) { return fArray[i*D2+j]; } inline T& operator[](unsigned int i) { return fArray[i]; } inline const T& operator[](unsigned int i) const { return fArray[i]; } inline T apply(unsigned int i) const { return fArray[i]; } inline T* Array() { return fArray; } inline const T* Array() const { return fArray; } template inline MatRepStd& operator+=(const R& rhs) { for(unsigned int i=0; i inline MatRepStd& operator-=(const R& rhs) { for(unsigned int i=0; i inline MatRepStd& operator=(const R& rhs) { for(unsigned int i=0; i inline bool operator==(const R& rhs) const { bool rc = true; for(unsigned int i=0; i // struct Creator { // static const RowOffsets & Offsets() { // static RowOffsets off; // return off; // } /** Static structure to keep the conversion from (i,j) to offsets in the storage data for a symmetric matrix */ template struct RowOffsets { inline RowOffsets() { int v[D]; v[0]=0; for (unsigned int i=1; i struct RowOffsets<1> { RowOffsets() {} int operator()(unsigned int , unsigned int ) const { return 0; } // Just one element int apply(unsigned int ) const { return 0; } }; template<> struct RowOffsets<2> { RowOffsets() {} int operator()(unsigned int i, unsigned int j) const { return i+j; /*fOff2x2[i*2+j];*/ } int apply(unsigned int i) const { return fOff2x2[i]; } }; template<> struct RowOffsets<3> { RowOffsets() {} int operator()(unsigned int i, unsigned int j) const { return fOff3x3[i*3+j]; } int apply(unsigned int i) const { return fOff3x3[i]; } }; template<> struct RowOffsets<4> { RowOffsets() {} int operator()(unsigned int i, unsigned int j) const { return fOff4x4[i*4+j]; } int apply(unsigned int i) const { return fOff4x4[i]; } }; template<> struct RowOffsets<5> { inline RowOffsets() {} inline int operator()(unsigned int i, unsigned int j) const { return fOff5x5[i*5+j]; } // int operator()(unsigned int i, unsigned int j) const { // if(j <= i) return (i * (i + 1)) / 2 + j; // else return (j * (j + 1)) / 2 + i; // } inline int apply(unsigned int i) const { return fOff5x5[i]; } }; template<> struct RowOffsets<6> { RowOffsets() {} int operator()(unsigned int i, unsigned int j) const { return fOff6x6[i*6+j]; } int apply(unsigned int i) const { return fOff6x6[i]; } }; template<> struct RowOffsets<7> { RowOffsets() {} int operator()(unsigned int i, unsigned int j) const { return fOff7x7[i*7+j]; } int apply(unsigned int i) const { return fOff7x7[i]; } }; template<> struct RowOffsets<8> { RowOffsets() {} int operator()(unsigned int i, unsigned int j) const { return fOff8x8[i*8+j]; } int apply(unsigned int i) const { return fOff8x8[i]; } }; template<> struct RowOffsets<9> { RowOffsets() {} int operator()(unsigned int i, unsigned int j) const { return fOff9x9[i*9+j]; } int apply(unsigned int i) const { return fOff9x9[i]; } }; template<> struct RowOffsets<10> { RowOffsets() {} int operator()(unsigned int i, unsigned int j) const { return fOff10x10[i*10+j]; } int apply(unsigned int i) const { return fOff10x10[i]; } }; //_________________________________________________________________________________ /** MatRepSym Matrix storage representation for a symmetric matrix of dimension NxN This class is a template on the contained type and on the symmetric matrix size, N. It has as data member an array of type T of size N*(N+1)/2, containing the lower diagonal block of the matrix. The order follows the lower diagonal block, still in a row-major convention. For example for a symmetric 3x3 matrix the order of the 6 elements \f$ \left[a_0,a_1.....a_5 \right]\f$ is: \f[ M = \left( \begin{array}{ccc} a_0 & a_1 & a_3 \\ a_1 & a_2 & a_4 \\ a_3 & a_4 & a_5 \end{array} \right) \f] @ingroup MatRep */ template class MatRepSym { public: MatRepSym() :fOff(0) { CreateOffsets(); } typedef T value_type; inline const T& operator()(unsigned int i, unsigned int j) const { return fArray[Offsets()(i,j)]; } inline T& operator()(unsigned int i, unsigned int j) { return fArray[Offsets()(i,j)]; } inline T& operator[](unsigned int i) { return fArray[Offsets().apply(i) ]; //return fArray[Offsets()(i/D, i%D)]; } inline const T& operator[](unsigned int i) const { return fArray[Offsets().apply(i) ]; //return fArray[Offsets()(i/D, i%D)]; } inline T apply(unsigned int i) const { return fArray[Offsets().apply(i) ]; //return operator()(i/D, i%D); } inline T* Array() { return fArray; } inline const T* Array() const { return fArray; } /** assignment : only symmetric to symmetric allowed */ template inline MatRepSym& operator=(const R&) { STATIC_CHECK(0==1, Cannot_assign_general_to_symmetric_matrix_representation); return *this; } inline MatRepSym& operator=(const MatRepSym& rhs) { for(unsigned int i=0; i inline MatRepSym& operator+=(const R&) { STATIC_CHECK(0==1, Cannot_add_general_to_symmetric_matrix_representation); return *this; } inline MatRepSym& operator+=(const MatRepSym& rhs) { for(unsigned int i=0; i inline MatRepSym& operator-=(const R&) { STATIC_CHECK(0==1, Cannot_substract_general_to_symmetric_matrix_representation); return *this; } inline MatRepSym& operator-=(const MatRepSym& rhs) { for(unsigned int i=0; i inline bool operator==(const R& rhs) const { bool rc = true; for(unsigned int i=0; i off; fOff = &off; } inline const RowOffsets & Offsets() const { return *fOff; } private: //T __attribute__ ((aligned (16))) fArray[kSize]; T fArray[kSize]; const RowOffsets * fOff; //! transient }; } // namespace Math } // namespace ROOT #endif // MATH_MATRIXREPRESENTATIONSSTATIC_H