// @(#)root/matrix:$Name: $:$Id: TMatrixUtils.h,v 1.18 2002/12/10 14:00:48 brun Exp $ // Author: Fons Rademakers 05/11/97 /************************************************************************* * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. * * All rights reserved. * * * * For the licensing terms see $ROOTSYS/LICENSE. * * For the list of contributors see $ROOTSYS/README/CREDITS. * *************************************************************************/ #ifndef ROOT_TMatrixUtils #define ROOT_TMatrixUtils ////////////////////////////////////////////////////////////////////////// // // // Matrix utility classes. // // // // This file defines utility classes for the Linear Algebra Package. // // The following classes are defined here: // // TElementAction // // TElementPosAction // // TLazyMatrix // // THaarMatrix // // THilbertMatrix // // TMatrixRow // // TMatrixColumn // // TMatrixDiag // // TMatrixFlat // // TMatrixPivoting // // // ////////////////////////////////////////////////////////////////////////// #ifndef ROOT_TMatrix #include "TMatrix.h" #endif ////////////////////////////////////////////////////////////////////////// // // // TElementAction // // // // A class to do a specific operation on every vector or matrix element // // (regardless of it position) as the object is being traversed. // // This is an abstract class. Derived classes need to implement the // // action function Operation(). // // // ////////////////////////////////////////////////////////////////////////// class TElementAction { friend class TMatrix; friend class TVector; private: virtual void Operation(Real_t &element) const = 0; void operator=(const TElementAction &) { } }; ////////////////////////////////////////////////////////////////////////// // // // TElementPosAction // // // // A class to do a specific operation on every vector or matrix element // // as the object is being traversed. This is an abstract class. // // Derived classes need to implement the action function Operation(). // // In the action function the location of the current element is // // known (fI=row, fJ=columns). // // // ////////////////////////////////////////////////////////////////////////// class TElementPosAction { friend class TMatrix; friend class TVector; protected: mutable Int_t fI; // i position of element being passed to Operation() mutable Int_t fJ; // j position of element being passed to Operation() private: virtual void Operation(Real_t &element) const = 0; void operator=(const TElementPosAction &) { } }; ////////////////////////////////////////////////////////////////////////// // // // TLazyMatrix // // // // Class used to make a lazy copy of a matrix, i.e. only copy matrix // // when really needed (when accessed). // // // ////////////////////////////////////////////////////////////////////////// class TLazyMatrix : public TObject { friend class TMatrix; protected: Int_t fRowUpb; Int_t fRowLwb; Int_t fColUpb; Int_t fColLwb; TLazyMatrix(const TLazyMatrix &) : TObject() { } void operator=(const TLazyMatrix &) { } private: virtual void FillIn(TMatrix &m) const = 0; public: TLazyMatrix() { fRowUpb = fRowLwb = fColUpb = fColLwb = 0; } TLazyMatrix(Int_t nrows, Int_t ncols) : fRowUpb(nrows-1), fRowLwb(0), fColUpb(ncols-1), fColLwb(0) { } TLazyMatrix(Int_t row_lwb, Int_t row_upb, Int_t col_lwb, Int_t col_upb) : fRowUpb(row_upb), fRowLwb(row_lwb), fColUpb(col_upb), fColLwb(col_lwb) { } ClassDef(TLazyMatrix,1) // Lazy matrix }; class THaarMatrix : public TLazyMatrix { private: void FillIn(TMatrix &m) const; public: THaarMatrix(Int_t n, Int_t no_cols = 0); ClassDef(THaarMatrix,1) // Haar matrix }; class THilbertMatrix : public TLazyMatrix { private: void FillIn(TMatrix &m) const; public: THilbertMatrix(Int_t no_rows, Int_t no_cols); THilbertMatrix(Int_t row_lwb, Int_t row_upb, Int_t col_lwb, Int_t col_upb); ClassDef(THilbertMatrix,1) // Hilbert matrix }; ////////////////////////////////////////////////////////////////////////// // // // TMatrixRow // // // // Class represents a row of a TMatrix. // // // ////////////////////////////////////////////////////////////////////////// class TMatrixRow : public TObject { friend class TMatrix; friend class TVector; private: const TMatrix *fMatrix; //! the matrix I am a row of Int_t fRowInd; // effective row index Int_t fInc; // if ptr = @a[row,i], then ptr+inc = @a[row,i+1] Real_t *fPtr; //! pointer to the a[row,0] TMatrixRow() { fMatrix = 0; fInc = 0; fPtr = 0; } public: TMatrixRow(const TMatrix &matrix, Int_t row); void operator=(Real_t val); void operator+=(const TMatrixRow &r); void operator*=(const TMatrixRow &r); void operator+=(Real_t val); void operator*=(Real_t val); void operator=(const TMatrixRow &r); void operator=(const TVector &vec); const Real_t &operator()(Int_t i) const; Real_t &operator()(Int_t i); const Real_t &operator[](Int_t i) const; Real_t &operator[](Int_t i); ClassDef(TMatrixRow,1) // One row of a matrix }; ////////////////////////////////////////////////////////////////////////// // // // TMatrixColumn // // // // Class represents a column of a TMatrix. // // // ////////////////////////////////////////////////////////////////////////// class TMatrixColumn : public TObject { friend class TMatrix; friend class TVector; private: const TMatrix *fMatrix; //! the matrix I am a column of Int_t fColInd; // effective column index Real_t *fPtr; //! pointer to the a[0,i] column TMatrixColumn() { fMatrix = 0; fPtr = 0; } public: TMatrixColumn(const TMatrix &matrix, Int_t col); void operator=(Real_t val); void operator+=(const TMatrixColumn &c); void operator*=(const TMatrixColumn &c); void operator+=(Real_t val); void operator*=(Real_t val); void operator=(const TMatrixColumn &c); void operator=(const TVector &vec); const Real_t &operator()(Int_t i) const; Real_t &operator()(Int_t i); const Real_t &operator[](Int_t i) const; Real_t &operator[](Int_t i); ClassDef(TMatrixColumn,1) // One column of a matrix }; ////////////////////////////////////////////////////////////////////////// // // // TMatrixDiag // // // // Class represents the diagonal of a matrix (for easy manipulation). // // // ////////////////////////////////////////////////////////////////////////// class TMatrixDiag : public TObject { friend class TMatrix; friend class TVector; private: const TMatrix *fMatrix; //! the matrix I am the diagonal of Int_t fInc; // if ptr=@a[i,i], then ptr+inc = @a[i+1,i+1] Int_t fNdiag; // number of diag elems, min(nrows,ncols) Real_t *fPtr; //! pointer to the a[0,0] TMatrixDiag() { fMatrix = 0; fInc = 0; fNdiag = 0; fPtr = 0; } public: TMatrixDiag(const TMatrix &matrix); void operator=(Real_t val); void operator+=(const TMatrixDiag &d); void operator*=(const TMatrixDiag &d); void operator+=(Real_t val); void operator*=(Real_t val); void operator=(const TMatrixDiag &d); void operator=(const TVector &vec); const Real_t &operator()(Int_t i) const; Real_t &operator()(Int_t i); const Real_t &operator[](Int_t i) const; Real_t &operator[](Int_t i); Int_t GetNdiags() const { return fNdiag; } ClassDef(TMatrixDiag,1) // Diagonal of a matrix }; ////////////////////////////////////////////////////////////////////////// // // // TMatrixFlat // // // // Class represents a flat matrix (for easy manipulation). // // // ////////////////////////////////////////////////////////////////////////// class TMatrixFlat : public TObject { friend class TMatrix; friend class TVector; private: const TMatrix *fMatrix; //! the matrix I am the diagonal of Real_t *fPtr; //! pointer to the a[0,0] TMatrixFlat() { fMatrix = 0; fPtr = 0; } public: TMatrixFlat(const TMatrix &matrix); void operator=(Real_t val); void operator+=(const TMatrixFlat &d); void operator*=(const TMatrixFlat &d); void operator+=(Real_t val); void operator*=(Real_t val); void operator=(const TMatrixFlat &d); void operator=(const TVector &vec); const Real_t &operator()(Int_t i) const; Real_t &operator()(Int_t i); const Real_t &operator[](Int_t i) const; Real_t &operator[](Int_t i); ClassDef(TMatrixFlat,1) // Flat representation of a matrix }; ////////////////////////////////////////////////////////////////////////// // // // TMatrixPivoting // // // // This class inherits from TMatrix and it keeps additional information // // about what is being/has been pivoted. // // // ////////////////////////////////////////////////////////////////////////// class TMatrixPivoting : public TMatrix { private: typedef Real_t* Index_t; // wanted to have typeof(index[0]) Index_t *const fRowIndex; // fRowIndex[i] = ptr to the i-th // matrix row, or 0 if the row // has been pivoted. Note, // pivoted columns are marked // by setting fIndex[j] to zero. // Information about the pivot that was // just picked up Double_t fPivotValue; // Value of the pivoting element Index_t fPivotRow; // pivot's location (ptrs) Index_t fPivotCol; Int_t fPivotOdd; // parity of the pivot // (0 for even, 1 for odd) void PickUpPivot(); // Pick up a pivot from // not-pivoted rows and cols public: TMatrixPivoting(const TMatrix &m); ~TMatrixPivoting(); Double_t PivotingAndElimination(); // Perform the pivoting, return // the pivot value times (-1)^(pi+pj) // (pi,pj - pivot el row & col) }; //----- inlines ---------------------------------------------------------------- #ifndef __CINT__ inline TMatrixRow::TMatrixRow(const TMatrix &matrix, Int_t row) : fMatrix(&matrix), fInc(matrix.fNrows) { if (!matrix.IsValid()) { Error("TMatrixRow", "matrix is not initialized"); return; } fRowInd = row - matrix.fRowLwb; if (fRowInd >= matrix.fNrows || fRowInd < 0) { Error("TMatrixRow", "row #%d is not within the matrix", row); return; } fPtr = &(matrix.fIndex[0][fRowInd]); } inline void TMatrixRow::operator=(const TMatrixRow &mr) { if (fMatrix != mr.fMatrix && AreCompatible(*fMatrix,*mr.fMatrix)) { Real_t *rp1 = fPtr; Real_t *rp2 = mr.fPtr; for ( ; rp1 < fPtr + fMatrix->fNelems; rp1 += fInc,rp2 += fInc) *rp1 = *rp2; } } inline Real_t &TMatrixRow::operator()(Int_t i) { return (Real_t&)((*(const TMatrixRow *)this)(i)); } inline const Real_t &TMatrixRow::operator[](Int_t i) const { return (Real_t&)((*(const TMatrixRow *)this)(i)); } inline Real_t &TMatrixRow::operator[](Int_t i) { return (Real_t&)((*(const TMatrixRow *)this)(i)); } inline TMatrixColumn::TMatrixColumn(const TMatrix &matrix, Int_t col) : fMatrix(&matrix) { if (!matrix.IsValid()) { Error("TMatrixColumn", "matrix is not initialized"); return; } fColInd = col - matrix.fColLwb; if (fColInd >= matrix.fNcols || fColInd < 0) { Error("TMatrixColumn", "column #%d is not within the matrix", col); return; } fPtr = &(matrix.fIndex[fColInd][0]); } inline void TMatrixColumn::operator=(const TMatrixColumn &mc) { if (fMatrix != mc.fMatrix && AreCompatible(*fMatrix,*mc.fMatrix)) { Real_t *cp1 = fPtr; Real_t *cp2 = mc.fPtr; while (cp1 < fPtr + fMatrix->fNrows) *cp1++ = *cp2++; } } inline Real_t &TMatrixColumn::operator()(Int_t i) { return (Real_t&)((*(const TMatrixColumn *)this)(i)); } inline const Real_t &TMatrixColumn::operator[](Int_t i) const { return (Real_t&)((*(const TMatrixColumn *)this)(i)); } inline Real_t &TMatrixColumn::operator[](Int_t i) { return (Real_t&)((*(const TMatrixColumn *)this)(i)); } inline TMatrixDiag::TMatrixDiag(const TMatrix &matrix) : fMatrix(&matrix), fInc(matrix.fNrows+1), fNdiag(TMath::Min(matrix.fNrows, matrix.fNcols)) { if (!matrix.IsValid()) { Error("TMatrixDiag", "matrix is not initialized"); return; } fPtr = &(matrix.fElements[0]); } inline void TMatrixDiag::operator=(const TMatrixDiag &md) { if (fMatrix != md.fMatrix && AreCompatible(*fMatrix,*md.fMatrix)) { Real_t *dp1 = fPtr; Real_t *dp2 = md.fPtr; Int_t i; for (i = 0; i < fNdiag; i++, dp1 += fInc, dp2 += fInc) *dp1 = *dp2; } } inline Real_t &TMatrixDiag::operator()(Int_t i) { return (Real_t&)((*(const TMatrixDiag *)this)(i)); } inline const Real_t &TMatrixDiag::operator[](Int_t i) const { return (Real_t&)((*(const TMatrixDiag *)this)(i)); } inline Real_t &TMatrixDiag::operator[](Int_t i) { return (Real_t&)((*(const TMatrixDiag *)this)(i)); } inline TMatrixFlat::TMatrixFlat(const TMatrix &matrix) : fMatrix(&matrix) { if (!matrix.IsValid()) { Error("TMatrixFlat", "matrix is not initialized"); return; } fPtr = &(matrix.fElements[0]); } inline void TMatrixFlat::operator=(const TMatrixFlat &mf) { if (fMatrix != mf.fMatrix && AreCompatible(*fMatrix,*mf.fMatrix)) { Real_t *fp1 = fPtr; Real_t *fp2 = mf.fPtr; while (fp1 < fPtr+mf.fMatrix->fNelems) *fp1++ = *fp2++; } } inline Real_t &TMatrixFlat::operator()(Int_t i) { return (Real_t&)((*(const TMatrixFlat *)this)(i)); } inline const Real_t &TMatrixFlat::operator[](Int_t i) const { return (Real_t&)((*(const TMatrixFlat *)this)(i)); } inline Real_t &TMatrixFlat::operator[](Int_t i) { return (Real_t&)((*(const TMatrixFlat *)this)(i)); } #endif #endif