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

Last change on this file since 2615 was 2615, checked in by cmv, 21 years ago

using namespace sophya enleve de machdefs.h, nouveau sopnamsp.h cmv 10/09/2004

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