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&);
00052
00053 mdp_complex* address();
00054 const uint rows() const;
00055 const uint cols() const;
00056 const uint size() const;
00057 uint rowmax() const;
00058 uint colmax() const;
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);
00065 friend mdp_matrix operator* (const mdp_matrix& a, const mdp_matrix& b);
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;
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
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
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