MatrixRepresentationsStatic.h

Go to the documentation of this file.
00001 // @(#)root/smatrix:$Id: MatrixRepresentationsStatic.h 34964 2010-08-24 13:58:51Z moneta $
00002 // Author: L. Moneta, J. Palacios    2006  
00003 
00004 #ifndef ROOT_Math_MatrixRepresentationsStatic
00005 #define ROOT_Math_MatrixRepresentationsStatic 1
00006 
00007 // Include files
00008 
00009 /** 
00010     @defgroup MatRep SMatrix Storage Representation 
00011     @ingroup SMatrixGroup
00012  
00013     @author Juan Palacios
00014     @date   2006-01-15
00015  
00016     Classes MatRepStd and MatRepSym for generic and symmetric matrix
00017     data storage and manipulation. Define data storage and access, plus
00018     operators =, +=, -=, ==.
00019  
00020  */
00021 
00022 #ifndef ROOT_Math_StaticCheck
00023 #include "Math/StaticCheck.h"
00024 #endif
00025 
00026 namespace ROOT {
00027    
00028 namespace Math {
00029 
00030    //________________________________________________________________________________    
00031    /**
00032       MatRepStd
00033       Standard Matrix representation for a general D1 x D2 matrix. 
00034       This class is itself a template on the contained type T, the number of rows and the number of columns.
00035       Its data member is an array T[nrows*ncols] containing the matrix data. 
00036       The data are stored in the row-major C convention. 
00037       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: 
00038       \f[
00039       M = \left( \begin{array}{ccc} 
00040       a_0 & a_1 & a_2  \\ 
00041       a_3 & a_4  & a_5  \\ 
00042       a_6 & a_7  & a_8   \end{array} \right)
00043       \f]
00044 
00045       @ingroup MatRep
00046    */
00047 
00048 
00049    template <class T, unsigned int D1, unsigned int D2=D1>
00050    class MatRepStd {
00051 
00052    public: 
00053 
00054       typedef T  value_type;
00055 
00056       inline const T& operator()(unsigned int i, unsigned int j) const {
00057          return fArray[i*D2+j];
00058       }
00059       inline T& operator()(unsigned int i, unsigned int j) {
00060          return fArray[i*D2+j];
00061       }
00062       inline T& operator[](unsigned int i) { return fArray[i]; }
00063 
00064       inline const T& operator[](unsigned int i) const { return fArray[i]; }
00065 
00066       inline T apply(unsigned int i) const { return fArray[i]; }
00067 
00068       inline T* Array() { return fArray; }  
00069 
00070       inline const T* Array() const { return fArray; }  
00071 
00072       template <class R>
00073       inline MatRepStd<T, D1, D2>& operator+=(const R& rhs) {
00074          for(unsigned int i=0; i<kSize; ++i) fArray[i] += rhs[i];
00075          return *this;
00076       }
00077 
00078       template <class R>
00079       inline MatRepStd<T, D1, D2>& operator-=(const R& rhs) {
00080          for(unsigned int i=0; i<kSize; ++i) fArray[i] -= rhs[i];
00081          return *this;
00082       }
00083 
00084       template <class R>
00085       inline MatRepStd<T, D1, D2>& operator=(const R& rhs) {
00086          for(unsigned int i=0; i<kSize; ++i) fArray[i] = rhs[i];
00087          return *this;
00088       }
00089 
00090       template <class R> 
00091       inline bool operator==(const R& rhs) const {
00092          bool rc = true;
00093          for(unsigned int i=0; i<kSize; ++i) {
00094             rc = rc && (fArray[i] == rhs[i]);
00095          }
00096          return rc;
00097       }
00098 
00099       enum {
00100          /// return no. of matrix rows
00101          kRows = D1,
00102          /// return no. of matrix columns
00103          kCols = D2,
00104          /// return no of elements: rows*columns
00105          kSize = D1*D2
00106       };
00107       
00108    private:
00109       //T __attribute__ ((aligned (16))) fArray[kSize];
00110       T  fArray[kSize];
00111    };
00112     
00113     
00114 //     template<unigned int D>
00115 //     struct Creator { 
00116 //       static const RowOffsets<D> & Offsets() {
00117 //      static RowOffsets<D> off;
00118 //      return off;
00119 //       }
00120 
00121    /**
00122       Static structure to keep the conversion from (i,j) to offsets in the storage data for a 
00123       symmetric matrix
00124    */
00125 
00126    template<unsigned int D>
00127    struct RowOffsets {
00128       inline RowOffsets() {
00129          int v[D];
00130          v[0]=0;
00131          for (unsigned int i=1; i<D; ++i)
00132             v[i]=v[i-1]+i;
00133          for (unsigned int i=0; i<D; ++i) { 
00134             for (unsigned int j=0; j<=i; ++j)
00135                fOff[i*D+j] = v[i]+j; 
00136             for (unsigned int j=i+1; j<D; ++j)
00137                fOff[i*D+j] = v[j]+i ;
00138          }
00139       }
00140       inline int operator()(unsigned int i, unsigned int j) const { return fOff[i*D+j]; }
00141       inline int apply(unsigned int i) const { return fOff[i]; }
00142       int fOff[D*D];
00143    };
00144 
00145 // Make the lookup tables available at compile time:
00146 // Add them to a namespace?
00147 static const int fOff1x1[] = {0};
00148 static const int fOff2x2[] = {0, 1, 1, 2};
00149 static const int fOff3x3[] = {0, 1, 3, 1, 2, 4, 3, 4, 5};
00150 static const int fOff4x4[] = {0, 1, 3, 6, 1, 2, 4, 7, 3, 4, 5, 8, 6, 7, 8, 9};
00151 static const int fOff5x5[] = {0, 1, 3, 6, 10, 1, 2, 4, 7, 11, 3, 4, 5, 8, 12, 6, 7, 8, 9, 13, 10, 11, 12, 13, 14};
00152 static const int fOff6x6[] = {0, 1, 3, 6, 10, 15, 1, 2, 4, 7, 11, 16, 3, 4, 5, 8, 12, 17, 6, 7, 8, 9, 13, 18, 10, 11, 12, 13, 14, 19, 15, 16, 17, 18, 19, 20};
00153 
00154 static const int fOff7x7[] = {0, 1, 3, 6, 10, 15, 21, 1, 2, 4, 7, 11, 16, 22, 3, 4, 5, 8, 12, 17, 23, 6, 7, 8, 9, 13, 18, 24, 10, 11, 12, 13, 14, 19, 25, 15, 16, 17, 18, 19, 20, 26, 21, 22, 23, 24, 25, 26, 27};
00155 
00156 static const int fOff8x8[] = {0, 1, 3, 6, 10, 15, 21, 28, 1, 2, 4, 7, 11, 16, 22, 29, 3, 4, 5, 8, 12, 17, 23, 30, 6, 7, 8, 9, 13, 18, 24, 31, 10, 11, 12, 13, 14, 19, 25, 32, 15, 16, 17, 18, 19, 20, 26, 33, 21, 22, 23, 24, 25, 26, 27, 34, 28, 29, 30, 31, 32, 33, 34, 35};
00157 
00158 static const int fOff9x9[] = {0, 1, 3, 6, 10, 15, 21, 28, 36, 1, 2, 4, 7, 11, 16, 22, 29, 37, 3, 4, 5, 8, 12, 17, 23, 30, 38, 6, 7, 8, 9, 13, 18, 24, 31, 39, 10, 11, 12, 13, 14, 19, 25, 32, 40, 15, 16, 17, 18, 19, 20, 26, 33, 41, 21, 22, 23, 24, 25, 26, 27, 34, 42, 28, 29, 30, 31, 32, 33, 34, 35, 43, 36, 37, 38, 39, 40, 41, 42, 43, 44};
00159 
00160 static const int fOff10x10[] = {0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 1, 2, 4, 7, 11, 16, 22, 29, 37, 46, 3, 4, 5, 8, 12, 17, 23, 30, 38, 47, 6, 7, 8, 9, 13, 18, 24, 31, 39, 48, 10, 11, 12, 13, 14, 19, 25, 32, 40, 49, 15, 16, 17, 18, 19, 20, 26, 33, 41, 50, 21, 22, 23, 24, 25, 26, 27, 34, 42, 51, 28, 29, 30, 31, 32, 33, 34, 35, 43, 52, 36, 37, 38, 39, 40, 41, 42, 43, 44, 53, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54};
00161 
00162 template<>
00163         struct RowOffsets<1> {
00164           RowOffsets() {}
00165           int operator()(unsigned int , unsigned int ) const { return 0; } // Just one element
00166           int apply(unsigned int ) const { return 0; }
00167         };
00168 
00169 template<>
00170         struct RowOffsets<2> {
00171           RowOffsets() {}
00172           int operator()(unsigned int i, unsigned int j) const { return i+j; /*fOff2x2[i*2+j];*/ }
00173           int apply(unsigned int i) const { return fOff2x2[i]; }
00174         };
00175 
00176 template<>
00177         struct RowOffsets<3> {
00178           RowOffsets() {}
00179           int operator()(unsigned int i, unsigned int j) const { return fOff3x3[i*3+j]; }
00180           int apply(unsigned int i) const { return fOff3x3[i]; }
00181         };
00182 
00183 template<>
00184         struct RowOffsets<4> {
00185           RowOffsets() {}
00186           int operator()(unsigned int i, unsigned int j) const { return fOff4x4[i*4+j]; }
00187           int apply(unsigned int i) const { return fOff4x4[i]; }
00188         };
00189 
00190         template<>
00191         struct RowOffsets<5> {
00192           inline RowOffsets() {}
00193           inline int operator()(unsigned int i, unsigned int j) const { return fOff5x5[i*5+j]; }
00194 //      int operator()(unsigned int i, unsigned int j) const {
00195 //        if(j <= i) return (i * (i + 1)) / 2 + j;
00196 //              else return (j * (j + 1)) / 2 + i;
00197 //        }  
00198         inline int apply(unsigned int i) const { return fOff5x5[i]; }
00199         };
00200 
00201 template<>
00202         struct RowOffsets<6> {
00203           RowOffsets() {}
00204           int operator()(unsigned int i, unsigned int j) const { return fOff6x6[i*6+j]; }
00205           int apply(unsigned int i) const { return fOff6x6[i]; }
00206         };
00207 
00208 template<>
00209         struct RowOffsets<7> {
00210           RowOffsets() {}
00211           int operator()(unsigned int i, unsigned int j) const { return fOff7x7[i*7+j]; }
00212           int apply(unsigned int i) const { return fOff7x7[i]; }
00213         };
00214 
00215 template<>
00216         struct RowOffsets<8> {
00217           RowOffsets() {}
00218           int operator()(unsigned int i, unsigned int j) const { return fOff8x8[i*8+j]; }
00219           int apply(unsigned int i) const { return fOff8x8[i]; }
00220         };
00221 
00222 template<>
00223         struct RowOffsets<9> {
00224           RowOffsets() {}
00225           int operator()(unsigned int i, unsigned int j) const { return fOff9x9[i*9+j]; }
00226           int apply(unsigned int i) const { return fOff9x9[i]; }
00227         };
00228 
00229 template<>
00230         struct RowOffsets<10> {
00231           RowOffsets() {}
00232           int operator()(unsigned int i, unsigned int j) const { return fOff10x10[i*10+j]; }
00233           int apply(unsigned int i) const { return fOff10x10[i]; }
00234         };
00235 
00236 //_________________________________________________________________________________
00237    /**
00238       MatRepSym
00239       Matrix storage representation for a symmetric matrix of dimension NxN
00240       This class is a template on the contained type and on the symmetric matrix size, N. 
00241       It has as data member an array of type T of size N*(N+1)/2, 
00242       containing the lower diagonal block of the matrix.
00243       The order follows the lower diagonal block, still in a row-major convention. 
00244       For example for a symmetric 3x3 matrix the order of the 6 elements 
00245       \f$ \left[a_0,a_1.....a_5 \right]\f$ is: 
00246       \f[
00247       M = \left( \begin{array}{ccc} 
00248       a_0 & a_1  & a_3  \\ 
00249       a_1 & a_2  & a_4  \\
00250       a_3 & a_4 & a_5   \end{array} \right)
00251       \f]
00252 
00253       @ingroup MatRep 
00254    */
00255    template <class T, unsigned int D>
00256    class MatRepSym {
00257 
00258    public: 
00259 
00260       MatRepSym() :fOff(0) { CreateOffsets(); } 
00261 
00262       typedef T  value_type;
00263 
00264       inline const T& operator()(unsigned int i, unsigned int j) const {
00265          return fArray[Offsets()(i,j)];
00266       }
00267       inline T& operator()(unsigned int i, unsigned int j) {
00268          return fArray[Offsets()(i,j)];
00269       }
00270 
00271       inline T& operator[](unsigned int i) { 
00272          return fArray[Offsets().apply(i) ];
00273 //return fArray[Offsets()(i/D, i%D)];
00274       }
00275 
00276       inline const T& operator[](unsigned int i) const {
00277          return fArray[Offsets().apply(i) ];
00278 //return fArray[Offsets()(i/D, i%D)];
00279       }
00280 
00281       inline T apply(unsigned int i) const {
00282          return fArray[Offsets().apply(i) ];
00283          //return operator()(i/D, i%D);
00284       }
00285 
00286       inline T* Array() { return fArray; }  
00287 
00288       inline const T* Array() const { return fArray; }  
00289 
00290       /**
00291          assignment : only symmetric to symmetric allowed
00292        */
00293       template <class R>
00294       inline MatRepSym<T, D>& operator=(const R&) {
00295          STATIC_CHECK(0==1,
00296                       Cannot_assign_general_to_symmetric_matrix_representation);
00297          return *this;
00298       }
00299       inline MatRepSym<T, D>& operator=(const MatRepSym& rhs) {
00300          for(unsigned int i=0; i<kSize; ++i) fArray[i] = rhs.Array()[i];
00301          return *this;
00302       }
00303 
00304       /**
00305          self addition : only symmetric to symmetric allowed
00306        */
00307       template <class R>
00308       inline MatRepSym<T, D>& operator+=(const R&) {
00309          STATIC_CHECK(0==1,
00310                       Cannot_add_general_to_symmetric_matrix_representation);
00311          return *this;
00312       }
00313       inline MatRepSym<T, D>& operator+=(const MatRepSym& rhs) {
00314          for(unsigned int i=0; i<kSize; ++i) fArray[i] += rhs.Array()[i];
00315          return *this;
00316       }
00317 
00318       /**
00319          self subtraction : only symmetric to symmetric allowed
00320        */
00321       template <class R>
00322       inline MatRepSym<T, D>& operator-=(const R&) {
00323          STATIC_CHECK(0==1,
00324                       Cannot_substract_general_to_symmetric_matrix_representation);
00325          return *this;
00326       }
00327       inline MatRepSym<T, D>& operator-=(const MatRepSym& rhs) {
00328          for(unsigned int i=0; i<kSize; ++i) fArray[i] -= rhs.Array()[i];
00329          return *this;
00330       }
00331       template <class R> 
00332       inline bool operator==(const R& rhs) const {
00333          bool rc = true;
00334          for(unsigned int i=0; i<D*D; ++i) {
00335             rc = rc && (operator[](i) == rhs[i]);
00336          }
00337          return rc;
00338       }
00339       
00340       enum {
00341          /// return no. of matrix rows
00342          kRows = D,
00343          /// return no. of matrix columns
00344          kCols = D,
00345          /// return no of elements: rows*columns
00346          kSize = D*(D+1)/2
00347       };
00348 
00349       
00350       void CreateOffsets() {
00351          const static RowOffsets<D> off;
00352          fOff = &off;
00353       }
00354       
00355       inline const RowOffsets<D> & Offsets() const {
00356          return *fOff;
00357       }
00358 
00359    private:
00360       //T __attribute__ ((aligned (16))) fArray[kSize];
00361       T fArray[kSize];
00362 
00363       const RowOffsets<D> * fOff;   //! transient
00364 
00365    };
00366 
00367 
00368  
00369 } // namespace Math
00370 } // namespace ROOT
00371 
00372 
00373 #endif // MATH_MATRIXREPRESENTATIONSSTATIC_H

Generated on Tue Jul 5 14:25:35 2011 for ROOT_528-00b_version by  doxygen 1.5.1