// @(#)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_TVectorT #define ROOT_TVectorT ////////////////////////////////////////////////////////////////////////// // // // TVectorT // // // // Template class of Vectors in the linear algebra package // // // ////////////////////////////////////////////////////////////////////////// #include "TMatrixT.h" #include "TMatrixTSym.h" #include "TMatrixTSparse.h" template class TVectorT : public TObject { protected: Int_t fNrows{0}; // number of rows Int_t fRowLwb{0}; // lower bound of the row index Element *fElements{nullptr}; //[fNrows] elements themselves enum {kSizeMax = 5}; // size data container on stack, see New_m(),Delete_m() enum {kWorkMax = 100}; // size of work array's in several routines Element fDataStack[kSizeMax]; //! data container Bool_t fIsOwner{kTRUE}; //!default kTRUE, when Use array kFALSE 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 row_lwb = 0,Int_t init = 0); enum EVectorStatusBits { kStatus = BIT(14) // set if vector object is valid }; public: TVectorT() : fNrows(0), fRowLwb(0), fElements(nullptr), fDataStack (), fIsOwner(kTRUE) { } explicit TVectorT(Int_t n); TVectorT(Int_t lwb,Int_t upb); TVectorT(Int_t n,const Element *elements); TVectorT(Int_t lwb,Int_t upb,const Element *elements); TVectorT(const TVectorT &another); TVectorT(const TMatrixTRow_const &mr); TVectorT(const TMatrixTColumn_const &mc); TVectorT(const TMatrixTDiag_const &md); template TVectorT(const TVectorT &another) { R__ASSERT(another.IsValid()); Allocate(another.GetUpb()-another.GetLwb()+1,another.GetLwb()); *this = another; } #ifndef __CINT__ TVectorT(Int_t lwb,Int_t upb,Double_t iv1, ...); #endif ~TVectorT() override { TVectorT::Clear(); } inline Int_t GetLwb () const { return fRowLwb; } inline Int_t GetUpb () const { return fNrows+fRowLwb-1; } inline Int_t GetNrows () const { return fNrows; } inline Int_t GetNoElements() const { return fNrows; } inline Element *GetMatrixArray () { return fElements; } inline const Element *GetMatrixArray () const { return fElements; } inline void Invalidate () { SetBit(kStatus); } inline void MakeValid () { ResetBit(kStatus); } inline Bool_t IsValid () const { return !TestBit(kStatus); } inline Bool_t IsOwner () const { return fIsOwner; } inline void SetElements(const Element *elements) { R__ASSERT(IsValid()); memcpy(fElements,elements,fNrows*sizeof(Element)); } inline TVectorT &Shift (Int_t row_shift) { fRowLwb += row_shift; return *this; } TVectorT &ResizeTo (Int_t lwb,Int_t upb); inline TVectorT &ResizeTo (Int_t n) { return ResizeTo(0,n-1); } inline TVectorT &ResizeTo (const TVectorT &v) { return ResizeTo(v.GetLwb(),v.GetUpb()); } TVectorT &Use (Int_t lwb,Int_t upb,Element *data); const TVectorT &Use (Int_t lwb,Int_t upb,const Element *data) const { return (const TVectorT&)(const_cast *>(this))->Use(lwb,upb,const_cast(data)); } TVectorT &Use (Int_t n,Element *data); const TVectorT &Use (Int_t n,const Element *data) const ; TVectorT &Use (TVectorT &v); const TVectorT &Use (const TVectorT &v) const ; TVectorT &GetSub (Int_t row_lwb,Int_t row_upb,TVectorT &target,Option_t *option="S") const; TVectorT GetSub (Int_t row_lwb,Int_t row_upb,Option_t *option="S") const; TVectorT &SetSub (Int_t row_lwb,const TVectorT &source); TVectorT &Zero(); TVectorT &Abs (); TVectorT &Sqr (); TVectorT &Sqrt(); TVectorT &Invert(); TVectorT &SelectNonZeros(const TVectorT &select); Element Norm1 () const; Element Norm2Sqr() const; Element NormInf () const; Int_t NonZeros() const; Element Sum () const; Element Min () const; Element Max () const; inline const Element &operator()(Int_t index) const; inline Element &operator()(Int_t index); inline const Element &operator[](Int_t index) const { return (*this)(index); } inline Element &operator[](Int_t index) { return (*this)(index); } TVectorT &operator= (const TVectorT &source); TVectorT &operator= (const TMatrixTRow_const &mr); TVectorT &operator= (const TMatrixTColumn_const &mc); TVectorT &operator= (const TMatrixTDiag_const &md); TVectorT &operator= (const TMatrixTSparseRow_const &md); TVectorT &operator= (const TMatrixTSparseDiag_const &md); template TVectorT &operator= (const TVectorT &source) { if (!AreCompatible(*this,source)) { Error("operator=(const TVectorT2 &)","vectors not compatible"); return *this; } TObject::operator=(source); const Element2 * const ps = source.GetMatrixArray(); Element * const pt = GetMatrixArray(); for (Int_t i = 0; i < this->fNrows; i++) pt[i] = ps[i]; return *this; } TVectorT &operator= (Element val); TVectorT &operator+=(Element val); TVectorT &operator-=(Element val); TVectorT &operator*=(Element val); TVectorT &operator+=(const TVectorT &source); TVectorT &operator-=(const TVectorT &source); TVectorT &operator*=(const TMatrixT &a); TVectorT &operator*=(const TMatrixTSym &a); TVectorT &operator*=(const TMatrixTSparse &a); Bool_t operator==(Element val) const; Bool_t operator!=(Element val) const; Bool_t operator< (Element val) const; Bool_t operator<=(Element val) const; Bool_t operator> (Element val) const; Bool_t operator>=(Element val) const; Bool_t MatchesNonZeroPattern(const TVectorT &select); Bool_t SomePositive (const TVectorT &select); void AddSomeConstant (Element val,const TVectorT &select); void Randomize (Element alpha,Element beta,Double_t &seed); TVectorT &Apply(const TElementActionT &action); TVectorT &Apply(const TElementPosActionT &action); void Add(const TVectorT &v); void Add(const TVectorT &v1, const TVectorT &v2); void Clear(Option_t * /*option*/ = "") override { if (fIsOwner) Delete_m(fNrows, fElements); else fElements = nullptr; fNrows = 0; } void Draw(Option_t *option = "") override; // *MENU* void Print(Option_t *option = "") const override; // *MENU* ClassDefOverride(TVectorT,4) // Template of Vector 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 *TVectorT::Class(); #endif // __CINT__ template inline TVectorT &TVectorT::Use (Int_t n,Element *data) { return Use(0,n-1,data); } template inline const TVectorT &TVectorT::Use (Int_t n,const Element *data) const { return Use(0,n-1,data); } template inline TVectorT &TVectorT::Use (TVectorT &v) { R__ASSERT(v.IsValid()); return Use(v.GetLwb(),v.GetUpb(),v.GetMatrixArray()); } template inline const TVectorT &TVectorT::Use (const TVectorT &v) const { R__ASSERT(v.IsValid()); return Use(v.GetLwb(),v.GetUpb(),v.GetMatrixArray()); } template inline TVectorT TVectorT::GetSub (Int_t row_lwb,Int_t row_upb,Option_t *option) const { TVectorT tmp; this->GetSub(row_lwb,row_upb,tmp,option); return tmp; } template inline const Element &TVectorT::operator()(Int_t ind) const { // Access a vector element. R__ASSERT(IsValid()); const Int_t aind = ind-fRowLwb; if (aind >= fNrows || aind < 0) { Error("operator()","Request index(%d) outside vector range of %d - %d",ind,fRowLwb,fRowLwb+fNrows); return TMatrixTBase::NaNValue(); } return fElements[aind]; } template inline Element &TVectorT::operator()(Int_t ind) { // Access a vector element. R__ASSERT(IsValid()); const Int_t aind = ind-fRowLwb; if (aind >= fNrows || aind < 0) { Error("operator()","Request index(%d) outside vector range of %d - %d",ind,fRowLwb,fRowLwb+fNrows); return TMatrixTBase::NaNValue(); } return fElements[aind]; } inline namespace TMatrixTAutoloadOps { template Bool_t operator== (const TVectorT &source1,const TVectorT &source2); template TVectorT operator+ (const TVectorT &source1,const TVectorT &source2); template TVectorT operator- (const TVectorT &source1,const TVectorT &source2); template Element operator* (const TVectorT &source1,const TVectorT &source2); template TVectorT operator* (const TMatrixT &a, const TVectorT &source); template TVectorT operator* (const TMatrixTSym &a, const TVectorT &source); template TVectorT operator* (const TMatrixTSparse &a, const TVectorT &source); template TVectorT operator* ( Element val, const TVectorT &source); template inline TVectorT operator* (const TVectorT &source, Element val) { return val * source; } template Element Dot (const TVectorT &source1,const TVectorT &source2); template TMatrixT OuterProduct(const TVectorT &v1, const TVectorT &v2); template TMatrixT &OuterProduct( TMatrixT &target, const TVectorT &v1, const TVectorT &v2); template Element1 Mult (const TVectorT &v1, const TMatrixT &m, const TVectorT &v2); template TVectorT &Add ( TVectorT &target, Element scalar, const TVectorT &source); template TVectorT &Add ( TVectorT &target, Element scalar, const TMatrixT &a, const TVectorT &source); template TVectorT &Add ( TVectorT &target, Element scalar, const TMatrixTSym &a, const TVectorT &source); template TVectorT &Add ( TVectorT &target, Element scalar, const TMatrixTSparse &a, const TVectorT &source); template TVectorT &AddElemMult ( TVectorT &target, Element scalar, const TVectorT &source1, const TVectorT &source2); template TVectorT &AddElemMult ( TVectorT &target, Element scalar, const TVectorT &source1, const TVectorT &source2,const TVectorT &select); template TVectorT &AddElemDiv ( TVectorT &target, Element scalar, const TVectorT &source1, const TVectorT &source2); template TVectorT &AddElemDiv ( TVectorT &target, Element scalar, const TVectorT &source1, const TVectorT &source2,const TVectorT &select); template TVectorT &ElementMult ( TVectorT &target, const TVectorT &source); template TVectorT &ElementMult ( TVectorT &target, const TVectorT &source, const TVectorT &select); template TVectorT &ElementDiv ( TVectorT &target, const TVectorT &source); template TVectorT &ElementDiv ( TVectorT &target, const TVectorT &source, const TVectorT &select); template Bool_t AreCompatible(const TVectorT &v1,const TVectorT &v2,Int_t verbose=0); // Check matrix and vector for compatibility in multiply: M * v and v * M template Bool_t AreCompatible(const TMatrixT &m, const TVectorT &v, Int_t verbose=0); template Bool_t AreCompatible(const TVectorT &v, const TMatrixT &m, Int_t verbose=0); template void Compare (const TVectorT &source1,const TVectorT &source2); template Bool_t VerifyVectorValue (const TVectorT &m, Element val,Int_t verbose, Element maxDevAllow); template Bool_t VerifyVectorValue (const TVectorT &m, Element val,Int_t verbose) { return VerifyVectorValue(m,val,verbose,Element(0.0)); } template Bool_t VerifyVectorValue (const TVectorT &m, Element val) { return VerifyVectorValue(m,val,1,Element(0.0)); } template Bool_t VerifyVectorIdentity (const TVectorT &m1,const TVectorT &m2, Int_t verbose, Element maxDevAllow); template Bool_t VerifyVectorIdentity (const TVectorT &m1,const TVectorT &m2, Int_t verbose) { return VerifyVectorIdentity(m1,m2,verbose,Element(0.0)); } template Bool_t VerifyVectorIdentity (const TVectorT &m1,const TVectorT &m2) { return VerifyVectorIdentity(m1,m2,1,Element(0.0)); } } // inline namespace TMatrixTAutoloadOps #endif