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

Last change on this file since 2786 was 2756, checked in by ansari, 20 years ago

certaines manipulation ios (iomanip) supprimees (Compile pas sur OSF1-cxx) - Reza 23/05/2005

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