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

Last change on this file since 2153 was 1624, checked in by cmv, 24 years ago

On enleve les SetTemp() inutiles cmv 6/8/01

File size: 11.9 KB
RevLine 
[1624]1// $Id: tmatrix.cc,v 1.22 2001-08-06 22:48:43 cmv Exp $
[762]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
[926]9/*!
10 \class SOPHYA::TMatrix
11 \ingroup TArray
12 Class of matrixes
13 \sa TArray
14 */
[804]15
[762]16////////////////////////////////////////////////////////////////
17//**** Createur, Destructeur
[894]18//! Default constructor
[762]19template <class T>
20TMatrix<T>::TMatrix()
21// Constructeur par defaut.
[804]22 : TArray<T>()
[762]23{
[1099]24 arrtype_ = 1; // Type = Matrix
[762]25}
26
[894]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 */
[762]34template <class T>
[1156]35TMatrix<T>::TMatrix(sa_size_t r,sa_size_t c, short mm)
[762]36// Construit une matrice de r lignes et c colonnes.
[804]37 : TArray<T>()
[762]38{
[804]39 if ( (r == 0) || (c == 0) )
[1156]40 throw ParmError("TMatrix<T>::TMatrix(sa_size_t r,sa_size_t c) NRows or NCols = 0");
[1099]41 arrtype_ = 1; // Type = Matrix
[804]42 ReSize(r, c, mm);
[762]43}
44
[967]45//! Constructor by copy
[976]46/*!
47 \warning datas are \b SHARED with \b a.
48 \sa NDataBlock::NDataBlock(const NDataBlock<T>&)
49*/
[762]50template <class T>
51TMatrix<T>::TMatrix(const TMatrix<T>& a)
[967]52// Constructeur par copie
[804]53 : TArray<T>(a)
[762]54{
[1099]55 arrtype_ = 1; // Type = Matrix
[1103]56 UpdateMemoryMapping(a, SameMemoryMapping);
[762]57}
58
[894]59//! Constructor by copy
60/*!
61 \param share : if true, share data. If false copy data
62 */
[762]63template <class T>
[804]64TMatrix<T>::TMatrix(const TMatrix<T>& a, bool share)
[762]65// Constructeur par copie avec possibilite de forcer le partage ou non.
[804]66: TArray<T>(a, share)
[762]67{
[1099]68 arrtype_ = 1; // Type = Matrix
[1103]69 UpdateMemoryMapping(a, SameMemoryMapping);
[762]70}
71
[894]72//! Constructor of a matrix from a TArray \b a
[762]73template <class T>
[804]74TMatrix<T>::TMatrix(const TArray<T>& a)
75: TArray<T>(a)
[762]76{
[813]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 }
[1099]84 arrtype_ = 1; // Type = Matrix
[813]85 UpdateMemoryMapping(a, SameMemoryMapping);
[762]86}
87
[894]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 */
[762]94template <class T>
[804]95TMatrix<T>::TMatrix(const TArray<T>& a, bool share, short mm )
96: TArray<T>(a, share)
[762]97{
[813]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 }
[1099]105 arrtype_ = 1; // Type = Matrix
[804]106 UpdateMemoryMapping(a, mm);
[762]107}
108
[1099]109//! Constructor of a matrix from a TArray \b a , with a different data type
[1081]110template <class T>
111TMatrix<T>::TMatrix(const BaseArray& a)
112: TArray<T>()
113{
[1099]114 arrtype_ = 1; // Type = Matrix
[1103]115 UpdateMemoryMapping(a, SameMemoryMapping);
[1081]116 SetBA(a);
117}
118
119
120
[894]121//! Destructor
[762]122template <class T>
[804]123TMatrix<T>::~TMatrix()
[762]124{
125}
126
[976]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*/
[804]132template <class T>
133TArray<T>& TMatrix<T>::Set(const TArray<T>& a)
[762]134{
[813]135 if (a.NbDimensions() > 2)
136 throw SzMismatchError("TMatrix<T>::Set(const TArray<T>& a) a.NbDimensions() > 2");
[1099]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");
[813]139 TArray<T>::Set(a);
[970]140 if (NbDimensions() == 1) {
[813]141 size_[1] = 1;
142 step_[1] = size_[0]*step_[0];
143 ndim_ = 2;
144 }
[970]145 UpdateMemoryMapping(*this, SameMemoryMapping);
[813]146 return(*this);
[762]147}
148
[1081]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");
[1099]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");
[1081]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
[894]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 */
[804]176template <class T>
[1156]177void TMatrix<T>::ReSize(sa_size_t r, sa_size_t c, short mm)
[762]178{
[804]179 if(r==0||c==0)
180 throw(SzMismatchError("TMatrix::ReSize r or c==0 "));
[1099]181 if ((arrtype_ == 2) && (r > 1) && (c > 1))
182 throw(SzMismatchError("TMatrix::ReSize r>1&&c>1 for Vector "));
[1156]183 sa_size_t size[BASEARRAY_MAXNDIMS];
184 for(int_4 kk=0; kk<BASEARRAY_MAXNDIMS; kk++) size[kk] = 0;
[804]185 if (mm == SameMemoryMapping) mm = GetMemoryMapping();
[813]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 }
[804]194 TArray<T>::ReSize(2, size, 1);
[813]195 UpdateMemoryMapping(mm);
[762]196}
197
[894]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 */
[762]207template <class T>
[1156]208void TMatrix<T>::Realloc(sa_size_t r,sa_size_t c, short mm, bool force)
[762]209{
[804]210 if(r==0||c==0)
211 throw(SzMismatchError("TMatrix::Realloc r or c==0 "));
[1099]212 if ((arrtype_ == 2) && (r > 1) && (c > 1))
213 throw(SzMismatchError("TMatrix::Realloc r>1&&c>1 for Vector "));
[1156]214 sa_size_t size[BASEARRAY_MAXNDIMS];
215 for(int_4 kk=0; kk<BASEARRAY_MAXNDIMS; kk++) size[kk] = 0;
[813]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 }
[804]225 TArray<T>::Realloc(2, size, 1, force);
[813]226 UpdateMemoryMapping(mm);
[762]227}
228
[804]229// $CHECK$ Reza 03/2000 Doit-on declarer cette methode const ?
[894]230//! Return a submatrix define by \b Range \b rline and \b rcol
[762]231template <class T>
[813]232TMatrix<T> TMatrix<T>::SubMatrix(Range rline, Range rcol) const
[762]233{
[813]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 return(sm);
[762]241}
242
[804]243////////////////////////////////////////////////////////////////
244// Transposition
[1412]245//! Transpose matrix in place, by changing the memory mapping
[762]246template <class T>
[1412]247TMatrix<T>& TMatrix<T>::TransposeSelf()
[804]248{
[813]249 short vt = (marowi_ == veceli_) ? ColumnVector : RowVector;
[1156]250 int_4 rci = macoli_;
[804]251 macoli_ = marowi_;
252 marowi_ = rci;
[813]253 veceli_ = (vt == ColumnVector ) ? marowi_ : macoli_;
[804]254 return(*this);
[762]255}
256
257
[1412]258//! Returns the transpose of the original matrix.
[894]259/*!
[1412]260 The data is shared between the two matrices
261 \return return a new matrix
262 */
263template <class T>
264TMatrix<T> TMatrix<T>::Transpose()
265{
266 TMatrix<T> tm(*this);
267 tm.TransposeSelf();
268 return tm;
269}
270
271//! Returns a new matrix, corresponding to the transpose of the original matrix
272/*!
[894]273 \param mm : define the memory mapping type
274 (SameMemoryMapping,CMemoryMapping,FortranMemoryMapping)
275 \return return a new matrix
276 */
[762]277template <class T>
[804]278TMatrix<T> TMatrix<T>::Transpose(short mm)
[762]279{
[804]280 if (mm == SameMemoryMapping) mm = GetMemoryMapping();
281 TMatrix<T> tm(NCols(), NRows(), mm);
[1156]282 for(sa_size_t i=0; i<NRows(); i++)
283 for(sa_size_t j=0; j<NCols(); j++)
[804]284 tm(j,i) = (*this)(i,j);
285 return tm;
[762]286}
287
[1412]288//! Rearrange data in memory according to \b mm
[894]289/*!
290 \param mm : define the memory mapping type
291 (SameMemoryMapping,CMemoryMapping,FortranMemoryMapping)
292 \warning If identical, return a matrix that share the datas
293 */
[762]294template <class T>
[804]295TMatrix<T> TMatrix<T>::Rearrange(short mm)
[762]296{
[813]297 if ( mm == SameMemoryMapping) mm = GetMemoryMapping();
298 else if ( (mm != CMemoryMapping) && (mm != FortranMemoryMapping) )
299 mm = GetDefaultMemoryMapping();
300
301 if (mm == GetMemoryMapping())
302 return (TMatrix<T>(*this, true));
303
[804]304 TMatrix<T> tm(NRows(), NCols(), mm);
[1156]305 for(sa_size_t i=0; i<NRows(); i++)
306 for(sa_size_t j=0; j<NCols(); j++)
[804]307 tm(i,j) = (*this)(i,j);
308 return tm;
[762]309}
310
[894]311//! Set the matrix to the identity matrix \b imx
[762]312template <class T>
[804]313TMatrix<T>& TMatrix<T>::SetIdentity(IdentityMatrix imx)
[762]314{
[804]315 if (ndim_ == 0) {
[1156]316 sa_size_t sz = imx.Size();
[804]317 if (sz < 1) sz = 1;
318 ReSize(sz, sz);
319 }
320 T diag = (T)imx.Diag();
321 if (NRows() != NCols())
322 throw SzMismatchError("TMatrix::operator= (IdentityMatrix) NRows() != NCols()") ;
[996]323 *this = (T) 0;
[1156]324 for(sa_size_t i=0; i<NRows(); i++) (*this)(i,i) = diag;
[762]325
[804]326 return (*this);
[762]327}
328
[804]329
330
331////////////////////////////////////////////////////////////////
332//**** Impression
[894]333//! Return info on number of rows, column and type \b T
[762]334template <class T>
[813]335string TMatrix<T>::InfoString() const
336{
337 string rs = "TMatrix<";
338 rs += typeid(T).name();
339 char buff[64];
340 sprintf(buff, ">(NRows=%ld, NCols=%ld)", (long)NRows(), (long)NCols());
341 rs += buff;
342 return(rs);
343}
344
[894]345//! Print matrix
346/*!
[1554]347 \param os : output stream
[894]348 \param maxprt : maximum numer of print
349 \param si : if true, display attached DvList
[1554]350 \param ascd : if true, suppresses the display of line numbers,
351 suitable for ascii dump format.
[894]352 \sa SetMaxPrint
353 */
[813]354template <class T>
[1581]355void TMatrix<T>::Print(ostream& os, sa_size_t maxprt, bool si, bool ascd) const
[762]356{
[804]357 if (maxprt < 0) maxprt = max_nprt_;
[1156]358 sa_size_t npr = 0;
[804]359 Show(os, si);
[850]360 if (ndim_ < 1) return;
[1156]361 sa_size_t kc,kr;
[804]362 for(kr=0; kr<size_[marowi_]; kr++) {
[1554]363 if ( (size_[marowi_] > 1) && (size_[macoli_] > 10) && ascd) cout << "----- Line= " << kr << endl;
[804]364 for(kc=0; kc<size_[macoli_]; kc++) {
[1554]365 if(kc > 0) os << " ";
[804]366 os << (*this)(kr, kc); npr++;
[1156]367 if (npr >= (sa_size_t) maxprt) {
[804]368 if (npr < totsize_) os << "\n .... " << endl; return;
369 }
370 }
371 os << endl;
372 }
[813]373 os << endl;
[762]374}
375
376////////////////////////////////////////////////////////////////
[804]377//**** Multiplication matricielle *****
[762]378////////////////////////////////////////////////////////////////
379
[894]380//! Return the matrix product C = (*this)*B
381/*!
382 \param mm : define the memory mapping type for the return matrix
383 */
[804]384template <class T>
385TMatrix<T> TMatrix<T>::Multiply(const TMatrix<T>& b, short mm) const
386{
387 if (NCols() != b.NRows())
388 throw(SzMismatchError("TMatrix<T>::Multiply(b) NCols() != b.NRows() ") );
389 if (mm == SameMemoryMapping) mm = GetMemoryMapping();
390 TMatrix<T> rm(NRows(), b.NCols(), mm);
[762]391
[804]392 const T * pea;
393 const T * peb;
394 T sum;
[1156]395 sa_size_t r,c,k;
396 sa_size_t stepa = Step(ColsKA());
[1415]397 sa_size_t stepb = b.Step(b.RowsKA());
[804]398 // Calcul de C=rm = A*B (A=*this)
399 for(r=0; r<rm.NRows(); r++) // Boucle sur les lignes de A
400 for(c=0; c<rm.NCols(); c++) { // Boucle sur les colonnes de B
401 sum = 0;
402 pea = &((*this)(r,0)); // 1er element de la ligne r de A
403 peb = &(b(0,c)); // 1er element de la colonne c de B
404 for(k=0; k<NCols(); k++) sum += pea[k*stepa]*peb[k*stepb];
405 rm(r,c) = sum;
406 }
407
408 return rm;
409}
410
[762]411///////////////////////////////////////////////////////////////
412#ifdef __CXX_PRAGMA_TEMPLATES__
413#pragma define_template TMatrix<uint_2>
[1543]414#pragma define_template TMatrix<uint_8>
[762]415#pragma define_template TMatrix<int_4>
416#pragma define_template TMatrix<int_8>
417#pragma define_template TMatrix<r_4>
[804]418#pragma define_template TMatrix<r_8>
[762]419#pragma define_template TMatrix< complex<r_4> >
420#pragma define_template TMatrix< complex<r_8> >
421#endif
422
423#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
424template class TMatrix<uint_2>;
[1543]425template class TMatrix<uint_8>;
[762]426template class TMatrix<int_4>;
427template class TMatrix<int_8>;
428template class TMatrix<r_4>;
429template class TMatrix<r_8>;
430template class TMatrix< complex<r_4> >;
431template class TMatrix< complex<r_8> >;
432#endif
Note: See TracBrowser for help on using the repository browser.