Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

mdp_matrix.h

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00022 class mdp_matrix {
00023 private:
00024 
00025   enum {FREE, HARD} flag;
00026   uint irows,icols,imax;
00027   mdp_complex *m;
00028 
00029   uint& rows(); 
00030   uint& cols();
00031 
00032 public:
00033   void allocate();
00034   void reallocate();
00035   void deallocate();
00036   void dimension(const uint, const uint);
00037   mdp_matrix();
00038   mdp_matrix(const mdp_matrix& a);
00039   mdp_matrix(const uint r, const uint c);
00040   mdp_matrix(mdp_complex* z, const uint r, const uint c);
00041   virtual ~mdp_matrix();
00042 
00043   const mdp_matrix& operator=(const mdp_matrix& a);
00044   mdp_complex& operator[] (const uint i);
00045   const mdp_complex& operator[] (const uint i) const;
00046 
00047   mdp_complex& operator() (const uint i, const uint j);
00048   const mdp_complex& operator() (const uint i, const uint j) const;
00049   mdp_matrix operator() (const uint i);
00050 
00051   friend void prepare(mdp_matrix&); // does nothing, here for compatibility
00052 
00053   mdp_complex* address();
00054   const uint rows() const; 
00055   const uint cols() const;
00056   const uint size() const;
00057   uint rowmax() const; // compatibility function 
00058   uint colmax() const; // compatibility function
00059 
00060   friend mdp_matrix operator+ (const mdp_matrix& a);
00061   friend mdp_matrix operator- (const mdp_matrix& a);
00062   
00063   friend mdp_matrix operator+ (const mdp_matrix& a, const mdp_matrix& b);
00064   friend mdp_matrix operator- (const mdp_matrix& a, const mdp_matrix& b); // sse2
00065   friend mdp_matrix operator* (const mdp_matrix& a, const mdp_matrix& b); // sse2
00066   friend mdp_matrix operator/ (const mdp_matrix& a, const mdp_matrix& b);
00067 
00068   friend mdp_matrix operator+ (const mdp_matrix& a, mdp_complex b);
00069   friend mdp_matrix operator- (const mdp_matrix& a, mdp_complex b);
00070   friend mdp_matrix operator* (const mdp_matrix& a, mdp_complex b);
00071   friend mdp_matrix operator/ (const mdp_matrix& a, mdp_complex b);
00072 
00073   friend mdp_matrix operator+ (mdp_complex a, const mdp_matrix& b);
00074   friend mdp_matrix operator- (mdp_complex a, const mdp_matrix& b);
00075   friend mdp_matrix operator* (mdp_complex a, const mdp_matrix& b);
00076   friend mdp_matrix operator/ (mdp_complex a, const mdp_matrix& b);
00077 
00078   friend mdp_matrix operator+ (const mdp_matrix& a, mdp_real b);
00079   friend mdp_matrix operator- (const mdp_matrix& a, mdp_real b);
00080   friend mdp_matrix operator* (const mdp_matrix& a, mdp_real b);
00081   friend mdp_matrix operator/ (const mdp_matrix& a, mdp_real b);
00082 
00083   friend mdp_matrix operator+ (mdp_real a, const mdp_matrix& b);
00084   friend mdp_matrix operator- (mdp_real a, const mdp_matrix& b);
00085   friend mdp_matrix operator* (mdp_real a, const mdp_matrix& b);
00086   friend mdp_matrix operator/ (mdp_real a, const mdp_matrix& b);
00087 
00088   mdp_matrix operator+=(const mdp_matrix& a);  
00089   mdp_matrix operator-=(const mdp_matrix& a);
00090   mdp_matrix operator*=(const mdp_matrix& a);
00091   mdp_matrix operator/=(const mdp_matrix& a);
00092 
00093   mdp_matrix operator+=(mdp_complex a);
00094   mdp_matrix operator-=(mdp_complex a);
00095   mdp_matrix operator*=(mdp_complex a);
00096   mdp_matrix operator/=(mdp_complex a);
00097 
00098   mdp_matrix operator+=(mdp_real a);
00099   mdp_matrix operator-=(mdp_real a);
00100   mdp_matrix operator*=(mdp_real a);
00101   mdp_matrix operator/=(mdp_real a);
00102 
00103   void operator=(mdp_complex a);
00104   void operator=(mdp_real a);
00105 
00106   friend mdp_matrix inv(const mdp_matrix& a);
00107   friend mdp_matrix pow(const mdp_matrix& a, uint b);
00108   friend mdp_matrix exp(const mdp_matrix& a);
00109   friend mdp_matrix log(const mdp_matrix& a);
00110   friend mdp_matrix sin(const mdp_matrix& a);
00111   friend mdp_matrix cos(const mdp_matrix& a);
00112 
00113   friend mdp_matrix mdp_identity();
00114   friend mdp_matrix mdp_zero();
00115 
00116   friend mdp_real max(const mdp_matrix& a);
00117   friend mdp_matrix submatrix(const mdp_matrix& a, uint i, uint j);
00118   friend mdp_complex det(const mdp_matrix& a);
00119   friend mdp_complex trace(const mdp_matrix& a);
00120   friend mdp_matrix hermitian(const mdp_matrix& a);
00121   friend mdp_matrix transpose(const mdp_matrix& a);
00122   friend mdp_matrix conj(const mdp_matrix& a);
00123 
00124 };
00125 
00126 ostream& operator<< (ostream& os, const mdp_matrix& a) {
00127   uint i,j; // AW - unsigned added
00128   for(i=0; i<a.rows(); i++) {
00129     if(i==0) os << "[[";
00130     else     os << " [";
00131     for(j=0; j<a.cols(); j++) 
00132       if(j==0) os << " " << a(i,j);
00133       else os << ", " << a(i,j) << " ";
00134     if(i==(a.rows()-1)) os << "]]\n";
00135     else              os << "], \n";
00136   }
00137   return os;
00138 }
00139 
00140 // this is a compatibility function
00141 void print(const mdp_matrix& a) {
00142   cout << a;
00143 }
00144 
00145 void mdp_matrix::dimension(const uint a, const uint b) {
00146   flag=FREE;
00147   rows()=a; 
00148   cols()=b; 
00149   imax=a*b;
00150   reallocate();
00151 }
00152 
00153 mdp_matrix::mdp_matrix() {
00154   flag=FREE;
00155   rows()=0;  
00156   cols()=0;  
00157   imax=0;   
00158   allocate();
00159 }
00160 
00161 mdp_matrix::mdp_matrix(const mdp_matrix& a) {
00162   flag=FREE;
00163   rows()=a.rows(); 
00164   cols()=a.cols(); 
00165   imax=a.imax;
00166   allocate();
00167   for(uint i=0; i<imax; i++) m[i]=a[i];
00168 }
00169 
00170 mdp_matrix::mdp_matrix(const uint a, const uint b) {
00171   flag=FREE;
00172   rows()=a; 
00173   cols()=b; 
00174   imax=a*b; 
00175   allocate();
00176 }
00177 
00178 mdp_matrix::mdp_matrix(mdp_complex* z, const uint a, const uint b) {
00179   flag=HARD;
00180   rows()=a; 
00181   cols()=b; 
00182   imax=a*b;
00183   m=z;
00184 #if defined(USE_DOUBLE_PRECISION) && defined(MATRIX_SSE2)
00185   _sse_check_alignment((void*) m, 0xf);
00186 #endif
00187 }
00188 
00189 mdp_matrix::~mdp_matrix() {
00190   if(flag!=HARD) deallocate();
00191 }
00192 
00193 inline void mdp_matrix::allocate() {
00194   if(flag==HARD) error("mdp_matrix::allocate()\nCannot allocate a HARD object");
00195   m=new mdp_complex[imax];
00196   if(imax!=0 && m==0) error("mdp_matrix::allocate()\nOut of memory");
00197   memset(m,0,imax*sizeof(mdp_complex));
00198 }
00199 
00200 inline void mdp_matrix::reallocate() {
00201   if(flag==HARD) error("mdp_matrix::reallocate()\nCannot allocate a HARD object");
00202   deallocate();
00203   allocate();
00204 }
00205 
00206 inline void mdp_matrix::deallocate() {
00207   if(flag==HARD) error("mdp_matrix::deallocate()\nCannot allocate a HARD object");
00208   delete[] m;
00209   m=0; 
00210 }
00211  
00212 inline const mdp_matrix& mdp_matrix::operator=(const mdp_matrix& x) {
00213   uint i=0;
00214   if(rows()!=x.rows() || cols()!=x.cols()) {
00215     rows()=x.rows(); cols()=x.cols(); imax=x.imax;
00216     reallocate();
00217   }
00218   for(; i<imax; i++) m[i]=x[i];
00219   return *this;
00220 }
00221 
00222 inline mdp_complex& mdp_matrix::operator[] (uint i) {
00223   return m[i];
00224 }
00225 
00226 inline const mdp_complex& mdp_matrix::operator[] (uint i) const {
00227   return m[i];
00228 }
00229 
00230 
00231 inline mdp_complex& mdp_matrix::operator() (uint i, uint j) {
00232   return m[i*cols()+j];
00233 }
00234 
00235 inline const mdp_complex& mdp_matrix::operator() (uint i, uint j) const {
00236   return m[i*cols()+j];
00237 }
00238 
00239 inline mdp_matrix mdp_matrix::operator() (const uint i) {
00240   return mdp_matrix(m+i*cols(), cols(),1);
00241 }
00242 
00243 inline void prepare(mdp_matrix& a) {
00244 }
00245 
00246 inline mdp_complex* mdp_matrix::address() {
00247   return m;
00248 }
00249 
00250 inline uint& mdp_matrix::rows() {
00251   return irows;
00252 }
00253 
00254 inline uint& mdp_matrix::cols() {
00255   return icols;
00256 }
00257 
00258 inline const uint mdp_matrix::rows() const {
00259   return irows;
00260 }
00261 
00262 inline const uint mdp_matrix::cols() const {
00263   return icols;
00264 }
00265 
00266 inline const uint mdp_matrix::size() const {
00267   return imax;
00268 }
00269 
00270 inline uint mdp_matrix::rowmax() const {
00271   return irows;
00272 }
00273 
00274 inline uint mdp_matrix::colmax() const {
00275   return icols;
00276 }
00277 
00278 inline mdp_matrix operator+ (const mdp_matrix& a) {
00279   return a;
00280 }
00281 
00282 
00283 inline mdp_matrix operator- (const mdp_matrix& a) {
00284   mdp_matrix tmp(a.rows(), a.cols());
00285   uint i,j;
00286   for(i=0; i<a.rows(); i++)
00287     for(j=0; j<a.cols(); j++)
00288       tmp(i,j)=-a(i,j);
00289   return tmp;
00290 }
00291 
00292 
00293 
00294 inline mdp_matrix operator+ (const mdp_matrix& x, 
00295                              const mdp_matrix& y) {
00296   mdp_matrix z(x.rows(),x.cols());
00297 #if defined(CHECK_ALL)
00298   if(x.rows()!=y.rows() || x.cols()!=y.cols()) 
00299     error("mdp_matrix::operator+()\nWrong argument size");
00300 #endif
00301   for(register uint i=0; i<z.imax; i++) z[i]=x[i]+y[i];
00302   return z;
00303 }
00304 
00305 inline mdp_matrix operator- (const mdp_matrix& x, const mdp_matrix& y) {
00306   if(x.rows()!=y.rows() || x.cols()!=y.cols()) 
00307     error("mdp_matrix::operator-()\nwrong argument size");
00308   mdp_matrix z(x.rows(),x.cols());
00309   for(register uint i=0; i<z.imax; i++) z[i]=x[i]-y[i];
00310   return z;
00311 }
00312 
00313 inline mdp_matrix operator* (const mdp_matrix& x, const mdp_matrix& y) {
00314   register uint i, j, k;
00315   if(x.cols()!=y.rows()) 
00316     error("mdp_matrix::operator*()\nwrong argument size");
00317   mdp_matrix z(x.rows(),y.cols());
00318 #if defined(MATRIX_SSE2) && defined(USE_DOUBLE_PRECISION)
00319   if(x.rows()==x.cols() && y.rows()==3) {
00320     register int i, cols()=y.cols(), cols()2=2*cols();
00321     _sse_su3    *u  =(_sse_su3*) x.m;   
00322     _sse_double *in =(_sse_double*) y.m; 
00323     _sse_double *out=(_sse_double*) z.m;
00324     for(i=0; i<cols(); i++, in++, out++) {
00325       _sse_double_load_123(*in, *(in+cols()), *(in+cols()2));
00326       _sse_double_su3_multiply(*u);
00327       _sse_double_store_up_123(*out, *(out+cols()), *(out+cols()2));
00328     }
00329     return z;
00330   }
00331 #endif
00332 #if defined(MATRIX_SSE2) && !defined(USE_DOUBLE_PRECISION)
00333   if(x.rows()==x.cols() && y.imax==3) {
00334     _sse_su3        *u  =(_sse_su3*) x.m;   
00335     _sse_su3_vector *in =(_sse_su3_vector*) y.m; 
00336     _sse_su3_vector *out=(_sse_su3_vector*) z.m;    
00337     _sse_float_pair_load(*in, *in);
00338     _sse_float_su3_multiply(*u);
00339     _sse_float_pair_store_up(*out, *out);
00340     return z;
00341   }
00342 #endif
00343   for(i=0; i<x.rows(); i++)
00344     for(j=0; j<y.cols(); j++) {
00345       z(i,j)=x(i,0)*y(0,j);
00346       for(k=1; k<x.cols(); k++) z(i,j)+=x(i,k)*y(k,j);  
00347     }
00348   return z;
00349 }
00350 
00351 inline mdp_matrix operator/ (const mdp_matrix& a, 
00352                              const mdp_matrix& b) {
00353   return a*inv(b);
00354 }
00355     
00356 inline mdp_matrix operator+ (const mdp_matrix& a,  mdp_complex b) {
00357   if(a.cols()!=a.rows()) error("mdp_matrix::operator+(...)\nmdp_matrix is not squared");
00358   mdp_matrix tmp;
00359   register uint i;
00360   tmp=a;
00361   for(i=0; i<a.cols(); i++) tmp(i,i)+=b;
00362   return tmp;
00363 }
00364 
00365 inline mdp_matrix operator- (const mdp_matrix& a, mdp_complex b) {
00366   if(a.cols()!=a.rows()) error("mdp_matrix::operator-(...)\nmdp_matrix is not squared");
00367   mdp_matrix tmp;
00368   register uint i;
00369   tmp=a;
00370   for(i=0; i<a.cols(); i++) tmp(i,i)-=b;
00371   return tmp;
00372 }
00373 
00374 inline mdp_matrix operator* (const mdp_matrix& y, mdp_complex x) {
00375   register uint i;
00376   mdp_matrix z(y.rows(),y.cols());
00377 #if defined(MATRIX_SSE2)
00378   if(y.rows()==3) {
00379     static _sse_float  factor1 ALIGN16;   
00380     static _sse_float  factor2 ALIGN16;   
00381     static _sse_double factor3 ALIGN16;   
00382     static _sse_double factor4 ALIGN16;   
00383     _sse_su3_vector *in =(_sse_su3_vector*) y.m; 
00384     _sse_su3_vector *out=(_sse_su3_vector*) z.m;    
00385 #if defined(USE_DOUBLE_PRECISION)
00386     factor3.c1=factor3.c2=x.imag();
00387     factor4.c1=factor4.c2=x.real()/x.imag();
00388     for(i=0; i<y.cols(); i++, in++, out++) {
00389       _sse_double_load(*in);
00390       _sse_double_vector_mulc(factor3,factor4);
00391       _sse_double_store(*out);
00392     }
00393 #else 
00394     factor1.c1=factor1.c2=factor1.c3=factor1.c4=x.imag();
00395     factor2.c1=factor2.c2=factor2.c3=factor2.c4=x.real()/x.imag();
00396     for(i=0; i<y.cols()-1; i+=2, in+=2, out+=2) {
00397       _sse_float_pair_load(*in, *(in+1));
00398       _sse_float_vector_mulc(factor1,factor2);
00399       _sse_float_pair_store(*out, *(out+1));
00400       
00401     }
00402     if(i==y.cols()-1) {
00403       _sse_float_pair_load(*in, *in);
00404       _sse_float_vector_mulc(factor1,factor2);
00405       _sse_float_pair_store(*out, *out);
00406     }
00407 #endif
00408     return z;               
00409   }
00410 #endif
00411   for(i=0; i<y.imax; i++) z[i]=x*y[i];
00412   return z;
00413 }
00414 
00415 inline mdp_matrix operator/ (const mdp_matrix& a, mdp_complex b) {
00416   return a*(1.0/b);
00417 }
00418 ;
00419 inline mdp_matrix operator+ (mdp_complex b, const mdp_matrix& a) {
00420   return a+b;
00421 }
00422 
00423 inline mdp_matrix operator- (mdp_complex b, const mdp_matrix& a) {
00424   if(a.cols()!=a.rows()) error("mdp_matrix::operator-(...)\nmdp_matrix is not squared");
00425   mdp_matrix tmp(a.rows(), a.cols());
00426   uint i,j; 
00427   for(i=0; i<a.rows(); i++) {
00428     for(j=0; j<a.cols(); j++) tmp(i,j)=-a(i,j);
00429     tmp(i,i)+=b;
00430   }
00431   return tmp;
00432 }
00433 
00434 inline mdp_matrix operator* (mdp_complex x, const mdp_matrix& y) {
00435   return y*x;
00436 }
00437 
00438 inline mdp_matrix operator/ (mdp_complex b, const mdp_matrix& a) {
00439   return b*inv(a);
00440 }
00441 
00442 inline mdp_matrix operator+ (const mdp_matrix& a, mdp_real b) {
00443   if(a.cols()!=a.rows()) error("mdp_matrix::operator+(...)\nmdp_matrix is not squared");
00444   mdp_matrix tmp;
00445   uint i;
00446   tmp=a;
00447   for(i=0; i<a.cols(); i++) tmp(i,i).real()+=b;
00448   return tmp;  
00449 }
00450 
00451 inline mdp_matrix operator- (const mdp_matrix& a, mdp_real b) {
00452   if(a.cols()!=a.rows()) error("mdp_matrix::operator-(...)\nmdp_matrix is not squared");
00453   mdp_matrix tmp;
00454   uint i;
00455   tmp=a;
00456   for(i=0; i<a.cols(); i++) tmp(i,i).real()-=b;
00457   return tmp;  
00458 }
00459 
00460 inline mdp_matrix operator* (const mdp_matrix& y, mdp_real x) {
00461   register uint i;
00462   mdp_matrix z(y.rows(),y.cols());
00463 #if defined(MATRIX_SSE2)
00464   if(y.rows()==3) {
00465     static _sse_float  factor1 ALIGN16;   
00466     static _sse_double factor2 ALIGN16;   
00467 
00468     _sse_su3_vector *in =(_sse_su3_vector*) y.m; 
00469     _sse_su3_vector *out=(_sse_su3_vector*) z.m;    
00470 #if defined(USE_DOUBLE_PRECISION)
00471     factor2.c1=factor2.c2=x;
00472     for(i=0; i<y.cols(); i++, in++, out++) {
00473       _sse_double_load(*in);
00474       _sse_double_vector_mul(factor2);
00475       _sse_double_store(*out);
00476     }
00477 #else     
00478     factor1.c1=factor1.c2=factor1.c3=factor1.c4=x;
00479     for(i=0; i<y.cols()-1; i+=2, in+=2, out+=2) {
00480       _sse_float_pair_load(*in, *(in+1));
00481       _sse_float_vector_mul(factor1);
00482       _sse_float_pair_store(*out, *(out+1));
00483     }
00484     if(i==y.cols()-1) {
00485       _sse_float_pair_load(*in, *in);
00486       _sse_float_vector_mul(factor1);
00487       _sse_float_pair_store(*out, *out);
00488     }
00489 #endif
00490     return z;               
00491   }
00492 #endif
00493   for(i=0; i<y.imax; i++) z[i]=x*y[i];
00494   return z;
00495 }
00496 
00497 inline mdp_matrix operator/ (const mdp_matrix& a, mdp_real b) {
00498   return a*(1.0/b);
00499 }
00500 
00501 inline mdp_matrix operator+ (mdp_real b, const mdp_matrix& a) {
00502   return a+b;
00503 }
00504 
00505 inline mdp_matrix operator- (mdp_real b, const mdp_matrix& a) {
00506   if(a.cols()!=a.rows()) error("mdp_matrix::operator-(...)\nmdp_matrix is not squared");
00507   mdp_matrix tmp(a.rows(), a.cols());
00508   uint i,j; 
00509   for(i=0; i<a.rows(); i++) {
00510     for(j=0; j<a.cols(); j++) tmp(i,j)=-a(i,j);
00511     tmp(i,i)+=b;
00512   }
00513   return tmp;
00514 }
00515 
00516 inline mdp_matrix operator* (mdp_real a, const mdp_matrix& b) {
00517   return b*a;
00518 }
00519 
00520 inline mdp_matrix mdp_identity(uint i) {
00521   mdp_matrix tmp(i,i);
00522   register uint r,c;
00523   for(r=0; r<i; r++)
00524     for(c=0; c<i; c++)
00525       tmp(r,c)=(r==c)?mdp_complex(1,0):mdp_complex(0,0);
00526   return tmp;
00527 }
00528 
00529 inline mdp_matrix mdp_zero(uint i) {
00530   mdp_matrix tmp(i,i);
00531   register uint r,c;
00532   for(r=0; r<i; r++)
00533     for(c=0; c<i; c++)
00534       tmp(r,c)=(mdp_complex) 0;
00535   return tmp;
00536 }
00537 
00538 inline mdp_real max(const mdp_matrix& a) {
00539   register uint i;
00540   register double x=0,y=0;
00541   for(i=0; i<a.imax; i++) if ((y=abs(a[i]))>x) x=y;
00542   return x;
00543 }
00544 
00545 inline mdp_matrix submatrix (const mdp_matrix& a, uint i, uint j) {
00546 #ifdef CHECK_ALL
00547   if (((a.rows()<2) || (a.cols()<2)) || 
00548       ((a.rows()-1<i) || (a.cols()-1<j))) error("submatrix(...)\nWrong dimensions in submatrix");
00549 #endif
00550   mdp_matrix tmp(a.rows()-1,a.cols()-1);
00551   register uint r,c;
00552   for(r=0; r<i; r++)        
00553     for(c=0; c<j; c++)        tmp(r,c)  =a(r,c);
00554   for(r=i+1; r<a.rows(); r++) 
00555     for(c=0; c<j; c++)        tmp(r-1,c)=a(r,c);
00556   for(r=0; r<i; r++)        
00557     for(c=j+1; c<a.cols(); c++) tmp(r,c-1)=a(r,c);
00558   for(r=i+1; r<a.rows(); r++) 
00559     for(c=j+1; c<a.cols(); c++) tmp(r-1,c-1)=a(r,c);  
00560   return tmp;
00561 }
00562 
00563 inline mdp_complex det(const mdp_matrix& a) {
00564 #ifdef CHECK_ALL
00565   if (a.rows()!=a.cols()) error("det(...)\nmdp_matrix is not squared");
00566 #endif
00567   if (a.rows()==0) return 0;
00568   if (a.rows()==1) return a(0,0);
00569   register uint i,j,k,l;
00570   mdp_matrix A;
00571   A=a;
00572   mdp_complex tmp, pivot, x=mdp_complex(1,0);
00573   for(i=0; i<A.cols(); i++) {
00574     for(j=i; (A(i,j)==mdp_complex(0,0)) && (j<A.cols()); j++);
00575     if (j==A.cols()) return 0;
00576     if (i!=j) {
00577       for(k=0; k<A.rows(); k++) {
00578         tmp=A(k,j);
00579         A(k,j)=A(k,i);
00580         A(k,i)=tmp;
00581       }
00582       x*=-A(i,i);
00583     } else x*=A(i,i);
00584     for(k=i+1; k<A.rows(); k++) {
00585       pivot=A(k,i)/A(i,i);
00586       for(l=i; l<A.cols(); l++) A(k,l)-=pivot*A(i,l);
00587     }
00588   }
00589   return x;
00590 }
00591 
00592 inline mdp_matrix inv(const mdp_matrix& a) {
00593 #ifdef CHECK_ALL
00594   if ((a.rows()!=a.cols()) || (a.rows()==0)) error("inv(...)\nmdp_matrix is not squared");
00595 #endif
00596   mdp_matrix tma, tmp;
00597   mdp_complex x,pivot;
00598   register uint r,c,i,rmax;
00599   tma=a;
00600   tmp=mdp_identity(a.rows());
00601   for(c=0; c<a.cols(); c++) {
00602     rmax=c;
00603     pivot=tma(c,c);
00604     for(r=c+1; r<a.rows(); r++) 
00605       if(abs(tma(r,c))>abs(pivot)) {
00606         rmax=r;
00607         pivot=tma(r,c);
00608       }
00609     for(i=0; i<a.cols(); i++) {
00610       x=tma(rmax,i);
00611       tma(rmax,i)=tma(c,i);
00612       tma(c,i)=x/pivot;
00613       x=tmp(rmax,i);
00614       tmp(rmax,i)=tmp(c,i);
00615       tmp(c,i)=x/pivot;
00616     }
00617     for(r=0; r<a.rows(); r++) 
00618       if(r!=c) {
00619         pivot=tma(r,c);
00620         for(i=0; i<a.cols(); i++) {
00621           tma(r,i)-=pivot*tma(c,i);
00622           tmp(r,i)-=pivot*tmp(c,i);
00623         }
00624       }
00625   }
00626   return tmp;
00627 }
00628 
00629 inline mdp_matrix pow(const mdp_matrix& a, int i) {
00630 #ifdef CHECK_ALL
00631   if (a.rows()!=a.cols()) error("pow(...)\nmdp_matrix is not squared");
00632 #endif
00633   mdp_matrix tmp;
00634   tmp=mdp_identity(a.cols());
00635   uint j=(i<0)?-i:i;
00636   for(;j>0; j--) tmp=tmp*a;
00637   if (i<0) tmp=inv(tmp);
00638   return tmp;
00639 }
00640 
00641 inline mdp_matrix exp(const mdp_matrix& a) {
00642 #ifdef CHECK_ALL
00643   if (a.rows()!=a.cols()) error("exp(...)\nmdp_matrix is not squared");
00644 #endif
00645   mdp_matrix tmp;
00646   mdp_matrix term;
00647   register uint i=1;
00648   term=a;
00649   tmp=mdp_identity(a.rows());
00650   tmp+=a;
00651   do {
00652     term=(1./++i)*term*a;
00653     tmp+=term;
00654   } while (max(term)>mdp_precision);
00655   return tmp;
00656 }
00657 
00658 
00659 inline mdp_matrix mdp_matrix::operator+=(const mdp_matrix& a) {
00660   (*this)=(*this)+a;
00661   return *this;
00662 }
00663 
00664 inline mdp_matrix mdp_matrix::operator-=(const mdp_matrix& a) {
00665   (*this)=(*this)-a;
00666   return *this;
00667 }
00668 
00669 inline mdp_matrix mdp_matrix::operator*=(const mdp_matrix& a) {
00670   (*this)=(*this)*a;
00671   return *this;
00672 }
00673 
00674 inline mdp_matrix mdp_matrix::operator/=(const mdp_matrix& a) {
00675   (*this)=(*this)/a;
00676   return *this;
00677 }
00678 
00679 
00680 inline mdp_matrix mdp_matrix::operator+=(mdp_complex a) {
00681   (*this)=(*this)+a;
00682   return *this;
00683 }
00684 
00685 inline mdp_matrix mdp_matrix::operator-=(mdp_complex a) {
00686   (*this)=(*this)-a;
00687   return *this;
00688 }
00689 
00690 inline mdp_matrix mdp_matrix::operator*=(mdp_complex a) {
00691   (*this)=(*this)*a;
00692   return *this;
00693 }
00694 
00695 inline mdp_matrix mdp_matrix::operator/=(mdp_complex a) {
00696   (*this)=(*this)/a;
00697   return *this;
00698 }
00699 
00700 inline mdp_matrix mdp_matrix::operator+=(mdp_real a) {
00701   (*this)=(*this)+a;
00702   return *this;
00703 }
00704 
00705 inline mdp_matrix mdp_matrix::operator-=(mdp_real a) {
00706   (*this)=(*this)-a;
00707   return *this;
00708 }
00709 
00710 inline mdp_matrix mdp_matrix::operator*=(mdp_real a) {
00711   (*this)=(*this)*a;
00712   return *this;
00713 }
00714 
00715 inline mdp_matrix mdp_matrix::operator/=(mdp_real a) {
00716   (*this)=(*this)/a;
00717   return *this;
00718 }
00719 
00720 inline void mdp_matrix::operator=(mdp_complex a) {
00721   uint i,j;
00722   for(i=0; i<rows(); i++)
00723     for(j=0; j<cols(); j++)
00724       (*this)(i,j)=(i==j)?a:0;
00725 }
00726 
00727 inline void mdp_matrix::operator=(mdp_real a) {
00728   uint i,j;
00729   for(i=0; i<rows(); i++)
00730     for(j=0; j<cols(); j++)
00731       (*this)(i,j)=(i==j)?mdp_complex(a,0):0;
00732 }
00733 
00734 
00735 mdp_matrix log(const mdp_matrix& a) {
00736 #ifdef CHECK_ALL
00737   if (a.rows()!=a.cols()) error("log(...)\nmdp_matrix is not squared");
00738 #endif
00739   mdp_matrix tmp,b,c,t1;
00740   register uint i=1, j=1;
00741   b=mdp_identity(a.cols());   
00742   b=a-b;
00743   c=b;
00744   tmp=b;
00745   do { 
00746     c=c*b;
00747     t1=((mdp_real)(i=-i)/(j+=1))*c;
00748     tmp+=t1;
00749   } while (max(t1)>mdp_precision);
00750   return tmp;
00751 }
00752 
00753 mdp_matrix sin(const mdp_matrix& a) {
00754 #ifdef CHECK_ALL
00755   if (a.rows()!=a.cols()) error("sin(...)\nmdp_matrix is not squared");
00756 #endif
00757   mdp_matrix tmp, t1;
00758   register uint i=1;
00759   t1=a;
00760   tmp=t1;
00761   // pruintf("\n");
00762   do { 
00763     t1=((mdp_real) -1.0/(++i)/(++i))*t1*a*a;
00764     tmp+=t1;
00765   } while (max(t1)>mdp_precision);
00766   return tmp;
00767 }
00768 
00769 mdp_matrix cos(const mdp_matrix& a) {
00770 #ifdef CHECK_ALL
00771   if (a.rows()!=a.cols()) error("cos(...)\nmdp_matrix is not squared");
00772 #endif
00773   mdp_matrix tmp,t1;
00774   register uint i=0;
00775   t1=mdp_identity(a.rows());
00776   tmp=t1;
00777   do { 
00778     t1=((mdp_real) -1.0/(++i)/(++i))*t1*a*a;
00779       tmp+=t1;
00780   } while (max(t1)>mdp_precision);
00781   return tmp;
00782 }
00783 
00784 inline mdp_complex trace(const mdp_matrix& a) {
00785 #ifdef CHECK_ALL
00786   if (a.rows()!=a.cols()) error("trace(...)\nmdp_matrix is not squared");
00787 #endif
00788   register uint c;
00789   mdp_complex x;
00790   for(c=0; c<a.cols(); c++) x+=a(c,c);
00791   return x;
00792 }
00793 
00794 inline mdp_matrix transpose(const mdp_matrix& a) {
00795   mdp_matrix tmp(a.cols(), a.rows());
00796   register uint r,c;
00797   for(r=0; r<a.rows(); r++) 
00798     for(c=0; c<a.cols(); c++) 
00799       tmp(c,r)=a(r,c);
00800   return tmp;
00801 }
00802 
00803 inline mdp_matrix hermitian(const mdp_matrix& a) {
00804   mdp_matrix tmp(a.cols(), a.rows());
00805   
00806 #if defined(MATRIX_SSE2) && defined(USE_DOUBLE_PRECISION)
00807   if(a.cols()==3 && a.rows()==3) {
00808     _sse_double_hermitian_su3((_sse_double*) tmp.address(),
00809                               (_sse_double*) a.address());
00810     return tmp;
00811   }
00812 #endif  
00813   register uint r,c;
00814   for(r=0; r<a.rows(); r++) 
00815     for(c=0; c<a.cols(); c++) 
00816       tmp(c,r)=conj(a(r,c));
00817   return tmp;
00818 }
00819 
00820 
00821 inline mdp_matrix conj(const mdp_matrix& a) {
00822   mdp_matrix tmp(a.rows(), a.cols());
00823   register uint r,c;
00824   for(r=0; r<a.rows(); r++) 
00825     for(c=0; c<a.cols(); c++) 
00826       tmp(r,c)=conj(a(r,c));
00827   return tmp;
00828 }
00829 
00830 

Generated on Sun Feb 27 15:12:21 2005 by  doxygen 1.4.1