// @(#)root/smatrix:$Name: $:$Id: MatrixRepresentationsStatic.h,v 1.9 2006/06/30 14:45:46 moneta Exp $
// Authors: L. Moneta, J. Palacios 2006
#ifndef ROOT_Math_MatrixRepresentationsStatic
#define ROOT_Math_MatrixRepresentationsStatic 1
// Include files
/**
@defgroup MatRep Matrix Storage Representation
@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 {
/**
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 T, unsigned int D1, unsigned int D2=D1>
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 <class R>
inline MatRepStd<T, D1, D2>& operator+=(const R& rhs) {
for(unsigned int i=0; i<kSize; ++i) fArray[i] += rhs[i];
return *this;
}
template <class R>
inline MatRepStd<T, D1, D2>& operator-=(const R& rhs) {
for(unsigned int i=0; i<kSize; ++i) fArray[i] -= rhs[i];
return *this;
}
template <class R>
inline MatRepStd<T, D1, D2>& operator=(const R& rhs) {
for(unsigned int i=0; i<kSize; ++i) fArray[i] = rhs[i];
return *this;
}
template <class R>
inline bool operator==(const R& rhs) const {
bool rc = true;
for(unsigned int i=0; i<D1*D1; ++i) {
rc = rc && (fArray[i] == rhs[i]);
}
return rc;
}
enum {
/// return no. of matrix rows
kRows = D1,
/// return no. of matrix columns
kCols = D2,
/// return no of elements: rows*columns
kSize = D1*D2
};
private:
T fArray[kSize];
};
// template<unigned int D>
// struct Creator {
// static const RowOffsets<D> & Offsets() {
// static RowOffsets<D> off;
// return off;
// }
/**
Static structure to keep the conversion from (i,j) to offsets in the storage data for a
symmetric matrix
*/
template<unsigned int D>
struct RowOffsets {
RowOffsets() {
int v[D];
v[0]=0;
for (unsigned int i=1; i<D; ++i)
v[i]=v[i-1]+i;
for (unsigned int i=0; i<D; ++i) {
for (unsigned int j=0; j<=i; ++j)
fOff[i*D+j] = v[i]+j;
for (unsigned int j=i+1; j<D; ++j)
fOff[i*D+j] = v[j]+i ;
}
}
int operator()(unsigned int i, unsigned int j) const { return fOff[i*D+j]; }
int apply(unsigned int i) const { return fOff[i]; }
int fOff[D*D];
};
/**
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 T, unsigned int D>
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) ];
}
inline const T& operator[](unsigned int i) const {
return fArray[Offsets().apply(i) ];
}
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 <class R>
inline MatRepSym<T, D>& operator=(const R& rhs) {
STATIC_CHECK(0==1,
Cannot_assign_general_to_symmetric_matrix_representation);
return *this;
}
inline MatRepSym<T, D>& operator=(const MatRepSym& rhs) {
for(unsigned int i=0; i<kSize; ++i) fArray[i] = rhs.Array()[i];
return *this;
}
/**
self addition : only symmetric to symmetric allowed
*/
template <class R>
inline MatRepSym<T, D>& operator+=(const R& rhs) {
STATIC_CHECK(0==1,
Cannot_add_general_to_symmetric_matrix_representation);
return *this;
}
inline MatRepSym<T, D>& operator+=(const MatRepSym& rhs) {
for(unsigned int i=0; i<kSize; ++i) fArray[i] += rhs.Array()[i];
return *this;
}
/**
self subtraction : only symmetric to symmetric allowed
*/
template <class R>
inline MatRepSym<T, D>& operator-=(const R& rhs) {
STATIC_CHECK(0==1,
Cannot_substract_general_to_symmetric_matrix_representation);
return *this;
}
inline MatRepSym<T, D>& operator-=(const MatRepSym& rhs) {
for(unsigned int i=0; i<kSize; ++i) fArray[i] -= rhs.Array()[i];
return *this;
}
template <class R>
inline bool operator==(const R& rhs) const {
bool rc = true;
for(unsigned int i=0; i<D*D; ++i) {
rc = rc && (operator[](i) == rhs[i]);
}
return rc;
}
enum {
/// return no. of matrix rows
kRows = D,
/// return no. of matrix columns
kCols = D,
/// return no of elements: rows*columns
kSize = D*(D+1)/2
};
void CreateOffsets() {
static RowOffsets<D> off;
fOff = &off;
}
inline const RowOffsets<D> & Offsets() const {
return *fOff;
}
private:
T fArray[kSize];
RowOffsets<D> * fOff; //! transient
};
} // namespace Math
} // namespace ROOT
#endif // MATH_MATRIXREPRESENTATIONSSTATIC_H
ROOT page - Class index - Class Hierarchy - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.