source: Sophya/trunk/SophyaLib/TArray/tmatrix.cc@ 1099

Last change on this file since 1099 was 1099, checked in by ansari, 25 years ago

Protection integrite TMatrix,TVector - operateur = (BaseArray & pour TVector et operations entre matrices avec <> MemMapping (Pas termine) Reza 27/6/2000

File size: 11.3 KB
Line 
1// $Id: tmatrix.cc,v 1.14 2000-07-26 16:29:45 ansari Exp $
2// C.Magneville 04/99
3#include "machdefs.h"
4#include <stdio.h>
5#include <stdlib.h>
6#include "pexceptions.h"
7#include "tmatrix.h"
8
9/*!
10 \class SOPHYA::TMatrix
11 \ingroup TArray
12 Class of matrixes
13 \sa TArray
14 */
15
16////////////////////////////////////////////////////////////////
17//**** Createur, Destructeur
18//! Default constructor
19template <class T>
20TMatrix<T>::TMatrix()
21// Constructeur par defaut.
22 : TArray<T>()
23{
24 arrtype_ = 1; // Type = Matrix
25}
26
27//! constructor of a matrix with r lines et c columns.
28/*!
29 \param r : number of rows
30 \param c : number of columns
31 \param mm : define the memory mapping type
32 \sa ReSize
33 */
34template <class T>
35TMatrix<T>::TMatrix(uint_4 r,uint_4 c, short mm)
36// Construit une matrice de r lignes et c colonnes.
37 : TArray<T>()
38{
39 if ( (r == 0) || (c == 0) )
40 throw ParmError("TMatrix<T>::TMatrix(uint_4 r,uint_4 c) NRows or NCols = 0");
41 arrtype_ = 1; // Type = Matrix
42 ReSize(r, c, mm);
43}
44
45//! Constructor by copy
46/*!
47 \warning datas are \b SHARED with \b a.
48 \sa NDataBlock::NDataBlock(const NDataBlock<T>&)
49*/
50template <class T>
51TMatrix<T>::TMatrix(const TMatrix<T>& a)
52// Constructeur par copie
53 : TArray<T>(a)
54{
55 arrtype_ = 1; // Type = Matrix
56}
57
58//! Constructor by copy
59/*!
60 \param share : if true, share data. If false copy data
61 */
62template <class T>
63TMatrix<T>::TMatrix(const TMatrix<T>& a, bool share)
64// Constructeur par copie avec possibilite de forcer le partage ou non.
65: TArray<T>(a, share)
66{
67 arrtype_ = 1; // Type = Matrix
68}
69
70//! Constructor of a matrix from a TArray \b a
71template <class T>
72TMatrix<T>::TMatrix(const TArray<T>& a)
73: TArray<T>(a)
74{
75 if (a.NbDimensions() > 2)
76 throw SzMismatchError("TMatrix<T>::TMatrix(const TArray<T>& a) a.NbDimensions()>2 ");
77 if (a.NbDimensions() == 1) {
78 size_[1] = 1;
79 step_[1] = size_[0]*step_[0];
80 ndim_ = 2;
81 }
82 arrtype_ = 1; // Type = Matrix
83 UpdateMemoryMapping(a, SameMemoryMapping);
84}
85
86//! Constructor of a matrix from a TArray \b a
87/*!
88 \param a : TArray to be copied or shared
89 \param share : if true, share data. If false copy data
90 \param mm : define the memory mapping type
91 */
92template <class T>
93TMatrix<T>::TMatrix(const TArray<T>& a, bool share, short mm )
94: TArray<T>(a, share)
95{
96 if (a.NbDimensions() > 2)
97 throw SzMismatchError("TMatrix<T>::TMatrix(const TArray<T>& a, ...) a.NbDimensions()>2");
98 if (a.NbDimensions() == 1) {
99 size_[1] = 1;
100 step_[1] = size_[0]*step_[0];
101 ndim_ = 2;
102 }
103 arrtype_ = 1; // Type = Matrix
104 UpdateMemoryMapping(a, mm);
105}
106
107//! Constructor of a matrix from a TArray \b a , with a different data type
108template <class T>
109TMatrix<T>::TMatrix(const BaseArray& a)
110: TArray<T>()
111{
112 arrtype_ = 1; // Type = Matrix
113 SetBA(a);
114}
115
116
117
118//! Destructor
119template <class T>
120TMatrix<T>::~TMatrix()
121{
122}
123
124//! Set matrix equal to \b a and return *this
125/*!
126 \warning Datas are copied (cloned) from \b a.
127 \sa NDataBlock::operator=(const NDataBlock<T>&)
128*/
129template <class T>
130TArray<T>& TMatrix<T>::Set(const TArray<T>& a)
131{
132 if (a.NbDimensions() > 2)
133 throw SzMismatchError("TMatrix<T>::Set(const TArray<T>& a) a.NbDimensions() > 2");
134 if ((arrtype_ == 2) && (a.NbDimensions() > 1) && (a.Size(0) > 1) && (a.Size(1) > 1) )
135 throw SzMismatchError("TMatrix<T>::Set(const TArray<T>& a) Size(0,1)>1 for Vector");
136 TArray<T>::Set(a);
137 if (NbDimensions() == 1) {
138 size_[1] = 1;
139 step_[1] = size_[0]*step_[0];
140 ndim_ = 2;
141 }
142 UpdateMemoryMapping(*this, SameMemoryMapping);
143 return(*this);
144}
145
146template <class T>
147TArray<T>& TMatrix<T>::SetBA(const BaseArray& a)
148{
149 if (a.NbDimensions() > 2)
150 throw SzMismatchError("TMatrix<T>::SetBA(const BaseArray& a) a.NbDimensions() > 2");
151 if ((arrtype_ == 2) && (a.NbDimensions() > 1) && (a.Size(0) > 1) && (a.Size(1) > 1) )
152 throw SzMismatchError("TMatrix<T>::Set(const TArray<T>& a) Size(0,1)>1 for Vector");
153 TArray<T>::SetBA(a);
154 if (NbDimensions() == 1) {
155 size_[1] = 1;
156 step_[1] = size_[0]*step_[0];
157 ndim_ = 2;
158 }
159 UpdateMemoryMapping(*this, SameMemoryMapping);
160 return(*this);
161}
162
163
164
165//! Resize the matrix
166/*!
167 \param r : number of rows
168 \param c : number of columns
169 \param mm : define the memory mapping type
170 (SameMemoryMapping,CMemoryMapping
171 ,FortranMemoryMapping,DefaultMemoryMapping)
172 */
173template <class T>
174void TMatrix<T>::ReSize(uint_4 r, uint_4 c, short mm)
175{
176 if(r==0||c==0)
177 throw(SzMismatchError("TMatrix::ReSize r or c==0 "));
178 if ((arrtype_ == 2) && (r > 1) && (c > 1))
179 throw(SzMismatchError("TMatrix::ReSize r>1&&c>1 for Vector "));
180 uint_4 size[BASEARRAY_MAXNDIMS];
181 for(int kk=0; kk<BASEARRAY_MAXNDIMS; kk++) size[kk] = 0;
182 if (mm == SameMemoryMapping) mm = GetMemoryMapping();
183 else if ( (mm != CMemoryMapping) && (mm != FortranMemoryMapping) )
184 mm = GetDefaultMemoryMapping();
185 if (mm == CMemoryMapping) {
186 size[0] = c; size[1] = r;
187 }
188 else {
189 size[0] = r; size[1] = c;
190 }
191 TArray<T>::ReSize(2, size, 1);
192 UpdateMemoryMapping(mm);
193}
194
195//! Re-allocate space for the matrix
196/*!
197 \param r : number of rows
198 \param c : number of columns
199 \param mm : define the memory mapping type
200 \param force : if true re-allocation is forced, if not it occurs
201 only if the required space is greater than the old one.
202 \sa ReSize
203 */
204template <class T>
205void TMatrix<T>::Realloc(uint_4 r,uint_4 c, short mm, bool force)
206{
207 if(r==0||c==0)
208 throw(SzMismatchError("TMatrix::Realloc r or c==0 "));
209 if ((arrtype_ == 2) && (r > 1) && (c > 1))
210 throw(SzMismatchError("TMatrix::Realloc r>1&&c>1 for Vector "));
211 uint_4 size[BASEARRAY_MAXNDIMS];
212 for(int kk=0; kk<BASEARRAY_MAXNDIMS; kk++) size[kk] = 0;
213 if (mm == SameMemoryMapping) mm = GetMemoryMapping();
214 else if ( (mm != CMemoryMapping) && (mm != FortranMemoryMapping) )
215 mm = GetDefaultMemoryMapping();
216 if (mm == CMemoryMapping) {
217 size[0] = c; size[1] = r;
218 }
219 else {
220 size[0] = r; size[1] = c;
221 }
222 TArray<T>::Realloc(2, size, 1, force);
223 UpdateMemoryMapping(mm);
224}
225
226// $CHECK$ Reza 03/2000 Doit-on declarer cette methode const ?
227//! Return a submatrix define by \b Range \b rline and \b rcol
228template <class T>
229TMatrix<T> TMatrix<T>::SubMatrix(Range rline, Range rcol) const
230{
231 short mm = GetMemoryMapping();
232 Range rx, ry;
233 if (mm == CMemoryMapping) { rx = rcol; ry = rline; }
234 else { ry = rcol; rx = rline; }
235 TMatrix sm(SubArray(rx, ry, Range(0), Range(0), Range(0)),true, mm);
236 sm.UpdateMemoryMapping(mm);
237 sm.SetTemp(true);
238 return(sm);
239}
240
241////////////////////////////////////////////////////////////////
242// Transposition
243//! Transpose matrix in place
244template <class T>
245TMatrix<T>& TMatrix<T>::Transpose()
246{
247 short vt = (marowi_ == veceli_) ? ColumnVector : RowVector;
248 uint_4 rci = macoli_;
249 macoli_ = marowi_;
250 marowi_ = rci;
251 veceli_ = (vt == ColumnVector ) ? marowi_ : macoli_;
252 return(*this);
253}
254
255
256//! Transpose matrix into new matrix
257/*!
258 \param mm : define the memory mapping type
259 (SameMemoryMapping,CMemoryMapping,FortranMemoryMapping)
260 \return return a new matrix
261 */
262template <class T>
263TMatrix<T> TMatrix<T>::Transpose(short mm)
264{
265 if (mm == SameMemoryMapping) mm = GetMemoryMapping();
266 TMatrix<T> tm(NCols(), NRows(), mm);
267 for(uint_4 i=0; i<NRows(); i++)
268 for(uint_4 j=0; j<NCols(); j++)
269 tm(j,i) = (*this)(i,j);
270 tm.SetTemp(true);
271 return tm;
272}
273
274//! Rearrange data in memory memoire according to \b mm
275/*!
276 \param mm : define the memory mapping type
277 (SameMemoryMapping,CMemoryMapping,FortranMemoryMapping)
278 \warning If identical, return a matrix that share the datas
279 */
280template <class T>
281TMatrix<T> TMatrix<T>::Rearrange(short mm)
282{
283 if ( mm == SameMemoryMapping) mm = GetMemoryMapping();
284 else if ( (mm != CMemoryMapping) && (mm != FortranMemoryMapping) )
285 mm = GetDefaultMemoryMapping();
286
287 if (mm == GetMemoryMapping())
288 return (TMatrix<T>(*this, true));
289
290 TMatrix<T> tm(NRows(), NCols(), mm);
291 for(uint_4 i=0; i<NRows(); i++)
292 for(uint_4 j=0; j<NCols(); j++)
293 tm(i,j) = (*this)(i,j);
294 tm.SetTemp(true);
295 return tm;
296}
297
298//! Set the matrix to the identity matrix \b imx
299template <class T>
300TMatrix<T>& TMatrix<T>::SetIdentity(IdentityMatrix imx)
301{
302 if (ndim_ == 0) {
303 uint_4 sz = imx.Size();
304 if (sz < 1) sz = 1;
305 ReSize(sz, sz);
306 }
307 T diag = (T)imx.Diag();
308 if (NRows() != NCols())
309 throw SzMismatchError("TMatrix::operator= (IdentityMatrix) NRows() != NCols()") ;
310 *this = (T) 0;
311 for(uint_4 i=0; i<NRows(); i++) (*this)(i,i) = diag;
312
313 return (*this);
314}
315
316
317
318////////////////////////////////////////////////////////////////
319//**** Impression
320//! Return info on number of rows, column and type \b T
321template <class T>
322string TMatrix<T>::InfoString() const
323{
324 string rs = "TMatrix<";
325 rs += typeid(T).name();
326 char buff[64];
327 sprintf(buff, ">(NRows=%ld, NCols=%ld)", (long)NRows(), (long)NCols());
328 rs += buff;
329 return(rs);
330}
331
332//! Print matrix
333/*!
334 \param maxprt : maximum numer of print
335 \param si : if true, display attached DvList
336 \sa SetMaxPrint
337 */
338template <class T>
339void TMatrix<T>::Print(ostream& os, int_4 maxprt, bool si) const
340{
341 if (maxprt < 0) maxprt = max_nprt_;
342 uint_4 npr = 0;
343 Show(os, si);
344 if (ndim_ < 1) return;
345 uint_4 kc,kr;
346 for(kr=0; kr<size_[marowi_]; kr++) {
347 if ( (size_[marowi_] > 1) && (size_[macoli_] > 10) ) cout << "----- Ligne Line= " << kr << endl;
348 for(kc=0; kc<size_[macoli_]; kc++) {
349 if(kc > 0) os << ", ";
350 os << (*this)(kr, kc); npr++;
351 if (npr >= (uint_4) maxprt) {
352 if (npr < totsize_) os << "\n .... " << endl; return;
353 }
354 }
355 os << endl;
356 }
357 os << endl;
358}
359
360////////////////////////////////////////////////////////////////
361//**** Multiplication matricielle *****
362////////////////////////////////////////////////////////////////
363
364//! Return the matrix product C = (*this)*B
365/*!
366 \param mm : define the memory mapping type for the return matrix
367 */
368template <class T>
369TMatrix<T> TMatrix<T>::Multiply(const TMatrix<T>& b, short mm) const
370{
371 if (NCols() != b.NRows())
372 throw(SzMismatchError("TMatrix<T>::Multiply(b) NCols() != b.NRows() ") );
373 if (mm == SameMemoryMapping) mm = GetMemoryMapping();
374 TMatrix<T> rm(NRows(), b.NCols(), mm);
375
376 const T * pea;
377 const T * peb;
378 T sum;
379 uint_4 r,c,k;
380 uint_4 stepa = Step(ColsKA());
381 uint_4 stepb = b.Step(RowsKA());
382 // Calcul de C=rm = A*B (A=*this)
383 for(r=0; r<rm.NRows(); r++) // Boucle sur les lignes de A
384 for(c=0; c<rm.NCols(); c++) { // Boucle sur les colonnes de B
385 sum = 0;
386 pea = &((*this)(r,0)); // 1er element de la ligne r de A
387 peb = &(b(0,c)); // 1er element de la colonne c de B
388 for(k=0; k<NCols(); k++) sum += pea[k*stepa]*peb[k*stepb];
389 rm(r,c) = sum;
390 }
391
392 rm.SetTemp(true);
393 return rm;
394}
395
396///////////////////////////////////////////////////////////////
397#ifdef __CXX_PRAGMA_TEMPLATES__
398#pragma define_template TMatrix<uint_2>
399#pragma define_template TMatrix<int_4>
400#pragma define_template TMatrix<int_8>
401#pragma define_template TMatrix<r_4>
402#pragma define_template TMatrix<r_8>
403#pragma define_template TMatrix< complex<r_4> >
404#pragma define_template TMatrix< complex<r_8> >
405#endif
406
407#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
408template class TMatrix<uint_2>;
409template class TMatrix<int_4>;
410template class TMatrix<int_8>;
411template class TMatrix<r_4>;
412template class TMatrix<r_8>;
413template class TMatrix< complex<r_4> >;
414template class TMatrix< complex<r_8> >;
415#endif
Note: See TracBrowser for help on using the repository browser.