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

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

bug mise a zero elts hors diag SetIdentity cmv 2/5/00

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