TBCI Numerical high perf. C++ Library  2.8.0
matrix.h
Go to the documentation of this file.
1 
5 //-------------------------------------------------------------
6 // Attila Michael Bilgic, 1/97
7 // last update 97/10/04 AMB
8 // 98/11/03 KG
9 // $Id: matrix.h,v 1.57.2.142 2022/11/05 21:31:35 garloff Exp $
10 //-------------------------------------------------------------
11 
12 #ifndef TBCI_MATRIX_H
13 #define TBCI_MATRIX_H
14 
15 #include "tbci/basics.h"
16 #include "tbci/vector.h"
17 //#include "fs_vector.h"
18 #include "tbci/matrix_sig.h"
19 
20 #ifdef DEBUG_THREAD
21 # include <cstdio>
22 #endif
23 
24 // Avoid -fguiding-decls
25 #if !defined(NO_GD) && !defined(AUTO_DECL)
26 # include "tbci/matrix_gd.h"
27 #endif
28 
30 
31 
32 #ifdef HAVE_GCC295_FRIEND_BUG
33 # define _VEC getvec()
34 # define _ENDVEC getendvec()
35 # define _DIM size()
36 # define _ROW rows()
37 # define _COL columns()
38 # define _FAC getfac()
39 #else
40 # define _VEC vec
41 # define _ENDVEC endvec
42 # define _DIM dim
43 # define _ROW row
44 # define _COL col
45 # define _FAC fac
46 #endif
47 
48 
49 #ifndef TBCI_DISABLE_EXCEPT
50 //# include "except.h" in basics.h
51 
53 class MatErr : public NumErr
54 {
55  public:
57  : NumErr(/*errtext =*/ "Error in Matrix library") {}
58  MatErr(const char* t, const long i = 0)
59  : NumErr(t, i) {}
60  MatErr(const MatErr& me)
61  : NumErr(me) {}
62  virtual ~MatErr() throw() {}
63 };
64 #endif
65 
66 #ifdef PRAGMA_I
67 # pragma interface "matrix.h"
68 #endif
69 
70 enum rowcolvec { rowvec = 0, colvec = 1 };
71 
72 template <typename T> class Matrix;
73 template <typename T> class TMatrix;
74 template <typename T> class TSMatrix;
75 template <typename T> class Mat_Brack;
76 template <typename T> class BdMatrix;
77 template <typename T> class Tensor;
78 
79 template <typename T>
80 void do_mat_vec_mult (const unsigned start, const unsigned end,
81  TVector<T> *res, const Matrix<T> *mat,
82  const Vector<T> *vec);
83 
84 template <typename T>
85 void do_mat_tsv_mult (const unsigned start, const unsigned end,
86  TVector<T> *res, const Matrix<T> *mat,
87  const TSVector<T> *vec);
88 
89 template <typename T>
90 void do_mat_vec_transmult (const unsigned start, const unsigned end,
91  TVector<T> *res, const Matrix<T> *mat,
92  const Vector<T> *vec);
93 
94  /* TODO: Adjust dynamically (or at least depending on OPT target). */
95 #if defined(SMP) && !defined(SMP_MATSLICE)
96 # define SMP_MATSLICE 4096
97 #endif
98 #ifdef SMP
99 # define SMP_MATSLICE2 (SMP_MATSLICE/sizeof(T))
100 #endif
101 
102 //-----------------------------------------------------
107 //-----------------------------------------------------
108 template <typename T>
109 class TMatrix : public Matrix_Sig<T>
110 {
111  protected:
112  typedef T mat_t /*TALIGN(sizeof(T))*/;
113  typedef T* Tptr /*TALIGN(sizeof(T))*/;
114 
115  unsigned long dim;
116  unsigned int row, col:31;
117  mutable unsigned int freeable:1;
119  T **mat, *vec, *endvec;
120 
121  int set_ptrs ();
122 
123  public:
124 #if 1 //defined(HAVE_GCC295_FRIEND_BUG) || defined(HAVE_PROMOTION_BUG)
125  // allow access to vec and endvec
126  T* getvec () const { return vec; }
127  T* getendvec () const { return endvec; }
128 #endif
129  typedef T value_type;
130  typedef T element_type;
131  typedef T aligned_value_type TALIGN(MIN_ALIGN2);
132 
133  friend class Matrix<T>;
134  friend class TSMatrix<T>;
135  friend class Tensor<T>;
136  friend class Mat_Brack<T>;
137  friend class Vector<T>;
138  friend class TVector<T>;
139  friend class BdMatrix<T>;
140 
141  friend NOINST TMatrix<T> /*FRIEND_TBCI2__*/ LU_solve FGD (const BdMatrix<T>&, const Matrix<T>&);
142  friend NOINST TMatrix<T> /*FRIEND_TBCI2__*/ lu_solve FGD (BdMatrix<T>&, const Matrix<T>&);
143  friend NOINST TMatrix<T> /*FRIEND_TBCI2__*/ LU_invert FGD (const BdMatrix<T>&);
144  friend NOINST TMatrix<T> /*FRIEND_TBCI2__*/ lu_invert FGD (BdMatrix<T>&);
145 
146  friend void FRIEND_TBCI2__ do_mat_vec_mult FGD (const unsigned start, const unsigned end,
147  TVector<T> *res, const Matrix<T> *mat,
148  const Vector<T> *vec) HOT;
149  friend void FRIEND_TBCI2__ do_mat_tsv_mult FGD (const unsigned start, const unsigned end,
150  TVector<T> *res, const Matrix<T> *mat,
151  const TSVector<T> *tsv) HOT;
152  friend void FRIEND_TBCI2__ do_mat_vec_transmult_exact FGD (const unsigned start, const unsigned end,
153  TVector<T> *res, const Matrix<T> *mat,
154  const Vector<T> *vec) HOT;
155  friend void FRIEND_TBCI2__ do_mat_vec_transmult FGD (const unsigned start, const unsigned end,
156  TVector<T> *res, const Matrix<T> *mat,
157  const Vector<T> *vec) HOT;
158 
159  //protected:
160  public:
162  explicit TMatrix (const unsigned = 0);
164  TMatrix (const unsigned, const unsigned);
166  TMatrix (const T&, const unsigned, const unsigned);
168  explicit TMatrix (const Vector<T>&, const enum rowcolvec = colvec);
170  TMatrix (const TMatrix<T>&) HOT;
171  TMatrix (TSMatrix<T>);
173  TMatrix (const Matrix<T>&) HOT;
175  void real_destroy ();
177  void mark_destroy() const;
178 
179  // allow instantiation (Matrix_Sig)
180  /*virtual*/ static const char* mat_info () { return ("TMatrix"); }
181 
182  //public:
183  // empty destructor: TMatrix will never be destroyed but explicitly !!!
185  { if (freeable) real_destroy(); }
186 
187 #ifndef HAVE_PROMOTION_BUG
188 # ifndef HAVE_GCC295_TMPLFRNDCLS_BUG
189  // Promotion (only explicit)
190  template <typename U> friend class Matrix;
191  template <typename U> friend class TMatrix;
192 # endif
193  template <typename U> explicit TMatrix (const Matrix<U>& m)
194  : dim (m._DIM), row (m._ROW), col (m._COL),
195  freeable (0),
196  mat (dim>0?NEW(Tptr,row):0), vec (dim>0?NEW(T,dim):0)
197  { set_ptrs (); T *t = vec; U *u =m._VEC;
198  while (t < endvec) *t++ = *u++; }
199 
200  template <typename U> explicit TMatrix (const TMatrix<U>& tm)
201  : dim (tm._DIM), row (tm._ROW), col (tm._COL),
202  freeable (0),
203  mat (dim>0?NEW(Tptr,row):0), vec (dim>0?NEW(T,dim):0)
204  { set_ptrs (); T *t = vec; U *u =tm._VEC;
205  while (t < endvec) *t++ = *u++; }
206 #endif
207  //public:
210  TMatrix<T>& operator = (const TMatrix<T>&) HOT;
211  TMatrix<T>& operator = (TSMatrix<T>);
212  TMatrix<T>& operator = (const T&);
213  TMatrix<T>& alias (const TMatrix<T>& m);
214 
216  TMatrix<T>& operator += (TMatrix<T>); // arg will be destroyed
217  TMatrix<T>& operator += (const Matrix<T>&); // arg wont be destroyed
218  TMatrix<T>& operator += (const T&);
219  TMatrix<T>& operator += (TSMatrix<T>); // arg will be destroyed
220  TMatrix<T>& operator -= (TMatrix<T>);
221  TMatrix<T>& operator -= (const Matrix<T>&);
222  TMatrix<T>& operator -= (const T&);
223  TMatrix<T>& operator -= (TSMatrix<T>);
224 
225  TSMatrix<T> operator *= (const T&);
226  TSMatrix<T> operator /= (const T&);
227 
228  // operations
229  TMatrix<T>& operator - ();
230 
231  TMatrix<T>& operator + (TMatrix<T>); // arg will be destroyed
232  TMatrix<T>& operator + (TSMatrix<T>); // arg will be destroyed
233  TMatrix<T>& operator + (const Matrix<T>&); // arg wont be destroyed
234  TMatrix<T>& operator + (const T&);
235  TMatrix<T>& operator - (TMatrix<T>);
236  TMatrix<T>& operator - (TSMatrix<T>);
237  TMatrix<T>& operator - (const Matrix<T>&);
238  TMatrix<T>& operator - (const T&);
239  TSMatrix<T> operator * (const T&);
240  TSMatrix<T> operator / (const T&);
241 
242  TMatrix<T> operator * (const Matrix<T>&);
243  TMatrix<T> operator * (TMatrix<T>);
244  TMatrix<T> operator * (TSMatrix<T>);
245 
246  TVector<T> operator * (const Vector<T>& v)
247  { Matrix<T> m (*this); return (m * v); }
249  { Matrix<T> m (*this); return (m * tv); }
251  { Matrix<T> m (*this); return (m * tsv); }
252 
253  // friend operations
254 #ifndef HAVE_GCC295_FRIEND_BUG
255  friend NOINST TMatrix<T> FRIEND_TBCI__ operator + FGD (const T&, TMatrix<T>);
256  friend NOINST TMatrix<T> FRIEND_TBCI__ operator - FGD (const T&, TMatrix<T>);
257  friend NOINST TMatrix<T> FRIEND_TBCI__ operator + FGD (const T&, const Matrix<T>&);
258  friend NOINST TMatrix<T> FRIEND_TBCI__ operator - FGD (const T&, const Matrix<T>&);
259  friend NOINST TSMatrix<T> FRIEND_TBCI__ operator * FGD (const T&, TMatrix<T>);
260  friend NOINST TSMatrix<T> FRIEND_TBCI__ operator * FGD (const T&, const Matrix<T>&);
261 #endif
262 
265  TMatrix<T> transposed_copy() const;
267 
268  // Access
269 
270  //public:
272  T operator () (const unsigned int, const unsigned int) const HOT;
273  //T& operator () (const unsigned, const unsigned) const;
274 #ifndef TBCI_NEW_BRACKET
275  Mat_Brack<T> operator [] (const unsigned int i) const;
276 #else
277  T* operator [] (const unsigned int i) const;
278 #endif
279  // TVector<T> operator [] (const unsigned int i);
280 
281  T& setval(const T& val, const unsigned int r, const unsigned int c)
282  { return mat[r][c] = val; }
283  T& setval (const unsigned r, const unsigned c)
284  { return mat[r][c]; }
285 
287  typename tbci_traits<T>::const_refval_type
288  get (const unsigned r, const unsigned c) const
289  { return mat[r][c]; }
290  T& set (const T& val, const unsigned r, const unsigned c)
291  { return mat[r][c] = val; }
292  const T& getcref(const unsigned r, const unsigned c) const
293  { return mat[r][c]; }
294 
296  const T* getrowptr (const unsigned r) const { return mat[r]; }
297  T* getrowptr (const unsigned r) { return mat[r]; }
298 
300  bool operator == (const Matrix<T>& m);
301  bool operator != (const Matrix<T>& m)
302  { return !(*this == m); }
303 
305  { Matrix<T> m (tm); return (*this == m); }
307  { return !(*this == tm); }
308 
311  { return !(*this == ts); }
312 
313  //public:
315  unsigned int columns () const { return col; }
317  unsigned int rows () const { return row; }
319  unsigned long size () const { return dim; }
320 
322  TVector<T> operator () (const unsigned int) const;
324  TVector<T> get_row (const unsigned int) const;
326  TVector<T> get_col (const unsigned int) const;
327 
329  void set_row (const Vector<T>&, const unsigned int);
331  void set_col (const Vector<T>&, const unsigned int);
332  // On request of R. Prescott ...
334  void set_row_partial (const Vector<T>&, const unsigned int,
335  const unsigned int);
337  void set_col_partial (const Vector<T>&, const unsigned int,
338  const unsigned int);
339 #if 0
340  void set_row_indexed (const Vector<T>&, const unsigned int,
342  const BVector<unsigned int>&);
344  void set_row_indexed (const Vector<T>&, const unsigned int,
345  const BVector<unsigned int>&);
347  void set_submatrix (const Matrix<T>&,
348  const unsigned int, const unsigned int);
349 #endif
350 
351 #if 0
352  template <unsigned long dim>
353  void set_row (const FS_Vector<dim,T>& v, const unsigned int i)
354  {
355  BCHKNR(i >= row, MatErr, Illegal row index in set_row, i);
356  BCHKNR(dim != col, MatErr, Different sizes in set_row, dim);
357  TBCICOPY (mat[i], &v(0), T, dim);
358  }
359 #endif
360 
362  TMatrix<T>& resize (const unsigned int, const unsigned int);
364  TMatrix<T>& resize (const unsigned int d) { return this->resize (d, d); }
366  TMatrix<T>& resize (const T&, const unsigned int, const unsigned int);
368  TMatrix<T>& resize (const TMatrix<T>&);
370  TMatrix<T>& cheapdownsizerow (const unsigned);
372  TMatrix<T>& fill (const T& = (T)0);
374  TMatrix<T>& clear ();
376  TMatrix<T>& fill (const Vector<T>&);
378  TMatrix<T>& setunit (const T& = (T)1);
380  TMatrix<T>& row_expand (const unsigned int r);
382  TMatrix<T>& row_expand (const TMatrix<T>& m);
383 
385  T trace () const;
386 
388  double fabssqr () const;
389  double fabs () const { return GLBL__ MATH__ sqrt (fabssqr()); }
390 };
391 
392 
393 template <typename T>
395 {
396  if (UNLIKELY(dim)) {
398  }
399 }
400 
401 template <typename T>
402 inline void TMatrix<T>::mark_destroy () const
403 {
404  this->freeable = 1;
405 }
406 
407 
408 template <typename T>
409 inline int TMatrix<T>::set_ptrs ()
410 {
411  if (LIKELY(mat && vec)) {
412  //for (unsigned long i=0; i<dim; i++) vec[i] = 0;
413 #if 1
414  T* ptr = vec;
415  for (REGISTER unsigned i = 0; i < row; ++i) {
416  mat[i] = ptr; ptr += col;
417  //vec[i + i*d] = 1;
418  }
419  endvec = ptr;
420 #else
421  // Avoid this access in loop, so gcc4 could vectorize it
422  // Unfortunately, it still fails, as the loop counter i
423  // is used in the computation
424  const unsigned int ROW = row;
425  const unsigned int COL = col;
426  T* RESTRICT const VEC = vec;
427  T** RESTRICT const MAT = mat;
428  for (REGISTER unsigned i = 0; i < ROW; ++i)
429  MAT[i] = VEC + i*COL;
430  endvec = VEC + ROW*COL;
431 #endif
432  return 0;
433  } else {
434  if (UNLIKELY(vec))
435  TBCIDELETE(T, vec, dim);
436  if (UNLIKELY(mat))
437  TBCIDELETE(Tptr, mat, row);
438  dim = 0; row = 0; col = 0;
439  mat = (T**)0; vec = (T*)0; endvec = (T*)0;
440  return -1;
441  }
442 }
443 
444 template <typename T>
445 inline TMatrix<T>::TMatrix (const unsigned d)
446 : dim (((unsigned long)d)*d), row(d), col(d), freeable (0),
447  mat (d>0?NEW(Tptr,d):0), vec (d>0?NEW(T,d*d):0)
448 {
449  set_ptrs ();
450 }
451 
452 
453 template <typename T>
454 inline TMatrix<T>::TMatrix (const unsigned r, const unsigned c)
455 : dim(((unsigned long)r)*c), row (r), col (c), freeable (0),
456  mat (r*c>0?NEW(Tptr,r):0), vec (r*c>0?NEW(T,r*c):0)
457 {
458  set_ptrs ();
459 }
460 
461 template <typename T>
462 inline TMatrix<T>::TMatrix (const T& val, const unsigned r, const unsigned c)
463 : dim(((unsigned long)r)*c), row (r), col (c), freeable (0),
464  mat (r*c>0?NEW(Tptr,r):0), vec (r*c>0?NEW(T,r*c):0)
465 {
466  if (LIKELY(!set_ptrs ()))
467  TBCIFILL (vec, val, T, dim);
468 }
469 
470 
471 template <typename T>
472 inline TMatrix<T>::TMatrix (const Vector<T>& v, const enum rowcolvec r)
473 : dim(v.dim), row(r==rowvec?v.dim:1), col(r==rowvec?1:v.dim),
474  freeable(0),
475  mat (v.dim?(r==rowvec?NEW(Tptr,1):NEW(Tptr,v.dim)):0),
476  vec (v.dim>0?NEW(T,v.dim):0)
477 {
478  if (LIKELY(!set_ptrs ()))
479  TBCICOPY (vec, v.vec, T, dim);
480 }
481 
482 // data is duplicated
483 template <typename T>
485 : dim (m.dim), row (m.row), col (m.col),
486  freeable (0),
487  mat (m.dim>0?NEW(Tptr,m.row):0), vec (m.dim>0?NEW(T,m.dim):0)
488 {
489  if (LIKELY(!set_ptrs ()))
490  TBCICOPY (vec, m.vec, T, dim);
491 }
492 
493 
494 // copy constructor only copies pointers !
495 template <typename T>
496 inline TMatrix<T>::TMatrix (const TMatrix<T>& tm)
497 : dim (tm.dim), row (tm.row), col (tm.col), freeable (0),
498  mat (tm.mat), vec (tm.vec), endvec (tm.endvec)
499 {
500  BCHKNR(tm.freeable, MatErr, alias freeable object, (long)&tm);
501 }
502 
503 template <typename T>
505 {
506  BCHKNR(tm.freeable, MatErr, alias freeable object, (long)&tm);
507  real_destroy();
508  dim = tm.dim; row = tm.row; col = tm.col; freeable = 0;
509  mat = tm.mat; vec = tm.vec; endvec = tm.endvec;
510  return *this;
511 }
512 
513 template <typename T>
515 : dim (ts.dim), row (ts.row), col (ts.col), freeable (0)
516 {
517  ts.eval (); vec = ts.vec; mat = ts.mat;
518  endvec = ts.endvec; ts.mut = false;
519 }
520 
521 
522 template <typename T>
523 inline T TMatrix<T>::operator () (const unsigned int r, const unsigned int c) const
524 {
525  EXPCHK(r>=row, MatErr, Illegal row index, r, mat[0][0]);
526  EXPCHK(c>=col, MatErr, illegal col index, c, mat[0][0]);
527  mark_destroy ();
528  return mat[r][c];
529 }
530 
531 //copy
532 template <typename T>
534 {
535  BCHK(dim != a.dim, MatErr, Different sizes in assignment, a.dim, *this );
536  TBCICOPY(vec, a.vec, T, dim);
537  return *this;
538 }
539 
540 //alias (do we need it?)
541 template <typename T>
543 {
544  BCHK(row != a.row || col != a.col, MatErr, Different sizes in assignment, a.dim, *this );
545  this->alias(a);
546  //freeable = a.freeable;
547  return *this;
548 }
549 
550 template <typename T>
552 {
553  BCHK(col != a.col || row != a.row, MatErr, Different sizes in assignment, a.dim, *this );
554  a.eval (this);
555  return *this;
556 }
557 
558 //fill
559 template <typename T>
561 {
562  return this->fill (val);
563 }
564 
565 
566 template <typename T>
568 {
569  // This does only make sense for numbers, so the memset () is OK
570  if (LIKELY(dim))
571  TBCICLEAR (vec, T, dim);
572  BCHK(col!=row, MatErr, setunit makes only sense on quadratic matrices, col, *this);
573  unsigned iend = MIN(row,col);
574  for (REGISTER unsigned i = 0; i < iend; i++)
575  mat[i][i] = fac;
576  return *this;
577 }
578 
579 template <typename T>
581 {
582  // Assume 0 is uninitialized or zeroed state
583  if (UNLIKELY(dim))
584  TBCICLEAR (vec, T, dim);
585  return *this;
586 }
587 
588 template <typename T>
589 inline void TMatrix<T>::set_row (const Vector<T>& v, const unsigned int r)
590 {
591  BCHKNR(r >= row, MatErr, Illegal row index in set_row, r);
592  BCHKNR(v.dim != (unsigned long)col, MatErr, Wrong size vector, v.dim);
593  TBCICOPY(mat[r], v.vec, T, v.dim);
594 }
595 
596 template <typename T>
597 inline void TMatrix<T>::set_row_partial (const Vector<T>& v,
598  const unsigned int r, const unsigned off)
599 {
600  BCHKNR(r >= row, MatErr, Illegal row index in set_row_partial, r);
601  BCHKNR(v.dim > (unsigned long)col+off, MatErr, Too large vector, v.dim);
602  TBCICOPY(mat[r]+off, v.vec, T, v.dim);
603 }
604 
605 template <typename T>
606 inline void TMatrix<T>::set_col (const Vector<T>& v, const unsigned int c)
607 {
608  BCHKNR(c >= col, MatErr, Illegal col index in set_col, c);
609  BCHKNR(v.dim != (unsigned long)row, MatErr, Wrong size vector, v.dim);
610  const unsigned ROW = row;
611  for (REGISTER unsigned r = 0; r < ROW; ++r)
612  mat[r][c] = v.vec[r];
613 }
614 
615 template <typename T>
616 inline void TMatrix<T>::set_col_partial (const Vector<T>& v,
617  const unsigned int c, const unsigned off)
618 {
619  BCHKNR(c >= col, MatErr, Illegal col index in set_col, c);
620  BCHKNR(v.dim > (unsigned long)row+off, MatErr, Too large vector, v.dim);
621  const unsigned ROW = v.dim;
622  for (REGISTER unsigned r = 0; r < ROW; ++r)
623  mat[r+off][c] = v.vec[r];
624 }
625 
626 template <typename T>
627 inline TVector<T> TMatrix<T>::get_col (const unsigned int c) const
628 {
629  const unsigned ROW = row;
630  TVector<T> v(ROW);
631  BCHK(c >= col, MatErr, Illegal col index in get_col, c, v);
632  for (REGISTER unsigned j = 0; j < ROW; ++j)
633  v.vec[j] = mat[j][c];
634  mark_destroy();
635  return v;
636 }
637 
638 
639 template <typename T>
640 inline TVector<T> TMatrix<T>::get_row (const unsigned int r) const
641 {
642  TVector<T> v(col);
643  TBCICOPY (v.vec, mat[r], T, col);
644  mark_destroy();
645  return v;
646 }
647 
648 template <typename T>
649 inline TVector<T> TMatrix<T>::operator () (const unsigned int i) const
650 {
651  return this->get_row(i);
652 }
653 
654 template <typename T>
655 TMatrix<T>& TMatrix<T>::resize (const unsigned int r, const unsigned int c)
656 {
657  if (LIKELY(r == row && c == col))
658  return *this;
659  if (UNLIKELY(dim))
660  TBCIDELETE(Tptr, mat, row);
661  T* vv = vec;
662  unsigned long dd = dim;
663  dim = ((unsigned long)r)*c;
664  if (LIKELY(dim)) {
665  mat = NEW(Tptr,r); vec = NEW(T,dim);
666  row = r; col = c;
667  } else {
668  mat = (T**)0; vec = (T*)0; endvec = (T*)0;
669  }
670  if (!set_ptrs())
671  TBCICOPY(vec, vv, T, MIN(dim,dd));
672  if (UNLIKELY(dd))
673  TBCIDELETE(T, vv, dd);
674  return *this;
675 }
676 
677 template <typename T>
678 TMatrix<T>& TMatrix<T>::row_expand (const unsigned int r)
679 {
680  if (LIKELY(r == row))
681  return *this;
682  dim = ((unsigned long)r)*col;
683  if (LIKELY(dim)) {
684  REALLOC (vec, ((unsigned long)row)*col, T, dim);
685  TBCIDELETE (Tptr, mat, row);
686  mat = NEW (Tptr,r);
687  } else {
688  if (UNLIKELY(row*col)) {
689  TBCIDELETE (T, vec, (row*col)); TBCIDELETE (Tptr, mat, row);
690  }
691  mat = (T**)0; vec = (T*)0; endvec = (T*)0;
692  }
693  if (LIKELY(mat && vec)) {
694  T* ptr = vec;
695  for (REGISTER unsigned i=0; i<r; i++) {
696  mat[i] = ptr; ptr += col;
697  }
698  endvec = ptr; row = r;
699  } else { // Allocation failure
700  dim = 0; row = 0; col = 0;
701  mat = (T**)0; vec = (T*)0; endvec = (T*)0;
702  }
703  return *this;
704 }
705 
706 template <typename T>
708 {
709  if (LIKELY(m.dim == 0))
710  return *this;
711  unsigned long olddim = dim;
712  dim += m.dim;
713  row += m.row;
714  if (LIKELY(dim)) {
715  REALLOC (vec, olddim, T, dim);
716  TBCIDELETE (Tptr, mat, (row-m.row));
717  mat = NEW (Tptr, row);
718  if (LIKELY(mat && vec)) {
719  T* ptr = vec;
720  for (REGISTER unsigned i=0; i<row; i++) {
721  mat[i] = ptr; ptr += col;
722  }
723  endvec = ptr;
725  for (REGISTER unsigned long l=0; l<m.dim; l++)
726  vec[dim-m.dim+l] = m.vec[l];
727  return *this;
728  } else { // Allocation failure
729  if (UNLIKELY(vec))
730  TBCIDELETE(T, vec, dim);
731  if (UNLIKELY(mat))
732  TBCIDELETE(Tptr, mat, row);
733  }
734  } else if (olddim) {
735  TBCIDELETE (T, vec, olddim);
736  TBCIDELETE (Tptr, mat, row-m.row);
737  }
738  mat = (T**)0; vec = (T*)0; endvec = (T*)0;
739  dim = 0; row = 0; col = 0;
740  return *this;
741 }
742 
743 
744 template <typename T>
745 TMatrix<T>& TMatrix<T>::resize (const T& v, const unsigned int r, const unsigned int c)
746 {
747  if (LIKELY(r == row && c == col)) {
748  TBCIFILL (vec, v, T, dim);
749  return *this;
750  }
751  if (UNLIKELY(dim)) {
752  TBCIDELETE(T, vec, dim);
753  TBCIDELETE(Tptr, mat, row);
754  }
755  dim = ((unsigned long)r)*c;
756  row = r; col = c;
757  if (LIKELY(dim)) {
758  mat = NEW(Tptr,r); vec = NEW(T,dim);
759  if (!set_ptrs())
760  TBCIFILL(vec, v, T, dim);
761  } else {
762  mat = (T**)0; vec=(T*)0; endvec =(T*)0;
763  }
764  return *this;
765 }
766 
767 template <typename T>
769 {
770  if (LIKELY(m.row == row && m.col == col)) {
771  TBCICOPY (vec, m.vec, T, dim);
772  return *this;
773  }
774  if (UNLIKELY(dim)) {
775  TBCIDELETE(T, vec, dim);
776  TBCIDELETE(Tptr, mat, row);
777  }
778  dim = ((unsigned long)m.row)*m.col;
779  row = m.row; col = m.col;
780  if (LIKELY(dim)) {
781  mat = NEW(Tptr,m.row); vec = NEW(T,dim);
782  if (!set_ptrs())
783  TBCICOPY(vec, m.vec, T, dim);
784  } else {
785  mat = (T**)0; vec = (T*)0; endvec = (T*)0;
786  }
787  return *this;
788 }
789 
790 /* We don't really free space unless it's 0 */
791 template <typename T>
793 {
794  if (LIKELY(nr == row))
795  return *this;
796  BCHK (nr > row, MatErr, cheapdownsize does not upsize, nr, *this);
797  if (UNLIKELY(!nr))
798  return this->resize (nr, col);
799  dim = ((unsigned long)nr) * col;
800  row = nr; endvec = vec + dim;
801  return *this;
802 }
803 
804 template <typename T>
805 inline TMatrix<T>& TMatrix<T>::fill (const T& val)
806 {
807  TBCIFILL(vec, val, T, dim);
808  return *this;
809 }
810 
811 template <typename T>
812 inline T TMatrix<T>::trace () const
813 {
814  ALIGN3(REGISTER T tr, vec[0], MIN_ALIGN2);
815  BCHK (row != col, MatErr, Trace over non quadratic matrix, 0, tr=0);
816  for (REGISTER unsigned i = 1; i < row; i++)
817  tr += mat[i][i];
818  return tr;
819 }
820 
821 template <typename T>
823 {
824  BCHK (dim != v.dim, MatErr, Vector size does not match matrix size, v.dim, *this);
825  TBCICOPY (vec, v.vec, T, v.dim);
826  return *this;
827 }
828 
829 /************* Arithmetics *****************/
830 
831 // unary -
832 template <typename T>
834 {
835  do_vec_neg<T> (dim, vec);
836  return *this;
837 }
838 
839 template <typename T>
841 {
842  Matrix<T> th (*this);
843  if (LIKELY(row != m.row || col != m.col))
844  return false;
845  if (LIKELY(vec == m.vec || dim == 0))
846  return true;
847  if (TBCICOMP (vec, m.vec, T, dim))
848  return false;
849  /* else */
850  return true;
851 }
852 
853 template <typename T>
855 {
856  Matrix<T> th (*this);
857  if (LIKELY(row != ts.row || col != ts.col))
858  return (ts.real_destroy(), false);
859  if (LIKELY(dim == 0)) {
860  /*ts.real_destroy();*/
861  return true;
862  }
863  if (LIKELY(ts.fac == (T)1)) {
864  if (LIKELY(vec == ts.vec))
865  return true;
866  if (TBCICOMP (vec, ts.vec, T, dim)) {
867  ts.real_destroy (); return false;
868  }
869  } else {
870  if (LIKELY(vec == ts.vec))
871  return false;
872  for (REGISTER T *p1 = vec, *p2 = ts.vec; p1 < endvec; p1++, p2++)
873  if (UNLIKELY(*p1 != *p2 * ts.fac)) {
874  ts.real_destroy (); return false;
875  }
876  }
877  ts.real_destroy (); return true;
878 }
879 
880 
881 template <typename T>
883 {
884  BCHK(row != a.row, MatErr, number of rows differ in op, a.row, *this );
885  BCHK(col != a.col, MatErr, number of cols differ in op, a.col, *this );
886  STD_SMP_TEMPLATE2V(vec_add_vec, dim, vec, a.vec);
887  return *this;
888 }
889 template <typename T>
891 {
892  BCHK(row != a.row, MatErr, number of rows differ in op, a.row, *this );
893  BCHK(col != a.col, MatErr, number of cols differ in op, a.col, *this );
894  STD_SMP_TEMPLATE2V(vec_sub_vec, dim, vec, a.vec);
895  return *this;
896 }
897 
898 template <typename T>
900 {
901  BCHK(row != a.row, MatErr, number of rows differ in op, a.row, *this );
902  BCHK(col != a.col, MatErr, number of cols differ in op, a.col, *this );
903  STD_SMP_TEMPLATE3VC(vec_add_svc, dim, vec, a.vec, a.fac);
904  a.real_destroy(); return *this;
905 }
906 template <typename T>
908 {
909  BCHK(row != a.row, MatErr, number of rows differ in op, a.row, *this );
910  BCHK(col != a.col, MatErr, number of cols differ in op, a.col, *this );
911  STD_SMP_TEMPLATE3VC(vec_sub_svc, dim, vec, a.vec, a.fac);
912  a.real_destroy(); return *this;
913 }
914 
915 // Changing a TMatrix to a Matrix destroys it ...
916 template <typename T>
918 { return this->operator += (Matrix<T>(a)); }
919 template <typename T>
921 { return this->operator -= (Matrix<T>(a)); }
922 
923 template <typename T>
925 {
926  BCHK(row != ts.row, MatErr, number of rows differ in op, ts.row, *this );
927  BCHK(col != ts.col, MatErr, number of cols differ in op, ts.col, *this );
928  STD_SMP_TEMPLATE3VC(vec_add_svc, dim, vec, ts.vec, ts.fac);
929  ts.real_destroy (); return *this;
930 }
931 template <typename T>
933 {
934  BCHK(row != ts.row, MatErr, number of rows differ in op, ts.row, *this );
935  BCHK(col != ts.col, MatErr, number of cols differ in op, ts.col, *this );
936  STD_SMP_TEMPLATE3VC(vec_sub_svc, dim, vec, ts.vec, ts.fac);
937  ts.real_destroy (); return *this;
938 }
939 
940 //Change these to operate on diag only ?
941 template <typename T>
943 {
944  STD_SMP_TEMPLATE2C(vec_add_val, dim, vec, a);
945  return *this;
946 }
947 template <typename T>
949 {
950  STD_SMP_TEMPLATE2C(vec_add_val, dim, vec, a);
951  return *this;
952 }
953 
954 template <typename T>
956 { return TSMatrix<T> (*this, a); }
957 
958 template <typename T>
960 {
961  BCHK(a==(T)0, MatErr, Matrix division by zero, 0, TSMatrix<T> (*this));
962  return TSMatrix<T> (*this, (T)1/a);
963 }
964 
965 // temporaries can be changed, because we can't refer them
966 template <typename T>
968 { return this->operator += (a); }
969 template <typename T>
971 { return this->operator -= (a); }
972 
973 template <typename T>
975 { return this->operator += (Matrix<T>(a)); }
976 template <typename T>
978 { return this->operator -= (Matrix<T>(a)); }
979 
980 template <typename T>
982 { return this->operator += (a); }
983 template <typename T>
985 { return this->operator -= (a); }
986 
987 template <typename T>
989 { return TSMatrix<T> (*this, a); }
990 
991 template <typename T>
993 {
994  BCHK((b == (T)0), MatErr, Matrix division by 0, 0, TSMatrix<T> (*this));
995  return TSMatrix<T> (*this, (T)1/b);
996 }
997 
998 //friends
999 
1000 //Change to operate on diag only ?
1001 INST(template <typename T> class TMatrix friend TMatrix<T> operator + (const T&, TMatrix<T>);)
1002 template <typename T>
1003 inline TMatrix<T> operator + (const T& a, TMatrix<T> b)
1004 {
1005  STD_SMP_TEMPLATE2C(val_add_vec, b._DIM, b._VEC, a);
1006  return b;
1007 }
1008 INST(template <typename T> class TMatrix friend TMatrix<T> operator - (const T&, TMatrix<T>);)
1009 template <typename T>
1010 inline TMatrix<T> operator - (const T& a, TMatrix<T> b)
1011 {
1012  STD_SMP_TEMPLATE2C(val_sub_vec, b._DIM, b._VEC, a);
1013  return b;
1014 }
1015 
1016 INST(template <typename T> class TMatrix friend TSMatrix<T> operator * (const T&, TMatrix<T>);)
1017 template <typename T>
1018 inline TSMatrix<T> operator * (const T& a, TMatrix<T> b)
1019 { return TSMatrix<T> (b, a); }
1020 // Commutativity is assumed here !!!
1021 
1022 
1023 //Change to operate on diag only ?
1024 INST(template <typename T> class TMatrix friend TMatrix<T> operator + (const T&, const Matrix<T>&);)
1025 template <typename T>
1026 inline TMatrix<T> operator + (const T& a, const Matrix<T>& b)
1027 {
1028  TMatrix<T> c (b._ROW, b._COL);
1029  STD_SMP_TEMPLATE3VC(val_vec_add, b._DIM, c._VEC, b._VEC, a);
1030  return c;
1031 }
1032 INST(template <typename T> class TMatrix friend TMatrix<T> operator - (const T&, const Matrix<T>&);)
1033 template <typename T>
1034 inline TMatrix<T> operator - (const T& a, const Matrix<T>& b)
1035 {
1036  TMatrix<T> c (b._ROW, b._COL);
1037  STD_SMP_TEMPLATE3VC(val_vec_sub, b._DIM, c._VEC, b._VEC, a);
1038  return c;
1039 }
1040 
1041 INST(template <typename T> class TMatrix friend TSMatrix<T> operator * (const T&, const Matrix<T>&);)
1042 template <typename T>
1043 inline TSMatrix<T> operator * (const T& a, const Matrix<T>& b)
1044 { return TSMatrix<T> (b, a); }
1045 // Commutativity is assumed here !
1046 
1047 
1048 
1049 template <typename T>
1050 inline double TMatrix<T>::fabssqr () const
1051 { Matrix<T> m (*this); return m.fabssqr (); }
1052 
1053 template <typename T>
1054 inline double fabssqr (const TMatrix<T>& tm)
1055 {
1056  return tm.fabssqr ();
1057 }
1058 
1059 
1060 template <typename T>
1062 {
1063  TMatrix<T> trm(this->col, this->row);
1064  for (unsigned r = 0; r < this->row; ++r)
1065  for (unsigned c = 0; c < this->col; ++c)
1066  trm.mat[c][r] = this->mat[r][c];
1067  this->mark_destroy();
1068  return trm;
1069 }
1070 
1071 INST(template <typename T> class TMatrix friend TMatrix<T> transpose(const TMatrix<T>& tm);)
1072 template <typename T>
1074 {
1075  return tm.transposed_copy();
1076 }
1077 
1078 template <typename T>
1080 {
1081  if (this->col != this->row) {
1082  // for non quadratic shape, doing inplace swap ops is too hard
1083  Matrix<T> transmat(this->transposed_copy());
1084  return this->swap(transmat);
1085  } else {
1086  // do in place swap ops
1087  for (unsigned r = 1; r < this->row; ++r)
1088  for (unsigned c = 0; c < r; ++c)
1089  SWAP(this->mat[r][c], this->mat[c][r]);
1090  return *this;
1091  }
1092 }
1093 
1095 
1097 
1098 INST(template <typename T> class TBCI__ Matrix friend double fabs (const TBCI__ TMatrix<T>&);)
1099 template<typename T>
1100 inline double fabs (const TBCI__ TMatrix<T>& tm)
1101 { return tm.fabs (); }
1102 
1103 INST(template <typename T> class TBCI__ Matrix friend double fabs (const TBCI__ Matrix<T>&);)
1104 template<typename T>
1105 inline double fabs (const TBCI__ Matrix<T>& m)
1106 { return m.fabs (); }
1107 
1109 
1111 
1112 //-------------------------------------------------------------
1116 //-------------------------------------------------------------
1117 template <typename T>
1118 class TSMatrix : public Matrix_Sig<T> //: public TMatrix
1119 {
1120  protected:
1121  T* vec;
1122  unsigned long dim;
1123  unsigned int row, col;
1124  T** mat;
1126  T fac ALIGN(MIN_ALIGN2); //factor
1127  bool mut; //mutability: does vec point to changeable (non-refered) data ?
1128 
1129  void real_destroy ();
1130  void clone (bool = false, TMatrix<T>* = 0);
1131 #if 1 //def HAVE_GCC295_FRIEND_BUG
1132  public:
1133 #endif
1134  void detach (TMatrix<T>* = 0);
1135 
1136  typedef T* Tptr;
1137  public:
1138 
1139  friend class TMatrix<T>;
1140  friend class Matrix<T>;
1141 
1142  typedef T value_type;
1143  typedef T element_type;
1144  typedef T aligned_value_type TALIGN(MIN_ALIGN2);
1145 
1146 #if 1 //def HAVE_GCC295_FRIEND_BUG
1147  T* getvec () const { return vec; }
1148  T* getendvec () const { return endvec; }
1149  T& getfac () { return fac; }
1150  const T& getfac () const { return fac; }
1151 #endif
1152 
1153  TSMatrix () : vec((T*)0), dim(0), mat((T**)0), endvec((T*)0), mut(false) {}
1154  // empty destructor: TSMatrix will never be destroyed but explicitly !!!
1156 
1157  TSMatrix (const TMatrix<T>& tm, const T& f = (T)1)
1158  : vec(tm.vec), dim(tm.dim), row(tm.row), col(tm.col),
1159  mat(tm.mat), endvec(tm.endvec), fac(f), mut(true) {}
1160  TSMatrix (const Matrix<T>& m, const T& f = (T)1)
1161  : vec(m.vec), dim(m.dim), row(m.row), col(m.col),
1162  mat(m.mat), endvec(m.endvec), fac(f), mut(false) {}
1164  : vec(ts.vec), dim(ts.dim), row(ts.row), col(ts.col),
1165  mat(ts.mat), endvec(ts.endvec), fac(ts.fac), mut(ts.mut) {}
1166 
1167  // allow instantiation (Matrix_Sig)
1168  /*virtual*/ static const char* mat_info () { return ("TSMatrix"); }
1169 
1170  T operator () (const unsigned int r, const unsigned int c) HOT
1171  { T val = mat[r][c] * fac; real_destroy (); return val; }
1172 
1173  TSMatrix<T>& eval (TMatrix<T>* = 0);
1174 
1175  // These operations are very cheap now
1177  { real_destroy (); dim = ts.dim; row = ts.row; col = ts.col;
1178  mat = ts.mat; vec = ts.vec; endvec = ts.endvec;
1179  fac = ts.fac; mut = ts.mut; return *this; }
1180  TSMatrix<T>& operator = (const TMatrix<T>& tm)
1181  { real_destroy (); dim = tm.dim; row = tm.row; col = tm.col;
1182  mat = tm.mat; vec = tm.vec; endvec = tm.endvec;
1183  fac = (T)1; mut = true; return *this; }
1184 
1185  TSMatrix<T>& operator *= (const T& f) { fac *= f; return *this; }
1186  TSMatrix<T>& operator /= (const T& f) { fac /= f; return *this; }
1187  TSMatrix<T>& operator * (const T& f) { fac *= f; return *this; }
1188  TSMatrix<T>& operator / (const T& f) { fac /= f; return *this; }
1189 #ifndef HAVE_GCC295_FRIEND_BUG
1190  friend NOINST TSMatrix<T> FRIEND_TBCI__ operator * FGD (const T&, TSMatrix<T>);
1191 #endif
1192  TSMatrix<T>& operator - () { fac *= (T)(-1); return *this; }
1193 
1194  // Now for the more complicated
1195  TMatrix<T> operator + (const Matrix<T>&);
1196  TMatrix<T> operator + (const TMatrix<T>&);
1197  TMatrix<T> operator + (TSMatrix<T>);
1198  TMatrix<T> operator + (const T&);
1199  TMatrix<T> operator - (const Matrix<T>&);
1200  TMatrix<T> operator - (const TMatrix<T>&);
1201  TMatrix<T> operator - (TSMatrix<T>);
1202  TMatrix<T> operator - (const T&);
1203 
1204 #ifndef HAVE_GCC295_FRIEND_BUG
1205  // functions to work around the need for friends (gcc-2.95 hack)
1206  friend NOINST TMatrix<T> FRIEND_TBCI__ operator + FGD (const T&, const TSMatrix<T>&);
1207  friend NOINST TMatrix<T> FRIEND_TBCI__ operator - FGD (const T&, const TSMatrix<T>&);
1208 #endif
1209 
1210  TMatrix<T> operator * (const Matrix<T>& m);
1211  TMatrix<T> operator * (TMatrix<T> tm);
1212  TVector<T> operator * (const Vector<T>& v);
1214 
1215  bool operator == (const Matrix<T>&);
1216  bool operator != (const Matrix<T>& m) { return !(*this == m); }
1217 
1218  bool operator == (TSMatrix<T>&);
1219  bool operator != (TSMatrix<T>& ts) { return !(*this == ts); }
1220 
1221  bool operator == (TMatrix<T>& tm) { Matrix<T> m(tm); return (*this == m); }
1222  bool operator != (TMatrix<T>& tm) { return !(*this == tm); }
1223 
1224  double fabssqr ();
1225  double fabs () { return GLBL__ MATH__ sqrt (fabssqr ()); }
1226 
1227  unsigned long size () const { return dim; }
1228 };
1229 
1230 template <typename T>
1232 {
1233  if (LIKELY(!mut || !dim))
1234  return;
1236 }
1237 
1238 template <typename T>
1239 inline void TSMatrix<T>::detach (TMatrix<T>* tm)
1240 {
1241  if (LIKELY((!tm && mut) || !dim))
1242  return;
1243  if (!tm) { //mut = false
1244  vec = NEW(T, dim); if (!vec) {
1245  dim = 0; mat = (T**)0; return;
1246  }
1247  mat = NEW(Tptr,row); if (!mat) {
1248  TBCIDELETE(T, vec, dim); dim = 0; return;
1249  }
1250  for (REGISTER unsigned r = 0; r < row; r++)
1251  mat[r] = vec + r*col;
1252  endvec = vec + dim;
1253  } else { //tm = true, mut = ?
1254  vec = tm->vec; mat = tm->mat; endvec = tm->endvec;
1255  }
1256  mut = true;
1257 }
1258 
1259 template <typename T>
1260 void TSMatrix<T>::clone (bool evl, TMatrix<T>* tm)
1261 {
1262  if (LIKELY((mut && !tm)|| !dim))
1263  return;
1264  T* oldv = vec; T** oldm = mat; bool omut = mut;
1265  detach (tm);
1266  if (evl && fac != (T)1) {
1267  STD_SMP_TEMPLATE3VC(vec_val_mul, dim, vec, oldv, fac);
1268  fac = (T)1;
1269  } else
1270  TBCICOPY (vec, oldv, T, dim);
1271  if (tm && omut) {
1272  TBCIDELETE(T, oldv, dim); TBCIDELETE(Tptr, oldm, row);
1273  }
1274 }
1275 
1276 
1277 
1278 //creates mutable evaluated TSMatrix (can be easily converted to TMatrix)
1279 template <typename T>
1280 inline TSMatrix<T>& TSMatrix<T>::eval (TMatrix<T>* tm)
1281 {
1282  if (mut && !tm) {
1283  if (fac != (T)1) {
1284  STD_SMP_TEMPLATE2C(vec_mul_val, dim, vec, fac);
1285  fac = (T)1;
1286  }
1287  } else
1288  clone (true, tm);
1289  return (*this);
1290 }
1291 
1292 
1293 // Arithmetics
1294 template <typename T>
1295 inline TMatrix<T> TSMatrix<T>::operator + (const Matrix<T>& m)
1296 {
1297  BCHK(row != m.row || col != m.col, MatErr, Op + on diff size Mats, m.row, TMatrix<T> (*this));
1298  TSMatrix<T> ts (*this); ts.detach ();
1299  STD_SMP_TEMPLATE4V(svc_vec_add, dim, ts.vec, vec, m.vec, fac);
1300  ts.fac = (T)1; return TMatrix<T> (ts);
1301 }
1302 template <typename T>
1303 inline TMatrix<T> TSMatrix<T>::operator - (const Matrix<T>& m)
1304 {
1305  BCHK(row != m.row || col != m.col, MatErr, Op - on diff size Mats, m.row, TMatrix<T> (*this));
1306  TSMatrix<T> ts (*this); ts.detach ();
1307  STD_SMP_TEMPLATE4V(svc_vec_sub, dim, ts.vec, vec, m.vec, fac);
1308  ts.fac = (T)1; return TMatrix<T> (ts);
1309 }
1310 
1311 template <typename T>
1312 inline TMatrix<T> TSMatrix<T>::operator + (const TMatrix<T>& tm)
1313 {
1314  BCHK(row != tm.row || col != tm.col, MatErr, Op + on diff size Mats, tm.row, tm);
1315  STD_SMP_TEMPLATE3VC(vec_add_svc, dim, tm.vec, vec, fac);
1316  real_destroy (); return tm;
1317 }
1318 template <typename T>
1319 inline TMatrix<T> TSMatrix<T>::operator - (const TMatrix<T>& tm)
1320 {
1321  BCHK(row != tm.row || col != tm.col, MatErr, Op - on diff size Mats, tm.row, tm);
1322  STD_SMP_TEMPLATE3VC(vec_sub_svc_inv, dim, tm.vec, vec, fac);
1323  real_destroy (); return tm;
1324 }
1325 
1326 template <typename T>
1328 {
1329  BCHK(row != ts.row || col != ts.col, MatErr, Op op on diff size Mats, ts.row, TMatrix<T> (*this));
1330  TSMatrix<T> tm;
1331  if (LIKELY(!mut && ts.mut))
1332  tm = ts;
1333  else {
1334  tm = *this; tm.detach ();
1335  }
1336  STD_SMP_TEMPLATE5(svc_svc_add, dim, tm.vec, vec, ts.vec, fac, ts.fac);
1337  if (LIKELY(!mut && ts.mut))
1338  real_destroy ();
1339  else
1340  ts.real_destroy ();
1341  tm.fac = (T)1;
1342  return TMatrix<T> (tm);
1343 }
1344 
1345 template <typename T>
1347 {
1348  BCHK(row != ts.row || col != ts.col, MatErr, Op op on diff size Mats, ts.row, TMatrix<T> (*this));
1349  TSMatrix<T> tm;
1350  if (LIKELY(!mut && ts.mut))
1351  tm = ts;
1352  else {
1353  tm = *this; tm.detach ();
1354  }
1355  STD_SMP_TEMPLATE5(svc_svc_sub, dim, tm.vec, vec, ts.vec, fac, ts.fac);
1356  if (LIKELY(!mut && ts.mut))
1357  real_destroy ();
1358  else
1359  ts.real_destroy ();
1360  tm.fac = (T)1;
1361  return TMatrix<T> (tm);
1362 }
1363 
1364 template <typename T>
1365 inline TMatrix<T> TSMatrix<T>::operator + (const T& a)
1366 {
1367  TSMatrix<T> ts (*this); ts.detach ();
1368  STD_SMP_TEMPLATE4C(svc_val_add, dim, ts.vec, vec, fac, a);
1369  ts.fac = (T)1; return TMatrix<T> (ts);
1370 }
1371 
1372 template <typename T>
1373 inline TMatrix<T> TSMatrix<T>::operator - (const T& a)
1374 {
1375  TSMatrix<T> ts (*this); ts.detach ();
1376  STD_SMP_TEMPLATE4C(svc_val_sub, dim, ts.vec, vec, fac, a);
1377  ts.fac = (T)1; return TMatrix<T> (ts);
1378 }
1379 
1380 // operate on diag only?
1381 INST(template <typename T> class TSMatrix friend TMatrix<T> operator + (const T&, const TSMatrix<T>&);)
1382 template <typename T>
1383 inline TMatrix<T> operator + (const T& a, const TSMatrix<T>& ts)
1384 {
1385  TSMatrix<T> tm (ts); tm.detach ();
1386  STD_SMP_TEMPLATE4C(val_svc_add, tm._DIM, tm._VEC, ts._VEC, a, ts._FAC);
1387  tm._FAC = (T)1; return TMatrix<T> (tm);
1388 }
1389 INST(template <typename T> class TSMatrix friend TMatrix<T> operator - (const T&, const TSMatrix<T>&);)
1390 template <typename T>
1391 inline TMatrix<T> operator - (const T& a, const TSMatrix<T>& ts)
1392 {
1393  TSMatrix<T> tm (ts); tm.detach ();
1394  STD_SMP_TEMPLATE4C(val_svc_sub, tm._DIM, tm._VEC, ts._VEC, a, ts._FAC);
1395  tm._FAC = (T)1; return TMatrix<T> (tm);
1396 }
1397 
1398 
1399 template <typename T>
1400 TMatrix<T> TSMatrix<T>::operator * (const Matrix<T>& m)
1401 {
1402  TMatrix<T> c (row, m.col);
1403  BCHK(col != m.row, MatErr, Illegal sizes in TSMat-Mat multiplication, 0, (real_destroy(), c));
1404  T tmp ALIGN(MIN_ALIGN2);
1405  // TODO: Exact summation
1406  for (unsigned i=0; i<row; i++) {
1407  for (unsigned j=0; j<m.col; j++) {
1408  tmp = mat[i][0] * m.mat[0][j];
1409  for (REGISTER unsigned l=1; l<col; l++)
1410  tmp += mat[i][l] * m.mat[l][j];
1411  c.mat[i][j] = tmp * fac;
1412  }
1413  }
1414  real_destroy (); return c;
1415 }
1416 
1417 template <typename T>
1418 TMatrix<T> TSMatrix<T>::operator * (TMatrix<T> tm)
1419 {
1420  TMatrix<T> c (row, tm.col);
1421  BCHK(col != tm.row, MatErr, Illegal sizes in TSMat-TMat multiplication, 0, (real_destroy(), c));
1422  T tmp ALIGN(MIN_ALIGN2);
1423  // TODO: Exact summation
1424  for (unsigned i=0; i<row; i++) {
1425  for (unsigned j=0; j<tm.col; j++) {
1426  tmp = mat[i][0] * tm.get(0,j);
1427  for (REGISTER unsigned l=1; l<col; l++)
1428  tmp += mat[i][l] * tm.get(l,j);
1429  c.mat[i][j] = tmp * fac;
1430  }
1431  }
1432  real_destroy (); tm.mark_destroy(); return c;
1433 }
1434 
1435 template <typename T>
1437 {
1438  TVector<T> tv (row);
1439  BCHK (v.size() != col, MatErr, multiply TSMatrix w/ Vector: wrong config, v.size(), (real_destroy(), tv));
1440  // TODO: Exact summation
1441  for (unsigned r=0; r<row; r++) {
1442  ALIGN3(REGISTER T el, mat[r][0] * v(0), MIN_ALIGN2);
1443  for (REGISTER unsigned c=1; c<col; c++)
1444  el += mat[r][c] * v(c);
1445  tv.set (el * fac, r);
1446  }
1447  real_destroy (); return tv;
1448 }
1449 
1450 template <typename T>
1452 {
1453  TVector<T> tv (row);
1454  BCHK (v.size() != col, MatErr, multiply TSMatrix w/ TVector: wrong config, v.size(), (real_destroy(), tv));
1455  // TODO: Exact summation
1456  for (unsigned r=0; r<row; r++) {
1457  ALIGN3(REGISTER T el, mat[r][0] * v.get(0), MIN_ALIGN2);
1458  for (REGISTER unsigned c=1; c<col; c++)
1459  el += mat[r][c] * v.get(c);
1460  tv.set (el * fac, r);
1461  }
1462  real_destroy(); v.destroy(); return tv;
1463 }
1464 
1465 
1466 template <typename T>
1467 bool TSMatrix<T>::operator == (const Matrix<T>& m)
1468 {
1469  if (LIKELY(row != m.row || col != m.col)) {
1470  real_destroy (); return false;
1471  }
1472  if (LIKELY(dim == 0)) {
1473  /*real_destroy();*/ return true;
1474  }
1475  if (LIKELY(fac == (T)1)) {
1476  if (LIKELY(vec == m.vec))
1477  return true;
1478  if (TBCICOMP (vec, m.vec, T, dim)) {
1479  real_destroy (); return false;
1480  }
1481  } else {
1482  if (LIKELY(vec == m.vec))
1483  return false;
1484  for (REGISTER T *p1 = vec, *p2 = m.vec; p1 < endvec; p1++, p2++)
1485  if (UNLIKELY(*p1 * fac != *p2)) {
1486  real_destroy (); return false;
1487  }
1488  }
1489  real_destroy (); return true;
1490 }
1491 
1492 template <typename T>
1494 {
1495  if (LIKELY(row != ts.row || col != ts.col)) {
1496  real_destroy (); ts.real_destroy (); return false;
1497  }
1498  if (LIKELY(dim == 0)) {
1499  /*real_destroy(); ts.real_destroy();*/
1500  return true;
1501  }
1502  if (LIKELY(fac == ts.fac)) {
1503  if (LIKELY(vec == ts.vec)) {
1504  real_destroy (); return true;
1505  }
1506  if (TBCICOMP (vec, ts.vec, T, dim)) {
1507  real_destroy (); ts.real_destroy (); return false;
1508  }
1509  } else {
1510  if (LIKELY(vec == ts.vec)) {
1511  real_destroy (); return false;
1512  }
1513  for (REGISTER T *p1 = vec, *p2 = ts.vec; p1 < endvec; p1++, p2++)
1514  if (UNLIKELY(*p1 * fac != *p2)) {
1515  real_destroy (); ts.real_destroy (); return false;
1516  }
1517  }
1518  real_destroy (); ts.real_destroy ();
1519  return true;
1520 }
1521 
1522 
1523 INST(template <typename T> class TSMatrix friend TSMatrix<T> operator * (const T&, TSMatrix<T>);)
1524 template <typename T>
1525 inline TSMatrix<T> operator * (const T& f, TSMatrix<T> ts)
1526 { ts._FAC = f * ts._FAC; return ts; }
1527 
1528 
1529 template <typename T>
1531 {
1532  double res = 0.0;
1533  if (do_exactsum())
1534  do_vec_fabssqr_exact (dim, vec, res);
1535  else
1536  do_vec_fabssqr_quick (dim, vec, res);
1537  res *= GLBL2__ TBCI__ fabssqr (fac);
1538  real_destroy ();
1539  return res;
1540 }
1541 
1542 template <typename T>
1543 inline double fabssqr (TSMatrix<T>& tsm)
1544 {
1545  return tsm.fabssqr ();
1546 }
1547 
1549 
1551 
1552 INST(template <typename T> class TBCI__ TSMatrix friend double fabs (TBCI__ TSMatrix<T>&);)
1553 template <typename T>
1554 double fabs (TBCI__ TSMatrix<T>& ts)
1555 { return ts.fabs (); }
1556 
1558 
1560 //---------------------------------------------------------------
1572 //---------------------------------------------------------------
1573 template <typename T>
1574 class Matrix : public TMatrix<T>
1575 {
1576 
1577  public:
1578 
1579  friend class TSMatrix<T>;
1580 
1581  typedef T value_type;
1582  typedef T element_type;
1583  typedef T aligned_value_type TALIGN(MIN_ALIGN2);
1584 
1585  // constructor, destructor
1586 
1587  explicit Matrix (const unsigned d=0)
1588  : TMatrix<T> (d)
1589  { /* this->freeable = 1; */ }
1590  Matrix (const unsigned r, const unsigned c)
1591  : TMatrix<T> (r, c)
1592  { /* this->freeable = 1; */ }
1593  Matrix (const T& v, const unsigned r, const unsigned c)
1594  : TMatrix<T> (v, r, c)
1595  { /* this->freeable = 1; */ }
1596  Matrix (const Vector<T>& v, const enum rowcolvec r = colvec)
1597  : TMatrix<T> (v, r)
1598  { /* this->freeable = 1; */ }
1599 
1601  Matrix (const Matrix<T>& m)
1602  : TMatrix<T> (m)
1603  { /* this->freeable = 1; */ }
1605  Matrix (const TMatrix<T>& tm) HOT
1606  : TMatrix<T> (tm)
1607  { /* this->freeable = 1; */ }
1608  Matrix (const TSMatrix<T>& ts)
1609  : TMatrix<T> (ts)
1610  { /* this->freeable = 1; */ }
1611 
1612  ~Matrix () { this->freeable = 1; /* Let ~TMatrix do the job */ }
1613 
1614  // allow instantiation (Matrix_Sig)
1615  /*virtual*/ static const char* mat_info () { return ("Matrix"); }
1616 #ifndef HAVE_PROMOTION_BUG
1617  // Promotion (only explicit)
1618  template <typename U>
1619  explicit Matrix (const Matrix<U>& m)
1620  : TMatrix<T> (m)
1621  { /* this->freeable = 1; */ }
1622  template <typename U>
1623  explicit Matrix (const TMatrix<U>& tm)
1624  : TMatrix<T> (tm)
1625  { /* this->freeable = 1; */ }
1626  // basics
1627 #endif
1628 
1630  typename tbci_traits<T>::const_refval_type
1631  operator () (const unsigned int, const unsigned int) const HOT;
1633  T& operator () (const unsigned int, const unsigned int) HOT;
1635  TVector<T> operator () (const unsigned int) const;
1636 
1638  Matrix<T>& operator = (const Matrix<T>& m)
1639  { this->TMatrix<T>::operator = (m); return *this; }
1640  Matrix<T>& operator = (const TMatrix<T>& tm)
1641  { this->TMatrix<T>::operator = (tm); return *this; }
1642  Matrix<T>& operator = (TSMatrix<T> ts)
1643  { TMatrix<T>(this->TMatrix<T>::operator = (ts)); return *this; }
1644  Matrix<T>& operator = (const T& v)
1645  { this->TMatrix<T>::operator = (v); return *this; }
1646 
1647  Matrix<T>& resize (const unsigned r, const unsigned c)
1648  { this->TMatrix<T>::resize (r, c); return *this; }
1649  Matrix<T>& resize (const unsigned d)
1650  { return this->resize (d, d); }
1651  Matrix<T>& resize (const T& v, const unsigned r, const unsigned c)
1652  { this->TMatrix<T>::resize (v, r, c); return *this; }
1653  Matrix<T>& resize (const Matrix<T>& m)
1654  { this->TMatrix<T>::resize (m); return *this; }
1655  Matrix<T>& fill (const T& v = (T) 0)
1656  { this->TMatrix<T>::fill (v); return *this; }
1657  Matrix<T>& fill (const Vector<T>& v)
1658  { this->TMatrix<T>::fill (v); return *this; }
1659  Matrix<T>& setunit (const T& f = (T) 1)
1660  { this->TMatrix<T>::setunit (f); return *this; }
1661  Matrix<T>& clear ()
1662  { this->TMatrix<T>::clear (); return *this; }
1663 
1664  // How to make a Vector from a Matrix ...
1665  friend /*inline*/ BVector<T>& FRIEND_TBCI2__ bvfillm FGD (BVector<T>&, const Matrix<T>& m);
1666 
1667 
1668  // assignment ops (do we really need em ?)
1669  // Seems we have to make sure, that a Matrix and no TMatrix
1670  // is returned; otherwise there's danger to be destroyed
1671  Matrix<T>& operator += (const Matrix<T>& a)
1672  { this->TMatrix<T>::operator += (a); return *this; }
1673  Matrix<T>& operator -= (const Matrix<T>& a)
1674  { this->TMatrix<T>::operator -= (a); return *this; }
1675  Matrix<T>& operator += (TMatrix<T> a)
1676  { this->TMatrix<T>::operator += (a); return *this; }
1677  Matrix<T>& operator -= (TMatrix<T> a)
1678  { this->TMatrix<T>::operator -= (a); return *this; }
1679  Matrix<T>& operator += (TSMatrix<T> a)
1680  { this->TMatrix<T>::operator += (a); return *this; }
1681  Matrix<T>& operator -= (TSMatrix<T> a)
1682  { this->TMatrix<T>::operator -= (a); return *this; }
1683  Matrix<T>& operator += (const T& a)
1684  { this->TMatrix<T>::operator += (a); return *this; }
1685  Matrix<T>& operator -= (const T& a)
1686  { this->TMatrix<T>::operator -= (a); return *this; }
1687  Matrix<T>& operator *= (const T& a)
1688  /* { TMatrix<T>(this->TMatrix<T>::operator *= (a)); return *this; } */;
1689  Matrix<T>& operator /= (const T& a)
1690  /* { TMatrix<T>(this->TMatrix<T>::operator /= (a)); return *this; } */;
1691 
1692 
1693  // basic operations
1694  TMatrix<T> operator - () const { return -(TMatrix<T> (*this)); }
1695 
1696  TMatrix<T> operator + (const Matrix<T>&) const;
1697  TMatrix<T> operator - (const Matrix<T>&) const;
1698  TMatrix<T> operator * (const Matrix<T>&) const;
1699 
1700  TMatrix<T>& operator + (TMatrix<T>&) const;
1701  TMatrix<T>& operator - (TMatrix<T>&) const;
1702  TMatrix<T> operator * (TMatrix<T>&) const;
1703 
1704  TMatrix<T> operator + (TSMatrix<T>&) const;
1705  TMatrix<T> operator - (TSMatrix<T>&) const;
1706  TMatrix<T> operator * (TSMatrix<T>&) const;
1707 
1708  TMatrix<T> operator + (const T&) const;
1709  TMatrix<T> operator - (const T&) const;
1710  TSMatrix<T> operator * (const T&) const;
1711  TSMatrix<T> operator / (const T&) const;
1712 
1713  TVector<T> operator * (const Vector<T>&) const HOT;
1714  TVector<T> operator * (TVector<T>) const HOT;
1715  TVector<T> operator * (const TSVector <T>& tsv) const HOT;
1716  TVector<T> transMult (const Vector<T>&) const HOT;
1717  //friend TMatrix<T> operator + FGD (const T&, const Matrix<T>&);
1718  //friend TMatrix<T> operator - FGD (const T&, const Matrix<T>&);
1719  //friend TMatrix<T> operator * FGD (const T&, const Matrix<T>&);
1720 
1721  bool operator == (const Matrix<T>& m) const;
1722  bool operator != (const Matrix<T>& m) const
1723  { return !(*this == m); }
1724 
1725  bool operator == (TMatrix<T> tm) const
1726  { Matrix<T> m (tm); return (*this == m); }
1727  bool operator != (TMatrix<T> tm) const
1728  { return !(*this == tm); }
1729 
1730  bool operator == (TSMatrix<T>) const;
1731  bool operator != (TSMatrix<T> ts) const
1732  { return !(*this == ts); }
1733 
1735  Matrix<T>& mult_rows (const Vector<T>&);
1736  Matrix<T>& div_rows (const Vector<T>&);
1737  Matrix<T>& mult_row (const T&, const unsigned);
1738  Matrix<T>& div_row (const T&, const unsigned);
1739 
1740  // io-streams
1741 
1742  friend STD__ ostream& operator << FGDT (STD__ ostream&, const Matrix<T>&);
1743  friend STD__ istream& operator >> FGDT (STD__ istream&, Matrix<T>&);
1744 
1745  // solvers
1746  friend NOINST char FRIEND_TBCI2__ gaussj FGD (Matrix<T>&, Matrix<T>&);
1747 
1748  //friend int lu_solver(..);
1749 
1750  //misc
1751  double fabssqr () const;
1752  double fabs () const { return GLBL__ MATH__ sqrt (fabssqr()); }
1753 };
1754 
1755 
1756 // definitions
1757 
1758 template <typename T>
1759 inline TMatrix<T>& TMatrix<T>::swap (TMatrix<T>& m)
1760 {
1761  //BCHK(this->row != m.row || this->col != m.col, MatErr, Swapping Matrices w/ different layout, m.row, *this);
1762  SWAP(this->dim, m.dim);
1763  SWAP(this->row, m.row);
1764  //SWAP(this->col, m.col);
1765  unsigned int tcol = this->col; this->col = m.col; m.col = tcol;
1766  SWAP(this->mat, m.mat);
1767  SWAP(this->vec, m.vec); SWAP(this->endvec, m.endvec);
1768  // Hmmm, swap freeability???
1769  //SWAP(this->freeable, m.freeable);
1770  return *this;
1771 }
1772 
1773 template <typename T>
1774 inline typename tbci_traits<T>::const_refval_type
1775 Matrix<T>::operator () (const unsigned int i, const unsigned int j) const
1776 {
1777  EXPCHK(i>=this->row, MatErr, Illegal row index, i, this->mat[0][0]);
1778  EXPCHK(j>=this->col, MatErr, illegal col index, j, this->mat[0][0]);
1779  return this->mat[i][j];
1780 }
1781 
1782 template <typename T>
1783 inline T& Matrix<T>::operator () (const unsigned int i, const unsigned int j)
1784 {
1785  EXPCHK(i>=this->row, MatErr, Illegal row index, i, this->mat[0][0]);
1786  EXPCHK(j>=this->col, MatErr, illegal col index, j, this->mat[0][0]);
1787  return this->mat[i][j];
1788 }
1789 
1790 template <typename T>
1791 inline TVector<T> Matrix<T>::operator () (const unsigned int i) const
1792 {
1793  TVector<T> v(this->col);
1794  BCHK(i>= this->row, MatErr, Illegal row index, i, v);
1795  TBCICOPY (v.vec, this->mat[i], T, this->col);
1796  return v;
1797 }
1798 
1799 
1800 template <typename T>
1801 STD__ ostream& operator << (STD__ ostream& os, const Matrix<T>& m)
1802 {
1803  for (unsigned r=0; r<m.row; r++)
1804 #if 0
1805  os << m(i) << "\n";
1806 #else
1807  {
1808  for (unsigned c=0; c<m.col; c++)
1809  os << m(r,c) << " ";
1810  os << "\n";
1811  }
1812 #endif
1813  return os;
1814 }
1815 
1816 template <typename T>
1817 STD__ istream& operator >> (STD__ istream& in, Matrix<T>& m)
1818 {
1819  Vector<T> buf(m.col);
1820 
1821  for (unsigned i=0; i<m.row; i++)
1822  {
1823  in >> buf;
1824  m.set_row (buf, i);
1825  }
1826  return in;
1827 }
1828 
1829 INST(template <typename T> class TMatrix friend STD__ ostream& operator << (STD__ ostream& os, TMatrix<T> tm);)
1830 template <typename T>
1831 STD__ ostream& operator << (STD__ ostream& os, TMatrix<T> tm)
1832 {
1833  Matrix<T> m(tm);
1834  return os << m;
1835 }
1836 
1837 INST(template <typename T> class TSMatrix friend STD__ ostream& operator << (STD__ ostream& os, const TSMatrix<T>& ts);)
1838 template <typename T>
1839 STD__ ostream& operator << (STD__ ostream& os, const TSMatrix<T>& ts)
1840 {
1841  return os << Matrix<T>(ts);
1842 }
1843 
1844 
1845 /************** Arithmetics ***************/
1846 
1847 //Change these to operate on diag only ?
1848 template <typename T>
1849 inline Matrix<T>& Matrix<T>::operator *= (const T& a)
1850 {
1851  STD_SMP_TEMPLATE2C(vec_mul_val, this->dim, this->vec, a);
1852  return *this;
1853 }
1854 template <typename T>
1855 inline Matrix<T>& Matrix<T>::operator /= (const T& a)
1856 {
1857  STD_SMP_TEMPLATE2C(vec_div_val, this->dim, this->vec, a);
1858  return *this;
1859 }
1860 
1861 
1862 //change these to operate on diag only ?
1863 template <typename T>
1864 inline TMatrix<T> Matrix<T>::operator + (const T& a) const
1865 {
1866  TMatrix<T> t (this->row, this->col);
1867  STD_SMP_TEMPLATE3VC(vec_val_add, this->dim, t.vec, this->vec, a);
1868  return t;
1869 }
1870 template <typename T>
1871 inline TMatrix<T> Matrix<T>::operator - (const T& a) const
1872 {
1873  TMatrix<T> t (this->row, this->col);
1874  STD_SMP_TEMPLATE3VC(vec_val_sub, this->dim, t.vec, this->vec, a);
1875  return t;
1876 }
1877 
1878 template <typename T>
1879 inline TSMatrix<T> Matrix<T>::operator * (const T& a) const
1880 { return TSMatrix<T> (*this, a); }
1881 
1882 template <typename T>
1883 inline TSMatrix<T> Matrix<T>::operator / (const T& a) const
1884 {
1885  BCHK (a==(T)0, MatErr, Divide Mat by 0, 0, *this);
1886  return TSMatrix<T> (*this, (T)1/a);
1887 }
1888 
1889 template <typename T>
1890 inline TMatrix<T> Matrix<T>::operator + (const Matrix<T>& a) const
1891 {
1892  TMatrix<T> t (this->row, this->col);
1893  BCHK(this->dim != a.dim, MatErr, Operator + on diff size matrices, a.dim, t);
1894  STD_SMP_TEMPLATE3VV(vec_vec_add, this->dim, t.vec, this->vec, a.vec);
1895  return t;
1896 }
1897 template <typename T>
1898 inline TMatrix<T> Matrix<T>::operator - (const Matrix<T>& a) const
1899 {
1900  TMatrix<T> t (this->row, this->col);
1901  BCHK(this->dim != a.dim, MatErr, Operator - on diff size matrices, a.dim, t);
1902  STD_SMP_TEMPLATE3VV(vec_vec_sub, this->dim, t.vec, this->vec, a.vec);
1903  return t;
1904 }
1905 
1906 template <typename T>
1907 inline TMatrix<T>& Matrix<T>::operator + (TMatrix<T>& a) const
1908 {
1909  BCHK(this->dim != a.dim, MatErr, Applying + on diff. size matrices, a.dim, a);
1910  STD_SMP_TEMPLATE2V(vec_add_vec, this->dim, a.vec, this->vec);
1911  return a;
1912 }
1913 template <typename T>
1914 inline TMatrix<T>& Matrix<T>::operator - (TMatrix<T>& a) const
1915 {
1916  BCHK(this->dim != a.dim, MatErr, Applying - on diff. size matrices, a.dim, a);
1917  STD_SMP_TEMPLATE2V(vec_sub_vec_inv, this->dim, a.vec, this->vec);
1918  return a;
1919 }
1920 
1921 template <typename T>
1922 inline TMatrix<T> Matrix<T>::operator + (TSMatrix<T>& ts) const
1923 {
1924  BCHK(this->dim != ts.dim, MatErr, Applying + on diff. size matrices, ts.dim, (ts.real_destroy(),TMatrix<T> (*this)) );
1925  TSMatrix<T> tm (ts); tm.detach ();
1926  STD_SMP_TEMPLATE4V(vec_svc_add, this->dim, tm.vec, this->vec, ts.vec, ts.fac);
1927  tm.fac = (T)1; return TMatrix<T> (tm);
1928 }
1929 template <typename T>
1930 inline TMatrix<T> Matrix<T>::operator - (TSMatrix<T>& ts) const
1931 {
1932  BCHK(this->dim != ts.dim, MatErr, Applying - on diff. size matrices, ts.dim, (ts.real_destroy(),TMatrix<T> (*this)) );
1933  TSMatrix<T> tm (ts); tm.detach ();
1934  STD_SMP_TEMPLATE4V(vec_svc_sub, this->dim, tm.vec, this->vec, ts.vec, ts.fac);
1935  tm.fac = (T)1; return TMatrix<T> (tm);
1936 }
1937 
1938 /* costs of mat vec mult; ra = a.row, ca = a.col, cb = b.col */
1939 #define COST_MATMAT_OLD(ra,ca,cb) (ra*cb*(COST_UNIT_STORE+COST_LOOP \
1940  +ca*(3*COST_UNIT_LOAD/*+2*COST_CALL*/+COST_NU_LOAD+COST_MULT+COST_ADD+COST_LOOP)))
1941 #define COST_MATMAT_NEW(ra,ca,cb) (ra*cb*COST_MEMSET+ra*ca*(2*COST_UNIT_LOAD+COST_LOOP \
1942  /*+COST_CALL*/+cb*(3*COST_UNIT_LOAD/*+COST_CALL*/+COST_UNIT_STORE+COST_ADD+COST_MULT+COST_LOOP)))
1943 #ifdef OLD_MAT_MAT_MULT
1944 # define COST_MATMAT(ra,ca,cb) COST_MATMAT_OLD(ra,ca,cb)
1945 #else
1946 # define COST_MATMAT(ra,ca,cb) COST_MATMAT_NEW(ra,ca,cb)
1947 #endif
1948 
1949 // Matrix multiplication
1950 INST(template <typename T> class TMatrix friend void do_mat_mat_mult (const unsigned, const unsigned, \
1951  TMatrix<T> *, const Matrix<T> *, const Matrix<T> *);)
1952 
1953 #include "matrix_kernels.h"
1954 
1955 #if defined(SMP) && !defined(NOSMP_MATVEC)
1956 
1957 template <typename T>
1958 inline void job_mat_mat_mult (struct thr_ctrl *tc)
1959 {
1960  do_mat_mat_mult (tc->t_off, tc->t_size,
1961  (TMatrix<T>*)(tc->t_par[0]), (const Matrix<T>*)(tc->t_par[1]),
1962  (const Matrix<T>*)(tc->t_par[2]));
1963 }
1964 
1965 template <typename T>
1966 TMatrix<T> Matrix<T>::operator * (const Matrix<T>& b) const
1967 {
1968  TMatrix<T> c(this->row, b.col);
1969  /* FIXME: Should this be SMP_VECSLICE2? */
1970  const unsigned n_thr = threads_avail(this->col*this->row/SMP_MATSLICE2);
1971  update_n_thr(n_thr);
1972 #ifndef OLD_MAT_MAT_MULT
1973  c.clear();
1974 #endif
1975  BCHK(this->col != b.row, MatErr, Illegal sizes in Matrix multiplication, 0, c);
1976  if (LIKELY(n_thr < 2))
1977  do_mat_mat_mult<T> (0UL, this->row, &c, this, &b);
1978  else {
1979  PREFETCH_R(this->vec, 2);
1980  PREFETCH_R(b.vec, 2);
1981  PREFETCH_W(c.vec, 3);
1982  const unsigned long first = slice_offset(1, n_thr, this->row, (T*)0);
1983  unsigned long st, en = first;
1984  /* Start threads */
1985  for (unsigned t = 0; t < n_thr-1; ++t) {
1986  st = en; en = slice_offset(t+2, n_thr, this->row, (T*)0);
1987  thread_start_off (t, (thr_job_t)job_mat_mat_mult<T>,
1988  st, en, &c, this, &b, (void*)0);
1989  }
1990  /* The first slice is handled by the main thread */
1991  do_mat_mat_mult<T> (0UL, first, &c, this, &b);
1992  //sched_yield ();
1993  /* Wait for the end */
1994  for (unsigned s = 0; s < n_thr-1; ++s)
1995  thread_wait (s);
1996  }
1997  return c;
1998 }
1999 
2000 
2001 #else /* SMP */
2002 template <typename T>
2003 TMatrix<T> Matrix<T>::operator * (const Matrix<T>& b) const
2004 {
2005  TMatrix<T> c(this->row, b.col);
2006 #ifndef OLD_MAT_MAT_MULT
2007  c.clear();
2008 #endif
2009  BCHK(this->col != b.row, MatErr, Illegal sizes in Matrix multiplication, 0, c);
2010  do_mat_mat_mult <T> (0, this->row, &c, this, &b);
2011  return c;
2012 }
2013 #endif /* SMP */
2014 
2015 template <typename T>
2016 TMatrix<T> Matrix<T>::operator * (TSMatrix<T>& a) const
2017 {
2018  TMatrix<T> c(this->row, a.col);
2019  BCHK(this->col != a.row, MatErr, Illegal sizes in Matrix multiplication, 0, c);
2020  T tmp ALIGN(MIN_ALIGN2);
2021  for (unsigned i=0; i<this->row; i++) {
2022  for (unsigned j=0; j<a.col; j++) {
2023  tmp = this->mat[i][0] * a.mat[0][j];
2024  for (REGISTER unsigned l=1; l<this->col; l++)
2025  tmp += this->mat[i][l] * a.mat[l][j];
2026  c.mat[i][j] = tmp * a.fac;
2027  }
2028  }
2029  a.real_destroy (); return c;
2030 }
2031 
2032 
2033 template <typename T>
2034 inline TMatrix<T> Matrix<T>::operator * (TMatrix<T>& a) const
2035 {
2036  TMatrix<T> c (this->operator * (Matrix<T> (a)));
2037  return c;
2038 }
2039 
2040 template <typename T>
2041 inline TMatrix<T> TMatrix<T>::operator * (const Matrix<T>& a)
2042 {
2043  Matrix<T> m (*this);
2044  return (m * a);
2045 }
2046 
2047 
2048 template <typename T>
2049 inline TMatrix<T> TMatrix<T>::operator * (TMatrix<T> a)
2050 {
2051  Matrix<T> m (*this);
2052  return (m * (Matrix<T> (a)));
2053 }
2054 
2055 template <typename T>
2056 inline TMatrix<T> TMatrix<T>::operator * (TSMatrix<T> a)
2057 {
2058  Matrix<T> m (*this);
2059  return (m * a);
2060 }
2061 
2062 
2063 template <typename T>
2064 bool Matrix<T>::operator == (const Matrix<T>& m) const
2065 {
2066  if (LIKELY(this->row != m.row || this->col != m.col))
2067  return false;
2068  if (LIKELY(this->vec == m.vec || this->dim == 0))
2069  return true;
2070  if (TBCICOMP (this->vec, m.vec, T, this->dim))
2071  return false;
2072  else
2073  return true;
2074 }
2075 
2076 template <typename T>
2077 bool Matrix<T>::operator == (TSMatrix<T> ts) const
2078 {
2079  if (LIKELY(this->row != ts.row || this->col != ts.col))
2080  return (ts.real_destroy(), false);
2081  if (LIKELY(this->dim == 0)) {
2082  /*ts.real_destroy();*/ return true;
2083  }
2084  if (LIKELY(ts.fac == (T)1)) {
2085  if (LIKELY(this->vec == ts.vec))
2086  return true;
2087  if (TBCICOMP (this->vec, ts.vec, T, this->dim)) {
2088  ts.real_destroy (); return false;
2089  }
2090  } else {
2091  if (LIKELY(this->vec == ts.vec))
2092  return false;
2093  for (REGISTER T *p1 = this->vec, *p2 = ts.vec; p1 < this->endvec; p1++, p2++)
2094  if (UNLIKELY(*p1 != *p2 * ts.fac)) {
2095  ts.real_destroy (); return false;
2096  }
2097  }
2098  ts.real_destroy (); return true;
2099 }
2100 
2101 template <typename T>
2102 double Matrix<T>::fabssqr () const
2103 {
2104  double res = 0.0;
2105  if (do_exactsum())
2106  do_vec_fabssqr_exact (this->dim, this->vec, res);
2107  else
2108  do_vec_fabssqr_quick (this->dim, this->vec, res);
2109  return (res);
2110 }
2111 
2112 template <typename T>
2113 inline double fabssqr (const Matrix<T>& m)
2114 {
2115  return m.fabssqr ();
2116 }
2117 
2123 template<typename T>
2125 {
2126  Vector<T> cn (c);
2127  return (*this * cn);
2128 }
2129 
2130 
2131 #if defined(SMP) && !defined(NOSMP_MATVEC)
2132 
2133 template <typename T>
2134 inline void job_mat_vec_mult (struct thr_ctrl *tc)
2135 {
2136  do_mat_vec_mult (tc->t_off, tc->t_size,
2137  (TVector<T>*)(tc->t_par[0]), (const Matrix<T>*)(tc->t_par[1]),
2138  (const Vector<T>*)(tc->t_par[2]));
2139 }
2140 
2141 template <typename T>
2142 inline void job_mat_vec_transmult (struct thr_ctrl *tc)
2143 {
2144  do_mat_vec_transmult (tc->t_off, tc->t_size,
2145  (TVector<T>*)(tc->t_par[0]), (const Matrix<T>*)(tc->t_par[1]),
2146  (const Vector<T>*)(tc->t_par[2]));
2147 }
2148 
2149 
2150 template <typename T>
2152 {
2153  TVector<T> tv (this->row);
2154  /* use some heuristic to decide for the num of threads */
2155  const unsigned n_thr = threads_avail (this->row / SMP_MATSLICE2);
2156  update_n_thr(n_thr);
2157  //std::cout << "Mat*Vec: " << n_thr << " threads" << std::endl;
2158  BCHK (v.size() != this->col, MatErr, multiply Matrix w/ Vector: wrong config, v.size(), tv);
2159  if (LIKELY(n_thr < 2))
2160  do_mat_vec_mult<T> (0, this->row, &tv, this, &v);
2161  else {
2162  PREFETCH_R(this->vec, 2);
2163  PREFETCH_R(v.vec, 2);
2164  PREFETCH_W(tv.vec, 3);
2165  const unsigned long first = slice_offset(1, n_thr, this->row, (T*)0);
2166  unsigned long st, en = first;
2167  /* Start threads */
2168  for (unsigned t = 0; t < n_thr-1; ++t) {
2169  st = en; en = slice_offset(t+2, n_thr, this->row, (T*)0);
2170  thread_start_off (t, (thr_job_t)job_mat_vec_mult<T>,
2171  st, en, &tv, this, &v, (void*)0);
2172  }
2173  /* The first slice is handled by the main thread */
2174  do_mat_vec_mult<T> (0, first, &tv, this, &v);
2175  //sched_yield ();
2176  /* Wait for the end */
2177  for (unsigned s = 0; s < n_thr-1; ++s)
2178  thread_wait (s);
2179  }
2180  return tv;
2181 }
2182 
2183 template<typename T>
2185 {
2186  TVector<T> tv (this->col);
2187  const unsigned n_thr = threads_avail (this->col / SMP_MATSLICE2);
2188  update_n_thr(n_thr);
2189  BCHK (v.size() != this->row, MatErr, transMult Matrix w/ Vector: wrong config, v.size(), tv);
2190  if (LIKELY(n_thr < 2))
2191  do_mat_vec_transmult<T> (0, this->col, &tv, this, &v);
2192  else {
2193  /* FIXME: This does not use slice_offset yet! */
2194  const unsigned long first = slice_offset(1, n_thr, this->col, (T*)0);
2195  //const unsigned long first = this->col/n_thr - (this->col/n_thr)%4;
2196  unsigned long st, en = first;
2197  for (unsigned t = 0; t < n_thr-1; ++t) {
2198  //st = en; en = (t+2)*this->col/n_thr;
2199  //if (t < n_thr-2)
2200  // en -= en%4;
2201  st = en; en = slice_offset(t+2, n_thr, this->col, (T*)0);
2202  thread_start_off (t, (thr_job_t)job_mat_vec_transmult<T>,
2203  st, en, &tv, this, &v, (void*)0);
2204  }
2205  do_mat_vec_transmult<T> (0, first, &tv, this, &v);
2206  //sched_yield();
2207  for (unsigned s = 0; s < n_thr-1; ++s)
2208  thread_wait (s);
2209  }
2210  return tv;
2211 }
2212 
2213 #else /* SMP */
2214 
2215 template <typename T>
2217 {
2218  TVector<T> tv (this->row);
2219  BCHK (v.size() != this->col, MatErr, multiply Matrix w/ Vector: wrong config, v.size(), tv);
2220  do_mat_vec_mult (0, this->row, &tv, this, &v);
2221  return tv;
2222 }
2223 
2224 template<typename T>
2225 TVector<T> Matrix<T>::transMult (const Vector<T>& v) const
2226 {
2227  TVector<T> tv (this->col);
2228  BCHK (v.size() != this->row, MatErr, transMult Matrix w/ Vector: wrong config, v.size(), tv);
2229  do_mat_vec_transmult<T> (0, this->col, &tv, this, &v);
2230  return tv;
2231 }
2232 
2233 
2234 #endif /* SMP */
2235 
2236 /* No SMP version for Mat * TSV for now */
2237 template <typename T>
2239 {
2240  TVector<T> tv (this->row);
2241  BCHK (tsv.size() != this->col, MatErr, multiply Matrix w/ Vector: wrong config, tsv.size(), tv);
2242  do_mat_tsv_mult (0, this->row, &tv, this, &tsv);
2243  return tv;
2244 }
2245 
2246 
2247 template <typename T>
2248 inline BVector<T>& bvfillm (BVector<T>& bv, const Matrix<T>& m)
2249 {
2250  BCHK (bv.dim != m.dim, VecErr, Matrix size does not fit Vector, bv.dim, bv);
2251  TBCICOPY (bv.vec, m.vec, T, bv.dim);
2252  return bv;
2253 }
2254 
2255 
2256 
2257 
2258 /* Should be added for cplx, too */
2259 
2260 template <typename T>
2261 Matrix<T>& Matrix<T>::mult_rows (const Vector<T>& v)
2262 {
2263  BCHK (this->row != v.size(), MatErr, multiply rows: wrong sizes, v.size(), *this);
2264  for (unsigned r = 0; r < this->row; r++)
2265  {
2266  T fac = v (r);
2267  for (unsigned c = 0; c < this->col; c++)
2268  this->operator() (r, c) *= fac;
2269  }
2270  return *this;
2271 }
2272 
2273 template <typename T>
2274 Matrix<T>& Matrix<T>::div_rows (const Vector<T>& v)
2275 {
2276  BCHK (this->row != v.size(), MatErr, multiply rows: wrong sizes, v.size(), *this);
2277  for (unsigned r = 0; r < this->row; r++)
2278  {
2279  T fac = (T)1.0 / v (r);
2280  for (unsigned c = 0; c < this->col; c++)
2281  (*this) (r, c) *= fac;
2282  }
2283  return *this;
2284 }
2285 
2286 template <typename T>
2287 Matrix<T>& Matrix<T>::mult_row (const T& f, const unsigned r)
2288 {
2289  BCHK (r>this->row, MatErr, mult_row: wrong index, r, *this);
2290  for (unsigned c = 0; c < this->col; c++)
2291  (*this) (r, c) *= f;
2292  return *this;
2293 }
2294 
2295 template <typename T>
2296 Matrix<T>& Matrix<T>::div_row (const T& d, const unsigned r)
2297 {
2298  BCHK (r>this->row, MatErr, mult_row: wrong index, r, *this);
2299  BCHK (d == (T)0, MatErr, div_row by zero, r, *this);
2300  T f = (T)1.0 / d;
2301  for (unsigned c = 0; c < this->col; c++)
2302  (*this) (r, c) *= f;
2303  return *this;
2304 }
2305 
2306 
2307 /* New KG, 98/06/29 */
2308 /* Helper class for [] operator */
2309 template <typename T>
2310 class Mat_Brack
2311 {
2312  private:
2313  const TMatrix<T> & tmat;
2314  unsigned int idx;
2315  public:
2316  friend class TVector<T>;
2317  friend class Vector<T>;
2318  friend class TMatrix<T>;
2319  private:
2320  Mat_Brack (const TMatrix<T> &tm, unsigned int ix) : tmat(tm), idx (ix) {}
2321  Mat_Brack (const Mat_Brack<T>& m) : tmat(m.tmat), idx(m.idx) {}
2322  public:
2323  ~Mat_Brack() { tmat.mark_destroy(); }
2324  inline const T& operator [] (unsigned int j) const
2325  { EXPCHK(j >= tmat.col, MatErr, Idx2 out of range, j, tmat.mat[idx][0]);
2326  return tmat.mat[idx][j]; }
2327  inline T& operator [] (unsigned int j)
2328  { EXPCHK(j >= tmat.col, MatErr, Idx2 out of range, j, tmat.mat[idx][0]);
2329  return tmat.mat[idx][j]; }
2330 };
2331 
2332 template <typename T>
2334 {
2335  this->vec = mb.tmat.mat[mb.idx];
2336  this->dim = (unsigned long)mb.tmat.col; this->keep = true;
2337 }
2338 
2339 template <typename T>
2341 {
2342  this->dim = (unsigned long)mb.tmat.col;
2343  this->keep = false;
2344  if (LIKELY(this->dim)) {
2345  this->vec = NEW (T, this->dim);
2346  if (LIKELY(this->vec)) {
2347  TBCICOPY (this->vec, mb.tmat.mat[mb.idx], T, this->dim);
2348  return;
2349  }
2350  }
2351  this->dim = 0; this->vec = (T*)0;
2352 }
2353 #ifndef TBCI_NEW_BRACKET
2354 template <typename T>
2355 inline Mat_Brack<T> TMatrix<T>::operator [] (const unsigned int ix) const
2356 {
2357  EXPCHK(ix >= row, MatErr, Idx1 out of range, ix, Mat_Brack<T> (*this, 0));
2358  return Mat_Brack<T> (*this, ix);
2359 }
2360 #else
2361 template <typename T>
2362 inline T* TMatrix<T>::operator [] (const unsigned int ix) const
2363 {
2364  EXPCHK(ix >= row, MatErr, Idx1 out of range, ix, (T*)0);
2365  return mat[ix];
2366 }
2367 #endif
2368 
2369 
2370 #undef _DIM
2371 #undef _VEC
2372 #undef _ENDVEC
2373 #undef _ROW
2374 #undef _COL
2375 #undef _FAC
2376 
2377 /* GCC-4 ... 7 use FMA in ways that hurt perf. for lu_decomp */
2378 #if defined(__GNUC__) && __GNUC__ >= 5 && __GNUC__ < 8 && (defined(__x86_64__) || defined(__i386__))
2379 # define NOFMA __attribute__((target("no-fma")))
2380 #else
2381 # define NOFMA
2382 #endif
2383 
2384 template <typename T> int lu_decomp (Matrix<T>&) HOT NOFMA;
2385 
2386 
2387 template <typename T>
2389  public:
2390  T (*fn)(const unsigned i1, const unsigned i2, void* par);
2391  mat_fill_fn(T (*f)(const unsigned, const unsigned, void*))
2392  : fn(f) {};
2393 };
2394 
2395 template <typename T>
2396 void do_fill_mat(const unsigned firstrow, const unsigned lastrow, Matrix<T>* mat, mat_fill_fn<T> fn, void* par)
2397 
2398 {
2399  const unsigned cols = mat->columns();
2400  //printf("do_fill_mat(%i->%i)\n", firstrow, lastrow);
2401  for (unsigned r = firstrow; r < lastrow; ++r)
2402  for (REGISTER unsigned c = 0; c < cols; ++c)
2403  (*mat)(r,c) = fn.fn(r, c, par);
2404 }
2405 
2406 #ifdef SMP
2407 template <typename T>
2408 inline void job_fill_mat(struct thr_ctrl *tc)
2409 {
2410  do_fill_mat<T> (tc->t_off, tc->t_size,
2411  (Matrix<T>*)(tc->t_par[0]),
2412  *(mat_fill_fn<T>*)(tc->t_par[1]),
2413  tc->t_par[2]);
2414 }
2415 
2416 template <typename T>
2417 void par_fill(Matrix<T>& mat, mat_fill_fn<T> fn, void* par)
2418 {
2419  /* use some heuristic to decide for the num of threads */
2420  const unsigned rows = mat.rows();
2421  const unsigned n_thr = threads_avail (rows / SMP_MATSLICE2);
2422  update_n_thr(n_thr);
2423  //std::cout << "Mat*Vec: " << n_thr << " threads" << std::endl;
2424  if (LIKELY(n_thr < 2))
2425  do_fill_mat<T> (0, rows, &mat, fn, par);
2426  else {
2427  PREFETCH_W(&mat.setval(0,0), 3);
2428  const unsigned long first = slice_offset(1, n_thr, rows, (T*)0);
2429  unsigned long st, en = first;
2430  /* Start threads */
2431  for (unsigned t = 0; t < n_thr-1; ++t) {
2432  st = en; en = slice_offset(t+2, n_thr, rows, (T*)0);
2433  thread_start_off (t, (thr_job_t)job_fill_mat<T>,
2434  st, en, &mat, (void*)&fn, par, (void*)0);
2435  }
2436  /* The first slice is handled by the main thread */
2437  do_fill_mat<T> (0, first, &mat, fn, par);
2438  //sched_yield ();
2439  /* Wait for the end */
2440  for (unsigned s = 0; s < n_thr-1; ++s)
2441  thread_wait (s);
2442  }
2443 }
2444 
2445 #else
2446 template <typename T>
2447 void par_fill(Matrix<T>& mat, mat_fill_fn<T> fn, void* par)
2448 {
2449  do_fill_mat<T> (0, mat.rows(), &mat, fn, par);
2450 }
2451 #endif
2452 
2453 #if defined(SMP) && defined(HAVE_LIBNUMA)
2454 template <typename T>
2455 int numa_optimize(const Matrix<T>& m, bool fault_in)
2456 {
2457  if (!numa_avail && !fault_in)
2458  return 0;
2459  /* use some heuristic to decide for the num of threads */
2460  const unsigned rows = m.rows();
2461  const unsigned n_thr = threads_avail (rows / SMP_MATSLICE2);
2462  //update_n_thr(n_thr);
2463  //smp_barrier();
2464 
2465  if (LIKELY(n_thr < 2)) {
2466  if (fault_in)
2467  do_numa_move_pages(main_numa_node, 1,
2468  (unsigned long)m.getrowptr(0),
2469  (unsigned long)(m.getrowptr(rows-1)+m.columns()));
2470  return 0;
2471  } else {
2472  const unsigned first = slice_offset(1, n_thr, rows, (T*)0);
2473  unsigned long st, en = first;
2474  /* Start threads */
2475  unsigned long res = 0;
2476  for (unsigned t = 0; t < n_thr-1; ++t) {
2477  st = en; en = slice_offset(t+2, n_thr, rows, (T*)0);
2478  const T* endptr = (en == rows? m.getrowptr(en-1)+m.columns(): m.getrowptr(en));
2479  thread_start_off (t, (thr_job_t)numa_move_pages_job,
2480  threads[t].numa_node, fault_in,
2481  m.getrowptr(st), endptr, (void*)0);
2482  }
2483  /* The first slice is handled by the main thread */
2484  res = do_numa_move_pages(main_numa_node, fault_in,
2485  (unsigned long)(m.getrowptr(0)),
2486  (unsigned long)(m.getrowptr(first)));
2487  //sched_yield ();
2488  /* Wait for the end */
2489  for (unsigned t = 0; t < n_thr-1; ++t) {
2490  job_output out;
2491  thread_wait (t, &out);
2492  res += out.t_res_l;
2493  }
2494  //fprintf(stderr, "NUMA Optimize Matrix %p: %li pages moved\n", m.getrowptr(0), res);
2495  return res;
2496  }
2497 }
2498 #else
2499 template <typename T>
2500 int numa_optimize(const Matrix<T>& m, bool fault_in)
2501 {
2502  /* FIXME: We should emulate fault_in here, no? */
2503  return 0;
2504 }
2505 #endif
2506 
2507 
2509 
2510 #endif /* TBCI_MATRIX_H */
#define TBCICOPY(n, o, t, s)
Definition: basics.h:894
T mat_t
Definition: matrix.h:112
TVector< T > transMult(const Vector_Sig< T > &) const
BdMatrix< T > transpose(BdMatrix< T > &mat)
Definition: band_matrix.h:1393
void * t_par[6]
Definition: smp.h:173
TSMatrix< T > operator*=(const T &)
Definition: matrix.h:955
T ** mat
C storage layout: mat[row][col].
Definition: matrix.h:119
#define BCHKNR(cond, exc, txt, ind)
Definition: basics.h:586
Matrix< T > & clear()
Definition: matrix.h:1661
#define false
Definition: bool.h:23
T * vec
Definition: matrix.h:1121
Matrix< T > & resize(const unsigned r, const unsigned c)
Definition: matrix.h:1647
void do_mat_tsv_mult(const unsigned start, const unsigned end, TVector< T > *res, const Matrix< T > *mat, const TSVector< T > *vec)
void detach(TMatrix< T > *=0)
Definition: matrix.h:1239
#define STD_SMP_TEMPLATE3VV(oper, dm, a1, a2, a3)
Definition: vector.h:648
#define ALIGN(x)
Definition: basics.h:444
tm fac
Definition: f_matrix.h:1052
Matrix< T > & operator*=(const T &a)
Definition: matrix.h:1849
T aligned_value_type TALIGN(MIN_ALIGN2)
Definition: matrix.h:1144
void do_mat_vec_mult(const unsigned start, const unsigned end, TVector< T > *res, const Matrix< T > *mat, const Vector< T > *vec)
T trace() const
Trace.
Definition: matrix.h:812
Matrix< T > & operator-=(const Matrix< T > &a)
Definition: matrix.h:1673
void job_mat_vec_transmult(struct thr_ctrl *tc)
Definition: matrix.h:2142
T value_type
Definition: matrix.h:1142
TSMatrix< T > & operator*=(const T &f)
Definition: matrix.h:1185
bool operator!=(const Matrix< T > &m)
Definition: matrix.h:1216
TMatrix< T > & operator+=(TMatrix< T >)
arithmetics ...
Definition: matrix.h:917
void destroy()
Definition: bvector.h:268
Matrix(const Matrix< T > &m)
copy, does a real copy, as TM(M) is invoked (not TM(TM))
Definition: matrix.h:1601
TMatrix< T > operator-() const
Definition: matrix.h:1694
The class BdMatrix is an implementation to store and do operations on sparse Matrices with a band str...
Definition: band_matrix.h:103
int numa_avail
Definition: smp.cc:105
STD__ istream & operator>>(STD__ istream &istr, BdMatrix< T > &mat)
Definition: band_matrix.h:2739
T element_type
Definition: matrix.h:1143
const unsigned end
double fabssqr()
Definition: matrix.h:1530
#define large
void real_destroy()
real destructor
Definition: matrix.h:394
bool operator==(const Matrix< T > &m) const
Definition: matrix.h:2064
T element_type
Definition: matrix.h:130
~TMatrix()
Definition: matrix.h:184
#define REGISTER
Definition: basics.h:108
return c
Definition: f_matrix.h:760
double fabs(const int a)
Definition: basics.h:1215
unsigned int row
Definition: matrix.h:1123
#define _DIM
Definition: matrix.h:42
TVector< T > get_col(const unsigned int) const
Column vector.
Definition: matrix.h:627
#define MIN(a, b)
Definition: basics.h:655
#define FRIEND_TBCI__
Definition: basics.h:334
void set_row(const Vector< T > &, const unsigned int)
Fill complete row.
Definition: matrix.h:589
bool mut
Definition: matrix.h:1127
#define NAMESPACE_TBCI
Definition: basics.h:317
#define VEC
~Mat_Brack()
Definition: matrix.h:2323
T * Tptr
Definition: matrix.h:1136
virtual ~MatErr()
Definition: matrix.h:62
TSMatrix< T > & operator=(const TSMatrix< T > &ts)
Definition: matrix.h:1176
#define NOFMA
Definition: matrix.h:2381
T * getvec() const
Definition: matrix.h:1147
T * getendvec() const
Definition: matrix.h:1148
mat_fill_fn(T(*f)(const unsigned, const unsigned, void *))
Definition: matrix.h:2391
const T & getcref(const unsigned r, const unsigned c) const
Definition: matrix.h:292
TMatrix(const TMatrix< U > &tm)
Definition: matrix.h:200
bool operator==(const Matrix< T > &)
Definition: matrix.h:1467
exception base class for the TBCI NumLib
Definition: except.h:58
F_TMatrix< double > lu_solve(const F_Matrix< double > &A, const F_Matrix< double > &B, int overwriteA=0)
Definition: lapack.cpp:156
TSMatrix< T > operator/(const T &)
Definition: matrix.h:992
TVector< T > get_row(const unsigned int) const
Row vector.
Definition: matrix.h:640
T & setval(const unsigned r, const unsigned c)
Definition: matrix.h:283
unsigned int rows() const
NAMESPACE_TBCI char gaussj(Matrix< T > &a, Matrix< T > &b)
Definition: gauss_jordan.h:46
T * endvec
Definition: matrix.h:119
Common interface definition (signature) for all Matrices.
Definition: matrix_sig.h:45
tbci_traits< T >::const_refval_type get(const unsigned long i) const
Definition: vector.h:190
#define MIN_ALIGN2
Definition: basics.h:424
TMatrix< T > & transpose()
Definition: matrix.h:1079
void set_row_partial(const Vector< T > &, const unsigned int, const unsigned int)
Fill partial row.
Definition: matrix.h:597
MatErr()
Definition: matrix.h:56
T operator()(const unsigned int r, const unsigned int c) HOT
Definition: matrix.h:1170
bool operator!=(const Matrix< T > &m) const
Definition: matrix.h:1722
unsigned long dim
Definition: bvector.h:74
Matrix(const unsigned r, const unsigned c)
Definition: matrix.h:1590
TMatrix< T > & resize(const unsigned int, const unsigned int)
Resize Matrix, specifying rows and columns.
Definition: matrix.h:655
#define STD_SMP_TEMPLATE5(oper, dm, a1, a2, a3, a4, a5)
Definition: vector.h:658
void mark_destroy() const
mark destructible
Definition: matrix.h:402
TSMatrix< T > operator/(const T &) const
Definition: matrix.h:1883
#define BCHK(cond, exc, txt, ind, rtval)
Definition: basics.h:575
void par_fill(Matrix< T > &mat, mat_fill_fn< T > fn, void *par)
Definition: matrix.h:2417
friend class TMatrix
Definition: matrix.h:191
tbci_traits< T >::const_refval_type operator()(const unsigned int, const unsigned int) const HOT
ro element access
Definition: matrix.h:1775
Vector(const unsigned long d=0)
Definition: vector.h:1539
#define NAMESPACE_CSTD_END
Definition: basics.h:325
long t_res_l
Definition: smp.h:148
Matrix(const T &v, const unsigned r, const unsigned c)
Definition: matrix.h:1593
unsigned int col
Definition: matrix.h:116
Matrix< T > & resize(const Matrix< T > &m)
Definition: matrix.h:1653
#define TBCIFILL(n, v, t, s)
Definition: basics.h:910
BVector< T > & bvfillm(BVector< T > &bv, const Matrix< T > &m)
Definition: matrix.h:2248
#define UNLIKELY(expr)
Definition: basics.h:101
T value_type
Definition: matrix.h:129
#define SMP_MATSLICE2
Definition: matrix.h:99
double fabs() const
Definition: matrix.h:389
Definition: smp.h:168
#define REALLOC(v, os, t, s)
Definition: malloc_cache.h:636
Matrix< T > & setunit(const T &f=(T) 1)
Definition: matrix.h:1659
double fabssqr() const
Definition: matrix.h:2102
void(* thr_job_t)(struct thr_ctrl *)
Before the double inclusion guard on purpose!
Definition: smp.h:126
unsigned int freeable
Definition: matrix.h:117
T value_type
Definition: matrix.h:1581
#define FRIEND_TBCI2__
Definition: basics.h:335
unsigned long size() const
number of elements
Definition: matrix.h:319
TMatrix< T > LU_invert(const BdMatrix< T > &lu)
return the inverse Matrix for an already LU decomposed BdMatrix
Definition: bd_lu_solver.h:338
TSMatrix< T > & operator/=(const T &f)
Definition: matrix.h:1186
T & set(const T &val, const unsigned long i) const
Definition: vector.h:194
#define MAT
#define STD_SMP_TEMPLATE4C(oper, dm, a1, a2, a3, a4)
Definition: vector.h:656
T & setval(const T &val, const unsigned int r, const unsigned int c)
Definition: matrix.h:281
int set_ptrs()
Definition: matrix.h:409
bool operator!=(const Matrix< T > &m)
Definition: matrix.h:301
T fac ALIGN(MIN_ALIGN2)
#define FGDT
Definition: basics.h:145
static const char * mat_info()
Definition: matrix.h:1168
#define NEW(t, s)
Definition: malloc_cache.h:633
double sqrt(const int a)
Definition: basics.h:1216
void job_fill_mat(struct thr_ctrl *tc)
Definition: matrix.h:2408
Matrix< T > & div_row(const T &, const unsigned)
Definition: matrix.h:2296
double fabssqr() const
Sum over all squared elements.
Definition: matrix.h:1050
struct thr_struct * threads
Definition: smp.cc:106
TMatrix< T > operator+(const Matrix< T > &)
Definition: matrix.h:1295
#define _COL
Definition: matrix.h:44
void set_col(const Vector< T > &, const unsigned int)
Fill complete column.
Definition: matrix.h:606
#define U
Definition: bdmatlib.cc:21
int lu_decomp(Matrix< T > &) HOT
LU decomposes the TBCI::Matrix mat.
Definition: lu_solver.h:94
void job_mat_vec_mult(struct thr_ctrl *tc)
Definition: matrix.h:2134
TMatrix< T > & clear()
Clear matrix (fill with 0)
Definition: matrix.h:580
unsigned long t_size
Definition: smp.h:171
#define PREFETCH_R(addr, loc)
In case gcc does not yet support __builtin_prefetch(), we have handcoded assembly with gcc for a few ...
Definition: basics.h:748
#define _ROW
Definition: matrix.h:43
Matrix(const Vector< T > &v, const enum rowcolvec r=colvec)
Definition: matrix.h:1596
T(* fn)(const unsigned i1, const unsigned i2, void *par)
Definition: matrix.h:2390
Matrix< T > & fill(const T &v=(T) 0)
Definition: matrix.h:1655
TVector(const unsigned long d=0)
Definition: vector.h:84
unsigned int columns() const
number of columns
Definition: matrix.h:315
Matrix(const TMatrix< T > &tm) HOT
alias
Definition: matrix.h:1605
Tensor class including arithmetics.
Definition: f_matrix.h:53
F_TSMatrix< T > ts
Definition: f_matrix.h:1052
#define TBCI__
Definition: basics.h:332
Matrix(const unsigned d=0)
Definition: matrix.h:1587
TMatrix< T > & operator-()
Definition: matrix.h:833
Matrix< T > & mult_row(const T &, const unsigned)
Definition: matrix.h:2287
double fabs()
Definition: matrix.h:1225
TMatrix< T > & cheapdownsizerow(const unsigned)
Resize number of rows without actually freeing memory (efficiency)
Definition: matrix.h:792
TMatrix< T > transposed_copy() const
Inefficient! Use transMult if possible.
Definition: matrix.h:1061
long int Vector< T > & index
Definition: LM_fit.h:69
TVector< T > transMult(const Vector< T > &) const HOT
Definition: matrix.h:2184
friend NOINST TMatrix< T > LU_solve FGD(const BdMatrix< T > &, const Matrix< T > &)
TMatrix(const Matrix< U > &m)
Definition: matrix.h:193
void set_col_partial(const Vector< T > &, const unsigned int, const unsigned int)
Fill partial column.
Definition: matrix.h:616
T aligned_value_type TALIGN(MIN_ALIGN2)
Definition: matrix.h:1583
F_TMatrix< T > b
Definition: f_matrix.h:736
unsigned long size() const
Definition: matrix.h:1227
Matrix< T > & fill(const Vector< T > &v)
Definition: matrix.h:1657
void do_mat_vec_transmult(const unsigned start, const unsigned end, TVector< T > *res, const Matrix< T > *mat, const Vector< T > *vec)
T aligned_value_type TALIGN(MIN_ALIGN2)
Definition: matrix.h:131
TSMatrix< T > operator*(const T &)
Definition: matrix.h:988
TSMatrix< T > & operator/(const T &f)
Definition: matrix.h:1188
Matrix< T > & resize(const unsigned d)
Definition: matrix.h:1649
~TSMatrix()
Definition: matrix.h:1155
Matrix< T > & operator+=(const Matrix< T > &a)
Definition: matrix.h:1671
void clone(bool=false, TMatrix< T > *=0)
Definition: matrix.h:1260
#define GLBL__
Definition: basics.h:342
if(value==0) return 1
TSMatrix< T > operator/=(const T &)
Definition: matrix.h:959
exception class
Definition: matrix.h:53
bool operator==(const Matrix< T > &m)
Comparison.
Definition: matrix.h:840
Matrix(const TSMatrix< T > &ts)
Definition: matrix.h:1608
#define NAMESPACE_CSTD
Definition: basics.h:319
void do_fill_mat(const unsigned firstrow, const unsigned lastrow, Matrix< T > *mat, mat_fill_fn< T > fn, void *par)
Definition: matrix.h:2396
TMatrix< T > & operator-=(TMatrix< T >)
Definition: matrix.h:920
void SWAP(T &a, T &b)
SWAP function Note: We could implement a swap function without temporaries: a -= b b += a a -= b a = ...
Definition: basics.h:813
TMatrix< T > & operator=(const Matrix< T > &) HOT
assignment, non-resizing
Definition: matrix.h:533
T * vec
Definition: matrix.h:119
unsigned long dim
Definition: matrix.h:1122
unsigned long size() const
Definition: vector.h:104
#define STD_SMP_TEMPLATE2C(oper, dm, a1, a2)
Definition: vector.h:646
MatErr(const char *t, const long i=0)
Definition: matrix.h:58
~Matrix()
Definition: matrix.h:1612
#define FGD
Definition: basics.h:144
Definition: bvector.h:49
Matrix< T > & operator=(const Matrix< T > &m)
Assignment, non-resizing.
Definition: matrix.h:1638
unsigned int col
Definition: matrix.h:1123
TMatrix< T > & operator+(TMatrix< T >)
Definition: matrix.h:974
T & getfac()
Definition: matrix.h:1149
Matrix(const TMatrix< U > &tm)
Definition: matrix.h:1623
#define PREFETCH_W(addr, loc)
Definition: basics.h:749
tm detach()
static const char * mat_info()
Definition: matrix.h:1615
Matrix(const Matrix< U > &m)
Definition: matrix.h:1619
TMatrix< T > & fill(const T &=(T) 0)
Fill matrix.
Definition: matrix.h:805
TMatrix< T > operator*(const Matrix< T > &) const
Definition: matrix.h:1966
#define INST(x)
Definition: basics.h:238
#define EXPCHK(cond, exc, txt, ind, rtval)
Definition: basics.h:630
Matrix< T > & operator/=(const T &a)
Definition: matrix.h:1855
T * getrowptr(const unsigned r)
Definition: matrix.h:297
TMatrix< T > & row_expand(const unsigned int r)
Set new numbers of rows to matrix (expansion only)
Definition: matrix.h:678
const T & operator[](unsigned int j) const
Definition: matrix.h:2324
int i
Definition: LM_fit.h:71
TSMatrix(const TSMatrix< T > &ts)
Definition: matrix.h:1163
unsigned long dim
Definition: matrix.h:115
double fabs() const
Definition: matrix.h:1752
TSMatrix< T > & operator*(const T &f)
Definition: matrix.h:1187
T operator()(const unsigned int, const unsigned int) const HOT
Element access (desctructive for TMatrix!)
Definition: matrix.h:523
#define STD_SMP_TEMPLATE2V(oper, dm, a1, a2)
Definition: vector.h:644
TMatrix< T > operator+(const Matrix< T > &) const
Definition: matrix.h:1890
#define TBCICLEAR(n, t, s)
Definition: basics.h:911
T ** mat
Definition: matrix.h:1124
#define STD__
Definition: basics.h:338
#define TBCIDELETE(t, v, sz)
Definition: malloc_cache.h:634
T * getendvec() const
Definition: matrix.h:127
T element_type
Definition: matrix.h:1582
#define threads_avail(x)
Definition: smp.h:322
unsigned long t_off
Definition: smp.h:172
Temporary Base Class Idiom: Class TVector is used for temporary variables.
Definition: bvector.h:52
unsigned long size() const
Definition: vector.h:1120
void thread_wait(const int thr_no, struct job_output *out)
Definition: smp.cc:997
TSMatrix()
Definition: matrix.h:1153
#define STD_SMP_TEMPLATE3VC(oper, dm, a1, a2, a3)
Definition: vector.h:650
TMatrix< T > & swap(TMatrix< T > &)
Definition: matrix.h:1759
T * Tptr
Definition: matrix.h:113
static const char * mat_info()
Definition: matrix.h:180
#define NAMESPACE_END
Definition: basics.h:323
TSMatrix< T > & operator-()
Definition: matrix.h:1192
Definition: bvector.h:54
Implementation of fixed sized Vectors (template argument) which is favorable for small Vectors...
Definition: fs_vector.h:45
Mat_Brack< T > operator[](const unsigned int i) const
Definition: matrix.h:2355
TVector< T > LU_solve(const BdMatrix< T > &lu, const Vector< T > &b)
Solve the equation Ax = b where A IS already LU decomposed.
Definition: bd_lu_solver.h:246
const Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > long int res
Definition: LM_fit.h:199
int numa_node
Definition: smp.h:133
T * vec
Definition: bvector.h:73
#define ALIGN3(v, i, x)
Definition: basics.h:442
double fabssqr(const double a)
Definition: basics.h:1157
TMatrix< T > & setunit(const T &=(T) 1)
Set to unit matrix (optionally scaled)
Definition: matrix.h:567
#define T
Definition: bdmatlib.cc:20
#define TBCICOMP(n, o, t, s)
Definition: basics.h:979
#define HOT
Definition: basics.h:495
MatErr(const MatErr &me)
Definition: matrix.h:60
int main_numa_node
Definition: smp.cc:110
#define true
Definition: bool.h:24
const T & getfac() const
Definition: matrix.h:1150
void real_destroy()
Definition: matrix.h:1231
friend BVector< T > &FRIEND_TBCI2__ bvfillm FGD(BVector< T > &, const Matrix< T > &m)
const T * getrowptr(const unsigned r) const
Helpers for matvecmul.
Definition: matrix.h:296
T & set(const T &val, const unsigned r, const unsigned c)
Definition: matrix.h:290
unsigned int do_exactsum()
Definition: tbci_param.h:150
int numa_optimize(const BdMatrix< T > &bm, bool fault_in)
Definition: band_matrix.h:2915
#define RESTRICT
Definition: basics.h:89
const unsigned TMatrix< T > const Matrix< T > * a
Matrix< T > & div_rows(const Vector< T > &)
Definition: matrix.h:2274
void thread_start_off(const int thr_no, thr_job_t job, const unsigned long off, const unsigned long sz,...)
Definition: smp.cc:979
const Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > long int int char v
&lt; find minimun of func on grid with resolution res
Definition: LM_fit.h:205
TMatrix< T > lu_invert(BdMatrix< T > &mat)
return the inverse Matrix for a BdMatrix by doing an LU decomposition
Definition: bd_lu_solver.h:355
#define MATH__
Definition: basics.h:339
Definition: matrix.h:70
TMatrix< T > & resize(const unsigned int d)
Resize Matrix to square shape.
Definition: matrix.h:364
T * endvec
Definition: matrix.h:1125
T * getvec() const
Definition: matrix.h:126
Definition: matrix.h:70
Matrix< T > & resize(const T &v, const unsigned r, const unsigned c)
Definition: matrix.h:1651
#define LIKELY(expr)
branch prediction note that we sometimes on purpose mark the unlikely possibility likely and vice ver...
Definition: basics.h:100
Matrix< T > & mult_rows(const Vector< T > &)
Elementwise ops.
Definition: matrix.h:2261
unsigned int row
Definition: matrix.h:116
tbci_traits< T >::const_refval_type get(const unsigned r, const unsigned c) const
get, set and getcref are used internally and not for public consumption
Definition: matrix.h:288
unsigned int rows() const
number of rows
Definition: matrix.h:317
#define GLBL2__
Definition: basics.h:343
exception class
Definition: bvector.h:31
TSMatrix< T > & eval(TMatrix< T > *=0)
Definition: matrix.h:1280
rowcolvec
Definition: matrix.h:70
TMatrix< T > & alias(const TMatrix< T > &m)
Definition: matrix.h:504
#define STD_SMP_TEMPLATE4V(oper, dm, a1, a2, a3, a4)
Definition: vector.h:654