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

Last change on this file since 2444 was 2421, checked in by ansari, 22 years ago
  • Modifications methodes TMatrix::NRows() ::NCols() --> Peuvent etre

appelees sur des matrices non allouees.

  • Declaration const pour TMatrix::Transpose() et ::Rearrange(..)
  • remplacement THROW par throw ds Linfitter avec message explicite

Reza 08/08/2003

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