00001
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef TBCI_F_MATRIX_H
00015 #define TBCI_F_MATRIX_H
00016
00017 #include "vector.h"
00018 #include "matrix_sig.h"
00019 #include "matrix.h"
00020 #include "cscmatrix.h"
00021
00022
00023 #if !defined(NO_GD) && !defined(AUTO_DECL)
00024 # include "f_matrix_gd.h"
00025 #endif
00026
00027 NAMESPACE_TBCI
00028
00029 #ifdef HAVE_GCC295_FRIEND_BUG
00030 # define _VEC getvec()
00031 # define _ENDVEC getendvec()
00032 # define _DIM size()
00033 # define _ROW rows()
00034 # define _COL columns()
00035 # define _FAC getfac()
00036 #else
00037 # define _VEC vec
00038 # define _ENDVEC endvec
00039 # define _DIM dim
00040 # define _ROW row
00041 # define _COL col
00042 # define _FAC fac
00043 #endif
00044
00045
00047
00048 template <typename T> class CSCMatrix;
00049 template <typename T> class F_Matrix;
00050 template <typename T> class F_TMatrix;
00051 template <typename T> class F_TSMatrix;
00052 template <typename T> class BdMatrix;
00053 template <typename T> class Tensor;
00054
00055 template <typename T> class Matrix;
00056 template <typename T> class TMatrix;
00057
00058 #ifdef PRAGMA_I
00059 # pragma interface "f_matrix.h"
00060 #endif
00061
00062
00067
00068
00069 template <typename T>
00070 class F_TMatrix : public Matrix_Sig<T>
00071 {
00072 protected:
00073 typedef T mat_t ;
00074 T * vec;
00075 unsigned long dim;
00076 unsigned int row, col;
00078 T ** mat;
00079 T * endvec;
00080
00081 int set_ptrs();
00082
00083 public:
00084 typedef T value_type;
00085 typedef T element_type;
00086 typedef T aligned_value_type TALIGN(MIN_ALIGN2);
00087
00088 friend class F_Matrix<T>;
00089 friend class F_TSMatrix<T>;
00090 friend class Tensor<T>;
00091
00092
00093 #ifdef HAVE_GCC295_FRIEND_BUG
00094
00095 T* const getvec() const { return vec; }
00096 T* const getendvec() const { return endvec; }
00097 #endif
00098
00099
00100 public:
00101 explicit F_TMatrix (const unsigned = 0);
00102 F_TMatrix (const unsigned, const unsigned);
00103 F_TMatrix (const T&, const unsigned, const unsigned);
00104 F_TMatrix (const Vector<T>&, const enum rowcolvec = colvec);
00105
00106 F_TMatrix (const F_TMatrix<T>&);
00107 F_TMatrix (F_TSMatrix<T>&);
00108
00109 F_TMatrix (const F_Matrix<T>&);
00110
00111 void destroy ();
00112
00113
00114
00115 ~F_TMatrix () {}
00116
00117
00118 operator TMatrix<T>();
00119
00120 static const char* mat_info () { return ("F_TMatrix"); }
00121
00122
00123
00124 F_TMatrix<T>& operator = (const F_Matrix<T>&);
00125 F_TMatrix<T>& operator = (const F_TMatrix<T>&);
00126 F_TMatrix<T>& operator = (F_TSMatrix<T>);
00127 F_TMatrix<T>& operator = (const T&);
00128 F_TMatrix<T>& alias (const F_Matrix<T>& m)
00129 { destroy (); vec = m.vec; dim = m.dim; row = m.row; col = m.col; mat = m.mat; endvec = m.endvec; return *this; }
00130
00131 F_TMatrix<T>& operator += (F_TMatrix<T>);
00132 F_TMatrix<T>& operator += (const F_Matrix<T>&);
00133 F_TMatrix<T>& operator += (const T&);
00134 F_TMatrix<T>& operator -= (F_TMatrix<T>);
00135 F_TMatrix<T>& operator -= (const F_Matrix<T>&);
00136 F_TMatrix<T>& operator -= (const T&);
00137
00138 F_TSMatrix<T> operator *= (const T&);
00139 F_TSMatrix<T> operator /= (const T&);
00140
00141
00142 F_TMatrix<T>& operator - ();
00143 F_TMatrix<T>& herm ();
00144 F_TMatrix<T>& conj ();
00145 F_TMatrix<T>& trans();
00146
00147 F_TMatrix<T>& operator + (F_TMatrix<T>);
00148 F_TMatrix<T>& operator + (F_TSMatrix<T>);
00149 F_TMatrix<T>& operator + (const F_Matrix<T>&);
00150 F_TMatrix<T>& operator + (const T&);
00151 F_TMatrix<T>& operator - (F_TMatrix<T>);
00152 F_TMatrix<T>& operator - (F_TSMatrix<T>);
00153 F_TMatrix<T>& operator - (const F_Matrix<T>&);
00154 F_TMatrix<T>& operator - (const T&);
00155 F_TSMatrix<T> operator * (const T&);
00156 F_TSMatrix<T> operator / (const T&);
00157
00158 F_TMatrix<T> operator * (const F_Matrix<T>&);
00159 F_TMatrix<T> operator * (F_TMatrix<T>);
00160 F_TMatrix<T> operator * (F_TSMatrix<T>);
00161
00162
00163 TVector<T> operator * (const Vector<T>& v)
00164 { F_Matrix<T> m (*this); return (m * v); }
00165 TVector<T> operator * (TVector <T>& tv)
00166 { F_Matrix<T> m (*this); return (m * tv); }
00167
00168
00169 #ifndef HAVE_GCC295_FRIEND_BUG
00170 friend NOINST F_TMatrix<T> FRIEND_TBCI__ operator + FGD (const T&, F_TMatrix<T>);
00171 friend NOINST F_TMatrix<T> FRIEND_TBCI__ operator + FGD (const T&, const F_Matrix<T>&);
00172 friend NOINST F_TMatrix<T> FRIEND_TBCI__ operator - FGD (const T&, F_TMatrix<T>);
00173 friend NOINST F_TMatrix<T> FRIEND_TBCI__ operator - FGD (const T&, const F_Matrix<T>&);
00174 friend NOINST F_TSMatrix<T> FRIEND_TBCI__ operator * FGD (const T&, F_TMatrix<T>);
00175 friend NOINST F_TSMatrix<T> FRIEND_TBCI__ operator * FGD (const T&, const F_Matrix<T>&);
00176 #endif
00177
00178
00179 T& operator () (const unsigned int, const unsigned int) const;
00180
00181 T* get_fortran_matrix () const { return vec; }
00182 const T& get (const unsigned r, const unsigned c) const { return mat[c][r]; }
00183
00184 bool operator == (const F_Matrix<T>& m);
00185 bool operator != (const F_Matrix<T>& m)
00186 { return !(*this == m); }
00187
00188 bool operator == (F_TMatrix<T> tm)
00189 { F_Matrix<T> m (tm); return (*this == m); }
00190 bool operator != (F_TMatrix<T> tm)
00191 { return !(*this == tm); }
00192
00193 bool operator == (F_TSMatrix<T>);
00194 bool operator != (F_TSMatrix<T> ts)
00195 { return !(*this == ts); }
00196
00197
00198 unsigned int columns () const { return col; }
00199 unsigned int rows () const { return row; }
00200 unsigned long size () const { return dim; }
00201
00202 TVector<T> get_row (const unsigned int) const;
00203 TVector<T> get_col (const unsigned int) const;
00204 void set_row (const Vector<T>&, const unsigned int);
00205 void set_col (const Vector<T>&, const unsigned int);
00206 void setval(const T val, const unsigned int r, const unsigned int c)
00207 { this->operator() (r, c) = val; }
00208 T& setval(const unsigned int r, const unsigned int c)
00209 { return this->operator() (r, c); }
00210
00211 F_TMatrix<T>& resize (const unsigned int, const unsigned int);
00212 F_TMatrix<T>& resize (const unsigned int d) { return this->resize (d, d); }
00213 F_TMatrix<T>& resize (const T&, const unsigned int, const unsigned int);
00214 F_TMatrix<T>& fill (const T& = 0);
00215 F_TMatrix<T>& clear ();
00216 F_TMatrix<T>& setunit(const T& = 1);
00217
00218 F_TMatrix<T>& swap (F_TMatrix<T>&);
00220 F_TMatrix<T> transposed_copy() const;
00221 F_TMatrix<T>& transpose();
00222
00223
00224
00225 double fabs () const;
00226
00227 T trace () const;
00228
00229 };
00230
00231
00232 template <typename T>
00233 inline void F_TMatrix<T>::destroy ()
00234 {
00235 if (dim) {
00236 if (vec) TBCIDELETE(T , vec, dim);
00237 if (mat) TBCIDELETE(T*, mat, col);
00238 dim = 0;
00239 }
00240 }
00241
00242 template <typename T>
00243 F_TMatrix<T>::operator TMatrix<T>()
00244 {
00245 TMatrix<T> tm(row, col);
00246 for (unsigned int r = 0; r < row; ++r)
00247 for (unsigned int c = 0; c < col; ++c)
00248 tm.setval(this->get(r, c), r, c);
00249 destroy();
00250 return tm;
00251 }
00252
00253 template <typename T>
00254 int F_TMatrix<T>::set_ptrs()
00255 {
00256 if (mat && vec) {
00257 T* ptr = vec;
00258 for (unsigned int i=0; i<col; i++) {
00259 mat[i] = ptr;
00260 ptr += row;
00261 }
00262 endvec = ptr;
00263 return 0;
00264 } else {
00265 if (vec) { TBCIDELETE(T, vec, dim); vec = (T*) 0; }
00266 if (mat) { TBCIDELETE(T*,mat, col); mat = (T**)0; }
00267 dim = 0; col = 0; row = 0;
00268 endvec = (T*)0;
00269 return -1;
00270 }
00271 }
00272
00273
00274 template <typename T>
00275 inline F_TMatrix<T>::F_TMatrix (const unsigned d)
00276 : vec (d>0?NEW(T,d*d):0), dim (((unsigned long)d)*d), row(d), col(d), mat (d>0?NEW(T*,d):0)
00277 {
00278 set_ptrs();
00279 }
00280
00281
00282 template <typename T>
00283 inline F_TMatrix<T>::F_TMatrix (const unsigned r, const unsigned c)
00284 : vec(r*c>0?NEW(T,r*c):0), dim(((unsigned long)r)*c), row(r), col(c),
00285 mat(r*c>0?NEW(T*,c):0)
00286 {
00287 set_ptrs();
00288 }
00289
00290 template <typename T>
00291 inline F_TMatrix<T>::F_TMatrix (const T& val, const unsigned r, const unsigned c)
00292 : vec(r*c>0?NEW(T,r*c):0), dim(((unsigned long)r)*c), row(r), col(c),
00293 mat(r*c>0?NEW(T*,c):0)
00294 {
00295 if (LIKELY(!set_ptrs()))
00296 TBCIFILL (vec, val, T, dim);
00297 }
00298
00299
00300 template <typename T>
00301 inline F_TMatrix<T>::F_TMatrix (const Vector<T>& v, const enum rowcolvec r)
00302 : vec(v.dim>0?NEW(T,v.dim):0), dim(v.dim), row(r==rowvec?v.dim:1),
00303 col(r==rowvec?1:v.dim), mat(v.dim?(r==rowvec?NEW(T*,1):NEW(T*,v.dim)):0)
00304 {
00305 if (LIKELY(!set_ptrs()))
00306 TBCICOPY (vec, v.vec, T, dim);
00307 }
00308
00309
00310 template <typename T>
00311 inline F_TMatrix<T>::F_TMatrix (const F_Matrix<T>& m)
00312 : vec(m.dim>0?NEW(T,m.dim):0), dim(m.dim), row(m.row), col(m.col),
00313 mat(m.dim>0?NEW(T*,m.col):0)
00314 {
00315 if (LIKELY(!set_ptrs()))
00316 TBCICOPY (vec, m.vec, T, dim);
00317 }
00318
00319
00320 template <typename T>
00321 inline F_TMatrix<T>::F_TMatrix (const F_TMatrix<T>& tm)
00322 : vec (tm.vec), dim (tm.dim), row (tm.row), col (tm.col),
00323 mat (tm.mat), endvec (tm.endvec) {}
00324
00325 template <typename T>
00326 inline F_TMatrix<T>::F_TMatrix (F_TSMatrix<T>& ts)
00327 : dim (ts.dim), row (ts.row), col (ts.col)
00328 {
00329 ts.eval (); vec = ts.vec; mat = ts.mat;
00330 endvec = ts.endvec; ts.mut = false;
00331 }
00332
00333
00334 template <typename T>
00335 inline T& F_TMatrix<T>::operator () (const unsigned int r, const unsigned int c) const
00336 {
00337 BCHK(r>=row, MatErr, Illegal row index, r, mat[0][0]);
00338 BCHK(c>=col, MatErr, illegal col index, c, mat[0][0]);
00339 return mat[c][r];
00340 }
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354 template <typename T>
00355 inline F_TMatrix<T>& F_TMatrix<T>::operator = (const F_Matrix<T>& a)
00356 {
00357 BCHK(dim != a.dim, MatErr, Different sizes in assignment, a.dim, *this );
00358 TBCICOPY (vec, a.vec, T, dim);
00359 return *this;
00360 }
00361
00362
00363 template <typename T>
00364 inline F_TMatrix<T>& F_TMatrix<T>::operator = (const F_TMatrix<T>& a)
00365 {
00366 BCHK(row != a.row || col != a.col, MatErr, Different sizes in assignment, a.dim, *this );
00367 if (vec != a.vec)
00368 {
00369 this->destroy();
00370 vec = a.vec; dim = a.dim; row = a.row; col = a.col;
00371 mat = a.mat; endvec = a.endvec;
00372 }
00373 return *this;
00374 }
00375
00376 template <typename T>
00377 inline F_TMatrix<T>& F_TMatrix<T>::operator = (F_TSMatrix<T> a)
00378 {
00379 BCHK(col != a.col || row != a.row, MatErr, Different sizes in assignment, a.dim, *this );
00380 a.eval (this);
00381 return *this;
00382 }
00383
00384
00385 template <typename T>
00386 inline F_TMatrix<T>& F_TMatrix<T>::operator = (const T& val)
00387 {
00388 return this->fill (val);
00389 }
00390
00391
00392 template <typename T>
00393 inline F_TMatrix<T>& F_TMatrix<T>::setunit (const T& fac)
00394 {
00395 TBCIFILL (vec, 0, T, dim);
00396 BCHK(col!=row, MatErr, setunit makes only sense on quadratic matrices, col, *this);
00397 const unsigned iend = MIN(row,col);
00398 for (register unsigned i = 0; i < iend; i++) mat[i][i] = fac;
00399 return *this;
00400 }
00401
00402 template <typename T>
00403 inline F_TMatrix<T>& F_TMatrix<T>::clear ()
00404 {
00405 if (dim) TBCIFILL (vec, 0, T, dim);
00406 return *this;
00407 }
00408
00409 #if 0
00410 template <typename T>
00411 inline TVector<T> F_TMatrix<T>::operator () (const unsigned int i) const
00412 {
00413 TVector<T> v(col);
00414 BCHK(i<0 || i>= row, MatErr, Illegal row index, i, v);
00415 TBCICOPY (v.vec, mat[i], T, col);
00416 return v;
00417 }
00418 #endif
00419
00420 template <typename T>
00421 inline void F_TMatrix<T>::set_col (const Vector<T>& v, const unsigned int c)
00422 {
00423 BCHKNR(c >= col, MatErr, Illegal col index in set_col, c);
00424 BCHKNR(v.dim != (unsigned long)row, MatErr, Different sizes in set_row, v.dim);
00425 TBCICOPY(mat[c], v.vec, T, v.dim);
00426 }
00427
00428 template <typename T>
00429 inline TVector<T> F_TMatrix<T>::get_col (const unsigned int c) const
00430 {
00431 TVector<T> v(row);
00432
00433 TBCICOPY (v.vec, mat[c], T, row);
00434 return v;
00435 }
00436
00437 template <typename T>
00438 inline void F_TMatrix<T>::set_row (const Vector<T>& v, const unsigned int r)
00439 {
00440 BCHKNR(r >= row, MatErr, Illegal row index in set_row, r);
00441 for (register unsigned int j=0; j<col; j++)
00442 mat[j][r] = v.vec[j];
00443 }
00444
00445 template <typename T>
00446 inline TVector<T> F_TMatrix<T>::get_row (const unsigned int r) const
00447 {
00448 TVector<T> v(col);
00449 BCHK(r >= row, MatErr, Illegal row index in get_row, r, v);
00450 for (register unsigned int j=0; j<col; j++)
00451 v.vec[j] = mat[j][r];
00452 return v;
00453 }
00454
00455
00456 #ifndef LAPACK_INLINE
00457 # define LAPACK_INLINE
00458 #endif
00459 template <typename T>
00460 LAPACK_INLINE F_TMatrix<T>& F_TMatrix<T>::resize (const unsigned int r, const unsigned int c)
00461 {
00462 if (r == row && c == col)
00463 return *this;
00464 if (mat)
00465 TBCIDELETE(T*,mat,col);
00466 T* vv = vec;
00467 unsigned long dd =dim;
00468 dim = ((unsigned long)r)*c;
00469 row = r; col = c;
00470 if (dim) {
00471 vec = NEW(T,dim); mat = NEW(T*,c);
00472 } else {
00473 mat = (T**)0; vec = (T*)0; endvec = (T*)0;
00474 }
00475 if (!set_ptrs())
00476 TBCICOPY(vec, vv, T, MIN(dim,dd));
00477 if (dd && vv)
00478 TBCIDELETE(T, vv, dd);
00479 return *this;
00480 }
00481
00482 template <typename T>
00483 F_TMatrix<T>& F_TMatrix<T>::resize (const T& v, const unsigned int r, const unsigned int c)
00484 {
00485 if (r == row && c == col) {
00486 TBCIFILL(vec, v, T, dim);
00487 return *this;
00488 }
00489 if (mat) {
00490 TBCIDELETE(T*,mat,col);
00491 TBCIDELETE(T,vec, dim);
00492 }
00493 dim = r*c;
00494 row = r; col = c;
00495 if (dim) {
00496 vec = NEW(T,dim); mat = NEW(T*,c);
00497 } else {
00498 mat = (T**)0; vec = (T*)0; endvec = (T*)0;
00499 }
00500 if (LIKELY(!set_ptrs()))
00501 TBCIFILL (vec, v, T, dim);
00502 return *this;
00503 }
00504
00505
00506 template <typename T>
00507 inline F_TMatrix<T>& F_TMatrix<T>::fill (const T& val)
00508 {
00509 TBCIFILL(vec, val, T, dim);
00510 return *this;
00511 }
00512
00513 template <typename T>
00514 inline T F_TMatrix<T>::trace () const
00515 {
00516 ALIGN3(T tr, vec[0], MIN_ALIGN2);
00517 BCHK (row != col, MatErr, Trace over non quadratic matrix, 0, tr=0);
00518 for (register unsigned i = 1; i < row; i++)
00519 tr += mat[i][i];
00520 return tr;
00521 }
00522
00523
00524
00525
00526 template <typename T>
00527 F_TMatrix<T>& F_TMatrix<T>::trans()
00528 {
00529 if (rows() == columns())
00530 {
00531 for(unsigned int i=0; i<rows(); i++)
00532 for(unsigned int j=i+1; j<columns(); j++)
00533 SWAP(mat[i][j], mat[j][i]);
00534 } else
00535 {
00536 STD__ cout << "Not implemented!" << STD__ endl;
00537 }
00538 return (*this);
00539 }
00540
00541
00542 template <typename T>
00543 F_TMatrix<T>& F_TMatrix<T>::herm ()
00544 {
00545 STD__ cout << "WRONG: F_TMatrix<T>::herm()" << STD__ endl;
00546 if (rows() == columns())
00547 {
00548 for(unsigned int i=0; i<rows(); i++)
00549 {
00550
00551 for(unsigned int j=i+1; j<columns(); j++)
00552 {
00553
00554
00555 SWAP(mat[i][j], mat[j][i]);
00556 }
00557 }
00558 } else
00559 {
00560 STD__ cout << "Not implemented!" << STD__ endl;
00561 }
00562 return (*this);
00563 }
00564
00565
00566 template <typename T>
00567 F_TMatrix<T>& F_TMatrix<T>::conj ()
00568 {
00569 STD__ cout << "Wrong: F_TMatrix<T>::conf()" << STD__ endl;
00570
00571 return *this;
00572 }
00573
00574
00575 template <typename T>
00576 inline F_TMatrix<T>& F_TMatrix<T>::operator - ()
00577 {
00578 for (register T* ptr=vec; ptr<endvec; ptr++) *ptr = -(*ptr);
00579 return *this;
00580 }
00581
00582 template <typename T>
00583 bool F_TMatrix<T>::operator == (const F_Matrix<T>& m)
00584 {
00585 F_Matrix<T> th (*this);
00586 if (row != m.row || col != m.col) return false;
00587 if (vec == m.vec || dim == 0) return true;
00588 if (TBCICOMP (vec, m.vec, T, dim)) return false;
00589 return true;
00590 }
00591
00592 template <typename T>
00593 bool F_TMatrix<T>::operator == (F_TSMatrix<T> ts)
00594 {
00595 F_Matrix<T> th (*this);
00596 if (row != ts.row || col != ts.col) return (ts.destroy(), false);
00597 if (dim == 0) { return true; }
00598 if (ts.fac == (T)1)
00599 {
00600 if (vec == ts.vec) return true;
00601 if (TBCICOMP (vec, ts.vec, T, dim)) { ts.destroy (); return false; }
00602 }
00603 else
00604 {
00605 if (vec == ts.vec) return false;
00606 for (register T *p1 = vec, *p2 = ts.vec; p1 < endvec; p1++, p2++)
00607 if (*p1 != *p2 * ts.fac) { ts.destroy (); return false; }
00608 }
00609 ts.destroy (); return true;
00610 }
00611
00612
00613 #define F_TMFORALL_M(op) \
00614 template <typename T> \
00615 inline F_TMatrix<T>& F_TMatrix<T>::operator op (const F_Matrix<T>& a) \
00616 { \
00617 BCHK(row != a.row, MatErr, number of rows differ in op, a.row, *this ); \
00618 BCHK(col != a.col, MatErr, number of cols differ in op, a.col, *this ); \
00619 for (register T *p1 = vec, *p2 = a.vec; p1 < endvec; p1++, p2++) *p1 op *p2; \
00620 return *this; \
00621 }
00622
00623 F_TMFORALL_M(+=)
00624 F_TMFORALL_M(-=)
00625
00626
00627
00628 #define F_TMFORALL_TM(op) \
00629 template <typename T> \
00630 inline F_TMatrix<T>& F_TMatrix<T>::operator op (F_TMatrix<T> a)\
00631 { \
00632 return this->operator op (F_Matrix<T>(a)); \
00633 }
00634
00635 F_TMFORALL_TM(+=)
00636 F_TMFORALL_TM(-=)
00637
00638
00639 #define F_TMFORALL_TS(op) \
00640 template <typename T> \
00641 inline F_TMatrix<T>& F_TMatrix<T>::operator op (F_TSMatrix<T> ts) \
00642 { \
00643 BCHK(row != ts.row, MatErr, number of rows differ in op, ts.row, (ts.destroy(),*this) ); \
00644 BCHK(col != ts.col, MatErr, number of cols differ in op, ts.col, (ts.destroy(),*this) ); \
00645 for (register T *p1 = vec, *p2 = ts.vec; p1 < endvec; p1++, p2++) \
00646 *p1 op##= *p2 * ts.fac; \
00647 ts.destroy (); return *this; \
00648 }
00649
00650 F_TMFORALL_TS(+)
00651 F_TMFORALL_TS(-)
00652
00653
00654
00655 #define F_TMFORALL_T(op) \
00656 template <typename T> \
00657 inline F_TMatrix<T>& F_TMatrix<T>::operator op (const T& a) \
00658 { \
00659 for (register T* ptr = vec; ptr < endvec; ptr++) *ptr op a; \
00660 return *this; \
00661 }
00662
00663 F_TMFORALL_T(+=)
00664 F_TMFORALL_T(-=)
00665
00666
00667
00668
00669 template <typename T>
00670 inline F_TSMatrix<T> F_TMatrix<T>::operator *= (const T& a)
00671 { return F_TSMatrix<T> (*this, a); }
00672
00673 template <typename T>
00674 inline F_TSMatrix<T> F_TMatrix<T>::operator /= (const T& a)
00675 {
00676 BCHK(a==(T)0, MatErr, F_Matrix division by zero, 0, F_TSMatrix<T> (*this));
00677 return F_TSMatrix<T> (*this, (T)1/a);
00678 }
00679
00680
00681
00682 #define F_STDDEF_TMM(op) \
00683 template <typename T> \
00684 inline F_TMatrix<T>& F_TMatrix<T>::operator op (const F_Matrix<T>& a) \
00685 { return this->operator op##= (a); }
00686
00687 F_STDDEF_TMM(+)
00688 F_STDDEF_TMM(-)
00689
00690
00691 #define F_STDDEF_TMTM(op) \
00692 template <typename T> \
00693 inline F_TMatrix<T>& F_TMatrix<T>::operator op (F_TMatrix<T> a) \
00694 { return this->operator op##= (F_Matrix<T>(a)); }
00695
00696 F_STDDEF_TMTM(+)
00697 F_STDDEF_TMTM(-)
00698
00699
00700 #define F_STDDEF_TMT(op) \
00701 template <typename T> \
00702 inline F_TMatrix<T>& F_TMatrix<T>::operator op (const T& a) \
00703 { return this->operator op##= (a); }
00704
00705 F_STDDEF_TMT(+)
00706 F_STDDEF_TMT(-)
00707
00708
00709 template <typename T>
00710 inline F_TSMatrix<T> F_TMatrix<T>::operator * (const T& a)
00711 { return F_TSMatrix<T> (*this, a); }
00712
00713 template <typename T>
00714 inline F_TSMatrix<T> F_TMatrix<T>::operator / (const T& b)
00715 {
00716 BCHK((b == (T)0), MatErr, F_Matrix division by 0, 0, F_TSMatrix<T> (*this));
00717 return F_TSMatrix<T> (*this, (T)1/b);
00718 }
00719
00720
00721
00722
00723 #define F_STDDEF_TTM(op) \
00724 INST(template <typename T> class F_TMatrix friend F_TMatrix<T> operator op (const T&, F_TMatrix<T>);) \
00725 template <typename T> \
00726 inline F_TMatrix<T> operator op (const T& a, F_TMatrix<T> b) \
00727 { \
00728 for (register T* ptr=b._VEC; ptr<b._ENDVEC; ptr++) \
00729 *ptr = a op *ptr; \
00730 return b; \
00731 }
00732
00733 F_STDDEF_TTM(+)
00734 F_STDDEF_TTM(-)
00735
00736
00737
00738 INST(template <typename T> class F_TMatrix friend F_TSMatrix<T> operator * (const T&, F_TMatrix<T>);)
00739 template <typename T>
00740 inline F_TSMatrix<T> operator * (const T& a, F_TMatrix<T> b)
00741 { return F_TSMatrix<T> (b, a); }
00742
00743
00744
00745
00746 #define F_STDDEF_TM(op) \
00747 INST(template <typename T> class F_TMatrix friend F_TMatrix<T> operator op (const T&, const F_Matrix<T>&);) \
00748 template <typename T> \
00749 inline F_TMatrix<T> operator op (const T& a, const F_Matrix<T>& b) \
00750 { \
00751 F_TMatrix<T> c (b._ROW, b._COL); \
00752 for (register T *p1=c._VEC, *p2=b._VEC; p1<c._ENDVEC; p1++, p2++) \
00753 *p1 = a op *p2; \
00754 return c; \
00755 }
00756
00757 F_STDDEF_TM(+)
00758 F_STDDEF_TM(-)
00759
00760
00761
00762
00763 INST(template <typename T> class F_TMatrix friend F_TSMatrix<T> operator * (const T&, const F_Matrix<T>&);)
00764 template <typename T>
00765 inline F_TSMatrix<T> operator * (const T& a, const F_Matrix<T>& b)
00766 { return F_TSMatrix<T> (b, a); }
00767
00768
00769
00770 template <typename T>
00771 inline double F_TMatrix<T>::fabs () const
00772 { F_Matrix<T> m (*this); return m.fabs (); }
00773
00774
00778
00779 template <typename T>
00780 class F_TSMatrix : public Matrix_Sig<T>
00781 {
00782 protected:
00783 T* vec;
00784 unsigned long dim;
00785 unsigned int row, col;
00786 T** mat;
00787 T* endvec;
00788
00789 void destroy ();
00790 T fac ALIGN(MIN_ALIGN);
00791 bool mut;
00792
00793 void clone (bool = false, F_TMatrix<T>* = 0);
00794 #ifdef HAVE_GCC295_FRIEND_BUG
00795 public:
00796 T* const getvec () const { return vec; }
00797 T* const getendvec () const { return endvec; }
00798 T& getfac () { return fac; }
00799 const T& getfac () const { return fac; }
00800 #endif
00801 void detach (F_TMatrix<T>* = 0);
00802
00803 public:
00804 typedef T value_type;
00805 typedef T element_type;
00806 typedef T aligned_value_type TALIGN(MIN_ALIGN2);
00807
00808 friend class F_TMatrix<T>;
00809 friend class F_Matrix<T>;
00810
00811 F_TSMatrix () : vec((T*)0), dim(0), mat((T**)0), endvec((T*)0) {}
00812
00813 ~F_TSMatrix () {}
00814
00815 F_TSMatrix (const F_TMatrix<T>& tm, const T& f = (T)1)
00816 : vec(tm.vec), dim(tm.dim), row(tm.row), col(tm.col),
00817 mat(tm.mat), endvec(tm.endvec), fac(f), mut(true) {}
00818 F_TSMatrix (const F_Matrix<T>& m, const T& f = (T)1)
00819 : vec(m.vec), dim(m.dim), row(m.row), col(m.col),
00820 mat(m.mat), endvec(m.endvec), fac(f), mut(false) {}
00821 F_TSMatrix (const F_TSMatrix<T>& ts)
00822 : vec(ts.vec), dim(ts.dim), row(ts.row), col(ts.col),
00823 mat(ts.mat), endvec(ts.endvec), fac(ts.fac), mut(ts.mut) {}
00824
00825 T operator () (const unsigned r, const unsigned c)
00826 { T val = mat[c][r] * fac; destroy (); return val; }
00827 T get (const unsigned r, const unsigned c) const { return mat[c][r] * fac; }
00828
00829 F_TSMatrix<T>& eval (F_TMatrix<T>* = 0);
00830 operator TMatrix<T>();
00831
00832
00833 static const char* mat_info () { return ("F_TSMatrix"); }
00834
00835
00836 F_TSMatrix<T>& operator = (const F_TSMatrix<T>& ts)
00837 { destroy (); vec = ts.vec; dim = ts.dim; row = ts.row; col = ts.col;
00838 mat = ts.mat; endvec = ts.endvec; fac = ts.fac; mut = ts.mut; return *this; }
00839 F_TSMatrix<T>& operator = (const F_TMatrix<T>& tm)
00840 { destroy (); vec = tm.vec; dim = tm.dim; row = tm.row; col = tm.col;
00841 mat = tm.mat; endvec = tm.endvec; fac = (T)1; mut = true; return *this; }
00842
00843 F_TSMatrix<T>& operator *= (const T& f) { fac *= f; return *this; }
00844 F_TSMatrix<T>& operator /= (const T& f) { fac /= f; return *this; }
00845 F_TSMatrix<T>& operator * (const T& f) { fac *= f; return *this; }
00846 F_TSMatrix<T>& operator / (const T& f) { fac /= f; return *this; }
00847
00848 F_TSMatrix<T>& operator - () { fac *= (T)(-1); return *this; }
00849
00850
00851 F_TMatrix<T> operator + (const F_Matrix<T>&);
00852 F_TMatrix<T> operator + (const F_TMatrix<T>&);
00853 F_TMatrix<T> operator + (F_TSMatrix<T>);
00854 F_TMatrix<T> operator + (const T&);
00855 F_TMatrix<T> operator - (const F_Matrix<T>&);
00856 F_TMatrix<T> operator - (const F_TMatrix<T>&);
00857 F_TMatrix<T> operator - (F_TSMatrix<T>);
00858 F_TMatrix<T> operator - (const T&);
00859
00860 #ifndef HAVE_GCC295_FRIEND_BUG
00861 friend NOINST F_TSMatrix<T> FRIEND_TBCI__ operator * FGD (const T&, F_TSMatrix<T>);
00862 friend NOINST F_TMatrix<T> FRIEND_TBCI__ operator + FGD (const T&, F_TSMatrix<T>);
00863 friend NOINST F_TMatrix<T> FRIEND_TBCI__ operator - FGD (const T&, F_TSMatrix<T>);
00864 #endif
00865
00866 F_TMatrix<T> operator * (const F_Matrix<T>& m);
00867 F_TMatrix<T> operator * (const CSCMatrix<T>& m);
00868 TVector<T> operator * (const Vector<T>& v);
00869
00870 bool operator == (const F_Matrix<T>&);
00871 bool operator != (const F_Matrix<T>& m) { return !(*this == m); }
00872
00873 bool operator == (F_TSMatrix<T>);
00874 bool operator != (F_TSMatrix<T> ts) { return !(*this == ts); }
00875
00876 bool operator == (F_TMatrix<T> tm) { F_Matrix<T> m(tm); return (*this == m); }
00877 bool operator != (F_TMatrix<T> tm) { return !(*this == tm); }
00878
00879
00880
00881
00882 double fabs ();
00883 };
00884
00885
00886 template <typename T>
00887 F_TMatrix<T> F_TSMatrix<T>::operator * (const CSCMatrix<T>& m2)
00888 {
00889 F_TMatrix<T> m1(*this);
00890 F_TMatrix<T> erg(0, m1.rows(), m2.columns());
00891 for (unsigned int i=0; i<m1.rows(); i++)
00892 for (unsigned int j=0; j<m2.columns(); j++)
00893 {
00894 T val = (T)0;
00895
00896 for (unsigned int x=m2.pcol[j]; x<m2.pcol[j+1]; x++)
00897 val += m1(i, m2.irow[x] )*m2.comp[x];
00898 erg.setval(fac*val, i, j);
00899 }
00900
00901
00902 mut = true;
00903 destroy();
00904 return erg;
00905 }
00906
00907
00908
00909 template <typename T>
00910 inline void F_TSMatrix<T>::destroy ()
00911 {
00912 if (!mut || !dim) return;
00913 if (vec) TBCIDELETE(T, vec,dim); vec = (T*)0; endvec = (T*)0;
00914 if (mat) TBCIDELETE(T*,mat,col); dim = 0;
00915 }
00916
00917 template <typename T>
00918 inline void F_TSMatrix<T>::detach (F_TMatrix<T>* tm)
00919 {
00920 if ((!tm && mut) || !dim) return;
00921 if (!tm)
00922 {
00923 vec = NEW(T ,dim); if (!vec) { dim = 0; mat = (T**)0; endvec = (T*)0; return; }
00924 mat = NEW(T*,col); if (!mat) { TBCIDELETE(T,vec,dim); dim = 0; vec = (T*)0; endvec = (T*)0; return; }
00925 for (register unsigned c = 0; c < row; c++) mat[c] = vec + c*row;
00926 endvec = vec + dim;
00927 }
00928 else
00929 {
00930 vec = tm->vec; mat = tm->mat; endvec = tm->endvec;
00931 }
00932 mut = true;
00933 }
00934
00935 template <typename T>
00936 void F_TSMatrix<T>::clone (bool evl, F_TMatrix<T>* tm)
00937 {
00938 if ((mut && !tm)|| !dim) return;
00939 T* oldv = vec; T** oldm = mat; bool omut = mut;
00940 detach (tm);
00941 if (evl && fac != (T)1)
00942 {
00943 for (register T *p1 = vec, *p2 = oldv; p1 < endvec; p1++, p2++)
00944 *p1 = *p2 * fac;
00945 fac = (T)1;
00946 }
00947 else TBCICOPY (vec, oldv, T, dim);
00948 if (tm && omut)
00949 { TBCIDELETE(T,oldv,dim); TBCIDELETE(T*,oldm,col); }
00950 }
00951
00952
00953
00954
00955 template <typename T>
00956 inline F_TSMatrix<T>& F_TSMatrix<T>::eval (F_TMatrix<T>* tm)
00957 {
00958 if (mut && !tm)
00959 {
00960 if (fac != (T)1)
00961 {
00962 for (register T* ptr = vec; ptr < endvec; ptr++)
00963 *ptr *= fac;
00964 fac = (T)1;
00965 }
00966 }
00967 else
00968 clone (true, tm);
00969 return (*this);
00970 }
00971
00972
00973
00974
00975 #define F_STDDEF_TSM(op) \
00976 template <typename T> \
00977 inline F_TMatrix<T> F_TSMatrix<T>::operator op (const F_Matrix<T>& m) \
00978 { \
00979 BCHK(row != m.row || col != m.col, MatErr, Op op on diff size Mats, m.row, F_TMatrix<T> (*this)); \
00980 F_TSMatrix<T> ts (*this); ts.detach (); \
00981 for (register T *p1 = ts.vec, *p2 = vec, *p3 = m.vec; p2 < endvec; p1++, p2++, p3++) \
00982 *p1 = *p2 * fac op *p3; \
00983 ts.fac = (T)1; return F_TMatrix<T> (ts); \
00984 }
00985
00986 F_STDDEF_TSM(+)
00987 F_STDDEF_TSM(-)
00988
00989
00990 #define F_STDDEF_TSTM(op) \
00991 template <typename T> \
00992 inline F_TMatrix<T> F_TSMatrix<T>::operator op (const F_TMatrix<T>& tm) \
00993 { \
00994 BCHK(row != tm.row || col != tm.col, MatErr, Op op on diff size Mats, tm.row, tm); \
00995 for (register T *p1 = tm.vec, *p2 = vec; p2 < endvec; p1++, p2++) \
00996 *p1 = *p2 * fac op *p1; \
00997 destroy (); return tm; \
00998 }
00999
01000 F_STDDEF_TSTM(+)
01001 F_STDDEF_TSTM(-)
01002
01003
01004 #define F_STDDEF_TSTS(op) \
01005 template <typename T> \
01006 inline F_TMatrix<T> F_TSMatrix<T>::operator op (F_TSMatrix<T> ts) \
01007 { \
01008 BCHK(row != ts.row || col != ts.col, MatErr, Op op on diff size Mats, ts.row, F_TMatrix<T> (*this)); \
01009 F_TSMatrix<T> tm; \
01010 if (!mut && ts.mut) tm = ts; \
01011 else { tm = *this; tm.detach (); } \
01012 for (register T *p1 = tm.vec, *p2 = vec, *p3 = ts.vec; p2 < endvec; p1++, p2++, p3++) \
01013 *p1 = *p2 * fac op *p3 * ts.fac; \
01014 if (!mut && ts.mut) destroy (); else ts.destroy (); \
01015 tm.fac = (T)1; return F_TMatrix<T> (tm); \
01016 }
01017
01018 F_STDDEF_TSTS(+)
01019 F_STDDEF_TSTS(-)
01020
01021
01022 #define F_STDDEF_TST(op) \
01023 template <typename T> \
01024 inline F_TMatrix<T> F_TSMatrix<T>::operator op (const T& a) \
01025 { \
01026 F_TSMatrix<T> ts (*this); ts.detach (); \
01027 for (register T *p1 = ts.vec, *p2 = vec; p2 < endvec; p1++, p2++) \
01028 *p1 = *p2 * fac op a; \
01029 ts.fac = (T)1; return F_TMatrix<T> (ts); \
01030 }
01031
01032 F_STDDEF_TST(+)
01033 F_STDDEF_TST(-)
01034
01035
01036 #define F_STDDEF_TTS(op) \
01037 INST(template <typename T> class F_TSMatrix friend F_TMatrix<T> operator op (const T&, F_TSMatrix<T>);) \
01038 template <typename T> \
01039 inline F_TMatrix<T> operator op (const T& a, F_TSMatrix<T> ts) \
01040 { \
01041 F_TSMatrix<T> tm (ts); tm.detach (); \
01042 for (register T *p1 = tm._VEC, *p2 = ts._VEC; p1 < tm._ENDVEC; p1++, p2++) \
01043 *p1 = a op *p2 * ts._FAC; \
01044 tm._FAC = (T)1; return F_TMatrix<T> (tm); \
01045 }
01046
01047 F_STDDEF_TTS(+)
01048 F_STDDEF_TTS(-)
01049
01050
01051 template <typename T>
01052 F_TMatrix<T> F_TSMatrix<T>::operator * (const F_Matrix<T>& m)
01053 {
01054 F_TMatrix<T> ftm (row, m.col);
01055 BCHK(col != m.row, MatErr, Illegal sizes in F_Matrix multiplication, 0, (destroy(), ftm));
01056 register T tmp ALIGN(MIN_ALIGN);
01057 for (unsigned int r=0; r<row; r++) {
01058 for (unsigned int c=0; c<m.col; c++) {
01059 tmp = mat[0][r] * m(0, c);
01060 for (register unsigned int l=1; l<col; l++)
01061 tmp += mat[l][r] * m(l, c);
01062 ftm.setval(tmp*fac, r, c);
01063 }
01064 }
01065 destroy (); return ftm;
01066 }
01067
01068 template <typename T>
01069 TVector<T> F_TSMatrix<T>::operator * (const Vector<T>& v)
01070 {
01071 TVector<T> tv (row);
01072 BCHK (v.size() != col, MatErr, multiply F_Matrix w/ Vector: wrong config, v.size(), (destroy(), tv));
01073 for (unsigned int r=0; r<row; r++)
01074 {
01075 ALIGN3(register T el, mat[0][r] * v(0), MIN_ALIGN2);
01076 for (register unsigned int c=1; c<col; c++)
01077 el += mat[c][r] * v(c);
01078 tv.set (el * fac, r);
01079 }
01080 destroy (); return tv;
01081 }
01082
01083
01084 template <typename T>
01085 bool F_TSMatrix<T>::operator == (const F_Matrix<T>& m)
01086 {
01087 if (row != m.row || col != m.col) { destroy (); return false; }
01088 if (dim == 0) { return true; }
01089 if (fac == (T)1)
01090 {
01091 if (vec == m.vec) return true;
01092 if (TBCICOMP (vec, m.vec, T, dim)) { destroy (); return false; }
01093 }
01094 else
01095 {
01096 if (vec == m.vec) return false;
01097 for (register T *p1 = vec, *p2 = m.vec; p1 < endvec; p1++, p2++)
01098 if (*p1 * fac != *p2) { destroy (); return false; }
01099 }
01100 destroy (); return true;
01101 }
01102
01103
01104 template <typename T>
01105 bool F_TSMatrix<T>::operator == (F_TSMatrix<T> ts)
01106 {
01107 if (row != ts.row || col != ts.col) { destroy (); ts.destroy (); return false; }
01108 if (dim == 0) { return true; }
01109 if (fac == ts.fac)
01110 {
01111 if (vec == ts.vec) { destroy (); return true; }
01112 if (TBCICOMP (vec, ts.vec, T, dim)) { destroy (); ts.destroy (); return false; }
01113 }
01114 else
01115 {
01116 if (vec == ts.vec) { destroy (); return false; }
01117 for (register T *p1 = vec, *p2 = ts.vec; p1 < endvec; p1++, p2++)
01118 if (*p1 * fac != *p2) { destroy (); ts.destroy (); return false; }
01119 }
01120 destroy (); ts.destroy (); return true;
01121 }
01122
01123 template <typename T>
01124 F_TSMatrix<T>::operator TMatrix<T>()
01125 {
01126 TMatrix<T> tm(this->row, this->col);
01127 for (unsigned int c = 0; c < this->col; ++c)
01128 for (unsigned int r = 0; r < this->row; ++r)
01129 tm.setval(this->get(r, c), r, c);
01130 destroy();
01131 return tm;
01132 }
01133
01134
01135 template <typename T>
01136 double F_TSMatrix<T>::fabs ()
01137 {
01138 register T* ptr = vec;
01139 double register rv ALIGN(8) = fabssqr (*ptr++);
01140 for (; ptr < endvec; ptr++)
01141 rv += fabssqr (*ptr);
01142 rv *= fabssqr (fac);
01143 destroy (); return MATH__ sqrt (rv);
01144 }
01145
01146
01147 INST(template <typename T> class F_TSMatrix friend F_TSMatrix<T> operator * (const T&, F_TSMatrix<T>);)
01148 template <typename T>
01149 inline F_TSMatrix<T> operator * (const T& f, F_TSMatrix<T> ts)
01150 { ts._FAC = f * ts._FAC; return ts; }
01151
01152
01153
01154
01163 template <typename T>
01164 class F_Matrix : public F_TMatrix<T>
01165 {
01166
01167 public:
01168
01169 typedef T value_type;
01170 typedef T element_type;
01171 typedef T aligned_value_type TALIGN(MIN_ALIGN2);
01172
01173 friend class F_TSMatrix<T>;
01174
01175
01176 explicit F_Matrix (const unsigned d=0) : F_TMatrix<T> (d) {}
01177 F_Matrix (const unsigned r, const unsigned c) : F_TMatrix<T> (r, c) {}
01178 F_Matrix (const T& v, const unsigned r, const unsigned c) : F_TMatrix<T> (v, r, c) {}
01179
01180
01181
01182
01183 F_Matrix (const F_Matrix<T>& m) : F_TMatrix<T> (m) {}
01184 F_Matrix (const CSCMatrix<T>& m);
01185
01186
01187 F_Matrix (const F_TMatrix<T>& tm) : F_TMatrix<T> (tm) {}
01188 F_Matrix (F_TSMatrix<T>& ts) : F_TMatrix<T> (ts) {}
01189
01190 ~F_Matrix () { this->destroy (); }
01191
01192
01193 F_Matrix (const Matrix<T>& m);
01194 operator TMatrix<T>() const;
01195
01196
01197 static const char* mat_info () { return ("F_Matrix"); }
01198
01199
01200 T& operator () (const unsigned int, const unsigned int) const;
01201
01202 T* get_fortran_matrix() const { return this->vec; }
01203 const T& get (const unsigned r, const unsigned c) const
01204 { return this->mat[c][r]; }
01205
01206 unsigned int columns () const { return this->row; }
01207 unsigned int rows () const { return this->col; }
01208 unsigned long size () const { return this->dim; }
01209
01210 TVector<T> get_row (const unsigned int) const;
01211 TVector<T> get_col (const unsigned int) const;
01212 void set_row (const Vector<T>&, const unsigned int);
01213 void set_col (const Vector<T>&, const unsigned int);
01214 void setval(const T val, const unsigned int r, const unsigned int c)
01215 { this->operator() (r, c) = val; }
01216
01217
01218 F_Matrix<T>& operator = (const F_Matrix<T>& m)
01219 { this->F_TMatrix<T>::operator = (m); return *this; }
01220 F_Matrix<T>& operator = (const F_TMatrix<T>& tm)
01221 { this->F_TMatrix<T>::operator = (tm); return *this; }
01222 F_Matrix<T>& operator = (F_TSMatrix<T> ts)
01223 { F_TMatrix<T>(this->F_TMatrix<T>::operator = (ts)); return *this; }
01224 F_Matrix<T>& operator = (const T& v)
01225 { this->F_TMatrix<T>::operator = (v); return *this; }
01226
01227 F_Matrix<T>& resize (const unsigned r, const unsigned c)
01228 { this->F_TMatrix<T>::resize (r, c); return *this; }
01229 F_Matrix<T>& resize (const unsigned d)
01230 { return this->resize (d, d); }
01231 F_Matrix<T>& resize (const T& v, const unsigned r, const unsigned c)
01232 { this->F_TMatrix<T>::resize (v, r, c); return *this; }
01233 F_Matrix<T>& fill (const T& v = 0)
01234 { this->F_TMatrix<T>::fill (v); return *this; }
01235 F_Matrix<T>& setunit (const T& f = 1)
01236 { this->F_TMatrix<T>::setunit (f); return *this; }
01237 F_Matrix<T>& clear ()
01238 { this->F_TMatrix<T>::clear (); return *this; }
01239
01240
01241
01242
01243 F_Matrix<T>& operator += (const F_Matrix<T>& a)
01244 { this->F_TMatrix<T>::operator += (a); return *this; }
01245 F_Matrix<T>& operator -= (const F_Matrix<T>& a)
01246 { this->F_TMatrix<T>::operator -= (a); return *this; }
01247 F_Matrix<T>& operator += (F_TMatrix<T> a)
01248 { this->F_TMatrix<T>::operator += (a); return *this; }
01249 F_Matrix<T>& operator -= (F_TMatrix<T> a)
01250 { this->F_TMatrix<T>::operator -= (a); return *this; }
01251 F_Matrix<T>& operator += (const T& a)
01252 { this->F_TMatrix<T>::operator += (a); return *this; }
01253 F_Matrix<T>& operator -= (const T& a)
01254 { this->F_TMatrix<T>::operator -= (a); return *this; }
01255 F_Matrix<T>& operator *= (const T& a)
01256 { this->F_TMatrix<T>::operator *= (a); return *this; }
01257 F_Matrix<T>& operator /= (const T& a)
01258 { this->F_TMatrix<T>::operator /= (a); return *this; }
01259
01260
01261
01262 F_TMatrix<T> operator - () const { return -(F_TMatrix<T> (*this)); }
01263
01264 F_TMatrix<T> operator + (const F_Matrix<T>&) const;
01265 F_TMatrix<T> operator - (const F_Matrix<T>&) const;
01266 F_TMatrix<T> operator * (const F_Matrix<T>&) const;
01267
01268 F_TMatrix<T> operator + (F_TMatrix<T>) const;
01269 F_TMatrix<T> operator - (F_TMatrix<T>) const;
01270 F_TMatrix<T> operator * (F_TMatrix<T>) const;
01271
01272 F_TMatrix<T> operator + (F_TSMatrix<T>) const;
01273 F_TMatrix<T> operator - (F_TSMatrix<T>) const;
01274 F_TMatrix<T> operator * (F_TSMatrix<T>) const;
01275
01276 F_TMatrix<T> operator + (const T&) const;
01277 F_TMatrix<T> operator - (const T&) const;
01278 F_TSMatrix<T> operator * (const T&) const;
01279 F_TSMatrix<T> operator / (const T&) const;
01280
01281 TVector<T> operator * (const Vector<T>&) const;
01282 TVector<T> operator * (TVector<T>&) const;
01283
01284 bool operator == (const F_Matrix<T>& m) const;
01285 bool operator != (const F_Matrix<T>& m) const
01286 { return !(*this == m); }
01287
01288 bool operator == (F_TMatrix<T>& tm) const
01289 { F_Matrix<T> m (tm); return (*this == m); }
01290 bool operator != (F_TMatrix<T>& tm) const
01291 { return !(*this == tm); }
01292
01293 bool operator == (F_TSMatrix<T>&) const;
01294 bool operator != (F_TSMatrix<T>& ts) const
01295 { return !(*this == ts); }
01296
01297
01298
01299 friend STD__ ostream& operator << FGD (STD__ ostream&, const F_Matrix<T>&);
01300 friend STD__ istream& operator >> FGD (STD__ istream&, F_Matrix<T>&);
01301
01302
01303
01304 F_TMatrix<T> herm () const { return (F_TMatrix<T> (*this)).herm(); }
01305 F_TMatrix<T> conj () const { return (F_TMatrix<T> (*this)).conj(); }
01306 F_TMatrix<T> trans() const { return (F_TMatrix<T> (*this)).trans(); }
01307
01308 double fabs () const;
01309 };
01310
01311
01312
01313
01314 template <typename T>
01315 inline F_Matrix<T>::F_Matrix (const CSCMatrix<T>& m)
01316 : F_TMatrix<T>(m.rows(), m.columns())
01317 {
01318 for (unsigned int r=0; r<m.rows(); r++)
01319 for (unsigned int c=0; c<m.columns(); c++)
01320 operator()(r,c) = m(r,c);
01321 }
01322
01323 template <typename T>
01324 F_Matrix<T>::F_Matrix(const Matrix<T>& m)
01325 : F_TMatrix<T>(m.rows(), m.columns())
01326 {
01327 for (unsigned int r = 0; r < this->row; ++r)
01328 for (unsigned int c = 0; c < this->col; ++c)
01329 setval(m(r, c), r, c);
01330 }
01331
01332 template <typename T>
01333 F_Matrix<T>::operator TMatrix<T>() const
01334 {
01335 TMatrix<T> tm(this->row, this->col);
01336 for (unsigned int c = 0; c < this->col; ++c)
01337 for (unsigned int r = 0; r < this->row; ++r)
01338 tm.setval((*this)(r, c), r, c);
01339 return tm;
01340 }
01341
01342
01343 template <typename T>
01344 STD__ ostream& operator << (STD__ ostream& os, const F_Matrix<T>& m)
01345 {
01346 for (unsigned int r=0; r<m.row; r++) {
01347 for (unsigned int c=0; c<m.col; c++)
01348 os << m(r,c) << " ";
01349 os << "\n";
01350 }
01351 return os;
01352 }
01353
01354 INST(template <typename T> class F_TMatrix friend STD__ ostream& operator << (STD__ ostream& os, F_TMatrix<T> tm);)
01355 template <typename T>
01356 STD__ ostream& operator << (STD__ ostream& os, F_TMatrix<T> tm)
01357 {
01358 F_Matrix<T> fm(tm);
01359 return os << fm;
01360 }
01361
01362 #if 1
01363 INST(template <typename T> class F_TSMatrix friend STD__ ostream& operator << (STD__ ostream& os, F_TSMatrix<T> ts);)
01364 template <typename T>
01365 STD__ ostream& operator << (STD__ ostream& os, F_TSMatrix<T> ts)
01366 {
01367 return os << F_Matrix<T>(ts);
01368 }
01369 #endif
01370
01371 template <typename T>
01372 STD__ istream& operator >> (STD__ istream& in, F_Matrix<T>& m)
01373 {
01374 Vector<T> buf(m.row);
01375
01376 for (unsigned int i=0; i<m.col; i++)
01377 {
01378 in >> buf;
01379 m.set_col (buf, i);
01380 }
01381 return in;
01382 }
01383
01384
01385
01386
01387
01388 #define F_MSTDDEF_T(op) \
01389 template <typename T> \
01390 inline F_TMatrix<T> F_Matrix<T>::operator op (const T& a) const \
01391 { \
01392 F_TMatrix<T> t (this->row, this->col); \
01393 for (register T *p1=t.vec, *p2=this->vec; p2<this->endvec; ++p1, ++p2) \
01394 *p1 = *p2 op a; \
01395 return t; \
01396 }
01397
01398 F_MSTDDEF_T(+)
01399 F_MSTDDEF_T(-)
01400
01401 template <typename T>
01402 inline F_TSMatrix<T> F_Matrix<T>::operator * (const T& a) const
01403 { return F_TSMatrix<T> (*this, a); }
01404
01405 template <typename T>
01406 inline F_TSMatrix<T> F_Matrix<T>::operator / (const T& a) const
01407 {
01408 BCHK (a==(T)0, MatErr, Divide Mat by 0, 0, *this);
01409 return F_TSMatrix<T> (*this, (T)1/a);
01410 }
01411
01412
01413 #define F_MSTDDEF_M(op) \
01414 template <typename T> \
01415 inline F_TMatrix<T> F_Matrix<T>::operator op (const F_Matrix<T>& a) const \
01416 { \
01417 F_TMatrix<T> t (this->row, this->col); \
01418 BCHK(this->dim != a.dim, MatErr, Operator op on diff size matrices, a.dim, t); \
01419 for (register T *p1=t.vec, *p2=this->vec, *p3=a.vec; p2<this->endvec; ++p1, ++p2, ++p3) \
01420 *p1 = *p2 op *p3; \
01421 return t; \
01422 }
01423
01424 F_MSTDDEF_M(+)
01425 F_MSTDDEF_M(-)
01426
01427
01428 #define F_MSTDDEF_TM(op) \
01429 template <typename T> \
01430 inline F_TMatrix<T> F_Matrix<T>::operator op (F_TMatrix<T> a) const \
01431 { \
01432 BCHK(this->dim != a.dim, MatErr, Applying op on diff. size matrices, a.dim, a); \
01433 for (register T *p1=a.vec, *p2=this->vec; p2<this->endvec; ++p1, ++p2) \
01434 *p1 = *p2 op *p1; \
01435 return a; \
01436 }
01437
01438 F_MSTDDEF_TM(+)
01439 F_MSTDDEF_TM(-)
01440
01441 #define F_MSTDDEF_TS(op) \
01442 template <typename T> \
01443 inline F_TMatrix<T> F_Matrix<T>::operator op (F_TSMatrix<T> ts) const \
01444 { \
01445 BCHK(this->dim != ts.dim, MatErr, Applying op on diff. size matrices, ts.dim, (ts.destroy(),F_TMatrix<T> (*this)) ); \
01446 F_TSMatrix<T> tm (ts); tm.detach (); \
01447 for (register T *p1=tm.vec, *p2=this->vec, *p3=ts.vec; p2<this->endvec; ++p1, ++p2, ++p3) \
01448 *p1 = *p2 op *p3 * ts.fac; \
01449 tm.fac = (T)1; return F_TMatrix<T> (tm); \
01450 }
01451
01452 F_MSTDDEF_TS(+)
01453 F_MSTDDEF_TS(-)
01454
01455
01456
01457 template <typename T>
01458 F_TMatrix<T> F_Matrix<T>::operator * (const F_Matrix<T>& a) const
01459 {
01460 F_TMatrix<T> ftm(this->row, a.col);
01461 BCHK(this->col != a.row, MatErr, Illegal sizes in F_Matrix multiplication, 0, ftm);
01462 for (unsigned int r=0; r<this->row; ++r) {
01463 for (register unsigned int c=0; c<a.col; ++c) {
01464 ALIGN3(register T tmp, (*this)(r, 0) * a(0, c), MIN_ALIGN2);
01465 for (register unsigned int l=1; l<this->col; ++l)
01466 tmp += (*this)(r, l) * a(l, c);
01467 ftm.setval(tmp, r, c);
01468 }
01469 }
01470 return ftm;
01471 }
01472
01473 template <typename T>
01474 F_TMatrix<T> F_Matrix<T>::operator * (F_TSMatrix<T> a) const
01475 {
01476 F_TMatrix<T> ftm(this->row, a.col);
01477 BCHK(this->col != a.row, MatErr, Illegal sizes in F_Matrix multiplication, 0, ftm);
01478 register T tmp ALIGN(MIN_ALIGN2);
01479 for (unsigned int r=0; r<this->row; ++r) {
01480 for (register unsigned int c=0; c<a.col; ++c) {
01481 tmp = (*this)(c, 0) * a.mat[c][0];
01482 for (register unsigned int l=1; l<this->col; ++l)
01483 tmp += (*this)(r, l) * a.mat[c][l];
01484 ftm.setval(tmp*a.fac, r, c);
01485 }
01486 }
01487 a.destroy (); return ftm;
01488 }
01489
01490
01491 template <typename T>
01492 inline F_TMatrix<T> F_Matrix<T>::operator * (F_TMatrix<T> a) const
01493 {
01494 F_TMatrix<T> ftm (this->operator * (F_Matrix<T> (a)));
01495 return ftm;
01496 }
01497
01498 template <typename T>
01499 inline F_TMatrix<T> F_TMatrix<T>::operator * (const F_Matrix<T>& a)
01500 {
01501 F_Matrix<T> m (*this);
01502 return (m * a);
01503 }
01504
01505
01506 template <typename T>
01507 inline F_TMatrix<T> F_TMatrix<T>::operator * (F_TMatrix<T> a)
01508 {
01509 F_Matrix<T> m (*this);
01510 return (m * (F_Matrix<T> (a)));
01511 }
01512
01513 template <typename T>
01514 inline F_TMatrix<T> F_TMatrix<T>::operator * (F_TSMatrix<T> a)
01515 {
01516 F_Matrix<T> m (*this);
01517 return (m * a);
01518 }
01519
01520
01521 template <typename T>
01522 bool F_Matrix<T>::operator == (const F_Matrix<T>& m) const
01523 {
01524 if (this->row != m.row || this->col != m.col)
01525 return false;
01526 if (this->vec == m.vec || this->dim == 0)
01527 return true;
01528 if (TBCICOMP (this->vec, m.vec, T, this->dim))
01529 return false;
01530 else
01531 return true;
01532 }
01533
01534 template <typename T>
01535 bool F_Matrix<T>::operator == (F_TSMatrix<T>& ts) const
01536 {
01537 if (this->row != ts.row || this->col != ts.col)
01538 return (ts.destroy(), false);
01539 if (this->vec == 0) {
01540 return true;
01541 }
01542 if (ts.fac == (T)1) {
01543 if (this->vec == ts.vec)
01544 return true;
01545 if (TBCICOMP(this->vec, ts.vec, T, this->dim)) {
01546 ts.destroy (); return false;
01547 }
01548 } else {
01549 if (this->vec == ts.vec)
01550 return false;
01551 for (register T *p1 = this->vec, *p2 = ts.vec; p1 < this->endvec; ++p1, ++p2)
01552 if (*p1 != *p2 * ts.fac) {
01553 ts.destroy (); return false;
01554 }
01555 }
01556 ts.destroy ();
01557 return true;
01558 }
01559
01560
01561 template<typename T>
01562 TVector<T> F_Matrix<T>::operator * (const Vector<T>& v) const
01563 {
01564 TVector<T> tv (this->row);
01565 for (unsigned int r=0; r<this->row; ++r) {
01566 register T el = 0;
01567 for (register unsigned int c=0; c<this->col; ++c)
01568 el += this->operator() (r, c) * v(c);
01569 tv.set (el, r);
01570 }
01571 return tv;
01572 }
01573
01574 template<typename T>
01575 inline TVector<T> F_Matrix<T>::operator * (TVector<T>& c) const
01576 {
01577 Vector<T> cn (c);
01578 return (*this * cn);
01579 }
01580
01581 #if 0
01582 template <typename T>
01583 inline TVector<T> F_Matrix<T>::operator () (const unsigned int i) const
01584 {
01585 TVector<T> v(this->row);
01586 BCHK(i < 0 || i >= this->col, MatErr, Illegal row index in get_row, i, v);
01587 for (register unsigned int j=0; j<this->row; ++j)
01588 v.vec[j] = this->mat[j][i];
01589 return v;
01590 }
01591 #endif
01592
01593 template <typename T>
01594 inline void F_Matrix<T>::set_col (const Vector<T>& v, const unsigned int c)
01595 {
01596 F_TMatrix<T>::set_col(v, c);
01597 }
01598
01599 template <typename T>
01600 inline TVector<T> F_Matrix<T>::get_col (const unsigned int c) const
01601 {
01602 return F_TMatrix<T>::get_col(c);
01603 }
01604
01605 template <typename T>
01606 inline TVector<T> F_Matrix<T>::get_row (const unsigned int r) const
01607 {
01608 return F_TMatrix<T>::get_row(r);
01609 }
01610
01611 template <typename T>
01612 inline void F_Matrix<T>::set_row (const Vector<T>& v, const unsigned int r)
01613 {
01614 F_TMatrix<T>::set_row(v, r);
01615 }
01616
01617 template <typename T>
01618 inline T& F_Matrix<T>::operator () (const unsigned int r, const unsigned int c) const
01619 {
01620 BCHK(r>=this->row, MatErr, illegal row index, r, this->mat[0][0]);
01621 BCHK(c>=this->col, MatErr, Illegal col index, c, this->mat[0][0]);
01622 return this->mat[c][r];
01623 }
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635 template <typename T>
01636 double F_Matrix<T>::fabs () const
01637 {
01638 register double rv = 0.0;
01639 for (register T *ptr = this->vec; ptr < this->endvec; ++ptr)
01640 rv += fabssqr (*ptr);
01641 return MATH__ sqrt (rv);
01642 }
01643
01644
01645 template <typename T>
01646 F_TMatrix<T> F_TMatrix<T>::transposed_copy() const
01647 {
01648 F_TMatrix<T> trm(this->col, this->row);
01649 for (unsigned r = 0; r < this->row; ++r)
01650 for (unsigned c = 0; c < this->col; ++c)
01651 trm.mat[c][r] = this->mat[r][c];
01652
01653
01654
01655 return trm;
01656 }
01657
01658
01659 INST(template <typename T> class F_TMatrix friend F_TMatrix<T> transpose(const F_TMatrix<T>& tm);)
01660 template <typename T>
01661 inline F_TMatrix<T> transpose(const F_TMatrix<T>& ftm)
01662 {
01663 return ftm.transposed_copy();
01664 }
01665
01666 template <typename T>
01667 F_TMatrix<T>& F_TMatrix<T>::transpose()
01668 {
01669 if (this->col != this->row) {
01670
01671 F_Matrix<T> transmat(this->transposed_copy());
01672 return this->swap(transmat);
01673 } else {
01674
01675 for (unsigned r = 1; r < this->row; ++r)
01676 for (unsigned c = 0; c < r; ++c)
01677 SWAP(this->mat[r][c], this->mat[c][r]);
01678 return *this;
01679 }
01680 }
01681
01682 template <typename T>
01683 inline F_TMatrix<T>& F_TMatrix<T>::swap (F_TMatrix<T>& m)
01684 {
01685
01686 SWAP(this->dim, m.dim);
01687 SWAP(this->row, m.row);
01688
01689 unsigned int tcol = this->col; this->col = m.col; m.col = tcol;
01690 SWAP(this->mat, m.mat);
01691 SWAP(this->vec, m.vec); SWAP(this->endvec, m.endvec);
01692 return *this;
01693 }
01694
01695 #undef _DIM
01696 #undef _VEC
01697 #undef _ENDVEC
01698 #undef _ROW
01699 #undef _COL
01700 #undef _FAC
01701
01702 NAMESPACE_END
01703
01704 NAMESPACE_CSTD
01705
01706 INST(template <typename T> class TBCI__ F_TMatrix friend double fabs (const TBCI__ F_TMatrix<T>&);)
01707 template <typename T>
01708 inline double fabs (const TBCI__ F_TMatrix<T>& ftm)
01709 { return ftm.fabs (); }
01710
01711 INST(template <typename T> class TBCI__ F_Matrix friend double fabs (const TBCI__ F_Matrix<T>&);)
01712 template <typename T>
01713 inline double fabs (const TBCI__ F_Matrix<T>& fm)
01714 { return fm.fabs (); }
01715
01716 INST(template <typename T> class TBCI__ F_TSMatrix friend double fabs (TBCI__ F_TSMatrix<T>&);)
01717 template <typename T>
01718 inline double fabs ( TBCI__ F_TSMatrix<T>& ftsm)
01719 { return ftsm.fabs (); }
01720
01721 NAMESPACE_CSTD_END
01722
01723 #endif