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

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

Introduction du type sa_size_t (taille des tableaux), operateur - (TArray::operator - et NegateElt()) - Reza 29/8/2000

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