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

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

TMatrix et TVector suite cmv 17/5/99

File size: 10.4 KB
Line 
1// $Id: tmatrix.cc,v 1.5 1999-05-17 17:16:43 ansari Exp $
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"
11#include "generalfit.h"
12
13using namespace PlanckDPC;
14
15////////////////////////////////////////////////////////////////
16//**** Createur, Destructeur
17
18template <class T>
19TMatrix<T>::TMatrix()
20// Constructeur par defaut.
21: mNr(0), mNc(0), mNDBlock()
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.
28: mNr(r), mNc(c), mNDBlock(r*c)
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.
36: mNr(r), mNc(c), mNDBlock(r*c,values,br)
37{
38}
39
40template <class T>
41TMatrix<T>::TMatrix(const TMatrix<T>& a)
42// Constructeur par copie (partage si "a" temporaire).
43: mNr(a.mNr), mNc(a.mNc), mNDBlock(a.mNDBlock)
44{
45}
46
47template <class T>
48TMatrix<T>::TMatrix(const TMatrix<T>& a,bool share)
49// Constructeur par copie avec possibilite de forcer le partage ou non.
50: mNr(a.mNr), mNc(a.mNc), mNDBlock(a.mNDBlock,share)
51{
52}
53
54template <class T>
55TMatrix<T>::~TMatrix()
56// Destructeur
57{
58}
59
60////////////////////////////////////////////////////////////////
61// Operations matricielles
62template <class T>
63TMatrix<T> TMatrix<T>::Transpose(void) const
64// Transposition
65{
66TMatrix<T> a; a.Clone(*this); a.SetTemp(true);
67a.mNr = mNc; a.mNc = mNr;
68{for(int i=0; i<mNr; i++)
69 for(int j=0; j<mNc; j++) {
70 a(j,i) = (*this)(i,j);
71}}
72return a;
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{
83os<<"TMatrix::Print("<<mNr<<","<<mNc<<")"<<endl;
84if(lp>0)
85 {os<<" this="<<this<<endl; mNDBlock.Print(0,0);}
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;
90for(uint_4 i=i0;i<i1;i++) {
91 for(uint_4 j=j0;j<j1;j++) cout<<" "<<(*this)(i,j);
92 cout<<endl;
93}
94}
95
96////////////////////////////////////////////////////////////////
97//**** Surcharge de *= (INPLACE): TMatrix *= TMatrix;
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;
104if(ndata==0 || mNc!=a.mNr || a.mNr!=a.mNc)
105 throw(SzMismatchError("TMatrix::operator*=A size mismatch"));
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
127////////////////////////////////////////////////////////////////
128//**** Pour surcharge d'operateurs C = A (+,-,*,/) B
129
130template <class T> TMatrix<T> TMatrix<T>::Add(const TMatrix<T>& b) const
131{
132if(mNr!=b.mNr || mNc!=b.mNc)
133 throw(SzMismatchError("TMatrix operator C=A+B size mismatch\n"));
134TMatrix<T> result; result.SetTemp(true); result.mNr=mNr; result.mNc=mNc;
135result.mNDBlock = mNDBlock+b.mNDBlock;
136return result;
137}
138
139template <class T> TMatrix<T> TMatrix<T>::Sub(const TMatrix<T>& b) const
140{
141if(mNr!=b.mNr || mNc!=b.mNc)
142 throw(SzMismatchError("TMatrix operator C=A-B size mismatch\n"));
143TMatrix<T> result; result.SetTemp(true); result.mNr=mNr; result.mNc=mNc;
144result.mNDBlock = mNDBlock-b.mNDBlock;
145return result;
146}
147
148template <class T> TMatrix<T> TMatrix<T>::Mul(const TMatrix<T>& b) const
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)
152 throw(SzMismatchError("TMatrix operator C=A*B size mismatch\n"));
153TMatrix<T> r; r.SetTemp(true); r.ReSize(mNr,b.mNc);
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
165#include "matrix.h"
166////////////////////////////////////////////////////////////////
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
189TMatrix<r_8> TMatrix<r_8>::FitResidus(GeneralFit& gfit)
190// Retourne une classe contenant les residus du fit ``gfit''.
191// On suppose que x=j (colonnes) et y=i (lignes) pour m(i,j).
192{
193if(NCols()<=0||NRows()<=0)
194 throw(SzMismatchError("TMatrix::FitResidus size mismatch\n"));
195GeneralFunction* f = gfit.GetFunction();
196if(f==NULL)
197 throw(NullPtrError("TMatrix::FitResidus GeneraFit==NULL\n"));
198int npar = gfit.GetNPar();
199if(npar==0)
200 throw(SzMismatchError("TMatrix::FitResidus GeneraFit 0 parametre\n"));
201double* par = new double[npar];
202{for(int i=0;i<npar;i++) par[i] = gfit.GetParm(i);}
203TMatrix<r_8> m(*this);
204for(int i=0;i<NRows();i++) for(int j=0;j<NCols();j++) {
205 double x[2] = {(double)j,(double)i}; // attention x=col y=row!!
206 m(i,j) -= f->Value(x,par);
207}
208delete [] par;
209return m;
210}
211
212TMatrix<r_8> TMatrix<r_8>::FitFunction(GeneralFit& gfit)
213// Retourne une classe contenant la fonction du fit ``gfit''.
214// On suppose que x=j (colonnes) et y=i (lignes) pour m(i,j).
215{
216if(NCols()<=0||NRows()<=0)
217 throw(SzMismatchError("TMatrix::FitFunction size mismatch\n"));
218GeneralFunction* f = gfit.GetFunction();
219if(f==NULL)
220 throw(NullPtrError("TMatrix::FitFunction GeneraFit==NULL\n"));
221int npar = gfit.GetNPar();
222if(npar==0)
223 throw(SzMismatchError("TMatrix::FitFunction GeneraFit 0 parametre\n"));
224double* par = new double[npar];
225{for(int i=0;i<npar;i++) par[i] = gfit.GetParm(i);}
226TMatrix<r_8> m(*this);
227for(int i=0;i<NRows();i++) for(int j=0;j<NCols();j++) {
228 double x[2] = {(double)j,(double)i};
229 m(i,j) = f->Value(x,par);
230}
231delete [] par;
232return m;
233}
234
235////////////////////////////////////////////////////////////////
236// -------------------------------------------------------------------------
237// Les objets delegues pour la gestion de persistance
238// -------------------------------------------------------------------------
239
240template <class T>
241FIO_TMatrix<T>::FIO_TMatrix()
242{
243dobj=new TMatrix<T>;
244ownobj=true;
245}
246
247template <class T>
248FIO_TMatrix<T>::FIO_TMatrix(string const & filename)
249{
250dobj=new TMatrix<T>;
251ownobj=true;
252Read(filename);
253}
254
255template <class T>
256FIO_TMatrix<T>::FIO_TMatrix(const TMatrix<T> & obj)
257{
258dobj = new TMatrix<T>(obj);
259ownobj=true;
260}
261
262template <class T>
263FIO_TMatrix<T>::FIO_TMatrix(TMatrix<T> * obj)
264{
265dobj = obj;
266ownobj=false;
267}
268
269template <class T>
270FIO_TMatrix<T>::~FIO_TMatrix()
271{
272if (ownobj && dobj) delete dobj;
273}
274
275template <class T>
276AnyDataObj* FIO_TMatrix<T>::DataObj()
277{
278return(dobj);
279}
280
281
282template <class T>
283void FIO_TMatrix<T>::ReadSelf(PInPersist& is)
284{
285// On lit les 3 premiers uint_8
286// 0: Numero de version, 1 : NRows, 2 : NCol
287uint_4 itab[3];
288is.Get(itab,3);
289if (dobj == NULL) dobj = new TMatrix<T>(itab[1],itab[2]);
290else dobj->ReSize(itab[1],itab[2]);
291// On lit le NDataBlock
292FIO_NDataBlock<T> fio_nd(&dobj->DataBlock());
293fio_nd.Read(is);
294}
295
296template <class T>
297void FIO_TMatrix<T>::WriteSelf(POutPersist& os) const
298{
299if (dobj == NULL) return;
300// On ecrit 3 uint_4 ....
301// 0: Numero de version, 1 : NRows, 2 : NCol
302uint_4 itab[3];
303 itab[0] = 1; // Numero de version a 1
304itab[1] = dobj->NRows();
305itab[2] = dobj->NCols();
306os.Put(itab,3);
307// On ecrit le NDataBlock
308FIO_NDataBlock<T> fio_nd(&dobj->DataBlock());
309fio_nd.Write(os);
310}
311
312///////////////////////////////////////////////////////////////
313#ifdef __CXX_PRAGMA_TEMPLATES__
314#pragma define_template TMatrix<uint_1>
315#pragma define_template TMatrix<uint_2>
316#pragma define_template TMatrix<int_2>
317#pragma define_template TMatrix<int_4>
318#pragma define_template TMatrix<int_8>
319#pragma define_template TMatrix<uint_4>
320#pragma define_template TMatrix<uint_8>
321#pragma define_template TMatrix<r_4>
322#pragma define_template TMatrix<r_8>
323#pragma define_template TMatrix< complex<float> >
324#pragma define_template TMatrix< complex<double> >
325// Instances des delegues FileIO (PPersist)
326#pragma define_template FIO_TMatrix<uint_1>
327#pragma define_template FIO_TMatrix<uint_2>
328#pragma define_template FIO_TMatrix<int_2>
329#pragma define_template FIO_TMatrix<int_4>
330#pragma define_template FIO_TMatrix<int_8>
331#pragma define_template FIO_TMatrix<uint_4>
332#pragma define_template FIO_TMatrix<uint_8>
333#pragma define_template FIO_TMatrix<r_8>
334#pragma define_template FIO_TMatrix<r_4>
335#pragma define_template FIO_TMatrix< complex<float> >
336#pragma define_template FIO_TMatrix< complex<double> >
337#endif
338
339#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
340template class TMatrix<uint_1>;
341template class TMatrix<uint_2>;
342template class TMatrix<int_2>;
343template class TMatrix<int_4>;
344template class TMatrix<int_8>;
345template class TMatrix<uint_4>;
346template class TMatrix<uint_8>;
347template class TMatrix<r_4>;
348template class TMatrix<r_8>;
349template class TMatrix< complex<float> >;
350template class TMatrix< complex<double> >;
351// Instances des delegues FileIO (PPersist)
352template class FIO_TMatrix<uint_1>;
353template class FIO_TMatrix<uint_2>;
354template class FIO_TMatrix<int_2>;
355template class FIO_TMatrix<int_4>;
356template class FIO_TMatrix<int_8>;
357template class FIO_TMatrix<uint_4>;
358template class FIO_TMatrix<uint_8>;
359template class FIO_TMatrix<r_8>;
360template class FIO_TMatrix<r_4>;
361template class FIO_TMatrix< complex<float> >;
362template class FIO_TMatrix< complex<double> >;
363#endif
Note: See TracBrowser for help on using the repository browser.