// $Id: tmatrix.cc,v 1.6 1999-05-18 12:23:13 ansari Exp $ // C.Magneville 04/99 #include "machdefs.h" #include #include #include #include #include "pexceptions.h" #include "tmatrix.h" #include "objfio.h" #include "generalfit.h" using namespace PlanckDPC; //////////////////////////////////////////////////////////////// //**** Createur, Destructeur template TMatrix::TMatrix() // Constructeur par defaut. : mNr(0), mNc(0), mNDBlock() { } template TMatrix::TMatrix(uint_4 r,uint_4 c) // Construit une matrice de r lignes et c colonnes. : mNr(r), mNc(c), mNDBlock(r*c) { } template TMatrix::TMatrix(uint_4 r,uint_4 c,T* values,Bridge* br) // Construit une matrice de r lignes et c colonnes. On fournit // le tableau des valeurs et eventuellement un Bridge. : mNr(r), mNc(c), mNDBlock(r*c,values,br) { } template TMatrix::TMatrix(const TMatrix& a) // Constructeur par copie (partage si "a" temporaire). : mNr(a.mNr), mNc(a.mNc), mNDBlock(a.mNDBlock) { } template TMatrix::TMatrix(const TMatrix& a,bool share) // Constructeur par copie avec possibilite de forcer le partage ou non. : mNr(a.mNr), mNc(a.mNc), mNDBlock(a.mNDBlock,share) { } template TMatrix::~TMatrix() // Destructeur { } //////////////////////////////////////////////////////////////// // Operations matricielles template TMatrix TMatrix::Transpose(void) const // Transposition { TMatrix a; a.Clone(*this); a.SetTemp(true); a.mNr = mNc; a.mNc = mNr; {for(uint_4 i=0; i void TMatrix::Print(ostream& os,int lp ,uint_4 i0,uint_4 ni,uint_4 j0,uint_4 nj) const // Impression de la sous-matrice (i:i+ni-1,i:j+nj-1) { os<<"TMatrix::Print("<0) {os<<" this="<=mNr || j0>=mNc || ni==0 || nj==0) return; uint_4 i1 = i0+ni; if(i1>mNr) i1 = mNr; uint_4 j1 = j0+nj; if(j1>mNc) j1 = mNc; for(uint_4 i=i0;i TMatrix& TMatrix::operator *= (const TMatrix& a) // A = A*B -> A(n,m) = A(n,m)*B(m,m) { uint_4 ndata = mNr*mNc; if(ndata==0 || mNc!=a.mNr || a.mNr!=a.mNc) throw(SzMismatchError("TMatrix::operator*=A size mismatch")); // A(i,j) = Sum(k) A(i,k)*B(k,j) ... il faut sauver la ligne "i" de A // Vecteur oi : vecteur ou est sauve la ligne i de la matrice *this // oi,oe = pointeur de debut et de fin du vecteur temporaire // oij = pointeur parcourant le vecteur oi // Matrice *this: i = pointeur du debut de la ligne i // ij = pointeur parcourant la ligne i // Matrice a : aj = pointeur de debut de la colonne j // aji = pointeur parcourant la colonne j T* oi = new T[mNc]; T* oe = oi+mNc; for(T *i=Data(); i(a.Data()); aj TMatrix TMatrix::Add(const TMatrix& b) const { if(mNr!=b.mNr || mNc!=b.mNc) throw(SzMismatchError("TMatrix operator C=A+B size mismatch\n")); TMatrix result; result.SetTemp(true); result.mNr=mNr; result.mNc=mNc; result.mNDBlock = mNDBlock+b.mNDBlock; return result; } template TMatrix TMatrix::Sub(const TMatrix& b) const { if(mNr!=b.mNr || mNc!=b.mNc) throw(SzMismatchError("TMatrix operator C=A-B size mismatch\n")); TMatrix result; result.SetTemp(true); result.mNr=mNr; result.mNc=mNc; result.mNDBlock = mNDBlock-b.mNDBlock; return result; } template TMatrix TMatrix::Mul(const TMatrix& b) const // C = A(this)*B : Cij = Aik Bkj (allocation forcee dans tous les cas) { if(mNr==0 || mNc==0 || b.mNc==0 || mNc!=b.mNr) throw(SzMismatchError("TMatrix operator C=A*B size mismatch\n")); TMatrix r; r.SetTemp(true); r.ReSize(mNr,b.mNc); T *ai,*aik,*bj,*bkj,*ri,*rij; for(ri=const_cast(r.Data()),ai=const_cast(Data()); ri(b.Data());rij TMatrix::Inverse() const // Inversion { TMatrix b(mNc,mNr); TMatrix a(*this); b = 1.; if (fabs(TMatrix::GausPiv(a,b)) < 1.e-50) throw(MathExc("TMatrix Inverse() Singular Matrix")); return b; } double TMatrix::GausPiv(TMatrix& a, TMatrix& b) // Pivot de Gauss { Matrix A(a); Matrix B(b); return Matrix::GausPiv(A,B); } ////////////////////////////////////////////////////////// //**** Residus des fits TMatrix TMatrix::FitResidus(GeneralFit& gfit ,double xorg,double yorg,double dx,double dy) // Retourne une classe contenant les residus du fit ``gfit''. // On suppose que x=j (colonnes) et y=i (lignes) pour m(i,j). // Les coordonnees de l'element (i,j) sont : // (i,j) -> x = xorg+j*dx , y = yorg+i*dy { if(NCols()<=0||NRows()<=0) throw(SzMismatchError("TMatrix::FitResidus size mismatch\n")); GeneralFunction* f = gfit.GetFunction(); if(f==NULL) throw(NullPtrError("TMatrix::FitResidus GeneraFit==NULL\n")); int npar = gfit.GetNPar(); if(npar==0) throw(SzMismatchError("TMatrix::FitResidus GeneraFit 0 parametre\n")); double* par = new double[npar]; {for(int i=0;i m(*this); for(uint_4 i=0;iValue(x,par); } delete [] par; return m; } TMatrix TMatrix::FitFunction(GeneralFit& gfit ,double xorg,double yorg,double dx,double dy) // Retourne une classe contenant la fonction du fit ``gfit''. // On suppose que x=j (colonnes) et y=i (lignes) pour m(i,j). // Les coordonnees de l'element (i,j) sont : // (i,j) -> x = xorg + j*dx , y = yorg + i*dy { if(NCols()<=0||NRows()<=0) throw(SzMismatchError("TMatrix::FitFunction size mismatch\n")); GeneralFunction* f = gfit.GetFunction(); if(f==NULL) throw(NullPtrError("TMatrix::FitFunction GeneraFit==NULL\n")); int npar = gfit.GetNPar(); if(npar==0) throw(SzMismatchError("TMatrix::FitFunction GeneraFit 0 parametre\n")); double* par = new double[npar]; {for(int i=0;i m(*this); for(uint_4 i=0;iValue(x,par); } delete [] par; return m; } //////////////////////////////////////////////////////////////// // ------------------------------------------------------------------------- // Les objets delegues pour la gestion de persistance // ------------------------------------------------------------------------- template FIO_TMatrix::FIO_TMatrix() { dobj=new TMatrix; ownobj=true; } template FIO_TMatrix::FIO_TMatrix(string const & filename) { dobj=new TMatrix; ownobj=true; Read(filename); } template FIO_TMatrix::FIO_TMatrix(const TMatrix & obj) { dobj = new TMatrix(obj); ownobj=true; } template FIO_TMatrix::FIO_TMatrix(TMatrix * obj) { dobj = obj; ownobj=false; } template FIO_TMatrix::~FIO_TMatrix() { if (ownobj && dobj) delete dobj; } template AnyDataObj* FIO_TMatrix::DataObj() { return(dobj); } template void FIO_TMatrix::ReadSelf(PInPersist& is) { // On lit les 3 premiers uint_8 // 0: Numero de version, 1 : NRows, 2 : NCol uint_4 itab[3]; is.Get(itab,3); if (dobj == NULL) dobj = new TMatrix(itab[1],itab[2]); else dobj->ReSize(itab[1],itab[2]); // On lit le NDataBlock FIO_NDataBlock fio_nd(&dobj->DataBlock()); fio_nd.Read(is); } template void FIO_TMatrix::WriteSelf(POutPersist& os) const { if (dobj == NULL) return; // On ecrit 3 uint_4 .... // 0: Numero de version, 1 : NRows, 2 : NCol uint_4 itab[3]; itab[0] = 1; // Numero de version a 1 itab[1] = dobj->NRows(); itab[2] = dobj->NCols(); os.Put(itab,3); // On ecrit le NDataBlock FIO_NDataBlock fio_nd(&dobj->DataBlock()); fio_nd.Write(os); } /////////////////////////////////////////////////////////////// #ifdef __CXX_PRAGMA_TEMPLATES__ #pragma define_template TMatrix #pragma define_template TMatrix #pragma define_template TMatrix #pragma define_template TMatrix #pragma define_template TMatrix #pragma define_template TMatrix #pragma define_template TMatrix #pragma define_template TMatrix #pragma define_template TMatrix #pragma define_template TMatrix< complex > #pragma define_template TMatrix< complex > // Instances des delegues FileIO (PPersist) #pragma define_template FIO_TMatrix #pragma define_template FIO_TMatrix #pragma define_template FIO_TMatrix #pragma define_template FIO_TMatrix #pragma define_template FIO_TMatrix #pragma define_template FIO_TMatrix #pragma define_template FIO_TMatrix #pragma define_template FIO_TMatrix #pragma define_template FIO_TMatrix #pragma define_template FIO_TMatrix< complex > #pragma define_template FIO_TMatrix< complex > #endif #if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES) template class TMatrix; template class TMatrix; template class TMatrix; template class TMatrix; template class TMatrix; template class TMatrix; template class TMatrix; template class TMatrix; template class TMatrix; template class TMatrix< complex >; template class TMatrix< complex >; // Instances des delegues FileIO (PPersist) template class FIO_TMatrix; template class FIO_TMatrix; template class FIO_TMatrix; template class FIO_TMatrix; template class FIO_TMatrix; template class FIO_TMatrix; template class FIO_TMatrix; template class FIO_TMatrix; template class FIO_TMatrix; template class FIO_TMatrix< complex >; template class FIO_TMatrix< complex >; #endif