// This may look like C code, but it is really -*- C++ -*- // C.Magneville 04/99 #ifndef TMatrix_SEEN #define TMatrix_SEEN #include "machdefs.h" #include #include #include #include "ppersist.h" #include "anydataobj.h" #include "ndatablock.h" namespace PlanckDPC { class GeneralFit; template class TVector; template class TMatrixRC; template class TMatrix : public AnyDataObj { friend class TMatrixRC; friend class TVector; public: // Creation / destruction TMatrix(); TMatrix(uint_4 r,uint_4 c); TMatrix(uint_4 r,uint_4 c,T* values,Bridge* br=NULL); TMatrix(const TMatrix& a); TMatrix(const TMatrix& a,bool share); virtual ~TMatrix(); // Temporaire? inline bool IsTemp(void) const {return mNDBlock.IsTemp();} inline void SetTemp(bool temp=false) const {mNDBlock.SetTemp(temp);} // Gestion taille/Remplissage inline void Clone(const TMatrix& a) // Clone: copie des donnees de "a" {mNDBlock.Clone(a.mNDBlock); mNr = a.mNr; mNc = a.mNc;} inline void Reset(T v=0) {mNDBlock.Reset(v);} inline void ReSize(uint_4 r,uint_4 c) // Reallocation de place {if(r==0||c==0) throw(SzMismatchError("TMatrix::ReSize r ou c==0\n")); mNDBlock.ReSize(r*c); mNr = r; mNc = c;} inline void Realloc(uint_4 r,uint_4 c,bool force=false) {if(r==0||c==0) throw(SzMismatchError("TMatrix::Realloc r ou c==0\n")); mNDBlock.Realloc(r*c,force); mNr = r; mNc = c;} // Informations pointeur/data inline uint_4 NRows() const {return mNr;} inline uint_4 NCols() const {return mNc;} inline T const& operator()(uint_4 r,uint_4 c) const {return *(mNDBlock.Begin()+r*mNc+c);} inline T& operator()(uint_4 r,uint_4 c) {return *(mNDBlock.Begin()+r*mNc+c);} inline T const& operator[](uint_4 ip) const {return *(mNDBlock.Begin()+ip);} inline T& operator[](uint_4 ip) {return *(mNDBlock.Begin()+ip);} inline T* Data() {return mNDBlock.Begin();} inline const T* Data() const {return mNDBlock.Begin();} inline NDataBlock& DataBlock() {return mNDBlock;} inline const NDataBlock& DataBlock() const {return mNDBlock;} // Operations matricielles TMatrix Transpose(void) const; // Operateur d'affectation // A = x (matrice diagonale x*Identite) inline TMatrix& operator = (T x) {if(mNr!=mNc || mNr==0) throw(SzMismatchError("TMatrix::operator= mNc!=mNr ou ==0\n")); for(uint_4 r=0;r& operator = (const TMatrix& a) {if(this == &a) return *this; CloneOrShare(a); return *this;} // Impression void Print(ostream& os,int lp=0,uint_4 i0=0,uint_4 ni=10,uint_4 j0=0,uint_4 nj=10) const; inline void Print(int lp=0,uint_4 i0=0,uint_4 ni=10,uint_4 j0=0,uint_4 nj=10) const {Print(cout,lp,i0,ni,j0,nj);} // Surcharge d'operateurs INPLACE: A (+=,-=,*=,/=) (T) x inline TMatrix& operator += (T b) {mNDBlock += b; return *this;} inline TMatrix& operator -= (T b) {mNDBlock -= b; return *this;} inline TMatrix& operator *= (T b) {mNDBlock *= b; return *this;} inline TMatrix& operator /= (T b) {mNDBlock /= b; return *this;} // Surcharge d'operateurs INPLACE: A (+=,-=,*=,/=) B inline TMatrix& operator += (const TMatrix& a) {if(mNr==0 || mNc==0 || mNr!=a.mNr || mNc!=a.mNc) throw(SzMismatchError("TMatrix::operator+=A size mismatch")); mNDBlock += a.mNDBlock; return *this;} inline TMatrix& operator -= (const TMatrix& a) {if(mNr==0 || mNc==0 || mNr!=a.mNr || mNc!=a.mNc) throw(SzMismatchError("TMatrix::operator-=A size mismatch")); mNDBlock -= a.mNDBlock; return *this;} TMatrix& operator *= (const TMatrix& a); // Pour surcharge d'operateurs C = A (+,-,*) B TMatrix Add(const TMatrix& b) const; TMatrix Sub(const TMatrix& b) const; TMatrix Mul(const TMatrix& b) const; // Pivot de Gauss : diagonalise la matrice A, en effectuant les memes // operations sur la matrice B TMatrix Inverse() const; static T GausPiv(TMatrix& A, TMatrix& B); // Residus et fonction fittees. TMatrix FitResidus(GeneralFit& gfit ,double xorg=0.,double yorg=0.,double dx=1.,double dy=1.); TMatrix FitFunction(GeneralFit& gfit ,double xorg=0.,double yorg=0.,double dx=1.,double dy=1.); // Acces aux rangees et colonnes TMatrixRC Row(uint_4 r) const; TMatrixRC Col(uint_4 c) const; TMatrixRC Diag() const; protected: // partage les donnees si "a" temporaire, clone sinon. inline void CloneOrShare(const TMatrix& a) {mNDBlock.CloneOrShare(a.mNDBlock); mNr=a.mNr; mNc=a.mNc;} // Share: partage les donnees de "a" inline void Share(const TMatrix& a) {mNDBlock.Share(a.mNDBlock); mNr=a.mNr; mNc=a.mNc;} uint_4 mNr,mNc; NDataBlock mNDBlock; }; //////////////////////////////////////////////////////////////// // Impression template inline ostream& operator << (ostream& os, const TMatrix& a) {a.Print(os); return(os);} //////////////////////////////////////////////////////////////// // Surcharge d'operateurs A (+=,-=,*=,/=) (T) x template inline TMatrix operator + (const TMatrix& a, T b) {TMatrix result(a); result.SetTemp(true); result += b; return result;} template inline TMatrix operator + (T b,const TMatrix& a) {TMatrix result(a); result.SetTemp(true); result += b; return result;} template inline TMatrix operator - (const TMatrix& a, T b) {TMatrix result(a); result.SetTemp(true); result -= b; return result;} template inline TMatrix operator - (T b,const TMatrix& a) {TMatrix result(a); result.SetTemp(true); result.DataBlock() = b-result.DataBlock(); return result;} template inline TMatrix operator * (const TMatrix& a, T b) {TMatrix result(a); result.SetTemp(true); result *= b; return result;} template inline TMatrix operator * (T b,const TMatrix& a) {TMatrix result(a); result.SetTemp(true); result *= b; return result;} template inline TMatrix operator / (const TMatrix& a, T b) {TMatrix result(a); result.SetTemp(true); result /= b; return result;} //////////////////////////////////////////////////////////////// // Surcharge d'operateurs C = A (+,-,*,/) B template inline TMatrix operator + (const TMatrix& a,const TMatrix& b) {return a.Add(b);} template inline TMatrix operator - (const TMatrix& a,const TMatrix& b) {return a.Sub(b);} template inline TMatrix operator * (const TMatrix& a,const TMatrix& b) {return a.Mul(b);} //////////////////////////////////////////////////////////////// // Typedef pour simplifier et compatibilite Peida typedef TMatrix Matrix; ///////////////////////////////////////////////////////////////////////// // Classe pour la gestion de persistance template class FIO_TMatrix : public PPersist { public: FIO_TMatrix(); FIO_TMatrix(string const & filename); FIO_TMatrix(const TMatrix & obj); FIO_TMatrix(TMatrix * obj); virtual ~FIO_TMatrix(); virtual AnyDataObj* DataObj(); inline operator TMatrix() { return(*dobj); } protected : virtual void ReadSelf(PInPersist&); virtual void WriteSelf(POutPersist&) const; TMatrix * dobj; bool ownobj; }; template inline POutPersist& operator << (POutPersist& os, TMatrix & obj) { FIO_TMatrix fio(&obj); fio.Write(os); return(os); } template inline PInPersist& operator >> (PInPersist& is, TMatrix & obj) { FIO_TMatrix fio(&obj); fio.Read(is); return(is); } ///////////////////////////////////////////////////////////////////////// // Classe de lignes/colonnes de matrices enum TRCKind {TmatrixRow=0, TmatrixCol=1, TmatrixDiag=2}; template class TMatrixRC { friend class TVector; friend class TMatrix; public: TMatrixRC(); virtual ~TMatrixRC() {} int_4 Next(); int_4 Prev(); int_4 SetCol(int_4 c); int_4 SetRow(int_4 r); int_4 SetDiag(); static uint_4 Step(const TMatrix& m, TRCKind rckind); static T* Org(const TMatrix&, TRCKind rckind, uint_4 ind=0); TRCKind Kind() const { return kind; } uint_4 NElts() const; T& operator()(uint_4 i); T operator()(uint_4 i) const; TMatrixRC& operator = (const TMatrixRC& rc); TVector GetVect() const; TMatrixRC& operator += (const TMatrixRC& rc); TMatrixRC& operator -= (const TMatrixRC& rc); TMatrixRC& operator *= (T x); TMatrixRC& operator /= (T x); TMatrixRC& operator -= (T x); TMatrixRC& operator += (T x); TMatrixRC& LinComb(T a, T b, const TMatrixRC& rc, uint_4 first=0); TMatrixRC& LinComb(T b, const TMatrixRC& rc, uint_4 first=0); uint_4 IMaxAbs(uint_4 first=0); static void Swap(TMatrixRC& rc1, TMatrixRC& rc2); protected: TMatrixRC(TMatrix& m, TRCKind kind, uint_4 index=0); TMatrix* matrix; inline static double Abs_Value(uint_1 v) {return (double) v;} inline static double Abs_Value(uint_2 v) {return (double) v;} inline static double Abs_Value(int_2 v) {return (v>0)? (double) v: (double) -v;} inline static double Abs_Value(int_4 v) {return (v>0)? (double) v: (double) -v;} inline static double Abs_Value(int_8 v) {return (v>0)? (double) v: (double) -v;} inline static double Abs_Value(uint_4 v) {return (double) v;} inline static double Abs_Value(uint_8 v) {return (double) v;} inline static double Abs_Value(r_4 v) {return (double) fabsf(v);} inline static double Abs_Value(r_8 v) {return fabs(v);} inline static double Abs_Value(complex v) {return sqrt(v.real()*v.real()+v.imag()*v.imag());} inline static double Abs_Value(complex v) {return sqrt(v.real()*v.real()+v.imag()*v.imag());} T* data; int_4 index; uint_4 step; TRCKind kind; }; template inline T operator * (const TMatrixRC& a, const TMatrixRC& b) { if ( a.NElts() != b.NElts() ) throw(SzMismatchError("TMatrixRC::operator * size mismatch\n")); if ( a.Kind() != b.Kind() ) throw(SzMismatchError("TMatrixRC::operator * type mismatch\n")); T sum = 0; for(uint_4 i=0; i inline uint_4 TMatrixRC::Step(const TMatrix& m, TRCKind rckind) { switch (rckind) { case TmatrixRow : return 1; case TmatrixCol : return m.mNc; case TmatrixDiag : return m.mNc+1; } return 0; } template inline T* TMatrixRC::Org(const TMatrix& m, TRCKind rckind, uint_4 index) { switch (rckind) { case TmatrixRow : return const_cast(m.Data()) + index * m.mNc; case TmatrixCol : return const_cast(m.Data()) + index; case TmatrixDiag : return const_cast(m.Data()); } return NULL; } template inline uint_4 TMatrixRC::NElts() const { if (!matrix) return 0; switch (kind) { case TmatrixRow : return matrix->mNc; case TmatrixCol : return matrix->mNr; case TmatrixDiag : return matrix->mNc; } return 0; } template inline T& TMatrixRC::operator()(uint_4 i) {return data[i*step];} template inline T TMatrixRC::operator()(uint_4 i) const {return data[i*step];} //////////////////////////////////////////////////////////////// // Typedef pour simplifier et compatibilite Peida typedef TMatrixRC MatrixRC; } // Fin du namespace #endif