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
53class 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
70enum rowcolvec { rowvec = 0, colvec = 1 };
71
72template <typename T> class Matrix;
73template <typename T> class TMatrix;
74template <typename T> class TSMatrix;
75template <typename T> class Mat_Brack;
76template <typename T> class BdMatrix;
77template <typename T> class Tensor;
78
79template <typename T>
80void do_mat_vec_mult (const unsigned start, const unsigned end,
81 TVector<T> *res, const Matrix<T> *mat,
82 const Vector<T> *vec);
83
84template <typename T>
85void do_mat_tsv_mult (const unsigned start, const unsigned end,
86 TVector<T> *res, const Matrix<T> *mat,
87 const TSVector<T> *vec);
88
89template <typename T>
90void 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//-----------------------------------------------------
108template <typename T>
109class 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;
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;
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;
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:
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
222 TMatrix<T>& operator -= (const T&);
224
225 TSMatrix<T> operator *= (const T&);
226 TSMatrix<T> operator /= (const T&);
227
228 // operations
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&);
238 TMatrix<T>& operator - (const T&);
239 TSMatrix<T> operator * (const T&);
240 TSMatrix<T> operator / (const T&);
241
245
247 { Matrix<T> m (*this); return (m * v); }
249 { Matrix<T> m (*this); return (m * tv); }
250 TVector<T> operator * (const TSVector <T>& tsv)
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
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
341 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
393template <typename T>
395{
396 if (UNLIKELY(dim)) {
398 }
399}
400
401template <typename T>
402inline void TMatrix<T>::mark_destroy () const
403{
404 this->freeable = 1;
405}
406
407
408template <typename T>
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))
438 dim = 0; row = 0; col = 0;
439 mat = (T**)0; vec = (T*)0; endvec = (T*)0;
440 return -1;
441 }
442}
443
444template <typename T>
445inline 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
453template <typename T>
454inline 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
461template <typename T>
462inline 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
471template <typename T>
472inline 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
483template <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 !
495template <typename T>
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
503template <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
513template <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
522template <typename T>
523inline 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
532template <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?)
541template <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
550template <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
559template <typename T>
561{
562 return this->fill (val);
563}
564
565
566template <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
579template <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
588template <typename T>
589inline 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
596template <typename T>
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
605template <typename T>
606inline 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
615template <typename T>
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
626template <typename T>
627inline 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
639template <typename T>
640inline 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
648template <typename T>
649inline TVector<T> TMatrix<T>::operator () (const unsigned int i) const
650{
651 return this->get_row(i);
652}
653
654template <typename T>
655TMatrix<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))
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
677template <typename T>
678TMatrix<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);
686 mat = NEW (Tptr,r);
687 } else {
688 if (UNLIKELY(row*col)) {
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
706template <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))
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
744template <typename T>
745TMatrix<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);
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
767template <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);
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 */
791template <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
804template <typename T>
805inline TMatrix<T>& TMatrix<T>::fill (const T& val)
806{
807 TBCIFILL(vec, val, T, dim);
808 return *this;
809}
810
811template <typename T>
812inline 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
821template <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 -
832template <typename T>
834{
835 do_vec_neg<T> (dim, vec);
836 return *this;
837}
838
839template <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
853template <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
881template <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}
889template <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
898template <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}
906template <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 ...
916template <typename T>
919template <typename T>
922
923template <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}
931template <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 ?
941template <typename T>
943{
944 STD_SMP_TEMPLATE2C(vec_add_val, dim, vec, a);
945 return *this;
946}
947template <typename T>
949{
950 STD_SMP_TEMPLATE2C(vec_add_val, dim, vec, a);
951 return *this;
952}
953
954template <typename T>
956{ return TSMatrix<T> (*this, a); }
957
958template <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
966template <typename T>
968{ return this->operator += (a); }
969template <typename T>
971{ return this->operator -= (a); }
972
973template <typename T>
976template <typename T>
979
980template <typename T>
982{ return this->operator += (a); }
983template <typename T>
985{ return this->operator -= (a); }
986
987template <typename T>
989{ return TSMatrix<T> (*this, a); }
990
991template <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 ?
1001INST(template <typename T> class TMatrix friend TMatrix<T> operator + (const T&, TMatrix<T>);)
1002template <typename T>
1003inline 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}
1008INST(template <typename T> class TMatrix friend TMatrix<T> operator - (const T&, TMatrix<T>);)
1009template <typename T>
1010inline 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
1016INST(template <typename T> class TMatrix friend TSMatrix<T> operator * (const T&, TMatrix<T>);)
1017template <typename T>
1018inline 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 ?
1024INST(template <typename T> class TMatrix friend TMatrix<T> operator + (const T&, const Matrix<T>&);)
1025template <typename T>
1026inline 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}
1032INST(template <typename T> class TMatrix friend TMatrix<T> operator - (const T&, const Matrix<T>&);)
1033template <typename T>
1034inline 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
1041INST(template <typename T> class TMatrix friend TSMatrix<T> operator * (const T&, const Matrix<T>&);)
1042template <typename T>
1043inline TSMatrix<T> operator * (const T& a, const Matrix<T>& b)
1044{ return TSMatrix<T> (b, a); }
1045// Commutativity is assumed here !
1046
1047
1048
1049template <typename T>
1050inline double TMatrix<T>::fabssqr () const
1051{ Matrix<T> m (*this); return m.fabssqr (); }
1052
1053template <typename T>
1054inline double fabssqr (const TMatrix<T>& tm)
1055{
1056 return tm.fabssqr ();
1057}
1058
1059
1060template <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
1071INST(template <typename T> class TMatrix friend TMatrix<T> transpose(const TMatrix<T>& tm);)
1072template <typename T>
1074{
1075 return tm.transposed_copy();
1076}
1077
1078template <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
1098INST(template <typename T> class TBCI__ Matrix friend double fabs (const TBCI__ TMatrix<T>&);)
1099template<typename T>
1100inline double fabs (const TBCI__ TMatrix<T>& tm)
1101{ return tm.fabs (); }
1102
1103INST(template <typename T> class TBCI__ Matrix friend double fabs (const TBCI__ Matrix<T>&);)
1104template<typename T>
1105inline double fabs (const TBCI__ Matrix<T>& m)
1106{ return m.fabs (); }
1107
1109
1111
1112//-------------------------------------------------------------
1116//-------------------------------------------------------------
1117template <typename T>
1118class TSMatrix : public Matrix_Sig<T> //: public TMatrix
1119{
1120 protected:
1122 unsigned long dim;
1123 unsigned int row, col;
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;
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; }
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
1198 TMatrix<T> operator + (const 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
1214
1215 bool operator == (const Matrix<T>&);
1216 bool operator != (const Matrix<T>& m) { return !(*this == m); }
1217
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
1230template <typename T>
1232{
1233 if (LIKELY(!mut || !dim))
1234 return;
1236}
1237
1238template <typename T>
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
1259template <typename T>
1260void 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)
1279template <typename T>
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
1294template <typename T>
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}
1302template <typename T>
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
1311template <typename T>
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}
1318template <typename T>
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
1326template <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
1345template <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
1364template <typename T>
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
1372template <typename T>
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?
1381INST(template <typename T> class TSMatrix friend TMatrix<T> operator + (const T&, const TSMatrix<T>&);)
1382template <typename T>
1383inline 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}
1389INST(template <typename T> class TSMatrix friend TMatrix<T> operator - (const T&, const TSMatrix<T>&);)
1390template <typename T>
1391inline 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
1399template <typename T>
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
1417template <typename T>
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
1435template <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
1450template <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
1466template <typename T>
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
1492template <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
1523INST(template <typename T> class TSMatrix friend TSMatrix<T> operator * (const T&, TSMatrix<T>);)
1524template <typename T>
1525inline TSMatrix<T> operator * (const T& f, TSMatrix<T> ts)
1526{ ts._FAC = f * ts._FAC; return ts; }
1527
1528
1529template <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);
1538 real_destroy ();
1539 return res;
1540}
1541
1542template <typename T>
1543inline double fabssqr (TSMatrix<T>& tsm)
1544{
1545 return tsm.fabssqr ();
1546}
1547
1549
1551
1552INST(template <typename T> class TBCI__ TSMatrix friend double fabs (TBCI__ TSMatrix<T>&);)
1553template <typename T>
1555{ return ts.fabs (); }
1556
1558
1560//---------------------------------------------------------------
1572//---------------------------------------------------------------
1573template <typename T>
1574class Matrix : public TMatrix<T>
1575{
1576
1577 public:
1578
1579 friend class TSMatrix<T>;
1580
1581 typedef T value_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; */ }
1604
1606 : TMatrix<T> (tm)
1607 { /* this->freeable = 1; */ }
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
1639 { this->TMatrix<T>::operator = (m); return *this; }
1641 { this->TMatrix<T>::operator = (tm); return *this; }
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; }
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; }
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; }
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
1672 { this->TMatrix<T>::operator += (a); return *this; }
1674 { this->TMatrix<T>::operator -= (a); return *this; }
1676 { this->TMatrix<T>::operator += (a); return *this; }
1678 { this->TMatrix<T>::operator -= (a); return *this; }
1684 { this->TMatrix<T>::operator += (a); return *this; }
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
1703
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;
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
1726 { Matrix<T> m (tm); return (*this == m); }
1728 { return !(*this == tm); }
1729
1730 bool operator == (TSMatrix<T>) 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
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
1758template <typename T>
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
1773template <typename T>
1774inline typename tbci_traits<T>::const_refval_type
1775Matrix<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
1782template <typename T>
1783inline 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
1790template <typename T>
1791inline 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
1800template <typename T>
1801STD__ 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
1816template <typename T>
1817STD__ 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
1829INST(template <typename T> class TMatrix friend STD__ ostream& operator << (STD__ ostream& os, TMatrix<T> tm);)
1830template <typename T>
1831STD__ ostream& operator << (STD__ ostream& os, TMatrix<T> tm)
1832{
1833 Matrix<T> m(tm);
1834 return os << m;
1835}
1836
1837INST(template <typename T> class TSMatrix friend STD__ ostream& operator << (STD__ ostream& os, const TSMatrix<T>& ts);)
1838template <typename T>
1839STD__ 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 ?
1848template <typename T>
1850{
1851 STD_SMP_TEMPLATE2C(vec_mul_val, this->dim, this->vec, a);
1852 return *this;
1853}
1854template <typename T>
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 ?
1863template <typename T>
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}
1870template <typename T>
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
1878template <typename T>
1880{ return TSMatrix<T> (*this, a); }
1881
1882template <typename T>
1884{
1885 BCHK (a==(T)0, MatErr, Divide Mat by 0, 0, *this);
1886 return TSMatrix<T> (*this, (T)1/a);
1887}
1888
1889template <typename T>
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}
1897template <typename T>
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
1906template <typename T>
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}
1913template <typename T>
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
1921template <typename T>
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}
1929template <typename T>
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
1950INST(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
1957template <typename T>
1958inline 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
1965template <typename T>
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 */
2002template <typename T>
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
2015template <typename T>
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
2033template <typename T>
2035{
2036 TMatrix<T> c (this->operator * (Matrix<T> (a)));
2037 return c;
2038}
2039
2040template <typename T>
2042{
2043 Matrix<T> m (*this);
2044 return (m * a);
2045}
2046
2047
2048template <typename T>
2050{
2051 Matrix<T> m (*this);
2052 return (m * (Matrix<T> (a)));
2053}
2054
2055template <typename T>
2057{
2058 Matrix<T> m (*this);
2059 return (m * a);
2060}
2061
2062
2063template <typename T>
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
2076template <typename T>
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
2101template <typename T>
2102double 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
2112template <typename T>
2113inline double fabssqr (const Matrix<T>& m)
2114{
2115 return m.fabssqr ();
2116}
2117
2122
2123template<typename T>
2125{
2126 Vector<T> cn (c);
2127 return (*this * cn);
2128}
2129
2130
2131#if defined(SMP) && !defined(NOSMP_MATVEC)
2132
2133template <typename T>
2134inline 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
2141template <typename T>
2142inline void job_mat_vec_transmult (struct thr_ctrl *tc)
2143{
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
2150template <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);
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
2183template<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);
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
2215template <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
2224template<typename T>
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 */
2237template <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
2247template <typename T>
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
2260template <typename T>
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
2273template <typename T>
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
2286template <typename T>
2287Matrix<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
2295template <typename T>
2296Matrix<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 */
2309template <typename T>
2310class 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
2332template <typename T>
2334{
2335 this->vec = mb.tmat.mat[mb.idx];
2336 this->dim = (unsigned long)mb.tmat.col; this->keep = true;
2337}
2338
2339template <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
2354template <typename T>
2355inline 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
2361template <typename T>
2362inline 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
2384template <typename T> int lu_decomp (Matrix<T>&) HOT NOFMA;
2385
2386
2387template <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
2395template <typename T>
2396void 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
2407template <typename T>
2408inline 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
2416template <typename T>
2417void 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);
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
2446template <typename T>
2447void 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)
2454template <typename T>
2455int 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
2499template <typename T>
2500int 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 */
long int Vector< T > & index
Definition LM_fit.h:69
int i
Definition LM_fit.h:71
#define STD__
Definition basics.h:338
#define HOT
Definition basics.h:495
#define BCHK(cond, exc, txt, ind, rtval)
Definition basics.h:575
#define LIKELY(expr)
branch prediction note that we sometimes on purpose mark the unlikely possibility likely and vice ver...
Definition basics.h:100
#define FRIEND_TBCI__
Definition basics.h:334
#define NAMESPACE_CSTD
Definition basics.h:319
#define FGDT
Definition basics.h:145
#define MIN(a, b)
Definition basics.h:655
#define MIN_ALIGN2
Definition basics.h:424
#define ALIGN3(v, i, x)
Definition basics.h:442
#define FRIEND_TBCI2__
Definition basics.h:335
#define NAMESPACE_END
Definition basics.h:323
#define TBCICOMP(n, o, t, s)
Definition basics.h:981
#define TBCICLEAR(n, t, s)
Definition basics.h:913
#define INST(x)
Definition basics.h:238
#define EXPCHK(cond, exc, txt, ind, rtval)
Definition basics.h:630
#define NAMESPACE_CSTD_END
Definition basics.h:325
#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 NAMESPACE_TBCI
Definition basics.h:317
#define BCHKNR(cond, exc, txt, ind)
Definition basics.h:586
#define TBCI__
Definition basics.h:332
#define PREFETCH_W(addr, loc)
Definition basics.h:749
#define UNLIKELY(expr)
Definition basics.h:101
#define REGISTER
Definition basics.h:108
#define MATH__
Definition basics.h:339
#define NOINST
Definition basics.h:244
#define GLBL__
Definition basics.h:342
#define RESTRICT
Definition basics.h:89
#define TBCIFILL(n, v, t, s)
Definition basics.h:912
#define ALIGN(x)
Definition basics.h:444
#define TBCICOPY(n, o, t, s)
Definition basics.h:895
#define GLBL2__
Definition basics.h:343
#define FGD
Definition basics.h:144
TVector< T > LU_solve(const BdMatrix< T > &lu, const Vector< T > &b)
Solve the equation Ax = b where A IS already LU decomposed.
TMatrix< T > LU_invert(const BdMatrix< T > &lu)
return the inverse Matrix for an already LU decomposed BdMatrix
TMatrix< T > lu_invert(BdMatrix< T > &mat)
return the inverse Matrix for a BdMatrix by doing an LU decomposition
#define T
Definition bdmatlib.cc:20
#define U
Definition bdmatlib.cc:21
#define MAT
#define VEC
#define true
Definition bool.h:24
#define false
Definition bool.h:23
provides basic Vector functionality but arithmetic operators (+=, - , *, /...).
Definition bvector.h:68
unsigned long dim
Definition bvector.h:74
bool keep
Definition bvector.h:75
void destroy()
Definition bvector.h:268
T * vec
Definition bvector.h:73
The class BdMatrix is an implementation to store and do operations on sparse Matrices with a band str...
Implementation of fixed sized Vectors (template argument) which is favorable for small Vectors,...
Definition fs_vector.h:63
~Mat_Brack()
Definition matrix.h:2323
const T & operator[](unsigned int j) const
Definition matrix.h:2324
exception class
Definition matrix.h:54
MatErr(const char *t, const long i=0)
Definition matrix.h:58
virtual ~MatErr()
Definition matrix.h:62
MatErr()
Definition matrix.h:56
MatErr(const MatErr &me)
Definition matrix.h:60
TVector< T > transMult(const Vector_Sig< T > &) const
Matrix< T > & fill(const Vector< T > &v)
Definition matrix.h:1657
friend BVector< T > &FRIEND_TBCI2__ bvfillm FGD(BVector< T > &, const Matrix< T > &m)
bool operator!=(const Matrix< T > &m) const
Definition matrix.h:1722
Matrix(const Matrix< T > &m)
copy, does a real copy, as TM(M) is invoked (not TM(TM))
Definition matrix.h:1601
Matrix< T > & resize(const Matrix< T > &m)
Definition matrix.h:1653
Matrix< T > & mult_rows(const Vector< T > &)
Elementwise ops.
Definition matrix.h:2261
Matrix(const TSMatrix< T > &ts)
Definition matrix.h:1608
tbci_traits< T >::const_refval_type operator()(const unsigned int, const unsigned int) const HOT
ro element access
Definition matrix.h:1775
Matrix< T > & resize(const T &v, const unsigned r, const unsigned c)
Definition matrix.h:1651
Matrix(const TMatrix< U > &tm)
Definition matrix.h:1623
T aligned_value_type TALIGN(MIN_ALIGN2)
Definition matrix.h:1583
Matrix(const Matrix< U > &m)
Definition matrix.h:1619
TMatrix< T > operator*(const Matrix< T > &) const
Definition matrix.h:1966
Matrix< T > & setunit(const T &f=(T) 1)
Definition matrix.h:1659
Matrix(const Vector< T > &v, const enum rowcolvec r=colvec)
Definition matrix.h:1596
Matrix< T > & operator-=(const Matrix< T > &a)
Definition matrix.h:1673
friend NOINST char FRIEND_TBCI2__ gaussj FGD(Matrix< T > &, Matrix< T > &)
TSMatrix< T > operator/(const T &) const
Definition matrix.h:1883
Matrix(const unsigned d=0)
Definition matrix.h:1587
double fabs() const
Definition matrix.h:1752
Matrix< T > & operator+=(const Matrix< T > &a)
Definition matrix.h:1671
Matrix< T > & resize(const unsigned d)
Definition matrix.h:1649
double fabssqr() const
Definition matrix.h:2102
~Matrix()
Definition matrix.h:1612
Matrix< T > & operator*=(const T &a)
Definition matrix.h:1849
Matrix< T > & div_row(const T &, const unsigned)
Definition matrix.h:2296
Matrix(const T &v, const unsigned r, const unsigned c)
Definition matrix.h:1593
T value_type
Definition matrix.h:1581
T element_type
Definition matrix.h:1582
TMatrix< T > operator-() const
Definition matrix.h:1694
TMatrix< T > operator+(const Matrix< T > &) const
Definition matrix.h:1890
Matrix< T > & clear()
Definition matrix.h:1661
TVector< T > transMult(const Vector< T > &) const HOT
Definition matrix.h:2184
Matrix< T > & fill(const T &v=(T) 0)
Definition matrix.h:1655
static const char * mat_info()
Definition matrix.h:1615
Matrix< T > & operator/=(const T &a)
Definition matrix.h:1855
Matrix< T > & div_rows(const Vector< T > &)
Definition matrix.h:2274
Matrix(const TMatrix< T > &tm) HOT
alias
Definition matrix.h:1605
bool operator==(const Matrix< T > &m) const
Definition matrix.h:2064
Matrix< T > & mult_row(const T &, const unsigned)
Definition matrix.h:2287
Matrix< T > & operator=(const Matrix< T > &m)
Assignment, non-resizing.
Definition matrix.h:1638
Matrix< T > & resize(const unsigned r, const unsigned c)
Definition matrix.h:1647
Matrix(const unsigned r, const unsigned c)
Definition matrix.h:1590
NumErr()
Definition except.h:65
TMatrix< T > & row_expand(const unsigned int r)
Set new numbers of rows to matrix (expansion only).
Definition matrix.h:678
friend NOINST TMatrix< T > LU_invert FGD(const BdMatrix< T > &)
int set_ptrs()
Definition matrix.h:409
TMatrix(const Matrix< U > &m)
Definition matrix.h:193
friend void FRIEND_TBCI2__ do_mat_vec_transmult_exact FGD(const unsigned start, const unsigned end, TVector< T > *res, const Matrix< T > *mat, const Vector< T > *vec) HOT
void set_col_partial(const Vector< T > &, const unsigned int, const unsigned int)
Fill partial column.
Definition matrix.h:616
TVector< T > get_col(const unsigned int) const
Column vector.
Definition matrix.h:627
friend class TSMatrix< T >
Definition matrix.h:134
T aligned_value_type TALIGN(MIN_ALIGN2)
Definition matrix.h:131
~TMatrix()
Definition matrix.h:184
TMatrix< T > & operator-()
Definition matrix.h:833
void real_destroy()
real destructor
Definition matrix.h:394
const T & getcref(const unsigned r, const unsigned c) const
Definition matrix.h:292
friend class TVector< T >
Definition matrix.h:138
unsigned int freeable
Definition matrix.h:117
TSMatrix< T > operator*=(const T &)
Definition matrix.h:955
friend NOINST TMatrix< T > lu_invert FGD(BdMatrix< T > &)
TMatrix< T > & fill(const T &=(T) 0)
Fill matrix.
Definition matrix.h:805
TSMatrix< T > operator/(const T &)
Definition matrix.h:992
double fabs() const
Definition matrix.h:389
TMatrix< T > & resize(const unsigned int, const unsigned int)
Resize Matrix, specifying rows and columns.
Definition matrix.h:655
unsigned int rows() const
number of rows
Definition matrix.h:317
TMatrix< T > & swap(TMatrix< T > &)
Definition matrix.h:1759
TMatrix< T > & operator-=(TMatrix< T >)
Definition matrix.h:920
TMatrix< T > & clear()
Clear matrix (fill with 0).
Definition matrix.h:580
T operator()(const unsigned int, const unsigned int) const HOT
Element access (desctructive for TMatrix!).
Definition matrix.h:523
TMatrix< T > & resize(const unsigned int d)
Resize Matrix to square shape.
Definition matrix.h:364
T & set(const T &val, const unsigned r, const unsigned c)
Definition matrix.h:290
unsigned int col
Definition matrix.h:116
friend void FRIEND_TBCI2__ do_mat_tsv_mult FGD(const unsigned start, const unsigned end, TVector< T > *res, const Matrix< T > *mat, const TSVector< T > *tsv) HOT
void set_row(const Vector< T > &, const unsigned int)
Fill complete row.
Definition matrix.h:589
TMatrix< T > & alias(const TMatrix< T > &m)
Definition matrix.h:504
T * getendvec() const
Definition matrix.h:127
T * endvec
Definition matrix.h:119
friend class Matrix
Definition matrix.h:190
friend class TMatrix
Definition matrix.h:191
bool operator!=(const Matrix< T > &m)
Definition matrix.h:301
TMatrix< T > & operator=(const Matrix< T > &) HOT
assignment, non-resizing
Definition matrix.h:533
TMatrix< T > transposed_copy() const
Inefficient! Use transMult if possible.
Definition matrix.h:1061
T mat_t
Definition matrix.h:112
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
friend void FRIEND_TBCI2__ do_mat_vec_transmult FGD(const unsigned start, const unsigned end, TVector< T > *res, const Matrix< T > *mat, const Vector< T > *vec) HOT
double fabssqr() const
Sum over all squared elements.
Definition matrix.h:1050
TMatrix(const TMatrix< U > &tm)
Definition matrix.h:200
unsigned int row
Definition matrix.h:116
TSMatrix< T > operator/=(const T &)
Definition matrix.h:959
friend void FRIEND_TBCI2__ do_mat_vec_mult FGD(const unsigned start, const unsigned end, TVector< T > *res, const Matrix< T > *mat, const Vector< T > *vec) HOT
TSMatrix< T > operator*(const T &)
Definition matrix.h:988
static const char * mat_info()
Definition matrix.h:180
void mark_destroy() const
mark destructible
Definition matrix.h:402
T * Tptr
Definition matrix.h:113
unsigned int columns() const
number of columns
Definition matrix.h:315
Mat_Brack< T > operator[](const unsigned int i) const
Definition matrix.h:2355
TMatrix< T > & transpose()
Definition matrix.h:1079
T * getvec() const
Definition matrix.h:126
TMatrix< T > & operator+=(TMatrix< T >)
arithmetics ...
Definition matrix.h:917
TMatrix< T > & cheapdownsizerow(const unsigned)
Resize number of rows without actually freeing memory (efficiency).
Definition matrix.h:792
T ** mat
C storage layout: mat[row][col].
Definition matrix.h:119
unsigned long dim
Definition matrix.h:115
friend class Mat_Brack< T >
Definition matrix.h:136
T & setval(const unsigned r, const unsigned c)
Definition matrix.h:283
T * getrowptr(const unsigned r)
Definition matrix.h:297
void set_row_partial(const Vector< T > &, const unsigned int, const unsigned int)
Fill partial row.
Definition matrix.h:597
T value_type
Definition matrix.h:129
T * vec
Definition matrix.h:119
TVector< T > get_row(const unsigned int) const
Row vector.
Definition matrix.h:640
friend NOINST TMatrix< T > lu_solve FGD(BdMatrix< T > &, const Matrix< T > &)
friend NOINST TMatrix< T > LU_solve FGD(const BdMatrix< T > &, const Matrix< T > &)
const T * getrowptr(const unsigned r) const
Helpers for matvecmul.
Definition matrix.h:296
TMatrix< T > & operator+(TMatrix< T >)
Definition matrix.h:974
T & setval(const T &val, const unsigned int r, const unsigned int c)
Definition matrix.h:281
T element_type
Definition matrix.h:130
T trace() const
Trace.
Definition matrix.h:812
unsigned long size() const
number of elements
Definition matrix.h:319
void set_col(const Vector< T > &, const unsigned int)
Fill complete column.
Definition matrix.h:606
bool operator==(const Matrix< T > &m)
Comparison.
Definition matrix.h:840
TMatrix< T > & setunit(const T &=(T) 1)
Set to unit matrix (optionally scaled).
Definition matrix.h:567
TSMatrix()
Definition matrix.h:1153
T * getendvec() const
Definition matrix.h:1148
T fac ALIGN(MIN_ALIGN2)
friend class TMatrix< T >
Definition matrix.h:1139
bool mut
Definition matrix.h:1127
double fabssqr()
Definition matrix.h:1530
void detach(TMatrix< T > *=0)
Definition matrix.h:1239
T * Tptr
Definition matrix.h:1136
T & getfac()
Definition matrix.h:1149
TSMatrix(const Matrix< T > &m, const T &f=(T) 1)
Definition matrix.h:1160
T * endvec
Definition matrix.h:1125
const T & getfac() const
Definition matrix.h:1150
TMatrix< T > operator+(const Matrix< T > &)
Definition matrix.h:1295
bool operator!=(const Matrix< T > &m)
Definition matrix.h:1216
TSMatrix(const TMatrix< T > &tm, const T &f=(T) 1)
Definition matrix.h:1157
TSMatrix< T > & eval(TMatrix< T > *=0)
Definition matrix.h:1280
double fabs()
Definition matrix.h:1225
unsigned int col
Definition matrix.h:1123
T * getvec() const
Definition matrix.h:1147
bool operator==(const Matrix< T > &)
Definition matrix.h:1467
T aligned_value_type TALIGN(MIN_ALIGN2)
Definition matrix.h:1144
unsigned long size() const
Definition matrix.h:1227
T value_type
Definition matrix.h:1142
TSMatrix< T > & operator*=(const T &f)
Definition matrix.h:1185
unsigned int row
Definition matrix.h:1123
void clone(bool=false, TMatrix< T > *=0)
Definition matrix.h:1260
T * vec
Definition matrix.h:1121
static const char * mat_info()
Definition matrix.h:1168
~TSMatrix()
Definition matrix.h:1155
T element_type
Definition matrix.h:1143
TSMatrix< T > & operator/=(const T &f)
Definition matrix.h:1186
T ** mat
Definition matrix.h:1124
TSMatrix< T > & operator*(const T &f)
Definition matrix.h:1187
TSMatrix< T > & operator=(const TSMatrix< T > &ts)
Definition matrix.h:1176
TSMatrix< T > & operator-()
Definition matrix.h:1192
unsigned long dim
Definition matrix.h:1122
T operator()(const unsigned int r, const unsigned int c) HOT
Definition matrix.h:1170
void real_destroy()
Definition matrix.h:1231
TSMatrix< T > & operator/(const T &f)
Definition matrix.h:1188
TSMatrix(const TSMatrix< T > &ts)
Definition matrix.h:1163
unsigned long size() const
Definition vector.h:1120
Temporary Base Class Idiom: Class TVector is used for temporary variables.
Definition vector.h:73
tbci_traits< T >::const_refval_type get(const unsigned long i) const
Definition vector.h:190
unsigned long size() const
Definition vector.h:104
T & set(const T &val, const unsigned long i) const
Definition vector.h:194
TVector(const unsigned long d=0)
Definition vector.h:84
Tensor class including arithmetics.
Definition tensor.h:467
exception class
Definition bvector.h:32
Vector(const unsigned long d=0)
Definition vector.h:1539
T(* fn)(const unsigned i1, const unsigned i2, void *par)
Definition matrix.h:2390
mat_fill_fn(T(*f)(const unsigned, const unsigned, void *))
Definition matrix.h:2391
double fabs(const TBCI__ cplx< T > &c)
Definition cplx.h:746
NAMESPACE_END NAMESPACE_CSTD TBCI__ cplx< T > sqrt(const TBCI__ cplx< T > &z)
Definition cplx.h:751
F_TSMatrix< T > ts
Definition f_matrix.h:1052
return c
Definition f_matrix.h:760
tm fac
Definition f_matrix.h:1052
F_TMatrix< T > b
Definition f_matrix.h:736
tm detach()
NAMESPACE_TBCI char gaussj(Matrix< T > &a, Matrix< T > &b)
F_TMatrix< double > lu_solve(const F_Matrix< double > &A, const F_Matrix< double > &B, int overwriteA=0)
Definition lapack.cpp:156
#define TBCIDELETE(t, v, sz)
#define REALLOC(v, os, t, s)
#define NEW(t, s)
STD__ ostream & operator<<(STD__ ostream &os, const Matrix< T > &m)
Definition matrix.h:1801
double fabssqr(const TMatrix< T > &tm)
Definition matrix.h:1054
#define NOFMA
Definition matrix.h:2381
TMatrix< T > transpose(const TMatrix< T > &tm)
Definition matrix.h:1073
STD__ istream & operator>>(STD__ istream &in, Matrix< T > &m)
Definition matrix.h:1817
int numa_optimize(const Matrix< T > &m, bool fault_in)
Definition matrix.h:2500
void job_fill_mat(struct thr_ctrl *tc)
Definition matrix.h:2408
void do_mat_tsv_mult(const unsigned start, const unsigned end, TVector< T > *res, const Matrix< T > *mat, const TSVector< T > *vec)
#define _COL
Definition matrix.h:44
void par_fill(Matrix< T > &mat, mat_fill_fn< T > fn, void *par)
Definition matrix.h:2417
void do_mat_vec_mult(const unsigned start, const unsigned end, TVector< T > *res, const Matrix< T > *mat, const Vector< T > *vec)
void do_mat_vec_transmult(const unsigned start, const unsigned end, TVector< T > *res, const Matrix< T > *mat, const Vector< T > *vec)
BVector< T > & bvfillm(BVector< T > &bv, const Matrix< T > &m)
Definition matrix.h:2248
rowcolvec
Definition matrix.h:70
@ colvec
Definition matrix.h:70
@ rowvec
Definition matrix.h:70
void job_mat_vec_transmult(struct thr_ctrl *tc)
Definition matrix.h:2142
int lu_decomp(Matrix< T > &) HOT
LU decomposes the TBCI::Matrix mat.
Definition lu_solver.h:94
#define _DIM
Definition matrix.h:42
#define _ROW
Definition matrix.h:43
#define SMP_MATSLICE2
Definition matrix.h:99
void do_fill_mat(const unsigned firstrow, const unsigned lastrow, Matrix< T > *mat, mat_fill_fn< T > fn, void *par)
Definition matrix.h:2396
void job_mat_vec_mult(struct thr_ctrl *tc)
Definition matrix.h:2134
const unsigned TMatrix< T > const Matrix< T > * a
const unsigned end
const unsigned TMatrix< T > * res
void thread_start_off(const int thr_no, thr_job_t job, const unsigned long off, const unsigned long sz,...)
Definition smp.cc:979
void thread_wait(const int thr_no, struct job_output *out)
Definition smp.cc:997
int main_numa_node
Definition smp.cc:110
struct thr_struct * threads
Definition smp.cc:106
int numa_avail
Definition smp.cc:105
void(* thr_job_t)(struct thr_ctrl *)
Before the double inclusion guard on purpose!
Definition smp.h:126
#define threads_avail(x)
Definition smp.h:322
int numa_node
Definition smp.h:5
long t_res_l
Definition smp.h:148
unsigned long t_off
Definition smp.h:172
unsigned long t_size
Definition smp.h:171
void * t_par[6]
Definition smp.h:173
unsigned int do_exactsum()
Definition tbci_param.h:150
#define STD_SMP_TEMPLATE5(oper, dm, a1, a2, a3, a4, a5)
Definition vector.h:658
#define STD_SMP_TEMPLATE2V(oper, dm, a1, a2)
Definition vector.h:644
#define STD_SMP_TEMPLATE4V(oper, dm, a1, a2, a3, a4)
Definition vector.h:654
#define STD_SMP_TEMPLATE3VV(oper, dm, a1, a2, a3)
Definition vector.h:648
#define STD_SMP_TEMPLATE3VC(oper, dm, a1, a2, a3)
Definition vector.h:650
#define STD_SMP_TEMPLATE2C(oper, dm, a1, a2)
Definition vector.h:646
#define STD_SMP_TEMPLATE4C(oper, dm, a1, a2, a3, a4)
Definition vector.h:656
#define large