00001
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef TBCI_MATRIX_H
00013 #define TBCI_MATRIX_H
00014
00015 #include "basics.h"
00016 #include "vector.h"
00017
00018 #include "matrix_sig.h"
00019
00020 #ifdef DEBUG_THREAD
00021 # include <cstdio>
00022 #endif
00023
00024
00025 #if !defined(NO_GD) && !defined(AUTO_DECL)
00026 # include "matrix_gd.h"
00027 #endif
00028
00029 NAMESPACE_TBCI
00030
00031
00032 #ifdef HAVE_GCC295_FRIEND_BUG
00033 # define _VEC getvec()
00034 # define _ENDVEC getendvec()
00035 # define _DIM size()
00036 # define _ROW rows()
00037 # define _COL columns()
00038 # define _FAC getfac()
00039 #else
00040 # define _VEC vec
00041 # define _ENDVEC endvec
00042 # define _DIM dim
00043 # define _ROW row
00044 # define _COL col
00045 # define _FAC fac
00046 #endif
00047
00048
00049 #ifdef EXCEPT
00050
00051
00053 class MatErr : public NumErr
00054 {
00055 public:
00056 MatErr()
00057 : NumErr(errtext = "Error in Matrix library") {}
00058 MatErr(const char* t, const long i = 0)
00059 : NumErr(t, i) {}
00060 MatErr(const MatErr& me)
00061 : NumErr(me) {}
00062 virtual ~MatErr() throw() {}
00063 };
00064 #endif
00065
00066 #ifdef PRAGMA_I
00067 # pragma interface "matrix.h"
00068 #endif
00069
00070 enum rowcolvec { rowvec = 0, colvec = 1 };
00071
00072 template <typename T> class Matrix;
00073 template <typename T> class TMatrix;
00074 template <typename T> class TSMatrix;
00075 template <typename T> class Mat_Brack;
00076 template <typename T> class BdMatrix;
00077 template <typename T> class Tensor;
00078
00079 template <typename T>
00080 void do_mat_vec_mult (const unsigned start, const unsigned end,
00081 TVector<T> *res, const Matrix<T> *mat,
00082 const Vector<T> *vec);
00083
00084 template <typename T>
00085 void do_mat_tsv_mult (const unsigned start, const unsigned end,
00086 TVector<T> *res, const Matrix<T> *mat,
00087 const TSVector<T> *vec);
00088
00089 template <typename T>
00090 void do_mat_vec_transmult (const unsigned start, const unsigned end,
00091 TVector<T> *res, const Matrix<T> *mat,
00092 const Vector<T> *vec);
00093
00094
00095 #if defined(SMP) && !defined(SMP_MATSLICE)
00096 # define SMP_MATSLICE 1024
00097 #endif
00098
00099
00104
00105 template <typename T>
00106 class TMatrix : public Matrix_Sig<T>
00107 {
00108 protected:
00109 typedef T mat_t ;
00110 typedef T* Tptr ;
00111
00112 unsigned long dim;
00113 unsigned int row, col:31;
00114 mutable unsigned int freeable:1;
00116 T **mat, *vec, *endvec;
00117
00118 int set_ptrs ();
00119
00120 public:
00121 #if 1 //defined(HAVE_GCC295_FRIEND_BUG) || defined(HAVE_PROMOTION_BUG)
00122
00123 T* getvec () const { return vec; }
00124 T* getendvec () const { return endvec; }
00125 #endif
00126 typedef T value_type;
00127 typedef T element_type;
00128 typedef T aligned_value_type TALIGN(MIN_ALIGN2);
00129
00130 friend class Matrix<T>;
00131 friend class TSMatrix<T>;
00132 friend class Tensor<T>;
00133 friend class Mat_Brack<T>;
00134 friend class Vector<T>;
00135 friend class TVector<T>;
00136 friend class BdMatrix<T>;
00137
00138 friend NOINST TMatrix<T> LU_solve FGD (const BdMatrix<T>&, const Matrix<T>&);
00139 friend NOINST TMatrix<T> lu_solve FGD (BdMatrix<T>&, const Matrix<T>&);
00140 friend NOINST TMatrix<T> LU_invert FGD (const BdMatrix<T>&);
00141 friend NOINST TMatrix<T> lu_invert FGD (BdMatrix<T>&);
00142
00143 friend void FRIEND_TBCI2__ do_mat_vec_mult FGD (const unsigned start, const unsigned end,
00144 TVector<T> *res, const Matrix<T> *mat,
00145 const Vector<T> *vec) HOT;
00146 friend void FRIEND_TBCI2__ do_mat_tsv_mult FGD (const unsigned start, const unsigned end,
00147 TVector<T> *res, const Matrix<T> *mat,
00148 const TSVector<T> *tsv) HOT;
00149 friend void FRIEND_TBCI2__ do_mat_vec_transmult FGD (const unsigned start, const unsigned end,
00150 TVector<T> *res, const Matrix<T> *mat,
00151 const Vector<T> *vec) HOT;
00152
00153
00154 public:
00156 explicit TMatrix (const unsigned = 0);
00158 TMatrix (const unsigned, const unsigned);
00160 TMatrix (const T&, const unsigned, const unsigned);
00162 explicit TMatrix (const Vector<T>&, const enum rowcolvec = colvec);
00164 TMatrix (const TMatrix<T>&) HOT;
00165 TMatrix (TSMatrix<T>);
00167 TMatrix (const Matrix<T>&) HOT;
00169 void real_destroy ();
00171 void mark_destroy() const;
00172
00173
00174 static const char* mat_info () { return ("TMatrix"); }
00175
00176
00177
00178 ~TMatrix ()
00179 { if (freeable) real_destroy(); }
00180
00181 #ifndef HAVE_PROMOTION_BUG
00182 # ifndef HAVE_GCC295_TMPLFRNDCLS_BUG
00183
00184 template <typename U> friend class Matrix;
00185 template <typename U> friend class TMatrix;
00186 # endif
00187 template <typename U> explicit TMatrix (const Matrix<U>& m)
00188 : dim (m._DIM), row (m._ROW), col (m._COL),
00189 freeable (0),
00190 mat (dim>0?NEW(Tptr,row):0), vec (dim>0?NEW(T,dim):0)
00191 { set_ptrs (); T *t = vec; U *u =m._VEC;
00192 while (t < endvec) *t++ = *u++; }
00193
00194 template <typename U> explicit TMatrix (const TMatrix<U>& tm)
00195 : dim (tm._DIM), row (tm._ROW), col (tm._COL),
00196 freeable (0),
00197 mat (dim>0?NEW(Tptr,row):0), vec (dim>0?NEW(T,dim):0)
00198 { set_ptrs (); T *t = vec; U *u =tm._VEC;
00199 while (t < endvec) *t++ = *u++; }
00200 #endif
00201
00203 TMatrix<T>& operator = (const Matrix<T>&) HOT;
00204 TMatrix<T>& operator = (const TMatrix<T>&) HOT;
00205 TMatrix<T>& operator = (TSMatrix<T>);
00206 TMatrix<T>& operator = (const T&);
00207 TMatrix<T>& alias (const TMatrix<T>& m);
00208
00210 TMatrix<T>& operator += (TMatrix<T>);
00211 TMatrix<T>& operator += (const Matrix<T>&);
00212 TMatrix<T>& operator += (const T&);
00213 TMatrix<T>& operator += (TSMatrix<T>);
00214 TMatrix<T>& operator -= (TMatrix<T>);
00215 TMatrix<T>& operator -= (const Matrix<T>&);
00216 TMatrix<T>& operator -= (const T&);
00217 TMatrix<T>& operator -= (TSMatrix<T>);
00218
00219 TSMatrix<T> operator *= (const T&);
00220 TSMatrix<T> operator /= (const T&);
00221
00222
00223 TMatrix<T>& operator - ();
00224
00225 TMatrix<T>& operator + (TMatrix<T>);
00226 TMatrix<T>& operator + (TSMatrix<T>);
00227 TMatrix<T>& operator + (const Matrix<T>&);
00228 TMatrix<T>& operator + (const T&);
00229 TMatrix<T>& operator - (TMatrix<T>);
00230 TMatrix<T>& operator - (TSMatrix<T>);
00231 TMatrix<T>& operator - (const Matrix<T>&);
00232 TMatrix<T>& operator - (const T&);
00233 TSMatrix<T> operator * (const T&);
00234 TSMatrix<T> operator / (const T&);
00235
00236 TMatrix<T> operator * (const Matrix<T>&);
00237 TMatrix<T> operator * (TMatrix<T>);
00238 TMatrix<T> operator * (TSMatrix<T>);
00239
00240 TVector<T> operator * (const Vector<T>& v)
00241 { Matrix<T> m (*this); return (m * v); }
00242 TVector<T> operator * (TVector <T>& tv)
00243 { Matrix<T> m (*this); return (m * tv); }
00244 TVector<T> operator * (const TSVector <T>& tsv)
00245 { Matrix<T> m (*this); return (m * tsv); }
00246
00247
00248 #ifndef HAVE_GCC295_FRIEND_BUG
00249 friend NOINST TMatrix<T> FRIEND_TBCI__ operator + FGD (const T&, TMatrix<T>);
00250 friend NOINST TMatrix<T> FRIEND_TBCI__ operator - FGD (const T&, TMatrix<T>);
00251 friend NOINST TMatrix<T> FRIEND_TBCI__ operator + FGD (const T&, const Matrix<T>&);
00252 friend NOINST TMatrix<T> FRIEND_TBCI__ operator - FGD (const T&, const Matrix<T>&);
00253 friend NOINST TSMatrix<T> FRIEND_TBCI__ operator * FGD (const T&, TMatrix<T>);
00254 friend NOINST TSMatrix<T> FRIEND_TBCI__ operator * FGD (const T&, const Matrix<T>&);
00255 #endif
00256
00257 TMatrix<T>& swap (TMatrix<T>&);
00259 TMatrix<T> transposed_copy() const;
00260 TMatrix<T>& transpose();
00261
00262
00263
00264
00266 T operator () (const unsigned int, const unsigned int) const HOT;
00267
00268 #ifndef TBCI_NEW_BRACKET
00269 Mat_Brack<T> operator [] (const unsigned int i) const;
00270 #else
00271 T* operator [] (const unsigned int i) const;
00272 #endif
00273
00274
00275 T& setval(const T& val, const unsigned int r, const unsigned int c)
00276 { return mat[r][c] = val; }
00277 T& setval (const unsigned r, const unsigned c)
00278 { return mat[r][c]; }
00279
00281 typename tbci_traits<T>::const_refval_type
00282 get (const unsigned r, const unsigned c) const
00283 { return mat[r][c]; }
00284 T& set (const T& val, const unsigned r, const unsigned c)
00285 { return mat[r][c] = val; }
00286 const T& getcref(const unsigned r, const unsigned c) const
00287 { return mat[r][c]; }
00288
00290 const T* getcolptr (const unsigned r) const { return mat[r]; }
00291 T* getcolptr (const unsigned r) { return mat[r]; }
00292
00294 bool operator == (const Matrix<T>& m);
00295 bool operator != (const Matrix<T>& m)
00296 { return !(*this == m); }
00297
00298 bool operator == (TMatrix<T> tm)
00299 { Matrix<T> m (tm); return (*this == m); }
00300 bool operator != (TMatrix<T> tm)
00301 { return !(*this == tm); }
00302
00303 bool operator == (TSMatrix<T>);
00304 bool operator != (TSMatrix<T> ts)
00305 { return !(*this == ts); }
00306
00307
00309 unsigned int columns () const { return col; }
00311 unsigned int rows () const { return row; }
00313 unsigned long size () const { return dim; }
00314
00316 TVector<T> operator () (const unsigned int) const;
00318 TVector<T> get_row (const unsigned int) const;
00320 TVector<T> get_col (const unsigned int) const;
00321
00323 void set_row (const Vector<T>&, const unsigned int);
00325 void set_col (const Vector<T>&, const unsigned int);
00326
00328 void set_row_partial (const Vector<T>&, const unsigned int,
00329 const unsigned int);
00331 void set_col_partial (const Vector<T>&, const unsigned int,
00332 const unsigned int);
00333 #if 0
00335 void set_row_indexed (const Vector<T>&, const unsigned int,
00336 const BVector<unsigned int>&);
00338 void set_row_indexed (const Vector<T>&, const unsigned int,
00339 const BVector<unsigned int>&);
00341 void set_submatrix (const Matrix<T>&,
00342 const unsigned int, const unsigned int);
00343 #endif
00344
00345 #if 0
00346 template <unsigned long dim>
00347 void set_row (const FS_Vector<dim,T>& v, const unsigned int i)
00348 {
00349 BCHKNR(i < 0 || i >= row, MatErr, Illegal row index in set_row, i);
00350 BCHKNR(dim != col, MatErr, Different sizes in set_row, dim);
00351 TBCICOPY (mat[i], &v(0), T, dim);
00352 }
00353 #endif
00354
00356 TMatrix<T>& resize (const unsigned int, const unsigned int);
00358 TMatrix<T>& resize (const unsigned int d) { return this->resize (d, d); }
00360 TMatrix<T>& resize (const T&, const unsigned int, const unsigned int);
00362 TMatrix<T>& resize (const TMatrix<T>&);
00364 TMatrix<T>& cheapdownsizerow (const unsigned);
00366 TMatrix<T>& fill (const T& = (T)0);
00368 TMatrix<T>& clear ();
00370 TMatrix<T>& fill (const Vector<T>&);
00372 TMatrix<T>& setunit (const T& = (T)1);
00374 TMatrix<T>& row_expand (const unsigned int r);
00376 TMatrix<T>& row_expand (const TMatrix<T>& m);
00377
00379 T trace () const;
00380
00382 double fabssqr () const;
00383 double fabs () const { return GLBL__ MATH__ sqrt (fabssqr()); }
00384 };
00385
00386
00387 template <typename T>
00388 inline void TMatrix<T>::real_destroy ()
00389 {
00390 if (UNLIKELY(dim)) {
00391 TBCIDELETE(T, vec, dim); TBCIDELETE(Tptr, mat, row);
00392 }
00393 }
00394
00395 template <typename T>
00396 inline void TMatrix<T>::mark_destroy () const
00397 {
00398 this->freeable = 1;
00399 }
00400
00401
00402 template <typename T>
00403 inline int TMatrix<T>::set_ptrs ()
00404 {
00405 if (LIKELY(mat && vec)) {
00406
00407 #if 1
00408 T* ptr = vec;
00409 for (register unsigned i = 0; i < row; ++i) {
00410 mat[i] = ptr; ptr += col;
00411
00412 }
00413 endvec = ptr;
00414 #else
00415
00416
00417
00418 const unsigned int ROW = row;
00419 const unsigned int COL = col;
00420 T* RESTRICT const VEC = vec;
00421 T** RESTRICT const MAT = mat;
00422 for (register unsigned i = 0; i < ROW; ++i)
00423 MAT[i] = VEC + i*COL;
00424 endvec = VEC + ROW*COL;
00425 #endif
00426 return 0;
00427 } else {
00428 if (UNLIKELY(vec))
00429 TBCIDELETE(T, vec, dim);
00430 if (UNLIKELY(mat))
00431 TBCIDELETE(Tptr, mat, row);
00432 dim = 0; row = 0; col = 0;
00433 mat = (T**)0; vec = (T*)0; endvec = (T*)0;
00434 return -1;
00435 }
00436 }
00437
00438 template <typename T>
00439 inline TMatrix<T>::TMatrix (const unsigned d)
00440 : dim (((unsigned long)d)*d), row(d), col(d), freeable (0),
00441 mat (d>0?NEW(Tptr,d):0), vec (d>0?NEW(T,d*d):0)
00442 {
00443 set_ptrs ();
00444 }
00445
00446
00447 template <typename T>
00448 inline TMatrix<T>::TMatrix (const unsigned r, const unsigned c)
00449 : dim(((unsigned long)r)*c), row (r), col (c), freeable (0),
00450 mat (r*c>0?NEW(Tptr,r):0), vec (r*c>0?NEW(T,r*c):0)
00451 {
00452 set_ptrs ();
00453 }
00454
00455 template <typename T>
00456 inline TMatrix<T>::TMatrix (const T& val, const unsigned r, const unsigned c)
00457 : dim(((unsigned long)r)*c), row (r), col (c), freeable (0),
00458 mat (r*c>0?NEW(Tptr,r):0), vec (r*c>0?NEW(T,r*c):0)
00459 {
00460 if (LIKELY(!set_ptrs ()))
00461 TBCIFILL (vec, val, T, dim);
00462 }
00463
00464
00465 template <typename T>
00466 inline TMatrix<T>::TMatrix (const Vector<T>& v, const enum rowcolvec r)
00467 : dim(v.dim), row(r==rowvec?v.dim:1), col(r==rowvec?1:v.dim),
00468 freeable(0),
00469 mat (v.dim?(r==rowvec?NEW(Tptr,1):NEW(Tptr,v.dim)):0),
00470 vec (v.dim>0?NEW(T,v.dim):0)
00471 {
00472 if (LIKELY(!set_ptrs ()))
00473 TBCICOPY (vec, v.vec, T, dim);
00474 }
00475
00476
00477 template <typename T>
00478 inline TMatrix<T>::TMatrix (const Matrix<T>& m)
00479 : dim (m.dim), row (m.row), col (m.col),
00480 freeable (0),
00481 mat (m.dim>0?NEW(Tptr,m.row):0), vec (m.dim>0?NEW(T,m.dim):0)
00482 {
00483 if (LIKELY(!set_ptrs ()))
00484 TBCICOPY (vec, m.vec, T, dim);
00485 }
00486
00487
00488
00489 template <typename T>
00490 inline TMatrix<T>::TMatrix (const TMatrix<T>& tm)
00491 : dim (tm.dim), row (tm.row), col (tm.col), freeable (0),
00492 mat (tm.mat), vec (tm.vec), endvec (tm.endvec)
00493 {
00494 BCHKNR(tm.freeable, MatErr, alias freeable object, (long)&tm);
00495 }
00496
00497 template <typename T>
00498 inline TMatrix<T>& TMatrix<T>::alias (const TMatrix<T>& tm)
00499 {
00500 BCHKNR(tm.freeable, MatErr, alias freeable object, (long)&tm);
00501 real_destroy();
00502 dim = tm.dim; row = tm.row; col = tm.col; freeable = 0;
00503 mat = tm.mat; vec = tm.vec; endvec = tm.endvec;
00504 return *this;
00505 }
00506
00507 template <typename T>
00508 inline TMatrix<T>::TMatrix (TSMatrix<T> ts)
00509 : dim (ts.dim), row (ts.row), col (ts.col), freeable (0)
00510 {
00511 ts.eval (); vec = ts.vec; mat = ts.mat;
00512 endvec = ts.endvec; ts.mut = false;
00513 }
00514
00515
00516 template <typename T>
00517 inline T TMatrix<T>::operator () (const unsigned int r, const unsigned int c) const
00518 {
00519 BCHK(r>=row, MatErr, Illegal row index, r, mat[0][0]);
00520 BCHK(c>=col, MatErr, illegal col index, c, mat[0][0]);
00521 mark_destroy ();
00522 return mat[r][c];
00523 }
00524
00525
00526 template <typename T>
00527 inline TMatrix<T>& TMatrix<T>::operator = (const Matrix<T>& a)
00528 {
00529 BCHK(dim != a.dim, MatErr, Different sizes in assignment, a.dim, *this );
00530 TBCICOPY(vec, a.vec, T, dim);
00531 return *this;
00532 }
00533
00534
00535 template <typename T>
00536 inline TMatrix<T>& TMatrix<T>::operator = (const TMatrix<T>& a)
00537 {
00538 BCHK(row != a.row || col != a.col, MatErr, Different sizes in assignment, a.dim, *this );
00539 this->alias(a);
00540
00541 return *this;
00542 }
00543
00544 template <typename T>
00545 inline TMatrix<T>& TMatrix<T>::operator = (TSMatrix<T> a)
00546 {
00547 BCHK(col != a.col || row != a.row, MatErr, Different sizes in assignment, a.dim, *this );
00548 a.eval (this);
00549 return *this;
00550 }
00551
00552
00553 template <typename T>
00554 inline TMatrix<T>& TMatrix<T>::operator = (const T& val)
00555 {
00556 return this->fill (val);
00557 }
00558
00559
00560 template <typename T>
00561 inline TMatrix<T>& TMatrix<T>::setunit (const T& fac)
00562 {
00563
00564 if (LIKELY(dim))
00565 TBCICLEAR (vec, T, dim);
00566 BCHK(col!=row, MatErr, setunit makes only sense on quadratic matrices, col, *this);
00567 unsigned iend = MIN(row,col);
00568 for (register unsigned i = 0; i < iend; i++)
00569 mat[i][i] = fac;
00570 return *this;
00571 }
00572
00573 template <typename T>
00574 inline TMatrix<T>& TMatrix<T>::clear ()
00575 {
00576
00577 if (UNLIKELY(dim))
00578 TBCICLEAR (vec, T, dim);
00579 return *this;
00580 }
00581
00582 template <typename T>
00583 inline void TMatrix<T>::set_row (const Vector<T>& v, const unsigned int r)
00584 {
00585 BCHKNR(r < 0 || r >= row, MatErr, Illegal row index in set_row, r);
00586 BCHKNR(v.dim != (unsigned long)col, MatErr, Wrong size vector, v.dim);
00587 TBCICOPY(mat[r], v.vec, T, v.dim);
00588 }
00589
00590 template <typename T>
00591 inline void TMatrix<T>::set_row_partial (const Vector<T>& v,
00592 const unsigned int r, const unsigned off)
00593 {
00594 BCHKNR(r < 0 || r >= row, MatErr, Illegal row index in set_row_partial, r);
00595 BCHKNR(v.dim > (unsigned long)col+off, MatErr, Too large vector, v.dim);
00596 TBCICOPY(mat[r]+off, v.vec, T, v.dim);
00597 }
00598
00599 template <typename T>
00600 inline void TMatrix<T>::set_col (const Vector<T>& v, const unsigned int c)
00601 {
00602 BCHKNR(c < 0 || c >= col, MatErr, Illegal col index in set_col, c);
00603 BCHKNR(v.dim != (unsigned long)row, MatErr, Wrong size vector, v.dim);
00604 const unsigned ROW = row;
00605 for (register unsigned r = 0; r < ROW; ++r)
00606 mat[r][c] = v.vec[r];
00607 }
00608
00609 template <typename T>
00610 inline void TMatrix<T>::set_col_partial (const Vector<T>& v,
00611 const unsigned int c, const unsigned off)
00612 {
00613 BCHKNR(c < 0 || c >= col, MatErr, Illegal col index in set_col, c);
00614 BCHKNR(v.dim > (unsigned long)row+off, MatErr, Too large vector, v.dim);
00615 const unsigned ROW = v.dim;
00616 for (register unsigned r = 0; r < ROW; ++r)
00617 mat[r+off][c] = v.vec[r];
00618 }
00619
00620 template <typename T>
00621 inline TVector<T> TMatrix<T>::get_col (const unsigned int c) const
00622 {
00623 const unsigned ROW = row;
00624 TVector<T> v(ROW);
00625 BCHK(c < 0 || c >= col, MatErr, Illegal col index in get_col, c, v);
00626 for (register unsigned j = 0; j < ROW; ++j)
00627 v.vec[j] = mat[j][c];
00628 mark_destroy();
00629 return v;
00630 }
00631
00632
00633 template <typename T>
00634 inline TVector<T> TMatrix<T>::get_row (const unsigned int r) const
00635 {
00636 TVector<T> v(col);
00637 TBCICOPY (v.vec, mat[r], T, col);
00638 mark_destroy();
00639 return v;
00640 }
00641
00642 template <typename T>
00643 inline TVector<T> TMatrix<T>::operator () (const unsigned int i) const
00644 {
00645 return this->get_row(i);
00646 }
00647
00648 template <typename T>
00649 TMatrix<T>& TMatrix<T>::resize (const unsigned int r, const unsigned int c)
00650 {
00651 if (LIKELY(r == row && c == col))
00652 return *this;
00653 if (UNLIKELY(dim))
00654 TBCIDELETE(Tptr, mat, row);
00655 T* vv = vec;
00656 unsigned long dd = dim;
00657 dim = ((unsigned long)r)*c;
00658 if (LIKELY(dim)) {
00659 mat = NEW(Tptr,r); vec = NEW(T,dim);
00660 row = r; col = c;
00661 } else {
00662 mat = (T**)0; vec = (T*)0; endvec = (T*)0;
00663 }
00664 if (!set_ptrs())
00665 TBCICOPY(vec, vv, T, MIN(dim,dd));
00666 if (UNLIKELY(dd))
00667 TBCIDELETE(T, vv, dd);
00668 return *this;
00669 }
00670
00671 template <typename T>
00672 TMatrix<T>& TMatrix<T>::row_expand (const unsigned int r)
00673 {
00674 if (LIKELY(r == row))
00675 return *this;
00676 dim = ((unsigned long)r)*col;
00677 if (LIKELY(dim)) {
00678 REALLOC (vec, ((unsigned long)row)*col, T, dim);
00679 TBCIDELETE (Tptr, mat, row);
00680 mat = NEW (Tptr,r);
00681 } else {
00682 if (UNLIKELY(row*col)) {
00683 TBCIDELETE (T, vec, (row*col)); TBCIDELETE (Tptr, mat, row);
00684 }
00685 mat = (T**)0; vec = (T*)0; endvec = (T*)0;
00686 }
00687 if (LIKELY(mat && vec)) {
00688 T* ptr = vec;
00689 for (register unsigned i=0; i<r; i++) {
00690 mat[i] = ptr; ptr += col;
00691 }
00692 endvec = ptr; row = r;
00693 } else {
00694 dim = 0; row = 0; col = 0;
00695 mat = (T**)0; vec = (T*)0; endvec = (T*)0;
00696 }
00697 return *this;
00698 }
00699
00700 template <typename T>
00701 TMatrix<T>& TMatrix<T>::row_expand (const TMatrix<T>& m)
00702 {
00703 if (LIKELY(m.dim == 0))
00704 return *this;
00705 unsigned long olddim = dim;
00706 dim += m.dim;
00707 row += m.row;
00708 if (LIKELY(dim)) {
00709 REALLOC (vec, olddim, T, dim);
00710 TBCIDELETE (Tptr, mat, (row-m.row));
00711 mat = NEW (Tptr, row);
00712 if (LIKELY(mat && vec)) {
00713 T* ptr = vec;
00714 for (register unsigned i=0; i<row; i++) {
00715 mat[i] = ptr; ptr += col;
00716 }
00717 endvec = ptr;
00719 for (register unsigned long l=0; l<m.dim; l++)
00720 vec[dim-m.dim+l] = m.vec[l];
00721 return *this;
00722 } else {
00723 if (UNLIKELY(vec))
00724 TBCIDELETE(T, vec, dim);
00725 if (UNLIKELY(mat))
00726 TBCIDELETE(Tptr, mat, row);
00727 }
00728 } else if (olddim) {
00729 TBCIDELETE (T, vec, olddim);
00730 TBCIDELETE (Tptr, mat, row-m.row);
00731 }
00732 mat = (T**)0; vec = (T*)0; endvec = (T*)0;
00733 dim = 0; row = 0; col = 0;
00734 return *this;
00735 }
00736
00737
00738 template <typename T>
00739 TMatrix<T>& TMatrix<T>::resize (const T& v, const unsigned int r, const unsigned int c)
00740 {
00741 if (LIKELY(r == row && c == col)) {
00742 TBCIFILL (vec, v, T, dim);
00743 return *this;
00744 }
00745 if (UNLIKELY(dim)) {
00746 TBCIDELETE(T, vec, dim);
00747 TBCIDELETE(Tptr, mat, row);
00748 }
00749 dim = ((unsigned long)r)*c;
00750 row = r; col = c;
00751 if (LIKELY(dim)) {
00752 mat = NEW(Tptr,r); vec = NEW(T,dim);
00753 if (!set_ptrs())
00754 TBCIFILL(vec, v, T, dim);
00755 } else {
00756 mat = (T**)0; vec=(T*)0; endvec =(T*)0;
00757 }
00758 return *this;
00759 }
00760
00761 template <typename T>
00762 TMatrix<T>& TMatrix<T>::resize (const TMatrix<T>& m)
00763 {
00764 if (LIKELY(m.row == row && m.col == col)) {
00765 TBCICOPY (vec, m.vec, T, dim);
00766 return *this;
00767 }
00768 if (UNLIKELY(dim)) {
00769 TBCIDELETE(T, vec, dim);
00770 TBCIDELETE(Tptr, mat, row);
00771 }
00772 dim = ((unsigned long)m.row)*m.col;
00773 row = m.row; col = m.col;
00774 if (LIKELY(dim)) {
00775 mat = NEW(Tptr,m.row); vec = NEW(T,dim);
00776 if (!set_ptrs())
00777 TBCICOPY(vec, m.vec, T, dim);
00778 } else {
00779 mat = (T**)0; vec = (T*)0; endvec = (T*)0;
00780 }
00781 return *this;
00782 }
00783
00784
00785 template <typename T>
00786 TMatrix<T>& TMatrix<T>::cheapdownsizerow (const unsigned nr)
00787 {
00788 if (LIKELY(nr == row))
00789 return *this;
00790 BCHK (nr > row, MatErr, cheapdownsize does not upsize, nr, *this);
00791 if (UNLIKELY(!nr))
00792 return this->resize (nr, col);
00793 dim = ((unsigned long)nr) * col;
00794 row = nr; endvec = vec + dim;
00795 return *this;
00796 }
00797
00798 template <typename T>
00799 inline TMatrix<T>& TMatrix<T>::fill (const T& val)
00800 {
00801 TBCIFILL(vec, val, T, dim);
00802 return *this;
00803 }
00804
00805 template <typename T>
00806 inline T TMatrix<T>::trace () const
00807 {
00808 ALIGN3(register T tr, vec[0], MIN_ALIGN2);
00809 BCHK (row != col, MatErr, Trace over non quadratic matrix, 0, tr=0);
00810 for (register unsigned i = 1; i < row; i++)
00811 tr += mat[i][i];
00812 return tr;
00813 }
00814
00815 template <typename T>
00816 inline TMatrix<T>& TMatrix<T>::fill (const Vector<T>& v)
00817 {
00818 BCHK (dim != v.dim, MatErr, Vector size does not match matrix size, v.dim, *this);
00819 TBCICOPY (vec, v.vec, T, v.dim);
00820 return *this;
00821 }
00822
00823
00824
00825
00826 template <typename T>
00827 inline TMatrix<T>& TMatrix<T>::operator - ()
00828 {
00829 do_vec_neg<T> (dim, vec);
00830 return *this;
00831 }
00832
00833 template <typename T>
00834 bool TMatrix<T>::operator == (const Matrix<T>& m)
00835 {
00836 Matrix<T> th (*this);
00837 if (LIKELY(row != m.row || col != m.col))
00838 return false;
00839 if (LIKELY(vec == m.vec || dim == 0))
00840 return true;
00841 if (TBCICOMP (vec, m.vec, T, dim))
00842 return false;
00843
00844 return true;
00845 }
00846
00847 template <typename T>
00848 bool TMatrix<T>::operator == (TSMatrix<T> ts)
00849 {
00850 Matrix<T> th (*this);
00851 if (LIKELY(row != ts.row || col != ts.col))
00852 return (ts.real_destroy(), false);
00853 if (LIKELY(dim == 0)) {
00854
00855 return true;
00856 }
00857 if (LIKELY(ts.fac == (T)1)) {
00858 if (LIKELY(vec == ts.vec))
00859 return true;
00860 if (TBCICOMP (vec, ts.vec, T, dim)) {
00861 ts.real_destroy (); return false;
00862 }
00863 } else {
00864 if (LIKELY(vec == ts.vec))
00865 return false;
00866 for (register T *p1 = vec, *p2 = ts.vec; p1 < endvec; p1++, p2++)
00867 if (UNLIKELY(*p1 != *p2 * ts.fac)) {
00868 ts.real_destroy (); return false;
00869 }
00870 }
00871 ts.real_destroy (); return true;
00872 }
00873
00874
00875 template <typename T>
00876 inline TMatrix<T>& TMatrix<T>::operator += (const Matrix<T>& a)
00877 {
00878 BCHK(row != a.row, MatErr, number of rows differ in op, a.row, *this );
00879 BCHK(col != a.col, MatErr, number of cols differ in op, a.col, *this );
00880 STD_SMP_TEMPLATE2V(vec_add_vec, dim, vec, a.vec);
00881 return *this;
00882 }
00883 template <typename T>
00884 inline TMatrix<T>& TMatrix<T>::operator -= (const Matrix<T>& a)
00885 {
00886 BCHK(row != a.row, MatErr, number of rows differ in op, a.row, *this );
00887 BCHK(col != a.col, MatErr, number of cols differ in op, a.col, *this );
00888 STD_SMP_TEMPLATE2V(vec_sub_vec, dim, vec, a.vec);
00889 return *this;
00890 }
00891
00892 template <typename T>
00893 inline TMatrix<T>& TMatrix<T>::operator += (TSMatrix<T> a)
00894 {
00895 BCHK(row != a.row, MatErr, number of rows differ in op, a.row, *this );
00896 BCHK(col != a.col, MatErr, number of cols differ in op, a.col, *this );
00897 STD_SMP_TEMPLATE3VC(vec_add_svc, dim, vec, a.vec, a.fac);
00898 a.real_destroy(); return *this;
00899 }
00900 template <typename T>
00901 inline TMatrix<T>& TMatrix<T>::operator -= (TSMatrix<T> a)
00902 {
00903 BCHK(row != a.row, MatErr, number of rows differ in op, a.row, *this );
00904 BCHK(col != a.col, MatErr, number of cols differ in op, a.col, *this );
00905 STD_SMP_TEMPLATE3VC(vec_sub_svc, dim, vec, a.vec, a.fac);
00906 a.real_destroy(); return *this;
00907 }
00908
00909
00910 template <typename T>
00911 inline TMatrix<T>& TMatrix<T>::operator += (TMatrix<T> a)
00912 { return this->operator += (Matrix<T>(a)); }
00913 template <typename T>
00914 inline TMatrix<T>& TMatrix<T>::operator -= (TMatrix<T> a)
00915 { return this->operator -= (Matrix<T>(a)); }
00916
00917 template <typename T>
00918 inline TMatrix<T>& TMatrix<T>::operator + (TSMatrix<T> ts)
00919 {
00920 BCHK(row != ts.row, MatErr, number of rows differ in op, ts.row, *this );
00921 BCHK(col != ts.col, MatErr, number of cols differ in op, ts.col, *this );
00922 STD_SMP_TEMPLATE3VC(vec_add_svc, dim, vec, ts.vec, ts.fac);
00923 ts.real_destroy (); return *this;
00924 }
00925 template <typename T>
00926 inline TMatrix<T>& TMatrix<T>::operator - (TSMatrix<T> ts)
00927 {
00928 BCHK(row != ts.row, MatErr, number of rows differ in op, ts.row, *this );
00929 BCHK(col != ts.col, MatErr, number of cols differ in op, ts.col, *this );
00930 STD_SMP_TEMPLATE3VC(vec_sub_svc, dim, vec, ts.vec, ts.fac);
00931 ts.real_destroy (); return *this;
00932 }
00933
00934
00935 template <typename T>
00936 inline TMatrix<T>& TMatrix<T>::operator += (const T& a)
00937 {
00938 STD_SMP_TEMPLATE2C(vec_add_val, dim, vec, a);
00939 return *this;
00940 }
00941 template <typename T>
00942 inline TMatrix<T>& TMatrix<T>::operator -= (const T& a)
00943 {
00944 STD_SMP_TEMPLATE2C(vec_add_val, dim, vec, a);
00945 return *this;
00946 }
00947
00948 template <typename T>
00949 inline TSMatrix<T> TMatrix<T>::operator *= (const T& a)
00950 { return TSMatrix<T> (*this, a); }
00951
00952 template <typename T>
00953 inline TSMatrix<T> TMatrix<T>::operator /= (const T& a)
00954 {
00955 BCHK(a==(T)0, MatErr, Matrix division by zero, 0, TSMatrix<T> (*this));
00956 return TSMatrix<T> (*this, (T)1/a);
00957 }
00958
00959
00960 template <typename T>
00961 inline TMatrix<T>& TMatrix<T>::operator + (const Matrix<T>& a)
00962 { return this->operator += (a); }
00963 template <typename T>
00964 inline TMatrix<T>& TMatrix<T>::operator - (const Matrix<T>& a)
00965 { return this->operator -= (a); }
00966
00967 template <typename T>
00968 inline TMatrix<T>& TMatrix<T>::operator + (TMatrix<T> a)
00969 { return this->operator += (Matrix<T>(a)); }
00970 template <typename T>
00971 inline TMatrix<T>& TMatrix<T>::operator - (TMatrix<T> a)
00972 { return this->operator -= (Matrix<T>(a)); }
00973
00974 template <typename T>
00975 inline TMatrix<T>& TMatrix<T>::operator + (const T& a)
00976 { return this->operator += (a); }
00977 template <typename T>
00978 inline TMatrix<T>& TMatrix<T>::operator - (const T& a)
00979 { return this->operator -= (a); }
00980
00981 template <typename T>
00982 inline TSMatrix<T> TMatrix<T>::operator * (const T& a)
00983 { return TSMatrix<T> (*this, a); }
00984
00985 template <typename T>
00986 inline TSMatrix<T> TMatrix<T>::operator / (const T& b)
00987 {
00988 BCHK((b == (T)0), MatErr, Matrix division by 0, 0, TSMatrix<T> (*this));
00989 return TSMatrix<T> (*this, (T)1/b);
00990 }
00991
00992
00993
00994
00995 INST(template <typename T> class TMatrix friend TMatrix<T> operator + (const T&, TMatrix<T>);)
00996 template <typename T>
00997 inline TMatrix<T> operator + (const T& a, TMatrix<T> b)
00998 {
00999 STD_SMP_TEMPLATE2C(val_add_vec, b._DIM, b._VEC, a);
01000 return b;
01001 }
01002 INST(template <typename T> class TMatrix friend TMatrix<T> operator - (const T&, TMatrix<T>);)
01003 template <typename T>
01004 inline TMatrix<T> operator - (const T& a, TMatrix<T> b)
01005 {
01006 STD_SMP_TEMPLATE2C(val_sub_vec, b._DIM, b._VEC, a);
01007 return b;
01008 }
01009
01010 INST(template <typename T> class TMatrix friend TSMatrix<T> operator * (const T&, TMatrix<T>);)
01011 template <typename T>
01012 inline TSMatrix<T> operator * (const T& a, TMatrix<T> b)
01013 { return TSMatrix<T> (b, a); }
01014
01015
01016
01017
01018 INST(template <typename T> class TMatrix friend TMatrix<T> operator + (const T&, const Matrix<T>&);)
01019 template <typename T>
01020 inline TMatrix<T> operator + (const T& a, const Matrix<T>& b)
01021 {
01022 TMatrix<T> c (b._ROW, b._COL);
01023 STD_SMP_TEMPLATE3VC(val_vec_add, b._DIM, c._VEC, b._VEC, a);
01024 return c;
01025 }
01026 INST(template <typename T> class TMatrix friend TMatrix<T> operator - (const T&, const Matrix<T>&);)
01027 template <typename T>
01028 inline TMatrix<T> operator - (const T& a, const Matrix<T>& b)
01029 {
01030 TMatrix<T> c (b._ROW, b._COL);
01031 STD_SMP_TEMPLATE3VC(val_vec_sub, b._DIM, c._VEC, b._VEC, a);
01032 return c;
01033 }
01034
01035 INST(template <typename T> class TMatrix friend TSMatrix<T> operator * (const T&, const Matrix<T>&);)
01036 template <typename T>
01037 inline TSMatrix<T> operator * (const T& a, const Matrix<T>& b)
01038 { return TSMatrix<T> (b, a); }
01039
01040
01041
01042
01043 template <typename T>
01044 inline double TMatrix<T>::fabssqr () const
01045 { Matrix<T> m (*this); return m.fabssqr (); }
01046
01047 template <typename T>
01048 inline double fabssqr (const TMatrix<T>& tm)
01049 {
01050 return tm.fabssqr ();
01051 }
01052
01053
01054 template <typename T>
01055 TMatrix<T> TMatrix<T>::transposed_copy() const
01056 {
01057 TMatrix<T> trm(this->col, this->row);
01058 for (unsigned r = 0; r < this->row; ++r)
01059 for (unsigned c = 0; c < this->col; ++c)
01060 trm.mat[c][r] = this->mat[r][c];
01061 this->mark_destroy();
01062 return trm;
01063 }
01064
01065 INST(template <typename T> class TMatrix friend TMatrix<T> transpose(const TMatrix<T>& tm);)
01066 template <typename T>
01067 inline TMatrix<T> transpose(const TMatrix<T>& tm)
01068 {
01069 return tm.transposed_copy();
01070 }
01071
01072 template <typename T>
01073 TMatrix<T>& TMatrix<T>::transpose()
01074 {
01075 if (this->col != this->row) {
01076
01077 Matrix<T> transmat(this->transposed_copy());
01078 return this->swap(transmat);
01079 } else {
01080
01081 for (unsigned r = 1; r < this->row; ++r)
01082 for (unsigned c = 0; c < r; ++c)
01083 SWAP(this->mat[r][c], this->mat[c][r]);
01084 return *this;
01085 }
01086 }
01087
01088 NAMESPACE_END
01089
01090 NAMESPACE_CSTD
01091
01092 INST(template <typename T> class TBCI__ Matrix friend double fabs (const TBCI__ TMatrix<T>&);)
01093 template<typename T>
01094 inline double fabs (const TBCI__ TMatrix<T>& tm)
01095 { return tm.fabs (); }
01096
01097 INST(template <typename T> class TBCI__ Matrix friend double fabs (const TBCI__ Matrix<T>&);)
01098 template<typename T>
01099 inline double fabs (const TBCI__ Matrix<T>& m)
01100 { return m.fabs (); }
01101
01102 NAMESPACE_CSTD_END
01103
01104 NAMESPACE_TBCI
01105
01106
01110
01111 template <typename T>
01112 class TSMatrix : public Matrix_Sig<T>
01113 {
01114 protected:
01115 T* vec;
01116 unsigned long dim;
01117 unsigned int row, col;
01118 T** mat;
01119 T* endvec;
01120 T fac ALIGN(MIN_ALIGN2);
01121 bool mut;
01122
01123 void real_destroy ();
01124 void clone (bool = false, TMatrix<T>* = 0);
01125 #if 1 //def HAVE_GCC295_FRIEND_BUG
01126 public:
01127 #endif
01128 void detach (TMatrix<T>* = 0);
01129
01130 typedef T* Tptr;
01131 public:
01132
01133 friend class TMatrix<T>;
01134 friend class Matrix<T>;
01135
01136 typedef T value_type;
01137 typedef T element_type;
01138 typedef T aligned_value_type TALIGN(MIN_ALIGN2);
01139
01140 #if 1 //def HAVE_GCC295_FRIEND_BUG
01141 T* getvec () const { return vec; }
01142 T* getendvec () const { return endvec; }
01143 T& getfac () { return fac; }
01144 const T& getfac () const { return fac; }
01145 #endif
01146
01147 TSMatrix () : vec((T*)0), dim(0), mat((T**)0), endvec((T*)0), mut(false) {}
01148
01149 ~TSMatrix () {}
01150
01151 TSMatrix (const TMatrix<T>& tm, const T& f = (T)1)
01152 : vec(tm.vec), dim(tm.dim), row(tm.row), col(tm.col),
01153 mat(tm.mat), endvec(tm.endvec), fac(f), mut(true) {}
01154 TSMatrix (const Matrix<T>& m, const T& f = (T)1)
01155 : vec(m.vec), dim(m.dim), row(m.row), col(m.col),
01156 mat(m.mat), endvec(m.endvec), fac(f), mut(false) {}
01157 TSMatrix (const TSMatrix<T>& ts)
01158 : vec(ts.vec), dim(ts.dim), row(ts.row), col(ts.col),
01159 mat(ts.mat), endvec(ts.endvec), fac(ts.fac), mut(ts.mut) {}
01160
01161
01162 static const char* mat_info () { return ("TSMatrix"); }
01163
01164 T operator () (const unsigned int r, const unsigned int c) HOT
01165 { T val = mat[r][c] * fac; real_destroy (); return val; }
01166
01167 TSMatrix<T>& eval (TMatrix<T>* = 0);
01168
01169
01170 TSMatrix<T>& operator = (const TSMatrix<T>& ts)
01171 { real_destroy (); dim = ts.dim; row = ts.row; col = ts.col;
01172 mat = ts.mat; vec = ts.vec; endvec = ts.endvec;
01173 fac = ts.fac; mut = ts.mut; return *this; }
01174 TSMatrix<T>& operator = (const TMatrix<T>& tm)
01175 { real_destroy (); dim = tm.dim; row = tm.row; col = tm.col;
01176 mat = tm.mat; vec = tm.vec; endvec = tm.endvec;
01177 fac = (T)1; mut = true; return *this; }
01178
01179 TSMatrix<T>& operator *= (const T& f) { fac *= f; return *this; }
01180 TSMatrix<T>& operator /= (const T& f) { fac /= f; return *this; }
01181 TSMatrix<T>& operator * (const T& f) { fac *= f; return *this; }
01182 TSMatrix<T>& operator / (const T& f) { fac /= f; return *this; }
01183 #ifndef HAVE_GCC295_FRIEND_BUG
01184 friend NOINST TSMatrix<T> FRIEND_TBCI__ operator * FGD (const T&, TSMatrix<T>);
01185 #endif
01186 TSMatrix<T>& operator - () { fac *= (T)(-1); return *this; }
01187
01188
01189 TMatrix<T> operator + (const Matrix<T>&);
01190 TMatrix<T> operator + (const TMatrix<T>&);
01191 TMatrix<T> operator + (TSMatrix<T>);
01192 TMatrix<T> operator + (const T&);
01193 TMatrix<T> operator - (const Matrix<T>&);
01194 TMatrix<T> operator - (const TMatrix<T>&);
01195 TMatrix<T> operator - (TSMatrix<T>);
01196 TMatrix<T> operator - (const T&);
01197
01198 #ifndef HAVE_GCC295_FRIEND_BUG
01199
01200 friend NOINST TMatrix<T> FRIEND_TBCI__ operator + FGD (const T&, const TSMatrix<T>&);
01201 friend NOINST TMatrix<T> FRIEND_TBCI__ operator - FGD (const T&, const TSMatrix<T>&);
01202 #endif
01203
01204 TMatrix<T> operator * (const Matrix<T>& m);
01205 TMatrix<T> operator * (TMatrix<T> tm);
01206 TVector<T> operator * (const Vector<T>& v);
01207 TVector<T> operator * (TVector<T> tv);
01208
01209 bool operator == (const Matrix<T>&);
01210 bool operator != (const Matrix<T>& m) { return !(*this == m); }
01211
01212 bool operator == (TSMatrix<T>&);
01213 bool operator != (TSMatrix<T>& ts) { return !(*this == ts); }
01214
01215 bool operator == (TMatrix<T>& tm) { Matrix<T> m(tm); return (*this == m); }
01216 bool operator != (TMatrix<T>& tm) { return !(*this == tm); }
01217
01218 double fabssqr ();
01219 double fabs () { return GLBL__ MATH__ sqrt (fabssqr ()); }
01220
01221 unsigned long size () const { return dim; }
01222 };
01223
01224 template <typename T>
01225 inline void TSMatrix<T>::real_destroy ()
01226 {
01227 if (LIKELY(!mut || !dim))
01228 return;
01229 TBCIDELETE(T, vec, dim); TBCIDELETE(Tptr, mat, row);
01230 }
01231
01232 template <typename T>
01233 inline void TSMatrix<T>::detach (TMatrix<T>* tm)
01234 {
01235 if (LIKELY((!tm && mut) || !dim))
01236 return;
01237 if (!tm) {
01238 vec = NEW(T, dim); if (!vec) {
01239 dim = 0; mat = (T**)0; return;
01240 }
01241 mat = NEW(Tptr,row); if (!mat) {
01242 TBCIDELETE(T, vec, dim); dim = 0; return;
01243 }
01244 for (register unsigned r = 0; r < row; r++)
01245 mat[r] = vec + r*col;
01246 endvec = vec + dim;
01247 } else {
01248 vec = tm->vec; mat = tm->mat; endvec = tm->endvec;
01249 }
01250 mut = true;
01251 }
01252
01253 template <typename T>
01254 void TSMatrix<T>::clone (bool evl, TMatrix<T>* tm)
01255 {
01256 if (LIKELY((mut && !tm)|| !dim))
01257 return;
01258 T* oldv = vec; T** oldm = mat; bool omut = mut;
01259 detach (tm);
01260 if (evl && fac != (T)1) {
01261 STD_SMP_TEMPLATE3VC(vec_val_mul, dim, vec, oldv, fac);
01262 fac = (T)1;
01263 } else
01264 TBCICOPY (vec, oldv, T, dim);
01265 if (tm && omut) {
01266 TBCIDELETE(T, oldv, dim); TBCIDELETE(Tptr, oldm, row);
01267 }
01268 }
01269
01270
01271
01272
01273 template <typename T>
01274 inline TSMatrix<T>& TSMatrix<T>::eval (TMatrix<T>* tm)
01275 {
01276 if (mut && !tm) {
01277 if (fac != (T)1) {
01278 STD_SMP_TEMPLATE2C(vec_mul_val, dim, vec, fac);
01279 fac = (T)1;
01280 }
01281 } else
01282 clone (true, tm);
01283 return (*this);
01284 }
01285
01286
01287
01288 template <typename T>
01289 inline TMatrix<T> TSMatrix<T>::operator + (const Matrix<T>& m)
01290 {
01291 BCHK(row != m.row || col != m.col, MatErr, Op + on diff size Mats, m.row, TMatrix<T> (*this));
01292 TSMatrix<T> ts (*this); ts.detach ();
01293 STD_SMP_TEMPLATE4V(svc_vec_add, dim, ts.vec, vec, m.vec, fac);
01294 ts.fac = (T)1; return TMatrix<T> (ts);
01295 }
01296 template <typename T>
01297 inline TMatrix<T> TSMatrix<T>::operator - (const Matrix<T>& m)
01298 {
01299 BCHK(row != m.row || col != m.col, MatErr, Op - on diff size Mats, m.row, TMatrix<T> (*this));
01300 TSMatrix<T> ts (*this); ts.detach ();
01301 STD_SMP_TEMPLATE4V(svc_vec_sub, dim, ts.vec, vec, m.vec, fac);
01302 ts.fac = (T)1; return TMatrix<T> (ts);
01303 }
01304
01305 template <typename T>
01306 inline TMatrix<T> TSMatrix<T>::operator + (const TMatrix<T>& tm)
01307 {
01308 BCHK(row != tm.row || col != tm.col, MatErr, Op + on diff size Mats, tm.row, tm);
01309 STD_SMP_TEMPLATE3VC(vec_add_svc, dim, tm.vec, vec, fac);
01310 real_destroy (); return tm;
01311 }
01312 template <typename T>
01313 inline TMatrix<T> TSMatrix<T>::operator - (const TMatrix<T>& tm)
01314 {
01315 BCHK(row != tm.row || col != tm.col, MatErr, Op - on diff size Mats, tm.row, tm);
01316 STD_SMP_TEMPLATE3VC(vec_sub_svc_inv, dim, tm.vec, vec, fac);
01317 real_destroy (); return tm;
01318 }
01319
01320 template <typename T>
01321 inline TMatrix<T> TSMatrix<T>::operator + (TSMatrix<T> ts)
01322 {
01323 BCHK(row != ts.row || col != ts.col, MatErr, Op op on diff size Mats, ts.row, TMatrix<T> (*this));
01324 TSMatrix<T> tm;
01325 if (LIKELY(!mut && ts.mut))
01326 tm = ts;
01327 else {
01328 tm = *this; tm.detach ();
01329 }
01330 STD_SMP_TEMPLATE5(svc_svc_add, dim, tm.vec, vec, ts.vec, fac, ts.fac);
01331 if (LIKELY(!mut && ts.mut))
01332 real_destroy ();
01333 else
01334 ts.real_destroy ();
01335 tm.fac = (T)1;
01336 return TMatrix<T> (tm);
01337 }
01338
01339 template <typename T>
01340 inline TMatrix<T> TSMatrix<T>::operator - (TSMatrix<T> ts)
01341 {
01342 BCHK(row != ts.row || col != ts.col, MatErr, Op op on diff size Mats, ts.row, TMatrix<T> (*this));
01343 TSMatrix<T> tm;
01344 if (LIKELY(!mut && ts.mut))
01345 tm = ts;
01346 else {
01347 tm = *this; tm.detach ();
01348 }
01349 STD_SMP_TEMPLATE5(svc_svc_sub, dim, tm.vec, vec, ts.vec, fac, ts.fac);
01350 if (LIKELY(!mut && ts.mut))
01351 real_destroy ();
01352 else
01353 ts.real_destroy ();
01354 tm.fac = (T)1;
01355 return TMatrix<T> (tm);
01356 }
01357
01358 template <typename T>
01359 inline TMatrix<T> TSMatrix<T>::operator + (const T& a)
01360 {
01361 TSMatrix<T> ts (*this); ts.detach ();
01362 STD_SMP_TEMPLATE4C(svc_val_add, dim, ts.vec, vec, fac, a);
01363 ts.fac = (T)1; return TMatrix<T> (ts);
01364 }
01365
01366 template <typename T>
01367 inline TMatrix<T> TSMatrix<T>::operator - (const T& a)
01368 {
01369 TSMatrix<T> ts (*this); ts.detach ();
01370 STD_SMP_TEMPLATE4C(svc_val_sub, dim, ts.vec, vec, fac, a);
01371 ts.fac = (T)1; return TMatrix<T> (ts);
01372 }
01373
01374
01375 INST(template <typename T> class TSMatrix friend TMatrix<T> operator + (const T&, const TSMatrix<T>&);)
01376 template <typename T>
01377 inline TMatrix<T> operator + (const T& a, const TSMatrix<T>& ts)
01378 {
01379 TSMatrix<T> tm (ts); tm.detach ();
01380 STD_SMP_TEMPLATE4C(val_svc_add, tm._DIM, tm._VEC, ts._VEC, a, ts._FAC);
01381 tm._FAC = (T)1; return TMatrix<T> (tm);
01382 }
01383 INST(template <typename T> class TSMatrix friend TMatrix<T> operator - (const T&, const TSMatrix<T>&);)
01384 template <typename T>
01385 inline TMatrix<T> operator - (const T& a, const TSMatrix<T>& ts)
01386 {
01387 TSMatrix<T> tm (ts); tm.detach ();
01388 STD_SMP_TEMPLATE4C(val_svc_sub, tm._DIM, tm._VEC, ts._VEC, a, ts._FAC);
01389 tm._FAC = (T)1; return TMatrix<T> (tm);
01390 }
01391
01392
01393 template <typename T>
01394 TMatrix<T> TSMatrix<T>::operator * (const Matrix<T>& m)
01395 {
01396 TMatrix<T> c (row, m.col);
01397 BCHK(col != m.row, MatErr, Illegal sizes in Matrix multiplication, 0, (real_destroy(), c));
01398 T tmp ALIGN(MIN_ALIGN2);
01399 for (unsigned i=0; i<row; i++) {
01400 for (unsigned j=0; j<m.col; j++) {
01401 tmp = mat[i][0] * m.mat[0][j];
01402 for (register unsigned l=1; l<col; l++)
01403 tmp += mat[i][l] * m.mat[l][j];
01404 c.mat[i][j] = tmp * fac;
01405 }
01406 }
01407 real_destroy (); return c;
01408 }
01409
01410 template <typename T>
01411 TMatrix<T> TSMatrix<T>::operator * (TMatrix<T> tm)
01412 {
01413 TMatrix<T> c (row, tm.col);
01414 BCHK(col != tm.row, MatErr, Illegal sizes in Matrix multiplication, 0, (real_destroy(), c));
01415 T tmp ALIGN(MIN_ALIGN2);
01416 for (unsigned i=0; i<row; i++) {
01417 for (unsigned j=0; j<tm.col; j++) {
01418 tmp = mat[i][0] * tm.get(0,j);
01419 for (register unsigned l=1; l<col; l++)
01420 tmp += mat[i][l] * tm.get(l,j);
01421 c.mat[i][j] = tmp * fac;
01422 }
01423 }
01424 real_destroy (); tm.mark_destroy(); return c;
01425 }
01426
01427 template <typename T>
01428 TVector<T> TSMatrix<T>::operator * (const Vector<T>& v)
01429 {
01430 TVector<T> tv (row);
01431 BCHK (v.size() != col, MatErr, multiply Matrix w/ Vector: wrong config, v.size(), (real_destroy(), tv));
01432 for (unsigned r=0; r<row; r++) {
01433 ALIGN3(register T el, mat[r][0] * v(0), MIN_ALIGN2);
01434 for (register unsigned c=1; c<col; c++)
01435 el += mat[r][c] * v(c);
01436 tv.set (el * fac, r);
01437 }
01438 real_destroy (); return tv;
01439 }
01440
01441 template <typename T>
01442 TVector<T> TSMatrix<T>::operator * (TVector<T> v)
01443 {
01444 TVector<T> tv (row);
01445 BCHK (v.size() != col, MatErr, multiply Matrix w/ Vector: wrong config, v.size(), (real_destroy(), tv));
01446 for (unsigned r=0; r<row; r++) {
01447 ALIGN3(register T el, mat[r][0] * v.get(0), MIN_ALIGN2);
01448 for (register unsigned c=1; c<col; c++)
01449 el += mat[r][c] * v.get(c);
01450 tv.set (el * fac, r);
01451 }
01452 real_destroy(); v.destroy(); return tv;
01453 }
01454
01455
01456 template <typename T>
01457 bool TSMatrix<T>::operator == (const Matrix<T>& m)
01458 {
01459 if (LIKELY(row != m.row || col != m.col)) {
01460 real_destroy (); return false;
01461 }
01462 if (LIKELY(dim == 0)) {
01463 return true;
01464 }
01465 if (LIKELY(fac == (T)1)) {
01466 if (LIKELY(vec == m.vec))
01467 return true;
01468 if (TBCICOMP (vec, m.vec, T, dim)) {
01469 real_destroy (); return false;
01470 }
01471 } else {
01472 if (LIKELY(vec == m.vec))
01473 return false;
01474 for (register T *p1 = vec, *p2 = m.vec; p1 < endvec; p1++, p2++)
01475 if (UNLIKELY(*p1 * fac != *p2)) {
01476 real_destroy (); return false;
01477 }
01478 }
01479 real_destroy (); return true;
01480 }
01481
01482 template <typename T>
01483 bool TSMatrix<T>::operator == (TSMatrix<T>& ts)
01484 {
01485 if (LIKELY(row != ts.row || col != ts.col)) {
01486 real_destroy (); ts.real_destroy (); return false;
01487 }
01488 if (LIKELY(dim == 0)) {
01489
01490 return true;
01491 }
01492 if (LIKELY(fac == ts.fac)) {
01493 if (LIKELY(vec == ts.vec)) {
01494 real_destroy (); return true;
01495 }
01496 if (TBCICOMP (vec, ts.vec, T, dim)) {
01497 real_destroy (); ts.real_destroy (); return false;
01498 }
01499 } else {
01500 if (LIKELY(vec == ts.vec)) {
01501 real_destroy (); return false;
01502 }
01503 for (register T *p1 = vec, *p2 = ts.vec; p1 < endvec; p1++, p2++)
01504 if (UNLIKELY(*p1 * fac != *p2)) {
01505 real_destroy (); ts.real_destroy (); return false;
01506 }
01507 }
01508 real_destroy (); ts.real_destroy ();
01509 return true;
01510 }
01511
01512
01513 INST(template <typename T> class TSMatrix friend TSMatrix<T> operator * (const T&, TSMatrix<T>);)
01514 template <typename T>
01515 inline TSMatrix<T> operator * (const T& f, TSMatrix<T> ts)
01516 { ts._FAC = f * ts._FAC; return ts; }
01517
01518
01519 template <typename T>
01520 double TSMatrix<T>::fabssqr ()
01521 {
01522 LONG_DOUBLE res = 0.0;
01523 do_vec_fabssqr (dim, vec, res);
01524 res *= GLBL2__ TBCI__ fabssqr (fac);
01525 real_destroy ();
01526 return res;
01527 }
01528
01529 template <typename T>
01530 inline double fabssqr (TSMatrix<T>& tsm)
01531 {
01532 return tsm.fabssqr ();
01533 }
01534
01535 NAMESPACE_END
01536
01537 NAMESPACE_CSTD
01538
01539 INST(template <typename T> class TBCI__ TSMatrix friend double fabs (TBCI__ TSMatrix<T>&);)
01540 template <typename T>
01541 double fabs (TBCI__ TSMatrix<T>& ts)
01542 { return ts.fabs (); }
01543
01544 NAMESPACE_CSTD_END
01545
01546 NAMESPACE_TBCI
01547
01559
01560 template <typename T>
01561 class Matrix : public TMatrix<T>
01562 {
01563
01564 public:
01565
01566 friend class TSMatrix<T>;
01567
01568 typedef T value_type;
01569 typedef T element_type;
01570 typedef T aligned_value_type TALIGN(MIN_ALIGN2);
01571
01572
01573
01574 explicit Matrix (const unsigned d=0)
01575 : TMatrix<T> (d)
01576 { }
01577 Matrix (const unsigned r, const unsigned c)
01578 : TMatrix<T> (r, c)
01579 { }
01580 Matrix (const T& v, const unsigned r, const unsigned c)
01581 : TMatrix<T> (v, r, c)
01582 { }
01583 Matrix (const Vector<T>& v, const enum rowcolvec r = colvec)
01584 : TMatrix<T> (v, r)
01585 { }
01586
01588 Matrix (const Matrix<T>& m)
01589 : TMatrix<T> (m)
01590 { }
01592 Matrix (const TMatrix<T>& tm) HOT
01593 : TMatrix<T> (tm)
01594 { }
01595 Matrix (const TSMatrix<T>& ts)
01596 : TMatrix<T> (ts)
01597 { }
01598
01599 ~Matrix () { this->freeable = 1; }
01600
01601
01602 static const char* mat_info () { return ("Matrix"); }
01603 #ifndef HAVE_PROMOTION_BUG
01604
01605 template <typename U>
01606 explicit Matrix (const Matrix<U>& m)
01607 : TMatrix<T> (m)
01608 { }
01609 template <typename U>
01610 explicit Matrix (const TMatrix<U>& tm)
01611 : TMatrix<T> (tm)
01612 { }
01613
01614 #endif
01615
01617 typename tbci_traits<T>::const_refval_type
01618 operator () (const unsigned int, const unsigned int) const HOT;
01620 T& operator () (const unsigned int, const unsigned int) HOT;
01622 TVector<T> operator () (const unsigned int) const;
01623
01625 Matrix<T>& operator = (const Matrix<T>& m)
01626 { this->TMatrix<T>::operator = (m); return *this; }
01627 Matrix<T>& operator = (const TMatrix<T>& tm)
01628 { this->TMatrix<T>::operator = (tm); return *this; }
01629 Matrix<T>& operator = (TSMatrix<T> ts)
01630 { TMatrix<T>(this->TMatrix<T>::operator = (ts)); return *this; }
01631 Matrix<T>& operator = (const T& v)
01632 { this->TMatrix<T>::operator = (v); return *this; }
01633
01634 Matrix<T>& resize (const unsigned r, const unsigned c)
01635 { this->TMatrix<T>::resize (r, c); return *this; }
01636 Matrix<T>& resize (const unsigned d)
01637 { return this->resize (d, d); }
01638 Matrix<T>& resize (const T& v, const unsigned r, const unsigned c)
01639 { this->TMatrix<T>::resize (v, r, c); return *this; }
01640 Matrix<T>& resize (const Matrix<T>& m)
01641 { this->TMatrix<T>::resize (m); return *this; }
01642 Matrix<T>& fill (const T& v = (T) 0)
01643 { this->TMatrix<T>::fill (v); return *this; }
01644 Matrix<T>& fill (const Vector<T>& v)
01645 { this->TMatrix<T>::fill (v); return *this; }
01646 Matrix<T>& setunit (const T& f = (T) 1)
01647 { this->TMatrix<T>::setunit (f); return *this; }
01648 Matrix<T>& clear ()
01649 { this->TMatrix<T>::clear (); return *this; }
01650
01651
01652 friend BVector<T>& FRIEND_TBCI2__ bvfillm FGD (BVector<T>&, const Matrix<T>& m);
01653
01654
01655
01656
01657
01658 Matrix<T>& operator += (const Matrix<T>& a)
01659 { this->TMatrix<T>::operator += (a); return *this; }
01660 Matrix<T>& operator -= (const Matrix<T>& a)
01661 { this->TMatrix<T>::operator -= (a); return *this; }
01662 Matrix<T>& operator += (TMatrix<T> a)
01663 { this->TMatrix<T>::operator += (a); return *this; }
01664 Matrix<T>& operator -= (TMatrix<T> a)
01665 { this->TMatrix<T>::operator -= (a); return *this; }
01666 Matrix<T>& operator += (TSMatrix<T> a)
01667 { this->TMatrix<T>::operator += (a); return *this; }
01668 Matrix<T>& operator -= (TSMatrix<T> a)
01669 { this->TMatrix<T>::operator -= (a); return *this; }
01670 Matrix<T>& operator += (const T& a)
01671 { this->TMatrix<T>::operator += (a); return *this; }
01672 Matrix<T>& operator -= (const T& a)
01673 { this->TMatrix<T>::operator -= (a); return *this; }
01674 Matrix<T>& operator *= (const T& a)
01675 ;
01676 Matrix<T>& operator /= (const T& a)
01677 ;
01678
01679
01680
01681 TMatrix<T> operator - () const { return -(TMatrix<T> (*this)); }
01682
01683 TMatrix<T> operator + (const Matrix<T>&) const;
01684 TMatrix<T> operator - (const Matrix<T>&) const;
01685 TMatrix<T> operator * (const Matrix<T>&) const;
01686
01687 TMatrix<T>& operator + (TMatrix<T>&) const;
01688 TMatrix<T>& operator - (TMatrix<T>&) const;
01689 TMatrix<T> operator * (TMatrix<T>&) const;
01690
01691 TMatrix<T> operator + (TSMatrix<T>&) const;
01692 TMatrix<T> operator - (TSMatrix<T>&) const;
01693 TMatrix<T> operator * (TSMatrix<T>&) const;
01694
01695 TMatrix<T> operator + (const T&) const;
01696 TMatrix<T> operator - (const T&) const;
01697 TSMatrix<T> operator * (const T&) const;
01698 TSMatrix<T> operator / (const T&) const;
01699
01700 TVector<T> operator * (const Vector<T>&) const HOT;
01701 TVector<T> operator * (TVector<T>) const HOT;
01702 TVector<T> operator * (const TSVector <T>& tsv) const HOT;
01703 TVector<T> transMult (const Vector<T>&) const HOT;
01704
01705
01706
01707
01708 bool operator == (const Matrix<T>& m) const;
01709 bool operator != (const Matrix<T>& m) const
01710 { return !(*this == m); }
01711
01712 bool operator == (TMatrix<T> tm) const
01713 { Matrix<T> m (tm); return (*this == m); }
01714 bool operator != (TMatrix<T> tm) const
01715 { return !(*this == tm); }
01716
01717 bool operator == (TSMatrix<T>) const;
01718 bool operator != (TSMatrix<T> ts) const
01719 { return !(*this == ts); }
01720
01722 Matrix<T>& mult_rows (const Vector<T>&);
01723 Matrix<T>& div_rows (const Vector<T>&);
01724 Matrix<T>& mult_row (const T&, const unsigned);
01725 Matrix<T>& div_row (const T&, const unsigned);
01726
01727
01728
01729 friend STD__ ostream& operator << FGDT (STD__ ostream&, const Matrix<T>&);
01730 friend STD__ istream& operator >> FGDT (STD__ istream&, Matrix<T>&);
01731
01732
01733 friend NOINST char FRIEND_TBCI2__ gaussj FGD (Matrix<T>&, Matrix<T>&);
01734
01735
01736
01737
01738 double fabssqr () const;
01739 double fabs () const { return GLBL__ MATH__ sqrt (fabssqr()); }
01740 };
01741
01742
01743
01744
01745 template <typename T>
01746 inline TMatrix<T>& TMatrix<T>::swap (TMatrix<T>& m)
01747 {
01748
01749 SWAP(this->dim, m.dim);
01750 SWAP(this->row, m.row);
01751
01752 unsigned int tcol = this->col; this->col = m.col; m.col = tcol;
01753 SWAP(this->mat, m.mat);
01754 SWAP(this->vec, m.vec); SWAP(this->endvec, m.endvec);
01755
01756
01757 return *this;
01758 }
01759
01760 template <typename T>
01761 inline typename tbci_traits<T>::const_refval_type
01762 Matrix<T>::operator () (const unsigned int i, const unsigned int j) const
01763 {
01764 BCHK(i<0 || i>=this->row, MatErr, Illegal row index, i, this->mat[0][0]);
01765 BCHK(j<0 || j>=this->col, MatErr, illegal col index, j, this->mat[0][0]);
01766 return this->mat[i][j];
01767 }
01768
01769 template <typename T>
01770 inline T& Matrix<T>::operator () (const unsigned int i, const unsigned int j)
01771 {
01772 BCHK(i<0 || i>=this->row, MatErr, Illegal row index, i, this->mat[0][0]);
01773 BCHK(j<0 || j>=this->col, MatErr, illegal col index, j, this->mat[0][0]);
01774 return this->mat[i][j];
01775 }
01776
01777 template <typename T>
01778 inline TVector<T> Matrix<T>::operator () (const unsigned int i) const
01779 {
01780 TVector<T> v(this->col);
01781 BCHK(i<0 || i>= this->row, MatErr, Illegal row index, i, v);
01782
01783 TBCICOPY (v.vec, this->mat[i], T, this->col);
01784 return v;
01785 }
01786
01787
01788 template <typename T>
01789 STD__ ostream& operator << (STD__ ostream& os, const Matrix<T>& m)
01790 {
01791 for (unsigned r=0; r<m.row; r++)
01792 #if 0
01793 os << m(i) << "\n";
01794 #else
01795 {
01796 for (unsigned c=0; c<m.col; c++)
01797 os << m(r,c) << " ";
01798 os << "\n";
01799 }
01800 #endif
01801 return os;
01802 }
01803
01804 template <typename T>
01805 STD__ istream& operator >> (STD__ istream& in, Matrix<T>& m)
01806 {
01807 Vector<T> buf(m.col);
01808
01809 for (unsigned i=0; i<m.row; i++)
01810 {
01811 in >> buf;
01812 m.set_row (buf, i);
01813 }
01814 return in;
01815 }
01816
01817 INST(template <typename T> class TMatrix friend STD__ ostream& operator << (STD__ ostream& os, TMatrix<T> tm);)
01818 template <typename T>
01819 STD__ ostream& operator << (STD__ ostream& os, TMatrix<T> tm)
01820 {
01821 Matrix<T> m(tm);
01822 return os << m;
01823 }
01824
01825 INST(template <typename T> class TSMatrix friend STD__ ostream& operator << (STD__ ostream& os, const TSMatrix<T>& ts);)
01826 template <typename T>
01827 STD__ ostream& operator << (STD__ ostream& os, const TSMatrix<T>& ts)
01828 {
01829 return os << Matrix<T>(ts);
01830 }
01831
01832
01833
01834
01835
01836 template <typename T>
01837 inline Matrix<T>& Matrix<T>::operator *= (const T& a)
01838 {
01839 STD_SMP_TEMPLATE2C(vec_mul_val, this->dim, this->vec, a);
01840 return *this;
01841 }
01842 template <typename T>
01843 inline Matrix<T>& Matrix<T>::operator /= (const T& a)
01844 {
01845 STD_SMP_TEMPLATE2C(vec_div_val, this->dim, this->vec, a);
01846 return *this;
01847 }
01848
01849
01850
01851 template <typename T>
01852 inline TMatrix<T> Matrix<T>::operator + (const T& a) const
01853 {
01854 TMatrix<T> t (this->row, this->col);
01855 STD_SMP_TEMPLATE3VC(vec_val_add, this->dim, t.vec, this->vec, a);
01856 return t;
01857 }
01858 template <typename T>
01859 inline TMatrix<T> Matrix<T>::operator - (const T& a) const
01860 {
01861 TMatrix<T> t (this->row, this->col);
01862 STD_SMP_TEMPLATE3VC(vec_val_sub, this->dim, t.vec, this->vec, a);
01863 return t;
01864 }
01865
01866 template <typename T>
01867 inline TSMatrix<T> Matrix<T>::operator * (const T& a) const
01868 { return TSMatrix<T> (*this, a); }
01869
01870 template <typename T>
01871 inline TSMatrix<T> Matrix<T>::operator / (const T& a) const
01872 {
01873 BCHK (a==(T)0, MatErr, Divide Mat by 0, 0, *this);
01874 return TSMatrix<T> (*this, (T)1/a);
01875 }
01876
01877 template <typename T>
01878 inline TMatrix<T> Matrix<T>::operator + (const Matrix<T>& a) const
01879 {
01880 TMatrix<T> t (this->row, this->col);
01881 BCHK(this->dim != a.dim, MatErr, Operator + on diff size matrices, a.dim, t);
01882 STD_SMP_TEMPLATE3VV(vec_vec_add, this->dim, t.vec, this->vec, a.vec);
01883 return t;
01884 }
01885 template <typename T>
01886 inline TMatrix<T> Matrix<T>::operator - (const Matrix<T>& a) const
01887 {
01888 TMatrix<T> t (this->row, this->col);
01889 BCHK(this->dim != a.dim, MatErr, Operator - on diff size matrices, a.dim, t);
01890 STD_SMP_TEMPLATE3VV(vec_vec_sub, this->dim, t.vec, this->vec, a.vec);
01891 return t;
01892 }
01893
01894 template <typename T>
01895 inline TMatrix<T>& Matrix<T>::operator + (TMatrix<T>& a) const
01896 {
01897 BCHK(this->dim != a.dim, MatErr, Applying + on diff. size matrices, a.dim, a);
01898 STD_SMP_TEMPLATE2V(vec_add_vec, this->dim, a.vec, this->vec);
01899 return a;
01900 }
01901 template <typename T>
01902 inline TMatrix<T>& Matrix<T>::operator - (TMatrix<T>& a) const
01903 {
01904 BCHK(this->dim != a.dim, MatErr, Applying - on diff. size matrices, a.dim, a);
01905 STD_SMP_TEMPLATE2V(vec_sub_vec_inv, this->dim, a.vec, this->vec);
01906 return a;
01907 }
01908
01909 template <typename T>
01910 inline TMatrix<T> Matrix<T>::operator + (TSMatrix<T>& ts) const
01911 {
01912 BCHK(this->dim != ts.dim, MatErr, Applying + on diff. size matrices, ts.dim, (ts.real_destroy(),TMatrix<T> (*this)) );
01913 TSMatrix<T> tm (ts); tm.detach ();
01914 STD_SMP_TEMPLATE4V(vec_svc_add, this->dim, tm.vec, this->vec, ts.vec, ts.fac);
01915 tm.fac = (T)1; return TMatrix<T> (tm);
01916 }
01917 template <typename T>
01918 inline TMatrix<T> Matrix<T>::operator - (TSMatrix<T>& ts) const
01919 {
01920 BCHK(this->dim != ts.dim, MatErr, Applying - on diff. size matrices, ts.dim, (ts.real_destroy(),TMatrix<T> (*this)) );
01921 TSMatrix<T> tm (ts); tm.detach ();
01922 STD_SMP_TEMPLATE4V(vec_svc_sub, this->dim, tm.vec, this->vec, ts.vec, ts.fac);
01923 tm.fac = (T)1; return TMatrix<T> (tm);
01924 }
01925
01926
01927 #define COST_MATMAT_OLD(ra,ca,cb) (ra*cb*(COST_UNIT_STORE+COST_LOOP \
01928 +ca*(3*COST_UNIT_LOAD+COST_NU_LOAD+COST_MULT+COST_ADD+COST_LOOP)))
01929 #define COST_MATMAT_NEW(ra,ca,cb) (ra*cb*COST_MEMSET+ra*ca*(2*COST_UNIT_LOAD+COST_LOOP \
01930 +cb*(3*COST_UNIT_LOAD+COST_UNIT_STORE+COST_ADD+COST_MULT+COST_LOOP)))
01931 #ifdef OLD_MAT_MAT_MULT
01932 # define COST_MATMAT(ra,ca,cb) COST_MATMAT_OLD(ra,ca,cb)
01933 #else
01934 # define COST_MATMAT(ra,ca,cb) COST_MATMAT_NEW(ra,ca,cb)
01935 #endif
01936
01937
01938 INST(template <typename T> class TMatrix friend void do_mat_mat_mult (const unsigned, const unsigned, \
01939 TMatrix<T> *, const Matrix<T> *, const Matrix<T> *);)
01940
01941 #include "matrix_kernels.h"
01942
01943 #if defined(SMP) && !defined(NOSMP_MATVEC)
01944
01945 template <typename T>
01946 inline void job_mat_mat_mult (struct thr_ctrl *tc)
01947 {
01948 do_mat_mat_mult (tc->t_off, tc->t_size,
01949 (TMatrix<T>*)(tc->t_par[0]), (const Matrix<T>*)(tc->t_par[1]),
01950 (const Matrix<T>*)(tc->t_par[2]));
01951 }
01952
01953 template <typename T>
01954 TMatrix<T> Matrix<T>::operator * (const Matrix<T>& b) const
01955 {
01956 TMatrix<T> c(this->row, b.col);
01957 const unsigned n_thr = threads_avail(this->col*this->row/SMP_MATSLICE);
01958 #ifndef OLD_MAT_MAT_MULT
01959 c.clear();
01960 #endif
01961 BCHK(this->col != b.row, MatErr, Illegal sizes in Matrix multiplication, 0, c);
01962 if (LIKELY(n_thr < 2))
01963 do_mat_mat_mult<T> (0UL, this->row, &c, this, &b);
01964 else {
01965 PREFETCH_W(c.vec, 3);
01966 const unsigned long first = slice_offset(1, n_thr, this->row, c.vec);
01967 unsigned long st, en = first;
01968
01969 for (unsigned t = 0; t < n_thr-1; ++t) {
01970 st = en; en = slice_offset(t+2, n_thr, this->row, c.vec);
01971 thread_start_off (t, (thr_job_t)job_mat_mat_mult<T>,
01972 st, en, &c, this, &b, (void*)0);
01973 }
01974
01975 do_mat_mat_mult<T> (0UL, first, &c, this, &b);
01976
01977
01978 for (unsigned s = 0; s < n_thr-1; ++s)
01979 thread_wait (s);
01980 }
01981 return c;
01982 }
01983
01984
01985 #else
01986 template <typename T>
01987 TMatrix<T> Matrix<T>::operator * (const Matrix<T>& b) const
01988 {
01989 TMatrix<T> c(this->row, b.col);
01990 #ifndef OLD_MAT_MAT_MULT
01991 c.clear();
01992 #endif
01993 BCHK(this->col != b.row, MatErr, Illegal sizes in Matrix multiplication, 0, c);
01994 do_mat_mat_mult <T> (0, this->row, &c, this, &b);
01995 return c;
01996 }
01997 #endif
01998
01999 template <typename T>
02000 TMatrix<T> Matrix<T>::operator * (TSMatrix<T>& a) const
02001 {
02002 TMatrix<T> c(this->row, a.col);
02003 BCHK(this->col != a.row, MatErr, Illegal sizes in Matrix multiplication, 0, c);
02004 T tmp ALIGN(MIN_ALIGN2);
02005 for (unsigned i=0; i<this->row; i++) {
02006 for (unsigned j=0; j<a.col; j++) {
02007 tmp = this->mat[i][0] * a.mat[0][j];
02008 for (register unsigned l=1; l<this->col; l++)
02009 tmp += this->mat[i][l] * a.mat[l][j];
02010 c.mat[i][j] = tmp * a.fac;
02011 }
02012 }
02013 a.real_destroy (); return c;
02014 }
02015
02016
02017 template <typename T>
02018 inline TMatrix<T> Matrix<T>::operator * (TMatrix<T>& a) const
02019 {
02020 TMatrix<T> c (this->operator * (Matrix<T> (a)));
02021 return c;
02022 }
02023
02024 template <typename T>
02025 inline TMatrix<T> TMatrix<T>::operator * (const Matrix<T>& a)
02026 {
02027 Matrix<T> m (*this);
02028 return (m * a);
02029 }
02030
02031
02032 template <typename T>
02033 inline TMatrix<T> TMatrix<T>::operator * (TMatrix<T> a)
02034 {
02035 Matrix<T> m (*this);
02036 return (m * (Matrix<T> (a)));
02037 }
02038
02039 template <typename T>
02040 inline TMatrix<T> TMatrix<T>::operator * (TSMatrix<T> a)
02041 {
02042 Matrix<T> m (*this);
02043 return (m * a);
02044 }
02045
02046
02047 template <typename T>
02048 bool Matrix<T>::operator == (const Matrix<T>& m) const
02049 {
02050 if (LIKELY(this->row != m.row || this->col != m.col))
02051 return false;
02052 if (LIKELY(this->vec == m.vec || this->dim == 0))
02053 return true;
02054 if (TBCICOMP (this->vec, m.vec, T, this->dim))
02055 return false;
02056 else
02057 return true;
02058 }
02059
02060 template <typename T>
02061 bool Matrix<T>::operator == (TSMatrix<T> ts) const
02062 {
02063 if (LIKELY(this->row != ts.row || this->col != ts.col))
02064 return (ts.real_destroy(), false);
02065 if (LIKELY(this->dim == 0)) {
02066 return true;
02067 }
02068 if (LIKELY(ts.fac == (T)1)) {
02069 if (LIKELY(this->vec == ts.vec))
02070 return true;
02071 if (TBCICOMP (this->vec, ts.vec, T, this->dim)) {
02072 ts.real_destroy (); return false;
02073 }
02074 } else {
02075 if (LIKELY(this->vec == ts.vec))
02076 return false;
02077 for (register T *p1 = this->vec, *p2 = ts.vec; p1 < this->endvec; p1++, p2++)
02078 if (UNLIKELY(*p1 != *p2 * ts.fac)) {
02079 ts.real_destroy (); return false;
02080 }
02081 }
02082 ts.real_destroy (); return true;
02083 }
02084
02085 template <typename T>
02086 double Matrix<T>::fabssqr () const
02087 {
02088 LONG_DOUBLE res = 0.0;
02089 do_vec_fabssqr (this->dim, this->vec, res);
02090 return (res);
02091 }
02092
02093 template <typename T>
02094 inline double fabssqr (const Matrix<T>& m)
02095 {
02096 return m.fabssqr ();
02097 }
02098
02104 template<typename T>
02105 inline TVector<T> Matrix<T>::operator * (TVector<T> c) const
02106 {
02107 Vector<T> cn (c);
02108 return (*this * cn);
02109 }
02110
02111
02112 #if defined(SMP) && !defined(NOSMP_MATVEC)
02113
02114 template <typename T>
02115 inline void job_mat_vec_mult (struct thr_ctrl *tc)
02116 {
02117 do_mat_vec_mult (tc->t_off, tc->t_size,
02118 (TVector<T>*)(tc->t_par[0]), (const Matrix<T>*)(tc->t_par[1]),
02119 (const Vector<T>*)(tc->t_par[2]));
02120 }
02121
02122 template <typename T>
02123 inline void job_mat_vec_transmult (struct thr_ctrl *tc)
02124 {
02125 do_mat_vec_transmult (tc->t_off, tc->t_size,
02126 (TVector<T>*)(tc->t_par[0]), (const Matrix<T>*)(tc->t_par[1]),
02127 (const Vector<T>*)(tc->t_par[2]));
02128 }
02129
02130
02131 template <typename T>
02132 TVector<T> Matrix<T>::operator * (const Vector<T>& v) const
02133 {
02134 TVector<T> tv (this->row);
02135
02136 const unsigned n_thr = threads_avail (this->row / SMP_MATSLICE);
02137
02138 BCHK (v.size() != this->col, MatErr, multiply Matrix w/ Vector: wrong config, v.size(), tv);
02139 if (LIKELY(n_thr < 2))
02140 do_mat_vec_mult<T> (0, this->row, &tv, this, &v);
02141 else {
02142 PREFETCH_W(tv.vec, 3);
02143 const unsigned long first = slice_offset(1, n_thr, this->row, tv.vec);
02144 unsigned long st, en = first;
02145
02146 for (unsigned t = 0; t < n_thr-1; ++t) {
02147 st = en; en = slice_offset(t+2, n_thr, this->row, tv.vec);
02148 thread_start_off (t, (thr_job_t)job_mat_vec_mult<T>,
02149 st, en, &tv, this, &v, (void*)0);
02150 }
02151
02152 do_mat_vec_mult<T> (0, first, &tv, this, &v);
02153
02154
02155 for (unsigned s = 0; s < n_thr-1; ++s)
02156 thread_wait (s);
02157 }
02158 return tv;
02159 }
02160
02161 template<typename T>
02162 TVector<T> Matrix<T>::transMult (const Vector<T>& v) const
02163 {
02164 TVector<T> tv (this->col);
02165 const unsigned n_thr = threads_avail (this->col / SMP_MATSLICE);
02166 BCHK (v.size() != this->row, MatErr, transMult Matrix w/ Vector: wrong config, v.size(), tv);
02167 if (LIKELY(n_thr < 2))
02168 do_mat_vec_transmult<T> (0, this->col, &tv, this, &v);
02169 else {
02170 const unsigned long first = this->col/n_thr - (this->col/n_thr)%4;
02171 unsigned long st, en = first;
02172 for (unsigned t = 0; t < n_thr-1; ++t) {
02173 st = en; en = (t+2)*this->col/n_thr;
02174 if (t < n_thr-2)
02175 en -= en%4;
02176 thread_start_off (t, (thr_job_t)job_mat_vec_transmult<T>,
02177 st, en, &tv, this, &v, (void*)0);
02178 }
02179 do_mat_vec_transmult<T> (0, first, &tv, this, &v);
02180
02181 for (unsigned s = 0; s < n_thr-1; ++s)
02182 thread_wait (s);
02183 }
02184 return tv;
02185 }
02186
02187 #else
02188
02189 template <typename T>
02190 TVector<T> Matrix<T>::operator * (const Vector<T>& v) const
02191 {
02192 TVector<T> tv (this->row);
02193 BCHK (v.size() != this->col, MatErr, multiply Matrix w/ Vector: wrong config, v.size(), tv);
02194 do_mat_vec_mult (0, this->row, &tv, this, &v);
02195 return tv;
02196 }
02197
02198 template<typename T>
02199 TVector<T> Matrix<T>::transMult (const Vector<T>& v) const
02200 {
02201 TVector<T> tv (this->col);
02202 BCHK (v.size() != this->row, MatErr, transMult Matrix w/ Vector: wrong config, v.size(), tv);
02203 do_mat_vec_transmult<T> (0, this->col, &tv, this, &v);
02204 return tv;
02205 }
02206
02207
02208 #endif
02209
02210
02211 template <typename T>
02212 TVector<T> Matrix<T>::operator * (const TSVector<T>& tsv) const
02213 {
02214 TVector<T> tv (this->row);
02215 BCHK (tsv.size() != this->col, MatErr, multiply Matrix w/ Vector: wrong config, tsv.size(), tv);
02216 do_mat_tsv_mult (0, this->row, &tv, this, &tsv);
02217 return tv;
02218 }
02219
02220
02221 template <typename T>
02222 inline BVector<T>& bvfillm (BVector<T>& bv, const Matrix<T>& m)
02223 {
02224 BCHK (bv.dim != m.dim, VecErr, Matrix size does not fit Vector, bv.dim, bv);
02225 TBCICOPY (bv.vec, m.vec, T, bv.dim);
02226 return bv;
02227 }
02228
02229
02230
02231
02232
02233
02234 template <typename T>
02235 Matrix<T>& Matrix<T>::mult_rows (const Vector<T>& v)
02236 {
02237 BCHK (this->row != v.size(), MatErr, multiply rows: wrong sizes, v.size(), *this);
02238 for (unsigned r = 0; r < this->row; r++)
02239 {
02240 T fac = v (r);
02241 for (unsigned c = 0; c < this->col; c++)
02242 this->operator() (r, c) *= fac;
02243 }
02244 return *this;
02245 }
02246
02247 template <typename T>
02248 Matrix<T>& Matrix<T>::div_rows (const Vector<T>& v)
02249 {
02250 BCHK (this->row != v.size(), MatErr, multiply rows: wrong sizes, v.size(), *this);
02251 for (unsigned r = 0; r < this->row; r++)
02252 {
02253 T fac = (T)1.0 / v (r);
02254 for (unsigned c = 0; c < this->col; c++)
02255 (*this) (r, c) *= fac;
02256 }
02257 return *this;
02258 }
02259
02260 template <typename T>
02261 Matrix<T>& Matrix<T>::mult_row (const T& f, const unsigned r)
02262 {
02263 BCHK (r>this->row, MatErr, mult_row: wrong index, r, *this);
02264 for (unsigned c = 0; c < this->col; c++)
02265 (*this) (r, c) *= f;
02266 return *this;
02267 }
02268
02269 template <typename T>
02270 Matrix<T>& Matrix<T>::div_row (const T& d, const unsigned r)
02271 {
02272 BCHK (r>this->row, MatErr, mult_row: wrong index, r, *this);
02273 BCHK (d == (T)0, MatErr, div_row by zero, r, *this);
02274 T f = (T)1.0 / d;
02275 for (unsigned c = 0; c < this->col; c++)
02276 (*this) (r, c) *= f;
02277 return *this;
02278 }
02279
02280
02281
02282
02283 template <typename T>
02284 class Mat_Brack
02285 {
02286 private:
02287 const TMatrix<T> & tmat;
02288 unsigned int idx;
02289 public:
02290 friend class TVector<T>;
02291 friend class Vector<T>;
02292 friend class TMatrix<T>;
02293 private:
02294 Mat_Brack (const TMatrix<T> &tm, unsigned int ix) : tmat(tm), idx (ix) {}
02295 Mat_Brack (const Mat_Brack<T>& m) : tmat(m.tmat), idx(m.idx) {}
02296 public:
02297 ~Mat_Brack() { tmat.mark_destroy(); }
02298 inline const T& operator [] (unsigned int j) const
02299 { BCHK(j >= tmat.col, MatErr, Idx2 out of range, j, tmat.mat[idx][0]);
02300 return tmat.mat[idx][j]; }
02301 inline T& operator [] (unsigned int j)
02302 { BCHK(j >= tmat.col, MatErr, Idx2 out of range, j, tmat.mat[idx][0]);
02303 return tmat.mat[idx][j]; }
02304 };
02305
02306 template <typename T>
02307 inline TVector<T>::TVector (const Mat_Brack<T>& mb)
02308 {
02309 this->vec = mb.tmat.mat[mb.idx];
02310 this->dim = (unsigned long)mb.tmat.col; this->keep = true;
02311 }
02312
02313 template <typename T>
02314 inline Vector<T>::Vector (const Mat_Brack<T>& mb)
02315 {
02316 this->dim = (unsigned long)mb.tmat.col;
02317 this->keep = false;
02318 if (LIKELY(this->dim)) {
02319 this->vec = NEW (T, this->dim);
02320 if (LIKELY(this->vec)) {
02321 TBCICOPY (this->vec, mb.tmat.mat[mb.idx], T, this->dim);
02322 return;
02323 }
02324 }
02325 this->dim = 0; this->vec = (T*)0;
02326 }
02327 #ifndef TBCI_NEW_BRACKET
02328 template <typename T>
02329 inline Mat_Brack<T> TMatrix<T>::operator [] (const unsigned int ix) const
02330 {
02331 BCHK(ix >= row, MatErr, Idx1 out of range, ix, Mat_Brack<T> (*this, 0));
02332 return Mat_Brack<T> (*this, ix);
02333 }
02334 #else
02335 template <typename T>
02336 inline T* TMatrix<T>::operator [] (const unsigned int ix) const
02337 {
02338 BCHK(ix >= row, MatErr, Idx1 out of range, ix, (T*)0);
02339 return mat[ix];
02340 }
02341 #endif
02342
02343
02344 #undef _DIM
02345 #undef _VEC
02346 #undef _ENDVEC
02347 #undef _ROW
02348 #undef _COL
02349 #undef _FAC
02350
02351 template <typename T> int lu_decomp (Matrix<T>&) HOT;
02352
02353 NAMESPACE_END
02354
02355 #endif