// @(#)root/matrix:$Id$ // Authors: Fons Rademakers, Eddy Offermann Feb 2004 /************************************************************************* * 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_TMatrixTSparse #define ROOT_TMatrixTSparse #include "TMatrixTBase.h" #include "TMatrixTUtils.h" #include #ifdef CBLAS #include //#include #endif ////////////////////////////////////////////////////////////////////////// // // // TMatrixTSparse // // // // Template class of a general sparse matrix in the Harwell-Boeing // // format // // // ////////////////////////////////////////////////////////////////////////// template class TMatrixT; template class TMatrixTSparse : public TMatrixTBase { protected: Int_t *fRowIndex; //[fNrowIndex] row index Int_t *fColIndex; //[fNelems] column index Element *fElements; //[fNelems] 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 = 0); // Elementary constructors void AMultB (const TMatrixTSparse &a,const TMatrixTSparse &b,Int_t constr=0) { const TMatrixTSparse bt(TMatrixTSparse::kTransposed,b); AMultBt(a,bt,constr); } void AMultB (const TMatrixTSparse &a,const TMatrixT &b,Int_t constr=0) { const TMatrixTSparse bsp = b; const TMatrixTSparse bt(TMatrixTSparse::kTransposed,bsp); AMultBt(a,bt,constr); } void AMultB (const TMatrixT &a,const TMatrixTSparse &b,Int_t constr=0) { const TMatrixTSparse bt(TMatrixTSparse::kTransposed,b); AMultBt(a,bt,constr); } void AMultBt(const TMatrixTSparse &a,const TMatrixTSparse &b,Int_t constr=0); void AMultBt(const TMatrixTSparse &a,const TMatrixT &b,Int_t constr=0); void AMultBt(const TMatrixT &a,const TMatrixTSparse &b,Int_t constr=0); void APlusB (const TMatrixTSparse &a,const TMatrixTSparse &b,Int_t constr=0); void APlusB (const TMatrixTSparse &a,const TMatrixT &b,Int_t constr=0); void APlusB (const TMatrixT &a,const TMatrixTSparse &b,Int_t constr=0) { APlusB(b,a,constr); } void AMinusB(const TMatrixTSparse &a,const TMatrixTSparse &b,Int_t constr=0); void AMinusB(const TMatrixTSparse &a,const TMatrixT &b,Int_t constr=0); void AMinusB(const TMatrixT &a,const TMatrixTSparse &b,Int_t constr=0); public: enum EMatrixCreatorsOp1 { kZero,kUnit,kTransposed,kAtA }; enum EMatrixCreatorsOp2 { kMult,kMultTranspose,kPlus,kMinus }; TMatrixTSparse() { fElements = nullptr; fRowIndex = nullptr; fColIndex = nullptr; } TMatrixTSparse(Int_t nrows,Int_t ncols); TMatrixTSparse(Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb); TMatrixTSparse(Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb,Int_t nr_nonzeros, Int_t *row, Int_t *col,Element *data); TMatrixTSparse(const TMatrixTSparse &another); TMatrixTSparse(const TMatrixT &another); TMatrixTSparse(EMatrixCreatorsOp1 op,const TMatrixTSparse &prototype); TMatrixTSparse(const TMatrixTSparse &a,EMatrixCreatorsOp2 op,const TMatrixTSparse &b); TMatrixTSparse(const TMatrixTSparse &a,EMatrixCreatorsOp2 op,const TMatrixT &b); TMatrixTSparse(const TMatrixT &a,EMatrixCreatorsOp2 op,const TMatrixTSparse &b); ~TMatrixTSparse() override { TMatrixTSparse::Clear(); } const Element *GetMatrixArray () const override; Element *GetMatrixArray () override; const Int_t *GetRowIndexArray() const override; Int_t *GetRowIndexArray() override; const Int_t *GetColIndexArray() const override; Int_t *GetColIndexArray() override; TMatrixTBase &SetRowIndexArray(Int_t *data) override { memmove(fRowIndex,data,(this->fNrows+1)*sizeof(Int_t)); return *this; } TMatrixTBase &SetColIndexArray(Int_t *data) override { memmove(fColIndex,data,this->fNelems*sizeof(Int_t)); return *this; } TMatrixTSparse &SetSparseIndex (Int_t nelem_new); TMatrixTSparse &SetSparseIndex (const TMatrixTBase &another); TMatrixTSparse &SetSparseIndexAB(const TMatrixTSparse &a,const TMatrixTSparse &b); TMatrixTSparse &SetSparseIndexAB(const TMatrixT &a,const TMatrixTSparse &b); TMatrixTSparse &SetSparseIndexAB(const TMatrixTSparse &a,const TMatrixT &b) { return SetSparseIndexAB(b,a); } void GetMatrix2Array (Element *data,Option_t * /*option*/ ="") const override; TMatrixTBase &SetMatrixArray (const Element *data,Option_t * /*option*/="") override { memcpy(fElements,data,this->fNelems*sizeof(Element)); return *this; } virtual TMatrixTBase &SetMatrixArray (Int_t nr_nonzeros,Int_t *irow,Int_t *icol,Element *data); TMatrixTBase &InsertRow (Int_t row,Int_t col,const Element *v,Int_t n=-1) override; void ExtractRow (Int_t row,Int_t col, Element *v,Int_t n=-1) const 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 TMatrixTSparse &m) {return ResizeTo(m.GetRowLwb(),m.GetRowUpb(),m.GetColLwb(), m.GetColUpb(),m.GetNoElements()); } void Clear(Option_t * /*option*/ ="") override { if (this->fIsOwner) { if (fElements) { delete [] fElements; fElements = nullptr; } if (fRowIndex) { delete [] fRowIndex; fRowIndex = nullptr; } if (fColIndex) { delete [] fColIndex; fColIndex = nullptr; } } this->fNelems = 0; this->fNrowIndex = 0; } TMatrixTSparse &Use (Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb,Int_t nr_nonzeros, Int_t *pRowIndex,Int_t *pColIndex,Element *pData); const TMatrixTSparse &Use (Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb,Int_t nr_nonzeros, const Int_t *pRowIndex,const Int_t *pColIndex,const Element *pData) const { return (const TMatrixTSparse&) ((const_cast *>(this))->Use(row_lwb,row_upb,col_lwb,col_upb,nr_nonzeros, const_cast(pRowIndex), const_cast(pColIndex), const_cast(pData))); } TMatrixTSparse &Use (Int_t nrows,Int_t ncols,Int_t nr_nonzeros, Int_t *pRowIndex,Int_t *pColIndex,Element *pData); const TMatrixTSparse &Use (Int_t nrows,Int_t ncols,Int_t nr_nonzeros, const Int_t *pRowIndex,const Int_t *pColIndex,const Element *pData) const; TMatrixTSparse &Use (TMatrixTSparse &a); const TMatrixTSparse &Use (const TMatrixTSparse &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; TMatrixTSparse 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; Bool_t IsSymmetric() const override { return (*this == TMatrixTSparse(kTransposed,*this)); } TMatrixTSparse &Transpose (const TMatrixTSparse &source); inline TMatrixTSparse &T () { return this->Transpose(*this); } inline void Mult(const TMatrixTSparse &a,const TMatrixTSparse &b) { AMultB(a,b,0); } TMatrixTBase &Zero () override; TMatrixTBase &UnitMatrix () override; Element RowNorm () const override; Element ColNorm () const override; Int_t NonZeros() const override { return this->fNelems; } TMatrixTBase &NormByDiag(const TVectorT &/*v*/,Option_t * /*option*/) override { MayNotUse("NormByDiag"); return *this; } // Either access a_ij as a(i,j) Element operator()(Int_t rown,Int_t coln) const override; Element &operator()(Int_t rown,Int_t coln) override; // or as a[i][j] inline const TMatrixTSparseRow_const operator[](Int_t rown) const { return TMatrixTSparseRow_const(*this,rown); } inline TMatrixTSparseRow operator[](Int_t rown) { return TMatrixTSparseRow (*this,rown); } TMatrixTSparse &operator=(const TMatrixT &source); TMatrixTSparse &operator=(const TMatrixTSparse &source); TMatrixTSparse &operator= (Element val); TMatrixTSparse &operator-=(Element val); TMatrixTSparse &operator+=(Element val); TMatrixTSparse &operator*=(Element val); TMatrixTSparse &operator+=(const TMatrixTSparse &source) { TMatrixTSparse tmp(*this); Clear(); if (this == &source) APlusB (tmp,tmp,1); else APlusB (tmp,source,1); return *this; } TMatrixTSparse &operator+=(const TMatrixT &source) { TMatrixTSparse tmp(*this); Clear(); APlusB(tmp,source,1); return *this; } TMatrixTSparse &operator-=(const TMatrixTSparse &source) { TMatrixTSparse tmp(*this); Clear(); if (this == &source) AMinusB (tmp,tmp,1); else AMinusB(tmp,source,1); return *this; } TMatrixTSparse &operator-=(const TMatrixT &source) { TMatrixTSparse tmp(*this); Clear(); AMinusB(tmp,source,1); return *this; } TMatrixTSparse &operator*=(const TMatrixTSparse &source) { TMatrixTSparse tmp(*this); Clear(); if (this == &source) AMultB (tmp,tmp,1); else AMultB (tmp,source,1); return *this; } TMatrixTSparse &operator*=(const TMatrixT &source) { TMatrixTSparse tmp(*this); Clear(); AMultB(tmp,source,1); return *this; } TMatrixTBase &Randomize (Element alpha,Element beta,Double_t &seed) override; virtual TMatrixTSparse &RandomizePD(Element alpha,Element beta,Double_t &seed); ClassDefOverride(TMatrixTSparse,3) // Template of Sparse 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 *TMatrixTSparse::Class(); #endif // __CINT__ template inline const Element *TMatrixTSparse::GetMatrixArray () const { return fElements; } template inline Element *TMatrixTSparse::GetMatrixArray () { return fElements; } template inline const Int_t *TMatrixTSparse::GetRowIndexArray() const { return fRowIndex; } template inline Int_t *TMatrixTSparse::GetRowIndexArray() { return fRowIndex; } template inline const Int_t *TMatrixTSparse::GetColIndexArray() const { return fColIndex; } template inline Int_t *TMatrixTSparse::GetColIndexArray() { return fColIndex; } template inline TMatrixTSparse &TMatrixTSparse::Use (Int_t nrows,Int_t ncols,Int_t nr_nonzeros, Int_t *pRowIndex,Int_t *pColIndex,Element *pData) { return Use(0,nrows-1,0,ncols-1,nr_nonzeros,pRowIndex,pColIndex,pData); } template inline const TMatrixTSparse &TMatrixTSparse::Use (Int_t nrows,Int_t ncols,Int_t nr_nonzeros, const Int_t *pRowIndex,const Int_t *pColIndex,const Element *pData) const { return Use(0,nrows-1,0,ncols-1,nr_nonzeros,pRowIndex,pColIndex,pData); } template inline TMatrixTSparse &TMatrixTSparse::Use (TMatrixTSparse &a) { R__ASSERT(a.IsValid()); return Use(a.GetRowLwb(),a.GetRowUpb(),a.GetColLwb(),a.GetColUpb(), a.GetNoElements(),a.GetRowIndexArray(), a.GetColIndexArray(),a.GetMatrixArray()); } template inline const TMatrixTSparse &TMatrixTSparse::Use (const TMatrixTSparse &a) const { R__ASSERT(a.IsValid()); return Use(a.GetRowLwb(),a.GetRowUpb(),a.GetColLwb(),a.GetColUpb(), a.GetNoElements(),a.GetRowIndexArray(), a.GetColIndexArray(),a.GetMatrixArray()); } template inline TMatrixTSparse TMatrixTSparse::GetSub(Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb, Option_t *option) const { TMatrixTSparse tmp; this->GetSub(row_lwb,row_upb,col_lwb,col_upb,tmp,option); return tmp; } template TMatrixTSparse operator+ (const TMatrixTSparse &source1,const TMatrixTSparse &source2); template TMatrixTSparse operator+ (const TMatrixTSparse &source1,const TMatrixT &source2); template TMatrixTSparse operator+ (const TMatrixT &source1,const TMatrixTSparse &source2); template TMatrixTSparse operator+ (const TMatrixTSparse &source , Element val ); template TMatrixTSparse operator+ ( Element val ,const TMatrixTSparse &source ); template TMatrixTSparse operator- (const TMatrixTSparse &source1,const TMatrixTSparse &source2); template TMatrixTSparse operator- (const TMatrixTSparse &source1,const TMatrixT &source2); template TMatrixTSparse operator- (const TMatrixT &source1,const TMatrixTSparse &source2); template TMatrixTSparse operator- (const TMatrixTSparse &source , Element val ); template TMatrixTSparse operator- ( Element val ,const TMatrixTSparse &source ); template TMatrixTSparse operator* (const TMatrixTSparse &source1,const TMatrixTSparse &source2); template TMatrixTSparse operator* (const TMatrixTSparse &source1,const TMatrixT &source2); template TMatrixTSparse operator* (const TMatrixT &source1,const TMatrixTSparse &source2); template TMatrixTSparse operator* ( Element val ,const TMatrixTSparse &source ); template TMatrixTSparse operator* (const TMatrixTSparse &source, Element val ); template TMatrixTSparse &Add (TMatrixTSparse &target, Element scalar, const TMatrixTSparse &source); template TMatrixTSparse &ElementMult(TMatrixTSparse &target,const TMatrixTSparse &source); template TMatrixTSparse &ElementDiv (TMatrixTSparse &target,const TMatrixTSparse &source); template Bool_t AreCompatible(const TMatrixTSparse &m1,const TMatrixTSparse &m2,Int_t verbose=0); #endif