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

Last change on this file since 2575 was 2575, checked in by ansari, 21 years ago

1/ Remplacement des methodes Add/Sub/Mul/DivElt(a) par

Add/Sub/Mul/DivElt(TArray a, TArray res)

2/ Operateurs += -= A+B A-B TArray et TMatrix/TVecteur modifies en consequence
3/ Ajout methode TArray::ScalarProduct()
4/ Methode TArray::SetT renomme en SetCst() SetT garde en alias
5/ Ajout parametre bool fzero (mise a zero) ajoute ds constructeur et

ReSize() de TMatrix et TVecteur.

Reza 29/07/2004

File size: 18.5 KB
RevLine 
[2575]1// $Id: tmatrix.cc,v 1.26 2004-07-29 12:31:16 ansari 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
[2574]9//#define DO_NOT_OPTIMIZE_PRODUCT
10
[926]11/*!
12 \class SOPHYA::TMatrix
13 \ingroup TArray
[2267]14
15 The TMatrix class specializes the TArray class for representing
16 two dimensional arrays as matrices. Matrix and vector operations,
17 such as matrix multiplication or transposition is implemented.
18 \b Matrix is a typedef for double precision floating point matrix ( TMatrix<r_8> ).
19
20 \sa SOPHYA::TArray SOPHYA::TVector
21 \sa SOPHYA::Range \sa SOPHYA::Sequence
22 \sa SOPHYA::MathArray \sa SOPHYA::SimpleMatrixOperation
23
24 The following sample code illustrates vector-matrix multiplication
25 and matrix inversion, using simple gauss inversion.
26 \code
27 #include "array.h"
28 // ....
29 int n = 5; // Size of matrix and vectors here
30 Matrix a(n,n);
31 a = RandomSequence(RandomSequence::Gaussian, 0., 2.5);
32 Vector x(n);
33 x = RegularSequence(1.,3.);
34 Vector b = a*x;
35 cout << " ----- Vector x = \n " << x << endl;
36 cout << " ----- Vector b = a*x = \n " << b << endl;
37 SimpleMatrixOperation<r_8> smo;
38 Matrix inva = smo.Inverse(a);
39 cout << " ----- Matrix Inverse(a) = \n " << inva << endl;
40 cout << " ----- Matrix a*Inverse(a) = \n " << inva*a << endl;
41 cout << " ----- Matrix Inverse(a)*b (=Inv(a)*a*x) = \n " << inva*b << endl;
42 cout << " ----- Matrix x-Inverse(a)*b = (=0 ?)\n " << x-inva*b << endl;
43 \endcode
44
[926]45 */
[804]46
[762]47////////////////////////////////////////////////////////////////
48//**** Createur, Destructeur
[894]49//! Default constructor
[762]50template <class T>
51TMatrix<T>::TMatrix()
52// Constructeur par defaut.
[804]53 : TArray<T>()
[762]54{
[1099]55 arrtype_ = 1; // Type = Matrix
[762]56}
57
[894]58//! constructor of a matrix with r lines et c columns.
59/*!
60 \param r : number of rows
61 \param c : number of columns
62 \param mm : define the memory mapping type
[2575]63 \param fzero : if \b true , set matrix elements to zero
[894]64 \sa ReSize
65 */
[762]66template <class T>
[2575]67TMatrix<T>::TMatrix(sa_size_t r,sa_size_t c, short mm, bool fzero)
[762]68// Construit une matrice de r lignes et c colonnes.
[804]69 : TArray<T>()
[762]70{
[804]71 if ( (r == 0) || (c == 0) )
[1156]72 throw ParmError("TMatrix<T>::TMatrix(sa_size_t r,sa_size_t c) NRows or NCols = 0");
[1099]73 arrtype_ = 1; // Type = Matrix
[2575]74 ReSize(r, c, mm, fzero);
[762]75}
76
[967]77//! Constructor by copy
[976]78/*!
79 \warning datas are \b SHARED with \b a.
80 \sa NDataBlock::NDataBlock(const NDataBlock<T>&)
81*/
[762]82template <class T>
83TMatrix<T>::TMatrix(const TMatrix<T>& a)
[967]84// Constructeur par copie
[804]85 : TArray<T>(a)
[762]86{
[1099]87 arrtype_ = 1; // Type = Matrix
[1103]88 UpdateMemoryMapping(a, SameMemoryMapping);
[762]89}
90
[894]91//! Constructor by copy
92/*!
93 \param share : if true, share data. If false copy data
94 */
[762]95template <class T>
[804]96TMatrix<T>::TMatrix(const TMatrix<T>& a, bool share)
[762]97// Constructeur par copie avec possibilite de forcer le partage ou non.
[804]98: TArray<T>(a, share)
[762]99{
[1099]100 arrtype_ = 1; // Type = Matrix
[1103]101 UpdateMemoryMapping(a, SameMemoryMapping);
[762]102}
103
[894]104//! Constructor of a matrix from a TArray \b a
[762]105template <class T>
[804]106TMatrix<T>::TMatrix(const TArray<T>& a)
107: TArray<T>(a)
[762]108{
[813]109 if (a.NbDimensions() > 2)
110 throw SzMismatchError("TMatrix<T>::TMatrix(const TArray<T>& a) a.NbDimensions()>2 ");
111 if (a.NbDimensions() == 1) {
112 size_[1] = 1;
113 step_[1] = size_[0]*step_[0];
114 ndim_ = 2;
115 }
[1099]116 arrtype_ = 1; // Type = Matrix
[813]117 UpdateMemoryMapping(a, SameMemoryMapping);
[762]118}
119
[894]120//! Constructor of a matrix from a TArray \b a
121/*!
122 \param a : TArray to be copied or shared
123 \param share : if true, share data. If false copy data
124 \param mm : define the memory mapping type
125 */
[762]126template <class T>
[804]127TMatrix<T>::TMatrix(const TArray<T>& a, bool share, short mm )
128: TArray<T>(a, share)
[762]129{
[813]130 if (a.NbDimensions() > 2)
131 throw SzMismatchError("TMatrix<T>::TMatrix(const TArray<T>& a, ...) a.NbDimensions()>2");
132 if (a.NbDimensions() == 1) {
133 size_[1] = 1;
134 step_[1] = size_[0]*step_[0];
135 ndim_ = 2;
136 }
[1099]137 arrtype_ = 1; // Type = Matrix
[804]138 UpdateMemoryMapping(a, mm);
[762]139}
140
[1099]141//! Constructor of a matrix from a TArray \b a , with a different data type
[1081]142template <class T>
143TMatrix<T>::TMatrix(const BaseArray& a)
144: TArray<T>()
145{
[1099]146 arrtype_ = 1; // Type = Matrix
[1103]147 UpdateMemoryMapping(a, SameMemoryMapping);
[1081]148 SetBA(a);
149}
150
151
152
[894]153//! Destructor
[762]154template <class T>
[804]155TMatrix<T>::~TMatrix()
[762]156{
157}
158
[976]159//! Set matrix equal to \b a and return *this
160/*!
161 \warning Datas are copied (cloned) from \b a.
162 \sa NDataBlock::operator=(const NDataBlock<T>&)
163*/
[804]164template <class T>
165TArray<T>& TMatrix<T>::Set(const TArray<T>& a)
[762]166{
[813]167 if (a.NbDimensions() > 2)
168 throw SzMismatchError("TMatrix<T>::Set(const TArray<T>& a) a.NbDimensions() > 2");
[1099]169 if ((arrtype_ == 2) && (a.NbDimensions() > 1) && (a.Size(0) > 1) && (a.Size(1) > 1) )
170 throw SzMismatchError("TMatrix<T>::Set(const TArray<T>& a) Size(0,1)>1 for Vector");
[813]171 TArray<T>::Set(a);
[970]172 if (NbDimensions() == 1) {
[813]173 size_[1] = 1;
174 step_[1] = size_[0]*step_[0];
175 ndim_ = 2;
176 }
[970]177 UpdateMemoryMapping(*this, SameMemoryMapping);
[813]178 return(*this);
[762]179}
180
[1081]181template <class T>
182TArray<T>& TMatrix<T>::SetBA(const BaseArray& a)
183{
184 if (a.NbDimensions() > 2)
185 throw SzMismatchError("TMatrix<T>::SetBA(const BaseArray& a) a.NbDimensions() > 2");
[1099]186 if ((arrtype_ == 2) && (a.NbDimensions() > 1) && (a.Size(0) > 1) && (a.Size(1) > 1) )
187 throw SzMismatchError("TMatrix<T>::Set(const TArray<T>& a) Size(0,1)>1 for Vector");
[1081]188 TArray<T>::SetBA(a);
189 if (NbDimensions() == 1) {
190 size_[1] = 1;
191 step_[1] = size_[0]*step_[0];
192 ndim_ = 2;
193 }
194 UpdateMemoryMapping(*this, SameMemoryMapping);
195 return(*this);
196}
197
198
199
[894]200//! Resize the matrix
201/*!
202 \param r : number of rows
203 \param c : number of columns
204 \param mm : define the memory mapping type
205 (SameMemoryMapping,CMemoryMapping
206 ,FortranMemoryMapping,DefaultMemoryMapping)
[2575]207 \param fzero : if \b true , set matrix elements to zero
[894]208 */
[804]209template <class T>
[2575]210void TMatrix<T>::ReSize(sa_size_t r, sa_size_t c, short mm, bool fzero)
[762]211{
[804]212 if(r==0||c==0)
213 throw(SzMismatchError("TMatrix::ReSize r or c==0 "));
[1099]214 if ((arrtype_ == 2) && (r > 1) && (c > 1))
215 throw(SzMismatchError("TMatrix::ReSize r>1&&c>1 for Vector "));
[1156]216 sa_size_t size[BASEARRAY_MAXNDIMS];
217 for(int_4 kk=0; kk<BASEARRAY_MAXNDIMS; kk++) size[kk] = 0;
[804]218 if (mm == SameMemoryMapping) mm = GetMemoryMapping();
[813]219 else if ( (mm != CMemoryMapping) && (mm != FortranMemoryMapping) )
220 mm = GetDefaultMemoryMapping();
221 if (mm == CMemoryMapping) {
222 size[0] = c; size[1] = r;
223 }
224 else {
225 size[0] = r; size[1] = c;
226 }
[2575]227 TArray<T>::ReSize(2, size, 1, fzero);
[813]228 UpdateMemoryMapping(mm);
[762]229}
230
[894]231//! Re-allocate space for the matrix
232/*!
233 \param r : number of rows
234 \param c : number of columns
235 \param mm : define the memory mapping type
236 \param force : if true re-allocation is forced, if not it occurs
237 only if the required space is greater than the old one.
238 \sa ReSize
239 */
[762]240template <class T>
[1156]241void TMatrix<T>::Realloc(sa_size_t r,sa_size_t c, short mm, bool force)
[762]242{
[804]243 if(r==0||c==0)
244 throw(SzMismatchError("TMatrix::Realloc r or c==0 "));
[1099]245 if ((arrtype_ == 2) && (r > 1) && (c > 1))
246 throw(SzMismatchError("TMatrix::Realloc r>1&&c>1 for Vector "));
[1156]247 sa_size_t size[BASEARRAY_MAXNDIMS];
248 for(int_4 kk=0; kk<BASEARRAY_MAXNDIMS; kk++) size[kk] = 0;
[813]249 if (mm == SameMemoryMapping) mm = GetMemoryMapping();
250 else if ( (mm != CMemoryMapping) && (mm != FortranMemoryMapping) )
251 mm = GetDefaultMemoryMapping();
252 if (mm == CMemoryMapping) {
253 size[0] = c; size[1] = r;
254 }
255 else {
256 size[0] = r; size[1] = c;
257 }
[804]258 TArray<T>::Realloc(2, size, 1, force);
[813]259 UpdateMemoryMapping(mm);
[762]260}
261
[804]262// $CHECK$ Reza 03/2000 Doit-on declarer cette methode const ?
[894]263//! Return a submatrix define by \b Range \b rline and \b rcol
[762]264template <class T>
[813]265TMatrix<T> TMatrix<T>::SubMatrix(Range rline, Range rcol) const
[762]266{
[813]267 short mm = GetMemoryMapping();
268 Range rx, ry;
269 if (mm == CMemoryMapping) { rx = rcol; ry = rline; }
270 else { ry = rcol; rx = rline; }
271 TMatrix sm(SubArray(rx, ry, Range(0), Range(0), Range(0)),true, mm);
272 sm.UpdateMemoryMapping(mm);
273 return(sm);
[762]274}
275
[804]276////////////////////////////////////////////////////////////////
277// Transposition
[1412]278//! Transpose matrix in place, by changing the memory mapping
[762]279template <class T>
[1412]280TMatrix<T>& TMatrix<T>::TransposeSelf()
[804]281{
[813]282 short vt = (marowi_ == veceli_) ? ColumnVector : RowVector;
[1156]283 int_4 rci = macoli_;
[804]284 macoli_ = marowi_;
285 marowi_ = rci;
[813]286 veceli_ = (vt == ColumnVector ) ? marowi_ : macoli_;
[804]287 return(*this);
[762]288}
289
290
[1412]291//! Returns the transpose of the original matrix.
[894]292/*!
[1412]293 The data is shared between the two matrices
294 \return return a new matrix
295 */
296template <class T>
[2421]297TMatrix<T> TMatrix<T>::Transpose() const
[1412]298{
299 TMatrix<T> tm(*this);
300 tm.TransposeSelf();
301 return tm;
302}
303
304//! Returns a new matrix, corresponding to the transpose of the original matrix
305/*!
[894]306 \param mm : define the memory mapping type
307 (SameMemoryMapping,CMemoryMapping,FortranMemoryMapping)
308 \return return a new matrix
309 */
[762]310template <class T>
[2421]311TMatrix<T> TMatrix<T>::Transpose(short mm) const
[762]312{
[804]313 if (mm == SameMemoryMapping) mm = GetMemoryMapping();
314 TMatrix<T> tm(NCols(), NRows(), mm);
[1156]315 for(sa_size_t i=0; i<NRows(); i++)
316 for(sa_size_t j=0; j<NCols(); j++)
[804]317 tm(j,i) = (*this)(i,j);
318 return tm;
[762]319}
320
[1412]321//! Rearrange data in memory according to \b mm
[894]322/*!
323 \param mm : define the memory mapping type
324 (SameMemoryMapping,CMemoryMapping,FortranMemoryMapping)
325 \warning If identical, return a matrix that share the datas
326 */
[762]327template <class T>
[2421]328TMatrix<T> TMatrix<T>::Rearrange(short mm) const
[762]329{
[813]330 if ( mm == SameMemoryMapping) mm = GetMemoryMapping();
331 else if ( (mm != CMemoryMapping) && (mm != FortranMemoryMapping) )
332 mm = GetDefaultMemoryMapping();
333
334 if (mm == GetMemoryMapping())
335 return (TMatrix<T>(*this, true));
336
[804]337 TMatrix<T> tm(NRows(), NCols(), mm);
[1156]338 for(sa_size_t i=0; i<NRows(); i++)
339 for(sa_size_t j=0; j<NCols(); j++)
[804]340 tm(i,j) = (*this)(i,j);
341 return tm;
[762]342}
343
[894]344//! Set the matrix to the identity matrix \b imx
[762]345template <class T>
[804]346TMatrix<T>& TMatrix<T>::SetIdentity(IdentityMatrix imx)
[762]347{
[804]348 if (ndim_ == 0) {
[1156]349 sa_size_t sz = imx.Size();
[804]350 if (sz < 1) sz = 1;
351 ReSize(sz, sz);
352 }
353 T diag = (T)imx.Diag();
354 if (NRows() != NCols())
355 throw SzMismatchError("TMatrix::operator= (IdentityMatrix) NRows() != NCols()") ;
[996]356 *this = (T) 0;
[1156]357 for(sa_size_t i=0; i<NRows(); i++) (*this)(i,i) = diag;
[762]358
[804]359 return (*this);
[762]360}
361
[804]362
363
364////////////////////////////////////////////////////////////////
365//**** Impression
[894]366//! Return info on number of rows, column and type \b T
[762]367template <class T>
[813]368string TMatrix<T>::InfoString() const
369{
370 string rs = "TMatrix<";
371 rs += typeid(T).name();
372 char buff[64];
373 sprintf(buff, ">(NRows=%ld, NCols=%ld)", (long)NRows(), (long)NCols());
374 rs += buff;
375 return(rs);
376}
377
[894]378//! Print matrix
379/*!
[1554]380 \param os : output stream
[894]381 \param maxprt : maximum numer of print
382 \param si : if true, display attached DvList
[1554]383 \param ascd : if true, suppresses the display of line numbers,
384 suitable for ascii dump format.
[894]385 \sa SetMaxPrint
386 */
[813]387template <class T>
[1581]388void TMatrix<T>::Print(ostream& os, sa_size_t maxprt, bool si, bool ascd) const
[762]389{
[804]390 if (maxprt < 0) maxprt = max_nprt_;
[1156]391 sa_size_t npr = 0;
[804]392 Show(os, si);
[850]393 if (ndim_ < 1) return;
[1156]394 sa_size_t kc,kr;
[804]395 for(kr=0; kr<size_[marowi_]; kr++) {
[1554]396 if ( (size_[marowi_] > 1) && (size_[macoli_] > 10) && ascd) cout << "----- Line= " << kr << endl;
[804]397 for(kc=0; kc<size_[macoli_]; kc++) {
[1554]398 if(kc > 0) os << " ";
[804]399 os << (*this)(kr, kc); npr++;
[1156]400 if (npr >= (sa_size_t) maxprt) {
[804]401 if (npr < totsize_) os << "\n .... " << endl; return;
402 }
403 }
404 os << endl;
405 }
[813]406 os << endl;
[762]407}
408
409////////////////////////////////////////////////////////////////
[804]410//**** Multiplication matricielle *****
[762]411////////////////////////////////////////////////////////////////
412
[894]413//! Return the matrix product C = (*this)*B
414/*!
415 \param mm : define the memory mapping type for the return matrix
416 */
[2574]417////////////// Routine de base sans optimisation //////////////
418/*
[804]419template <class T>
420TMatrix<T> TMatrix<T>::Multiply(const TMatrix<T>& b, short mm) const
421{
422 if (NCols() != b.NRows())
423 throw(SzMismatchError("TMatrix<T>::Multiply(b) NCols() != b.NRows() ") );
424 if (mm == SameMemoryMapping) mm = GetMemoryMapping();
425 TMatrix<T> rm(NRows(), b.NCols(), mm);
[762]426
[804]427 const T * pea;
428 const T * peb;
429 T sum;
[1156]430 sa_size_t r,c,k;
431 sa_size_t stepa = Step(ColsKA());
[1415]432 sa_size_t stepb = b.Step(b.RowsKA());
[804]433 // Calcul de C=rm = A*B (A=*this)
434 for(r=0; r<rm.NRows(); r++) // Boucle sur les lignes de A
435 for(c=0; c<rm.NCols(); c++) { // Boucle sur les colonnes de B
436 sum = 0;
437 pea = &((*this)(r,0)); // 1er element de la ligne r de A
438 peb = &(b(0,c)); // 1er element de la colonne c de B
439 for(k=0; k<NCols(); k++) sum += pea[k*stepa]*peb[k*stepb];
440 rm(r,c) = sum;
441 }
442
443 return rm;
444}
[2574]445*/
[804]446
[2574]447////////////// Routine optimisee //////////////
448template <class T>
449TMatrix<T> TMatrix<T>::Multiply(const TMatrix<T>& b, short mm) const
450{
451 if (NCols() != b.NRows())
452 throw(SzMismatchError("TMatrix<T>::Multiply(b) NCols() != b.NRows() ") );
453
454 // Commentaire: pas de difference de vitesse notable selon les mappings choisis pour la matrice produit "rm"
455 if (mm == SameMemoryMapping) mm = GetMemoryMapping();
456 TMatrix<T> rm(NRows(), b.NCols(), mm);
457 rm = (T) 0; // Rien ne garantit que rm soit mise a zero a la creation !
458
459 // Les "steps" pour l'adressage des colonnes de A et des lignes de B
460 sa_size_t stepa = Step(ColsKA());
461 sa_size_t stepb = b.Step(b.RowsKA());
462
463 // On decide si on optimise ou non selon les dimensions de A et B
464 // (il semble que optimiser ou non ne degrade pas notablement la vitesse pour les petites matrices)
465#ifdef DO_NOT_OPTIMIZE_PRODUCT
466 bool no_optim = true;
467#else
468 bool no_optim = false;
469 //NON juste pour memoire: if((stepa+stepb)*NCols()*sizeof(T)<100000) no_optim=true;
470#endif
471
472 // Calcul de C=rm = A*B (A=*this)
473 // Remember: C-like matrices are column packed
474 // Fortan-like matrices are line packed
475 sa_size_t r,c,k;
476 T sum;
477 const T * pe;
478
479 // Pas d'optimisation demandee
480 if( no_optim ) {
481 //cout<<"no_optim("<<no_optim<<") "<<stepa<<" "<<stepb<<endl;
482 const T * pea;
483 const T * peb;
484 for(r=0; r<rm.NRows(); r++) { // Boucle sur les lignes de A
485 for(c=0; c<rm.NCols(); c++) { // Boucle sur les colonnes de B
486 sum = 0;
487 pea = &((*this)(r,0));
488 peb = &(b(0,c));
489 // On gagne un peu en remplacant "pea[k*stepa]" par "pea+=stepa" pour les grosses matrices
490 //for(k=0; k<NCols(); k++) sum += pea[k*stepa]*peb[k*stepb];
491 for(k=0; k<NCols(); k++) {sum += (*pea)*(*peb); pea+=stepa; peb+=stepb;}
492 rm(r,c) = sum;
493 }
494 }
495 }
496 // A.col est packed et B.row est packed (on a interet a optimiser quand meme)
497 else if(stepa==1 && stepb==1) {
498 //cout<<"A.col packed && B.row not packed "<<stepa<<" "<<stepb<<endl;
499 T * pea = new T[rm.NCols()];
500 const T * peb;
501 for(r=0; r<rm.NRows(); r++) { // Boucle sur les lignes de A
502 pe = &((*this)(r,0));
503 for(k=0; k<NCols(); k++) {pea[k] = *(pe++);}
504 for(c=0; c<rm.NCols(); c++) { // Boucle sur les colonnes de B
505 sum = 0;
506 peb = &(b(0,c));
507 for(k=0; k<NCols(); k++) sum += *(peb++)*pea[k];
508 rm(r,c) = sum;
509 }
510 }
511 delete [] pea;
512 }
513 // A.col est packed et B.row n'est pas packed
514 else if(stepa==1 && stepb!=1) {
515 //cout<<"A.col packed && B.row not packed "<<stepa<<" "<<stepb<<endl;
516 const T * pea;
517 T * peb = new T[rm.NCols()];
518 for(c=0; c<rm.NCols(); c++) { // Boucle sur les colonnes de B
519 pe = &(b(0,c));
520 for(k=0; k<NCols(); k++) {peb[k] = *pe; pe+=stepb;}
521 for(r=0; r<rm.NRows(); r++) { // Boucle sur les lignes de A
522 sum = 0;
523 pea = &((*this)(r,0));
524 for(k=0; k<NCols(); k++) sum += pea[k]*peb[k];
525 rm(r,c) = sum;
526 }
527 }
528 delete [] peb;
529 }
530 // A.col n'est pas packed et B.row est packed
531 else if(stepa!=1 && stepb==1) {
532 //cout<<"A.col not packed && B.row packed "<<stepa<<" "<<stepb<<endl;
533 T * pea = new T[rm.NCols()];
534 const T * peb;
535 for(r=0; r<rm.NRows(); r++) { // Boucle sur les lignes de A
536 pe = &((*this)(r,0));
537 for(k=0; k<NCols(); k++) {pea[k] = *pe; pe+=stepa;}
538 for(c=0; c<rm.NCols(); c++) { // Boucle sur les colonnes de B
539 sum = 0;
540 peb = &(b(0,c));
541 for(k=0; k<NCols(); k++) sum += pea[k]*peb[k];
542 rm(r,c) = sum;
543 }
544 }
545 delete [] pea;
546 }
547 // A.col n'est pas packed et B.row n'est pas packed, stepb>stepa
548 else if(stepa!=1 && stepb!=1 && stepb>stepa) {
549 //cout<<"A.col not packed && B.row not packed ==> optimize on B "<<stepa<<" "<<stepb<<endl;
550 const T * pea;
551 T * peb = new T[rm.NCols()];
552 for(c=0; c<rm.NCols(); c++) { // Boucle sur les colonnes de B
553 pe = &(b(0,c));
554 for(k=0; k<NCols(); k++) {peb[k] = *pe; pe+=stepb;}
555 for(r=0; r<rm.NRows(); r++) { // Boucle sur les lignes de A
556 sum = 0;
557 pea = &((*this)(r,0));
558 for(k=0; k<NCols(); k++) {sum += (*pea)*peb[k]; pea+=stepa;}
559 rm(r,c) = sum;
560 }
561 }
562 delete [] peb;
563 }
564 // A.col n'est pas packed et B.row n'est pas packed, stepa>=stepb
565 else if(stepa!=1 && stepb!=1) {
566 //cout<<"A.col not packed && B.row not packed ==> optimize on A "<<stepa<<" "<<stepb<<endl;
567 T * pea = new T[rm.NCols()];
568 const T * peb;
569 for(r=0; r<rm.NRows(); r++) { // Boucle sur les lignes de A
570 pe = &((*this)(r,0));
571 for(k=0; k<NCols(); k++) {pea[k] = *pe; pe+=stepa;}
572 for(c=0; c<rm.NCols(); c++) { // Boucle sur les colonnes de B
573 sum = 0;
574 peb = &(b(0,c));
575 for(k=0; k<NCols(); k++) {sum += pea[k]*(*peb); peb+=stepb;}
576 rm(r,c) = sum;
577 }
578 }
579 delete [] pea;
580 }
581 else {
582 cout<<"TMatrix<T>::Multiply(b) Optimize case not treated... Please report BUG !!! "<<endl;
583 throw(SzMismatchError("TMatrix<T>::Multiply(b) Optimize case not treated... Please report BUG !!! ") );
584 }
585
586 return rm;
587}
588
[762]589///////////////////////////////////////////////////////////////
590#ifdef __CXX_PRAGMA_TEMPLATES__
591#pragma define_template TMatrix<uint_2>
[1543]592#pragma define_template TMatrix<uint_8>
[762]593#pragma define_template TMatrix<int_4>
594#pragma define_template TMatrix<int_8>
595#pragma define_template TMatrix<r_4>
[804]596#pragma define_template TMatrix<r_8>
[762]597#pragma define_template TMatrix< complex<r_4> >
598#pragma define_template TMatrix< complex<r_8> >
599#endif
600
601#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
602template class TMatrix<uint_2>;
[1543]603template class TMatrix<uint_8>;
[762]604template class TMatrix<int_4>;
605template class TMatrix<int_8>;
606template class TMatrix<r_4>;
607template class TMatrix<r_8>;
608template class TMatrix< complex<r_4> >;
609template class TMatrix< complex<r_8> >;
610#endif
Note: See TracBrowser for help on using the repository browser.