source: Sophya/trunk/SophyaLib/NTools/tmatrix.cc@ 301

Last change on this file since 301 was 301, checked in by ansari, 26 years ago

cmv 18/5/99

File size: 10.7 KB
RevLine 
[301]1// $Id: tmatrix.cc,v 1.6 1999-05-18 12:23:13 ansari Exp $
[279]2// C.Magneville 04/99
3#include "machdefs.h"
4#include <stdio.h>
5#include <stdlib.h>
6#include <iostream.h>
7#include <complex>
8#include "pexceptions.h"
9#include "tmatrix.h"
10#include "objfio.h"
[299]11#include "generalfit.h"
[279]12
13using namespace PlanckDPC;
14
15////////////////////////////////////////////////////////////////
[288]16//**** Createur, Destructeur
[279]17
18template <class T>
19TMatrix<T>::TMatrix()
20// Constructeur par defaut.
[286]21: mNr(0), mNc(0), mNDBlock()
[279]22{
23}
24
25template <class T>
26TMatrix<T>::TMatrix(uint_4 r,uint_4 c)
27// Construit une matrice de r lignes et c colonnes.
[286]28: mNr(r), mNc(c), mNDBlock(r*c)
[279]29{
30}
31
32template <class T>
33TMatrix<T>::TMatrix(uint_4 r,uint_4 c,T* values,Bridge* br)
34// Construit une matrice de r lignes et c colonnes. On fournit
35// le tableau des valeurs et eventuellement un Bridge.
[286]36: mNr(r), mNc(c), mNDBlock(r*c,values,br)
[279]37{
38}
39
40template <class T>
41TMatrix<T>::TMatrix(const TMatrix<T>& a)
[288]42// Constructeur par copie (partage si "a" temporaire).
[286]43: mNr(a.mNr), mNc(a.mNc), mNDBlock(a.mNDBlock)
[279]44{
45}
46
47template <class T>
48TMatrix<T>::TMatrix(const TMatrix<T>& a,bool share)
[288]49// Constructeur par copie avec possibilite de forcer le partage ou non.
[286]50: mNr(a.mNr), mNc(a.mNc), mNDBlock(a.mNDBlock,share)
[279]51{
52}
53
54template <class T>
55TMatrix<T>::~TMatrix()
56// Destructeur
57{
58}
59
60////////////////////////////////////////////////////////////////
[288]61// Operations matricielles
[279]62template <class T>
[288]63TMatrix<T> TMatrix<T>::Transpose(void) const
64// Transposition
[279]65{
[288]66TMatrix<T> a; a.Clone(*this); a.SetTemp(true);
67a.mNr = mNc; a.mNc = mNr;
[301]68{for(uint_4 i=0; i<mNr; i++)
69 for(uint_4 j=0; j<mNc; j++) {
[288]70 a(j,i) = (*this)(i,j);
71}}
72return a;
[279]73}
74
75////////////////////////////////////////////////////////////////
76//**** Impression
77
78template <class T>
79void TMatrix<T>::Print(ostream& os,int lp
80 ,uint_4 i0,uint_4 ni,uint_4 j0,uint_4 nj) const
81// Impression de la sous-matrice (i:i+ni-1,i:j+nj-1)
82{
[288]83os<<"TMatrix::Print("<<mNr<<","<<mNc<<")"<<endl;
[279]84if(lp>0)
[286]85 {os<<" this="<<this<<endl; mNDBlock.Print(0,0);}
[279]86if(mNr==0 || mNc==0) return;
87if(i0>=mNr || j0>=mNc || ni==0 || nj==0) return;
88uint_4 i1 = i0+ni; if(i1>mNr) i1 = mNr;
89uint_4 j1 = j0+nj; if(j1>mNc) j1 = mNc;
[286]90for(uint_4 i=i0;i<i1;i++) {
91 for(uint_4 j=j0;j<j1;j++) cout<<" "<<(*this)(i,j);
92 cout<<endl;
[279]93}
94}
95
96////////////////////////////////////////////////////////////////
[288]97//**** Surcharge de *= (INPLACE): TMatrix *= TMatrix;
[279]98
99template <class T>
100TMatrix<T>& TMatrix<T>::operator *= (const TMatrix<T>& a)
101// A = A*B -> A(n,m) = A(n,m)*B(m,m)
102{
103uint_4 ndata = mNr*mNc;
[286]104if(ndata==0 || mNc!=a.mNr || a.mNr!=a.mNc)
105 throw(SzMismatchError("TMatrix::operator*=A size mismatch"));
[279]106// A(i,j) = Sum(k) A(i,k)*B(k,j) ... il faut sauver la ligne "i" de A
107// Vecteur oi : vecteur ou est sauve la ligne i de la matrice *this
108// oi,oe = pointeur de debut et de fin du vecteur temporaire
109// oij = pointeur parcourant le vecteur oi
110// Matrice *this: i = pointeur du debut de la ligne i
111// ij = pointeur parcourant la ligne i
112// Matrice a : aj = pointeur de debut de la colonne j
113// aji = pointeur parcourant la colonne j
114T* oi = new T[mNc]; T* oe = oi+mNc;
115for(T *i=Data(); i<Data()+ndata; i+=mNc) {
116 {for(T *oij=oi,*ij=i; oij<oe;) *oij++ = *ij++;}
117 {for(T *ij=i,*aj=const_cast<T *>(a.Data()); aj<a.Data()+a.mNc; ij++,aj++) {
118 T sum = 0;
119 for(T *oij=oi,*aji=aj; oij<oe; oij++,aji+=a.mNc) sum += *oij * *aji;
120 *ij = sum;
121 }}
122}
123delete [] oi;
124return *this;
125}
126
[286]127////////////////////////////////////////////////////////////////
[288]128//**** Pour surcharge d'operateurs C = A (+,-,*,/) B
[286]129
[288]130template <class T> TMatrix<T> TMatrix<T>::Add(const TMatrix<T>& b) const
[286]131{
132if(mNr!=b.mNr || mNc!=b.mNc)
[299]133 throw(SzMismatchError("TMatrix operator C=A+B size mismatch\n"));
[288]134TMatrix<T> result; result.SetTemp(true); result.mNr=mNr; result.mNc=mNc;
135result.mNDBlock = mNDBlock+b.mNDBlock;
[286]136return result;
137}
138
[288]139template <class T> TMatrix<T> TMatrix<T>::Sub(const TMatrix<T>& b) const
[286]140{
141if(mNr!=b.mNr || mNc!=b.mNc)
[299]142 throw(SzMismatchError("TMatrix operator C=A-B size mismatch\n"));
[288]143TMatrix<T> result; result.SetTemp(true); result.mNr=mNr; result.mNc=mNc;
144result.mNDBlock = mNDBlock-b.mNDBlock;
[286]145return result;
146}
147
[288]148template <class T> TMatrix<T> TMatrix<T>::Mul(const TMatrix<T>& b) const
[286]149// C = A(this)*B : Cij = Aik Bkj (allocation forcee dans tous les cas)
150{
151if(mNr==0 || mNc==0 || b.mNc==0 || mNc!=b.mNr)
[299]152 throw(SzMismatchError("TMatrix operator C=A*B size mismatch\n"));
[288]153TMatrix<T> r; r.SetTemp(true); r.ReSize(mNr,b.mNc);
[286]154T *ai,*aik,*bj,*bkj,*ri,*rij;
155for(ri=const_cast<T *>(r.Data()),ai=const_cast<T *>(Data());
156 ri<r.Data()+r.mNr*r.mNc;ri+=r.mNc,ai+=mNc) {
157 for(rij=ri,bj=const_cast<T *>(b.Data());rij<ri+r.mNc;rij++,bj++) {
158 *rij = 0;
159 for(aik=ai,bkj=bj;aik<ai+mNc;aik++,bkj+=b.mNc) *rij += *aik * *bkj;
160 }
161}
162return r;
163}
164
[299]165#include "matrix.h"
[286]166////////////////////////////////////////////////////////////////
[299]167//**** Pour inversion
168TMatrix<r_8> TMatrix<r_8>::Inverse() const
169// Inversion
170{
171TMatrix<r_8> b(mNc,mNr);
172TMatrix<r_8> a(*this);
173b = 1.;
174if (fabs(TMatrix<r_8>::GausPiv(a,b)) < 1.e-50)
175 throw(MathExc("TMatrix Inverse() Singular Matrix"));
176return b;
177}
178
179double TMatrix<r_8>::GausPiv(TMatrix<r_8>& a, TMatrix<r_8>& b)
180// Pivot de Gauss
181{
182Matrix A(a);
183Matrix B(b);
184return Matrix::GausPiv(A,B);
185}
186
187//////////////////////////////////////////////////////////
188//**** Residus des fits
[301]189TMatrix<r_8> TMatrix<r_8>::FitResidus(GeneralFit& gfit
190 ,double xorg,double yorg,double dx,double dy)
191// Retourne une classe contenant les residus du fit ``gfit''.
192// On suppose que x=j (colonnes) et y=i (lignes) pour m(i,j).
193// Les coordonnees de l'element (i,j) sont :
194// (i,j) -> x = xorg+j*dx , y = yorg+i*dy
[299]195{
196if(NCols()<=0||NRows()<=0)
197 throw(SzMismatchError("TMatrix::FitResidus size mismatch\n"));
198GeneralFunction* f = gfit.GetFunction();
199if(f==NULL)
200 throw(NullPtrError("TMatrix::FitResidus GeneraFit==NULL\n"));
201int npar = gfit.GetNPar();
202if(npar==0)
203 throw(SzMismatchError("TMatrix::FitResidus GeneraFit 0 parametre\n"));
204double* par = new double[npar];
205{for(int i=0;i<npar;i++) par[i] = gfit.GetParm(i);}
206TMatrix<r_8> m(*this);
[301]207for(uint_4 i=0;i<NRows();i++) for(uint_4 j=0;j<NCols();j++) {
208 double x[2] = {xorg+j*dx,yorg+i*dy};
[299]209 m(i,j) -= f->Value(x,par);
210}
211delete [] par;
212return m;
213}
214
[301]215TMatrix<r_8> TMatrix<r_8>::FitFunction(GeneralFit& gfit
216 ,double xorg,double yorg,double dx,double dy)
217// Retourne une classe contenant la fonction du fit ``gfit''.
218// On suppose que x=j (colonnes) et y=i (lignes) pour m(i,j).
219// Les coordonnees de l'element (i,j) sont :
220// (i,j) -> x = xorg + j*dx , y = yorg + i*dy
[299]221{
222if(NCols()<=0||NRows()<=0)
223 throw(SzMismatchError("TMatrix::FitFunction size mismatch\n"));
224GeneralFunction* f = gfit.GetFunction();
225if(f==NULL)
226 throw(NullPtrError("TMatrix::FitFunction GeneraFit==NULL\n"));
227int npar = gfit.GetNPar();
228if(npar==0)
229 throw(SzMismatchError("TMatrix::FitFunction GeneraFit 0 parametre\n"));
230double* par = new double[npar];
231{for(int i=0;i<npar;i++) par[i] = gfit.GetParm(i);}
232TMatrix<r_8> m(*this);
[301]233for(uint_4 i=0;i<NRows();i++) for(uint_4 j=0;j<NCols();j++) {
234 double x[2] = {xorg+j*dx,yorg+i*dy};
[299]235 m(i,j) = f->Value(x,par);
236}
237delete [] par;
238return m;
239}
240
241////////////////////////////////////////////////////////////////
[286]242// -------------------------------------------------------------------------
243// Les objets delegues pour la gestion de persistance
244// -------------------------------------------------------------------------
245
246template <class T>
247FIO_TMatrix<T>::FIO_TMatrix()
248{
249dobj=new TMatrix<T>;
250ownobj=true;
251}
252
253template <class T>
254FIO_TMatrix<T>::FIO_TMatrix(string const & filename)
255{
256dobj=new TMatrix<T>;
257ownobj=true;
258Read(filename);
259}
260
261template <class T>
262FIO_TMatrix<T>::FIO_TMatrix(const TMatrix<T> & obj)
263{
264dobj = new TMatrix<T>(obj);
265ownobj=true;
266}
267
268template <class T>
269FIO_TMatrix<T>::FIO_TMatrix(TMatrix<T> * obj)
270{
271dobj = obj;
272ownobj=false;
273}
274
275template <class T>
276FIO_TMatrix<T>::~FIO_TMatrix()
277{
278if (ownobj && dobj) delete dobj;
279}
280
281template <class T>
282AnyDataObj* FIO_TMatrix<T>::DataObj()
283{
284return(dobj);
285}
286
287
288template <class T>
289void FIO_TMatrix<T>::ReadSelf(PInPersist& is)
290{
291// On lit les 3 premiers uint_8
[291]292// 0: Numero de version, 1 : NRows, 2 : NCol
293uint_4 itab[3];
294is.Get(itab,3);
295if (dobj == NULL) dobj = new TMatrix<T>(itab[1],itab[2]);
296else dobj->ReSize(itab[1],itab[2]);
[286]297// On lit le NDataBlock
[291]298FIO_NDataBlock<T> fio_nd(&dobj->DataBlock());
299fio_nd.Read(is);
[286]300}
301
302template <class T>
303void FIO_TMatrix<T>::WriteSelf(POutPersist& os) const
304{
305if (dobj == NULL) return;
[291]306// On ecrit 3 uint_4 ....
307// 0: Numero de version, 1 : NRows, 2 : NCol
308uint_4 itab[3];
309 itab[0] = 1; // Numero de version a 1
310itab[1] = dobj->NRows();
311itab[2] = dobj->NCols();
312os.Put(itab,3);
[286]313// On ecrit le NDataBlock
[291]314FIO_NDataBlock<T> fio_nd(&dobj->DataBlock());
315fio_nd.Write(os);
[286]316}
317
[279]318///////////////////////////////////////////////////////////////
319#ifdef __CXX_PRAGMA_TEMPLATES__
320#pragma define_template TMatrix<uint_1>
321#pragma define_template TMatrix<uint_2>
322#pragma define_template TMatrix<int_2>
323#pragma define_template TMatrix<int_4>
324#pragma define_template TMatrix<int_8>
325#pragma define_template TMatrix<uint_4>
326#pragma define_template TMatrix<uint_8>
327#pragma define_template TMatrix<r_4>
328#pragma define_template TMatrix<r_8>
[286]329#pragma define_template TMatrix< complex<float> >
330#pragma define_template TMatrix< complex<double> >
[279]331// Instances des delegues FileIO (PPersist)
[286]332#pragma define_template FIO_TMatrix<uint_1>
333#pragma define_template FIO_TMatrix<uint_2>
334#pragma define_template FIO_TMatrix<int_2>
335#pragma define_template FIO_TMatrix<int_4>
336#pragma define_template FIO_TMatrix<int_8>
337#pragma define_template FIO_TMatrix<uint_4>
338#pragma define_template FIO_TMatrix<uint_8>
339#pragma define_template FIO_TMatrix<r_8>
340#pragma define_template FIO_TMatrix<r_4>
341#pragma define_template FIO_TMatrix< complex<float> >
342#pragma define_template FIO_TMatrix< complex<double> >
[279]343#endif
344
345#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
346template class TMatrix<uint_1>;
347template class TMatrix<uint_2>;
348template class TMatrix<int_2>;
349template class TMatrix<int_4>;
350template class TMatrix<int_8>;
351template class TMatrix<uint_4>;
352template class TMatrix<uint_8>;
353template class TMatrix<r_4>;
354template class TMatrix<r_8>;
355template class TMatrix< complex<float> >;
356template class TMatrix< complex<double> >;
357// Instances des delegues FileIO (PPersist)
[286]358template class FIO_TMatrix<uint_1>;
359template class FIO_TMatrix<uint_2>;
360template class FIO_TMatrix<int_2>;
361template class FIO_TMatrix<int_4>;
362template class FIO_TMatrix<int_8>;
363template class FIO_TMatrix<uint_4>;
364template class FIO_TMatrix<uint_8>;
365template class FIO_TMatrix<r_8>;
366template class FIO_TMatrix<r_4>;
367template class FIO_TMatrix< complex<float> >;
368template class FIO_TMatrix< complex<double> >;
[279]369#endif
Note: See TracBrowser for help on using the repository browser.