// @(#)root/matrix:$Id$ // Authors: Fons Rademakers, Eddy Offermann Nov 2003 /************************************************************************* * 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_TMatrixT #define ROOT_TMatrixT ////////////////////////////////////////////////////////////////////////// // // // TMatrixT // // // // Template class of a general matrix in the linear algebra package // // // ////////////////////////////////////////////////////////////////////////// #include "TMatrixTBase.h" #include "TMatrixTUtils.h" #ifdef CBLAS #include //#include #endif #include "Rtypes.h" #include "TError.h" template class TMatrixTSym; template class TMatrixTSparse; template class TMatrixTLazy; template class TMatrixT : public TMatrixTBase { protected: Element fDataStack[TMatrixTBase::kSizeMax]; //! data container Element *fElements; //[fNelems] elements themselves Element *New_m (Int_t size); void Delete_m(Int_t size,Element*&); Int_t Memcpy_m(Element *newp,const Element *oldp,Int_t copySize, Int_t newSize,Int_t oldSize); void Allocate(Int_t nrows,Int_t ncols,Int_t row_lwb = 0,Int_t col_lwb = 0,Int_t init = 0, Int_t /*nr_nonzeros*/ = -1); public: enum {kWorkMax = 100}; enum EMatrixCreatorsOp1 { kZero,kUnit,kTransposed,kInverted,kAtA }; enum EMatrixCreatorsOp2 { kMult,kTransposeMult,kInvMult,kMultTranspose,kPlus,kMinus }; TMatrixT(): fDataStack(), fElements(nullptr) { } TMatrixT(Int_t nrows,Int_t ncols); TMatrixT(Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb); TMatrixT(Int_t nrows,Int_t ncols,const Element *data,Option_t *option=""); TMatrixT(Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb,const Element *data,Option_t *option=""); TMatrixT(const TMatrixT &another); TMatrixT(const TMatrixTSym &another); TMatrixT(const TMatrixTSparse &another); template TMatrixT(const TMatrixT &another): fElements(nullptr) { R__ASSERT(another.IsValid()); Allocate(another.GetNrows(),another.GetNcols(),another.GetRowLwb(),another.GetColLwb()); *this = another; } TMatrixT(EMatrixCreatorsOp1 op,const TMatrixT &prototype); TMatrixT(const TMatrixT &a,EMatrixCreatorsOp2 op,const TMatrixT &b); TMatrixT(const TMatrixT &a,EMatrixCreatorsOp2 op,const TMatrixTSym &b); TMatrixT(const TMatrixTSym &a,EMatrixCreatorsOp2 op,const TMatrixT &b); TMatrixT(const TMatrixTSym &a,EMatrixCreatorsOp2 op,const TMatrixTSym &b); TMatrixT(const TMatrixTLazy &lazy_constructor); ~TMatrixT() override { TMatrixT::Clear(); } // Elementary constructors void Plus (const TMatrixT &a,const TMatrixT &b); void Plus (const TMatrixT &a,const TMatrixTSym &b); void Plus (const TMatrixTSym &a,const TMatrixT &b) { Plus(b,a); } void Minus(const TMatrixT &a,const TMatrixT &b); void Minus(const TMatrixT &a,const TMatrixTSym &b); void Minus(const TMatrixTSym &a,const TMatrixT &b) { Minus(b,a); } void Mult (const TMatrixT &a,const TMatrixT &b); void Mult (const TMatrixT &a,const TMatrixTSym &b); void Mult (const TMatrixTSym &a,const TMatrixT &b); void Mult (const TMatrixTSym &a,const TMatrixTSym &b); void TMult(const TMatrixT &a,const TMatrixT &b); void TMult(const TMatrixT &a,const TMatrixTSym &b); void TMult(const TMatrixTSym &a,const TMatrixT &b) { Mult(a,b); } void TMult(const TMatrixTSym &a,const TMatrixTSym &b) { Mult(a,b); } void MultT(const TMatrixT &a,const TMatrixT &b); void MultT(const TMatrixT &a,const TMatrixTSym &b) { Mult(a,b); } void MultT(const TMatrixTSym &a,const TMatrixT &b); void MultT(const TMatrixTSym &a,const TMatrixTSym &b) { Mult(a,b); } const Element *GetMatrixArray () const override; Element *GetMatrixArray () override; const Int_t *GetRowIndexArray() const override { return nullptr; } Int_t *GetRowIndexArray() override { return nullptr; } const Int_t *GetColIndexArray() const override { return nullptr; } Int_t *GetColIndexArray() override { return nullptr; } TMatrixTBase &SetRowIndexArray(Int_t * /*data*/) override { MayNotUse("SetRowIndexArray(Int_t *)"); return *this; } TMatrixTBase &SetColIndexArray(Int_t * /*data*/) override { MayNotUse("SetColIndexArray(Int_t *)"); return *this; } void Clear(Option_t * /*option*/ ="") override { if (this->fIsOwner) Delete_m(this->fNelems, fElements); else fElements = nullptr; this->fNelems = 0; } TMatrixT &Use (Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb,Element *data); const TMatrixT &Use (Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb,const Element *data) const { return (const TMatrixT&) ((const_cast *>(this))->Use(row_lwb,row_upb,col_lwb,col_upb, const_cast(data))); } TMatrixT &Use (Int_t nrows,Int_t ncols,Element *data); const TMatrixT &Use (Int_t nrows,Int_t ncols,const Element *data) const; TMatrixT &Use (TMatrixT &a); const TMatrixT &Use (const TMatrixT &a) const; TMatrixTBase &GetSub (Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb, TMatrixTBase &target,Option_t *option="S") const override; TMatrixT GetSub (Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb,Option_t *option="S") const; TMatrixTBase &SetSub (Int_t row_lwb,Int_t col_lwb,const TMatrixTBase &source) override; TMatrixTBase &ResizeTo(Int_t nrows,Int_t ncols,Int_t /*nr_nonzeros*/ =-1) override; TMatrixTBase &ResizeTo(Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb,Int_t /*nr_nonzeros*/ =-1) override; inline TMatrixTBase &ResizeTo(const TMatrixT &m) { return ResizeTo(m.GetRowLwb(),m.GetRowUpb(),m.GetColLwb(),m.GetColUpb()); } Double_t Determinant () const override; void Determinant (Double_t &d1,Double_t &d2) const override; TMatrixT &Invert (Double_t *det = nullptr); TMatrixT &InvertFast (Double_t *det = nullptr); TMatrixT &Transpose (const TMatrixT &source); inline TMatrixT &T () { return this->Transpose(*this); } TMatrixT &Rank1Update (const TVectorT &v,Element alpha=1.0); TMatrixT &Rank1Update (const TVectorT &v1,const TVectorT &v2,Element alpha=1.0); Element Similarity (const TVectorT &v) const; TMatrixT &NormByColumn(const TVectorT &v,Option_t *option="D"); TMatrixT &NormByRow (const TVectorT &v,Option_t *option="D"); // Either access a_ij as a(i,j) inline Element operator()(Int_t rown,Int_t coln) const override; inline Element &operator()(Int_t rown,Int_t coln) override; // or as a[i][j] inline const TMatrixTRow_const operator[](Int_t rown) const { return TMatrixTRow_const(*this,rown); } inline TMatrixTRow operator[](Int_t rown) { return TMatrixTRow (*this,rown); } TMatrixT &operator= (const TMatrixT &source); TMatrixT &operator= (const TMatrixTSym &source); TMatrixT &operator= (const TMatrixTSparse &source); TMatrixT &operator= (const TMatrixTLazy &source); template TMatrixT &operator= (const TMatrixT &source) { if (!AreCompatible(*this,source)) { Error("operator=(const TMatrixT2 &)","matrices not compatible"); return *this; } TObject::operator=(source); const Element2 * const ps = source.GetMatrixArray(); Element * const pt = this->GetMatrixArray(); for (Int_t i = 0; i < this->fNelems; i++) pt[i] = ps[i]; this->fTol = source.GetTol(); return *this; } TMatrixT &operator= (Element val); TMatrixT &operator-=(Element val); TMatrixT &operator+=(Element val); TMatrixT &operator*=(Element val); TMatrixT &operator+=(const TMatrixT &source); TMatrixT &operator+=(const TMatrixTSym &source); TMatrixT &operator-=(const TMatrixT &source); TMatrixT &operator-=(const TMatrixTSym &source); TMatrixT &operator*=(const TMatrixT &source); TMatrixT &operator*=(const TMatrixTSym &source); TMatrixT &operator*=(const TMatrixTDiag_const &diag); TMatrixT &operator/=(const TMatrixTDiag_const &diag); TMatrixT &operator*=(const TMatrixTRow_const &row); TMatrixT &operator/=(const TMatrixTRow_const &row); TMatrixT &operator*=(const TMatrixTColumn_const &col); TMatrixT &operator/=(const TMatrixTColumn_const &col); const TMatrixT EigenVectors(TVectorT &eigenValues) const; ClassDefOverride(TMatrixT,4) // Template of General Matrix class }; #ifndef __CINT__ // When building with -fmodules, it instantiates all pending instantiations, // instead of delaying them until the end of the translation unit. // We 'got away with' probably because the use and the definition of the // explicit specialization do not occur in the same TU. // // In case we are building with -fmodules, we need to forward declare the // specialization in order to compile the dictionary G__Matrix.cxx. template <> TClass *TMatrixT::Class(); #endif // __CINT__ template inline const Element *TMatrixT::GetMatrixArray() const { return fElements; } template inline Element *TMatrixT::GetMatrixArray() { return fElements; } template inline TMatrixT &TMatrixT::Use (Int_t nrows,Int_t ncols,Element *data) { return Use(0,nrows-1,0,ncols-1,data); } template inline const TMatrixT &TMatrixT::Use (Int_t nrows,Int_t ncols,const Element *data) const { return Use(0,nrows-1,0,ncols-1,data); } template inline TMatrixT &TMatrixT::Use (TMatrixT &a) { R__ASSERT(a.IsValid()); return Use(a.GetRowLwb(),a.GetRowUpb(), a.GetColLwb(),a.GetColUpb(),a.GetMatrixArray()); } template inline const TMatrixT &TMatrixT::Use (const TMatrixT &a) const { R__ASSERT(a.IsValid()); return Use(a.GetRowLwb(),a.GetRowUpb(), a.GetColLwb(),a.GetColUpb(),a.GetMatrixArray()); } template inline TMatrixT TMatrixT::GetSub (Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb, Option_t *option) const { TMatrixT tmp; this->GetSub(row_lwb,row_upb,col_lwb,col_upb,tmp,option); return tmp; } template inline Element TMatrixT::operator()(Int_t rown,Int_t coln) const { R__ASSERT(this->IsValid()); const Int_t arown = rown-this->fRowLwb; const Int_t acoln = coln-this->fColLwb; if (arown >= this->fNrows || arown < 0) { Error("operator()","Request row(%d) outside matrix range of %d - %d",rown,this->fRowLwb,this->fRowLwb+this->fNrows); return TMatrixTBase::NaNValue(); } if (acoln >= this->fNcols || acoln < 0) { Error("operator()","Request column(%d) outside matrix range of %d - %d",coln,this->fColLwb,this->fColLwb+this->fNcols); return TMatrixTBase::NaNValue(); } return (fElements[arown*this->fNcols+acoln]); } template inline Element &TMatrixT::operator()(Int_t rown,Int_t coln) { R__ASSERT(this->IsValid()); const Int_t arown = rown-this->fRowLwb; const Int_t acoln = coln-this->fColLwb; if (arown >= this->fNrows || arown < 0) { Error("operator()","Request row(%d) outside matrix range of %d - %d",rown,this->fRowLwb,this->fRowLwb+this->fNrows); return TMatrixTBase::NaNValue(); } if (acoln >= this->fNcols || acoln < 0) { Error("operator()","Request column(%d) outside matrix range of %d - %d",coln,this->fColLwb,this->fColLwb+this->fNcols); return TMatrixTBase::NaNValue(); } return (fElements[arown*this->fNcols+acoln]); } inline namespace TMatrixTAutoloadOps { template TMatrixT operator+ (const TMatrixT &source1,const TMatrixT &source2); template TMatrixT operator+ (const TMatrixT &source1,const TMatrixTSym &source2); template TMatrixT operator+ (const TMatrixTSym &source1,const TMatrixT &source2); template TMatrixT operator+ (const TMatrixT &source , Element val ); template TMatrixT operator+ ( Element val ,const TMatrixT &source ); template TMatrixT operator- (const TMatrixT &source1,const TMatrixT &source2); template TMatrixT operator- (const TMatrixT &source1,const TMatrixTSym &source2); template TMatrixT operator- (const TMatrixTSym &source1,const TMatrixT &source2); template TMatrixT operator- (const TMatrixT &source , Element val ); template TMatrixT operator- ( Element val ,const TMatrixT &source ); template TMatrixT operator* ( Element val ,const TMatrixT &source ); template TMatrixT operator* (const TMatrixT &source , Element val ); template TMatrixT operator* (const TMatrixT &source1,const TMatrixT &source2); template TMatrixT operator* (const TMatrixT &source1,const TMatrixTSym &source2); template TMatrixT operator* (const TMatrixTSym &source1,const TMatrixT &source2); template TMatrixT operator* (const TMatrixTSym &source1,const TMatrixTSym &source2); // Preventing warnings with -Weffc++ in GCC since overloading the || and && operators was a design choice. #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 40600 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Weffc++" #endif template TMatrixT operator&& (const TMatrixT &source1,const TMatrixT &source2); template TMatrixT operator&& (const TMatrixT &source1,const TMatrixTSym &source2); template TMatrixT operator&& (const TMatrixTSym &source1,const TMatrixT &source2); template TMatrixT operator|| (const TMatrixT &source1,const TMatrixT &source2); template TMatrixT operator|| (const TMatrixT &source1,const TMatrixTSym &source2); template TMatrixT operator|| (const TMatrixTSym &source1,const TMatrixT &source2); #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 40600 #pragma GCC diagnostic pop #endif template TMatrixT operator> (const TMatrixT &source1,const TMatrixT &source2); template TMatrixT operator> (const TMatrixT &source1,const TMatrixTSym &source2); template TMatrixT operator> (const TMatrixTSym &source1,const TMatrixT &source2); template TMatrixT operator>= (const TMatrixT &source1,const TMatrixT &source2); template TMatrixT operator>= (const TMatrixT &source1,const TMatrixTSym &source2); template TMatrixT operator>= (const TMatrixTSym &source1,const TMatrixT &source2); template TMatrixT operator<= (const TMatrixT &source1,const TMatrixT &source2); template TMatrixT operator<= (const TMatrixT &source1,const TMatrixTSym &source2); template TMatrixT operator<= (const TMatrixTSym &source1,const TMatrixT &source2); template TMatrixT operator< (const TMatrixT &source1,const TMatrixT &source2); template TMatrixT operator< (const TMatrixT &source1,const TMatrixTSym &source2); template TMatrixT operator< (const TMatrixTSym &source1,const TMatrixT &source2); template TMatrixT operator!= (const TMatrixT &source1,const TMatrixT &source2); template TMatrixT operator!= (const TMatrixT &source1,const TMatrixTSym &source2); template TMatrixT operator!= (const TMatrixTSym &source1,const TMatrixT &source2); template TMatrixT &Add (TMatrixT &target, Element scalar,const TMatrixT &source); template TMatrixT &Add (TMatrixT &target, Element scalar,const TMatrixTSym &source); template TMatrixT &ElementMult(TMatrixT &target,const TMatrixT &source); template TMatrixT &ElementMult(TMatrixT &target,const TMatrixTSym &source); template TMatrixT &ElementDiv (TMatrixT &target,const TMatrixT &source); template TMatrixT &ElementDiv (TMatrixT &target,const TMatrixTSym &source); template void AMultB (const Element * const ap,Int_t na,Int_t ncolsa, const Element * const bp,Int_t nb,Int_t ncolsb,Element *cp); template void AtMultB(const Element * const ap,Int_t ncolsa, const Element * const bp,Int_t nb,Int_t ncolsb,Element *cp); template void AMultBt(const Element * const ap,Int_t na,Int_t ncolsa, const Element * const bp,Int_t nb,Int_t ncolsb,Element *cp); } // inline namespace TMatrixTAutoloadOps #endif