39 #ifndef GMM_MATRIX_H__
40 #define GMM_MATRIX_H__
56 struct identity_matrix {
57 template <
class MAT>
void build_with(
const MAT &) {}
60 template <
typename M>
inline
61 void add(
const identity_matrix&, M &v1) {
62 size_type n = std::min(gmm::mat_nrows(v1), gmm::mat_ncols(v1));
64 v1(i,i) +=
typename linalg_traits<M>::value_type(1);
66 template <
typename M>
inline
67 void add(
const identity_matrix &II,
const M &v1)
68 {
add(II, linalg_const_cast(v1)); }
70 template <
typename V1,
typename V2>
inline
71 void mult(
const identity_matrix&,
const V1 &v1, V2 &v2)
73 template <
typename V1,
typename V2>
inline
74 void mult(
const identity_matrix&,
const V1 &v1,
const V2 &v2)
76 template <
typename V1,
typename V2,
typename V3>
inline
77 void mult(
const identity_matrix&,
const V1 &v1,
const V2 &v2, V3 &v3)
79 template <
typename V1,
typename V2,
typename V3>
inline
80 void mult(
const identity_matrix&,
const V1 &v1,
const V2 &v2,
const V3 &v3)
82 template <
typename V1,
typename V2>
inline
83 void left_mult(
const identity_matrix&,
const V1 &v1, V2 &v2)
85 template <
typename V1,
typename V2>
inline
86 void left_mult(
const identity_matrix&,
const V1 &v1,
const V2 &v2)
88 template <
typename V1,
typename V2>
inline
89 void right_mult(
const identity_matrix&,
const V1 &v1, V2 &v2)
91 template <
typename V1,
typename V2>
inline
92 void right_mult(
const identity_matrix&,
const V1 &v1,
const V2 &v2)
94 template <
typename V1,
typename V2>
inline
95 void transposed_left_mult(
const identity_matrix&,
const V1 &v1, V2 &v2)
97 template <
typename V1,
typename V2>
inline
98 void transposed_left_mult(
const identity_matrix&,
const V1 &v1,
const V2 &v2)
100 template <
typename V1,
typename V2>
inline
101 void transposed_right_mult(
const identity_matrix&,
const V1 &v1, V2 &v2)
103 template <
typename V1,
typename V2>
inline
104 void transposed_right_mult(
const identity_matrix&,
const V1 &v1,
const V2 &v2)
106 template <
typename M>
void copy_ident(
const identity_matrix&, M &m) {
107 size_type i = 0, n = std::min(mat_nrows(m), mat_ncols(m));
109 for (; i < n; ++i) m(i,i) =
typename linalg_traits<M>::value_type(1);
111 template <
typename M>
inline void copy(
const identity_matrix&, M &m)
112 { copy_ident(identity_matrix(), m); }
113 template <
typename M>
inline void copy(
const identity_matrix &,
const M &m)
114 { copy_ident(identity_matrix(), linalg_const_cast(m)); }
115 template <
typename V1,
typename V2>
inline
116 typename linalg_traits<V1>::value_type
117 vect_sp(
const identity_matrix &,
const V1 &v1,
const V2 &v2)
119 template <
typename V1,
typename V2>
inline
120 typename linalg_traits<V1>::value_type
121 vect_hp(
const identity_matrix &,
const V1 &v1,
const V2 &v2)
123 template<
typename M>
inline bool is_identity(
const M&) {
return false; }
124 inline bool is_identity(
const identity_matrix&) {
return true; }
132 template<
typename V>
class row_matrix {
139 typedef typename linalg_traits<V>::reference reference;
140 typedef typename linalg_traits<V>::value_type value_type;
143 row_matrix(
void) : nc(0) {}
152 typename std::vector<V>::iterator begin(
void)
153 {
return li.begin(); }
154 typename std::vector<V>::iterator end(
void)
156 typename std::vector<V>::const_iterator begin(
void)
const
157 {
return li.begin(); }
158 typename std::vector<V>::const_iterator end(
void)
const
163 const V& row(
size_type i)
const {
return li[i]; }
164 V& operator[](
size_type i) {
return li[i]; }
165 const V& operator[](
size_type i)
const {
return li[i]; }
167 inline size_type nrows(
void)
const {
return li.size(); }
168 inline size_type ncols(
void)
const {
return nc; }
170 void swap(row_matrix<V> &m) { std::swap(li, m.li); std::swap(nc, m.nc); }
177 for (
size_type i=nr; i < m; ++i) gmm::resize(li[i], n);
179 for (
size_type i=0; i < nr; ++i) gmm::resize(li[i], n);
185 template<
typename V>
void row_matrix<V>::clear_mat()
188 template <
typename V>
struct linalg_traits<row_matrix<V> > {
189 typedef row_matrix<V> this_type;
190 typedef this_type origin_type;
191 typedef linalg_false is_reference;
192 typedef abstract_matrix linalg_type;
193 typedef typename linalg_traits<V>::value_type value_type;
194 typedef typename linalg_traits<V>::reference reference;
195 typedef typename linalg_traits<V>::storage_type storage_type;
196 typedef V & sub_row_type;
197 typedef const V & const_sub_row_type;
198 typedef typename std::vector<V>::iterator row_iterator;
199 typedef typename std::vector<V>::const_iterator const_row_iterator;
200 typedef abstract_null_type sub_col_type;
201 typedef abstract_null_type const_sub_col_type;
202 typedef abstract_null_type col_iterator;
203 typedef abstract_null_type const_col_iterator;
204 typedef row_major sub_orientation;
205 typedef linalg_true index_sorted;
206 static size_type nrows(
const this_type &m) {
return m.nrows(); }
207 static size_type ncols(
const this_type &m) {
return m.ncols(); }
208 static row_iterator row_begin(this_type &m) {
return m.begin(); }
209 static row_iterator row_end(this_type &m) {
return m.end(); }
210 static const_row_iterator row_begin(
const this_type &m)
211 {
return m.begin(); }
212 static const_row_iterator row_end(
const this_type &m)
214 static const_sub_row_type row(
const const_row_iterator &it)
215 {
return const_sub_row_type(*it); }
216 static sub_row_type row(
const row_iterator &it)
217 {
return sub_row_type(*it); }
218 static origin_type* origin(this_type &m) {
return &m; }
219 static const origin_type* origin(
const this_type &m) {
return &m; }
220 static void do_clear(this_type &m) { m.clear_mat(); }
221 static value_type access(
const const_row_iterator &itrow,
size_type j)
222 {
return (*itrow)[j]; }
223 static reference access(
const row_iterator &itrow,
size_type j)
224 {
return (*itrow)[j]; }
228 { GMM_ASSERT1(
false,
"Sorry, to be done"); }
231 template<
typename V> std::ostream &
operator <<
232 (std::ostream &o,
const row_matrix<V>& m) { gmm::write(o,m);
return o; }
240 template<
typename V>
class col_matrix {
247 typedef typename linalg_traits<V>::reference reference;
248 typedef typename linalg_traits<V>::value_type value_type;
251 col_matrix(
void) : nr(0) {}
261 const V& col(
size_type i)
const {
return li[i]; }
262 V& operator[](
size_type i) {
return li[i]; }
263 const V& operator[](
size_type i)
const {
return li[i]; }
265 typename std::vector<V>::iterator begin(
void)
266 {
return li.begin(); }
267 typename std::vector<V>::iterator end(
void)
269 typename std::vector<V>::const_iterator begin(
void)
const
270 {
return li.begin(); }
271 typename std::vector<V>::const_iterator end(
void)
const
274 inline size_type ncols(
void)
const {
return li.size(); }
275 inline size_type nrows(
void)
const {
return nr; }
277 void swap(col_matrix<V> &m) { std::swap(li, m.li); std::swap(nr, m.nr); }
284 for (
size_type i=nc; i < n; ++i) gmm::resize(li[i], m);
286 for (
size_type i=0; i < nc; ++i) gmm::resize(li[i], m);
291 template<
typename V>
void col_matrix<V>::clear_mat()
294 template <
typename V>
struct linalg_traits<col_matrix<V> > {
295 typedef col_matrix<V> this_type;
296 typedef this_type origin_type;
297 typedef linalg_false is_reference;
298 typedef abstract_matrix linalg_type;
299 typedef typename linalg_traits<V>::value_type value_type;
300 typedef typename linalg_traits<V>::reference reference;
301 typedef typename linalg_traits<V>::storage_type storage_type;
302 typedef V &sub_col_type;
303 typedef const V &const_sub_col_type;
304 typedef typename std::vector<V>::iterator col_iterator;
305 typedef typename std::vector<V>::const_iterator const_col_iterator;
306 typedef abstract_null_type sub_row_type;
307 typedef abstract_null_type const_sub_row_type;
308 typedef abstract_null_type row_iterator;
309 typedef abstract_null_type const_row_iterator;
310 typedef col_major sub_orientation;
311 typedef linalg_true index_sorted;
312 static size_type nrows(
const this_type &m) {
return m.nrows(); }
313 static size_type ncols(
const this_type &m) {
return m.ncols(); }
314 static col_iterator col_begin(this_type &m) {
return m.begin(); }
315 static col_iterator col_end(this_type &m) {
return m.end(); }
316 static const_col_iterator col_begin(
const this_type &m)
317 {
return m.begin(); }
318 static const_col_iterator col_end(
const this_type &m)
320 static const_sub_col_type col(
const const_col_iterator &it)
322 static sub_col_type col(
const col_iterator &it)
324 static origin_type* origin(this_type &m) {
return &m; }
325 static const origin_type* origin(
const this_type &m) {
return &m; }
326 static void do_clear(this_type &m) { m.clear_mat(); }
327 static value_type access(
const const_col_iterator &itcol,
size_type j)
328 {
return (*itcol)[j]; }
329 static reference access(
const col_iterator &itcol,
size_type j)
330 {
return (*itcol)[j]; }
334 { GMM_ASSERT1(
false,
"Sorry, to be done"); }
337 template<
typename V> std::ostream &
operator <<
338 (std::ostream &o,
const col_matrix<V>& m) { gmm::write(o,m);
return o; }
346 template<
typename T>
class dense_matrix :
public std::vector<T> {
349 typedef typename std::vector<T>::iterator iterator;
350 typedef typename std::vector<T>::const_iterator const_iterator;
351 typedef typename std::vector<T>::reference reference;
352 typedef typename std::vector<T>::const_reference const_reference;
360 GMM_ASSERT2(l < nbl && c < nbc,
"out of range");
361 return *(this->begin() + c*nbl+l);
364 GMM_ASSERT2(l < nbl && c < nbc,
"out of range");
365 return *(this->begin() + c*nbl+l);
368 std::vector<T> &as_vector(
void) {
return *
this; }
369 const std::vector<T> &as_vector(
void)
const {
return *
this; }
375 void fill(T a, T b = T(0));
376 inline size_type nrows(
void)
const {
return nbl; }
377 inline size_type ncols(
void)
const {
return nbc; }
378 void swap(dense_matrix<T> &m)
379 { std::vector<T>::swap(m); std::swap(nbc, m.nbc); std::swap(nbl, m.nbl); }
382 : std::vector<T>(c*l), nbc(c), nbl(l) {}
383 dense_matrix(
void) { nbl = nbc = 0; }
387 GMM_ASSERT2(n*m == nbl*nbc,
"dimensions mismatch");
391 template<
typename T>
void dense_matrix<T>::base_resize(
size_type m,
393 { std::vector<T>::resize(n*m); nbl = m; nbc = n; }
396 if (n*m > nbc*nbl) std::vector<T>::resize(n*m);
398 for (
size_type i = 1; i < std::min(nbc, n); ++i)
399 std::copy(this->begin()+i*nbl, this->begin()+(i*nbl+m),
401 for (
size_type i = std::min(nbc, n); i < n; ++i)
402 std::fill(this->begin()+(i*m), this->begin()+(i+1)*m, T(0));
405 for (
size_type i = std::min(nbc, n); i > 1; --i)
406 std::copy(this->begin()+(i-1)*nbl, this->begin()+i*nbl,
407 this->begin()+(i-1)*m);
408 for (
size_type i = 0; i < std::min(nbc, n); ++i)
409 std::fill(this->begin()+(i*m+nbl), this->begin()+(i+1)*m, T(0));
411 if (n*m < nbc*nbl) std::vector<T>::resize(n*m);
415 template<
typename T>
void dense_matrix<T>::fill(T a, T b) {
416 std::fill(this->begin(), this->end(), b);
418 if (a != b)
for (
size_type i = 0; i < n; ++i) (*
this)(i,i) = a;
421 template <
typename T>
struct linalg_traits<dense_matrix<T> > {
422 typedef dense_matrix<T> this_type;
423 typedef this_type origin_type;
424 typedef linalg_false is_reference;
425 typedef abstract_matrix linalg_type;
426 typedef T value_type;
427 typedef T& reference;
428 typedef abstract_dense storage_type;
429 typedef tab_ref_reg_spaced_with_origin<
typename this_type::iterator,
430 this_type> sub_row_type;
431 typedef tab_ref_reg_spaced_with_origin<
typename this_type::const_iterator,
432 this_type> const_sub_row_type;
433 typedef dense_compressed_iterator<
typename this_type::iterator,
434 typename this_type::iterator,
435 this_type *> row_iterator;
436 typedef dense_compressed_iterator<
typename this_type::const_iterator,
437 typename this_type::iterator,
438 const this_type *> const_row_iterator;
439 typedef tab_ref_with_origin<
typename this_type::iterator,
440 this_type> sub_col_type;
441 typedef tab_ref_with_origin<
typename this_type::const_iterator,
442 this_type> const_sub_col_type;
443 typedef dense_compressed_iterator<
typename this_type::iterator,
444 typename this_type::iterator,
445 this_type *> col_iterator;
446 typedef dense_compressed_iterator<
typename this_type::const_iterator,
447 typename this_type::iterator,
448 const this_type *> const_col_iterator;
449 typedef col_and_row sub_orientation;
450 typedef linalg_true index_sorted;
451 static size_type nrows(
const this_type &m) {
return m.nrows(); }
452 static size_type ncols(
const this_type &m) {
return m.ncols(); }
453 static const_sub_row_type row(
const const_row_iterator &it)
454 {
return const_sub_row_type(*it, it.nrows, it.ncols, it.origin); }
455 static const_sub_col_type col(
const const_col_iterator &it)
456 {
return const_sub_col_type(*it, *it + it.nrows, it.origin); }
457 static sub_row_type row(
const row_iterator &it)
458 {
return sub_row_type(*it, it.nrows, it.ncols, it.origin); }
459 static sub_col_type col(
const col_iterator &it)
460 {
return sub_col_type(*it, *it + it.nrows, it.origin); }
461 static row_iterator row_begin(this_type &m)
462 {
return row_iterator(m.begin(), m.size() ? 1 : 0, m.nrows(), m.ncols(), 0, &m); }
463 static row_iterator row_end(this_type &m)
464 {
return row_iterator(m.begin(), m.size() ? 1 : 0, m.nrows(), m.ncols(), m.nrows(), &m); }
465 static const_row_iterator row_begin(
const this_type &m)
466 {
return const_row_iterator(m.begin(), m.size() ? 1 : 0, m.nrows(), m.ncols(), 0, &m); }
467 static const_row_iterator row_end(
const this_type &m)
468 {
return const_row_iterator(m.begin(), m.size() ? 1 : 0, m.nrows(), m.ncols(), m.nrows(), &m); }
469 static col_iterator col_begin(this_type &m)
470 {
return col_iterator(m.begin(), m.nrows(), m.nrows(), m.ncols(), 0, &m); }
471 static col_iterator col_end(this_type &m)
472 {
return col_iterator(m.begin(), m.nrows(), m.nrows(), m.ncols(), m.ncols(), &m); }
473 static const_col_iterator col_begin(
const this_type &m)
474 {
return const_col_iterator(m.begin(), m.nrows(), m.nrows(), m.ncols(), 0, &m); }
475 static const_col_iterator col_end(
const this_type &m)
476 {
return const_col_iterator(m.begin(),m.nrows(),m.nrows(),m.ncols(),m.ncols(), &m); }
477 static origin_type* origin(this_type &m) {
return &m; }
478 static const origin_type* origin(
const this_type &m) {
return &m; }
479 static void do_clear(this_type &m) { m.fill(value_type(0)); }
480 static value_type access(
const const_col_iterator &itcol,
size_type j)
481 {
return (*itcol)[j]; }
482 static reference access(
const col_iterator &itcol,
size_type j)
483 {
return (*itcol)[j]; }
490 template<
typename T> std::ostream &
operator <<
491 (std::ostream &o,
const dense_matrix<T>& m) { gmm::write(o,m);
return o; }
500 template <
typename T,
typename IND_TYPE =
unsigned int,
int shift = 0>
504 std::vector<IND_TYPE> ir;
505 std::vector<IND_TYPE> jc;
508 typedef T value_type;
509 typedef T& access_type;
511 template <
typename Matrix>
void init_with_good_format(
const Matrix &B);
512 template <
typename Matrix>
void init_with(
const Matrix &A);
514 { init_with_good_format(B); }
515 void init_with(
const col_matrix<wsvector<T> > &B)
516 { init_with_good_format(B); }
517 template <
typename PT1,
typename PT2,
typename PT3,
int cshift>
518 void init_with(
const csc_matrix_ref<PT1,PT2,PT3,cshift>& B)
519 { init_with_good_format(B); }
520 template <
typename U,
int cshift>
521 void init_with(
const csc_matrix<U, IND_TYPE, cshift>& B)
522 { init_with_good_format(B); }
526 csc_matrix(
void) : nc(0), nr(0) {}
529 size_type nrows(
void)
const {
return nr; }
530 size_type ncols(
void)
const {
return nc; }
531 void swap(csc_matrix<T, IND_TYPE, shift> &m) {
533 std::swap(ir, m.ir); std::swap(jc, m.jc);
534 std::swap(nc, m.nc); std::swap(nr, m.nr);
537 {
return mat_col(*
this, j)[i]; }
540 template <
typename T,
typename IND_TYPE,
int shift>
template<
typename Matrix>
541 void csc_matrix<T, IND_TYPE, shift>::init_with_good_format(
const Matrix &B) {
542 typedef typename linalg_traits<Matrix>::const_sub_col_type col_type;
543 nc = mat_ncols(B); nr = mat_nrows(B);
547 jc[j+1] = IND_TYPE(jc[j] +
nnz(mat_const_col(B, j)));
552 col_type col = mat_const_col(B, j);
553 typename linalg_traits<typename org_type<col_type>::t>::const_iterator
554 it = vect_const_begin(col), ite = vect_const_end(col);
555 for (
size_type k = 0; it != ite; ++it, ++k) {
556 pr[jc[j]-shift+k] = *it;
557 ir[jc[j]-shift+k] = IND_TYPE(it.index() + shift);
562 template <
typename T,
typename IND_TYPE,
int shift>
563 template <
typename Matrix>
564 void csc_matrix<T, IND_TYPE, shift>::init_with(
const Matrix &A) {
565 col_matrix<wsvector<T> > B(mat_nrows(A), mat_ncols(A));
567 init_with_good_format(B);
570 template <
typename T,
typename IND_TYPE,
int shift>
571 void csc_matrix<T, IND_TYPE, shift>::init_with_identity(
size_type n) {
573 pr.resize(nc); ir.resize(nc); jc.resize(nc+1);
575 { ir[j] = jc[j] = shift + j; pr[j] = T(1); }
579 template <
typename T,
typename IND_TYPE,
int shift>
582 pr.resize(1); ir.resize(1); jc.resize(nc+1);
583 for (
size_type j = 0; j <= nc; ++j) jc[j] = shift;
586 template <
typename T,
typename IND_TYPE,
int shift>
587 struct linalg_traits<csc_matrix<T, IND_TYPE, shift> > {
588 typedef csc_matrix<T, IND_TYPE, shift> this_type;
589 typedef linalg_const is_reference;
590 typedef abstract_matrix linalg_type;
591 typedef T value_type;
592 typedef T origin_type;
594 typedef abstract_sparse storage_type;
595 typedef abstract_null_type sub_row_type;
596 typedef abstract_null_type const_sub_row_type;
597 typedef abstract_null_type row_iterator;
598 typedef abstract_null_type const_row_iterator;
599 typedef abstract_null_type sub_col_type;
600 typedef cs_vector_ref<const T *, const IND_TYPE *, shift>
602 typedef sparse_compressed_iterator<
const T *,
const IND_TYPE *,
603 const IND_TYPE *, shift>
605 typedef abstract_null_type col_iterator;
606 typedef col_major sub_orientation;
607 typedef linalg_true index_sorted;
608 static size_type nrows(
const this_type &m) {
return m.nrows(); }
609 static size_type ncols(
const this_type &m) {
return m.ncols(); }
610 static const_col_iterator col_begin(
const this_type &m)
611 {
return const_col_iterator(&m.pr[0],&m.ir[0],&m.jc[0], m.nr, &m.pr[0]); }
612 static const_col_iterator col_end(
const this_type &m) {
613 return const_col_iterator(&m.pr[0],&m.ir[0],&m.jc[0]+m.nc,
616 static const_sub_col_type col(
const const_col_iterator &it) {
617 return const_sub_col_type(it.pr + *(it.jc) - shift,
618 it.ir + *(it.jc) - shift,
619 *(it.jc + 1) - *(it.jc), it.n);
621 static const origin_type* origin(
const this_type &m) {
return &m.pr[0]; }
622 static void do_clear(this_type &m) { m.do_clear(); }
623 static value_type access(
const const_col_iterator &itcol,
size_type j)
624 {
return col(itcol)[j]; }
627 template <
typename T,
typename IND_TYPE,
int shift>
628 std::ostream &
operator <<
629 (std::ostream &o,
const csc_matrix<T, IND_TYPE, shift>& m)
630 { gmm::write(o,m);
return o; }
632 template <
typename T,
typename IND_TYPE,
int shift>
633 inline void copy(
const identity_matrix &, csc_matrix<T, IND_TYPE, shift>& M)
634 { M.init_with_identity(mat_nrows(M)); }
636 template <
typename Matrix,
typename T,
typename IND_TYPE,
int shift>
637 inline void copy(
const Matrix &A, csc_matrix<T, IND_TYPE, shift>& M)
646 template <
typename T,
typename IND_TYPE =
unsigned int,
int shift = 0>
650 std::vector<IND_TYPE> ir;
651 std::vector<IND_TYPE> jc;
654 typedef T value_type;
655 typedef T& access_type;
658 template <
typename Matrix>
void init_with_good_format(
const Matrix &B);
659 void init_with(
const row_matrix<wsvector<T> > &B)
660 { init_with_good_format(B); }
661 void init_with(
const row_matrix<rsvector<T> > &B)
662 { init_with_good_format(B); }
663 template <
typename PT1,
typename PT2,
typename PT3,
int cshift>
664 void init_with(
const csr_matrix_ref<PT1,PT2,PT3,cshift>& B)
665 { init_with_good_format(B); }
666 template <
typename U,
int cshift>
667 void init_with(
const csr_matrix<U, IND_TYPE, cshift>& B)
668 { init_with_good_format(B); }
670 template <
typename Matrix>
void init_with(
const Matrix &A);
673 csr_matrix(
void) : nc(0), nr(0) {}
676 size_type nrows(
void)
const {
return nr; }
677 size_type ncols(
void)
const {
return nc; }
678 void swap(csr_matrix<T, IND_TYPE, shift> &m) {
680 std::swap(ir,m.ir); std::swap(jc, m.jc);
681 std::swap(nc, m.nc); std::swap(nr,m.nr);
685 {
return mat_row(*
this, i)[j]; }
688 template <
typename T,
typename IND_TYPE,
int shift>
template <
typename Matrix>
689 void csr_matrix<T, IND_TYPE, shift>::init_with_good_format(
const Matrix &B) {
690 typedef typename linalg_traits<Matrix>::const_sub_row_type row_type;
691 nc = mat_ncols(B); nr = mat_nrows(B);
695 jc[j+1] = IND_TYPE(jc[j] +
nnz(mat_const_row(B, j)));
700 row_type row = mat_const_row(B, j);
701 typename linalg_traits<typename org_type<row_type>::t>::const_iterator
702 it = vect_const_begin(row), ite = vect_const_end(row);
703 for (
size_type k = 0; it != ite; ++it, ++k) {
704 pr[jc[j]-shift+k] = *it;
705 ir[jc[j]-shift+k] = IND_TYPE(it.index()+shift);
710 template <
typename T,
typename IND_TYPE,
int shift>
template <
typename Matrix>
711 void csr_matrix<T, IND_TYPE, shift>::init_with(
const Matrix &A) {
712 row_matrix<wsvector<T> > B(mat_nrows(A), mat_ncols(A));
714 init_with_good_format(B);
717 template <
typename T,
typename IND_TYPE,
int shift>
718 void csr_matrix<T, IND_TYPE, shift>::init_with_identity(
size_type n) {
720 pr.resize(nr); ir.resize(nr); jc.resize(nr+1);
722 { ir[j] = jc[j] = shift + j; pr[j] = T(1); }
726 template <
typename T,
typename IND_TYPE,
int shift>
729 pr.resize(1); ir.resize(1); jc.resize(nr+1);
730 for (
size_type j = 0; j < nr; ++j) jc[j] = shift;
735 template <
typename T,
typename IND_TYPE,
int shift>
736 struct linalg_traits<csr_matrix<T, IND_TYPE, shift> > {
737 typedef csr_matrix<T, IND_TYPE, shift> this_type;
738 typedef linalg_const is_reference;
739 typedef abstract_matrix linalg_type;
740 typedef T value_type;
741 typedef T origin_type;
743 typedef abstract_sparse storage_type;
744 typedef abstract_null_type sub_col_type;
745 typedef abstract_null_type const_sub_col_type;
746 typedef abstract_null_type col_iterator;
747 typedef abstract_null_type const_col_iterator;
748 typedef abstract_null_type sub_row_type;
749 typedef cs_vector_ref<const T *, const IND_TYPE *, shift>
751 typedef sparse_compressed_iterator<
const T *,
const IND_TYPE *,
752 const IND_TYPE *, shift>
754 typedef abstract_null_type row_iterator;
755 typedef row_major sub_orientation;
756 typedef linalg_true index_sorted;
757 static size_type nrows(
const this_type &m) {
return m.nrows(); }
758 static size_type ncols(
const this_type &m) {
return m.ncols(); }
759 static const_row_iterator row_begin(
const this_type &m)
760 {
return const_row_iterator(&m.pr[0], &m.ir[0], &m.jc[0], m.nc, &m.pr[0]); }
761 static const_row_iterator row_end(
const this_type &m)
762 {
return const_row_iterator(&m.pr[0], &m.ir[0], &m.jc[0] + m.nr, m.nc, &m.pr[0]); }
763 static const_sub_row_type row(
const const_row_iterator &it) {
764 return const_sub_row_type(it.pr + *(it.jc) - shift,
765 it.ir + *(it.jc) - shift,
766 *(it.jc + 1) - *(it.jc), it.n);
768 static const origin_type* origin(
const this_type &m) {
return &m.pr[0]; }
769 static void do_clear(this_type &m) { m.do_clear(); }
770 static value_type access(
const const_row_iterator &itrow,
size_type j)
771 {
return row(itrow)[j]; }
774 template <
typename T,
typename IND_TYPE,
int shift>
775 std::ostream &
operator <<
776 (std::ostream &o,
const csr_matrix<T, IND_TYPE, shift>& m)
777 { gmm::write(o,m);
return o; }
779 template <
typename T,
typename IND_TYPE,
int shift>
780 inline void copy(
const identity_matrix &, csr_matrix<T, IND_TYPE, shift>& M)
781 { M.init_with_identity(mat_nrows(M)); }
783 template <
typename Matrix,
typename T,
typename IND_TYPE,
int shift>
784 inline void copy(
const Matrix &A, csr_matrix<T, IND_TYPE, shift>& M)
793 template <
typename MAT>
class block_matrix {
795 std::vector<MAT> blocks;
798 std::vector<sub_interval> introw, intcol;
801 typedef typename linalg_traits<MAT>::value_type value_type;
802 typedef typename linalg_traits<MAT>::reference reference;
804 size_type nrows(
void)
const {
return introw[nrowblocks_-1].max; }
805 size_type ncols(
void)
const {
return intcol[ncolblocks_-1].max; }
806 size_type nrowblocks(
void)
const {
return nrowblocks_; }
807 size_type ncolblocks(
void)
const {
return ncolblocks_; }
808 const sub_interval &subrowinterval(
size_type i)
const {
return introw[i]; }
809 const sub_interval &subcolinterval(
size_type i)
const {
return intcol[i]; }
811 {
return blocks[j*ncolblocks_+i]; }
813 {
return blocks[j*ncolblocks_+i]; }
818 for (k = 0; k < nrowblocks_; ++k)
819 if (i >= introw[k].min && i < introw[k].max)
break;
820 for (l = 0; l < nrowblocks_; ++l)
821 if (j >= introw[l].min && j < introw[l].max)
break;
822 return (block(k, l))(i - introw[k].min, j - introw[l].min);
826 for (k = 0; k < nrowblocks_; ++k)
827 if (i >= introw[k].min && i < introw[k].max)
break;
828 for (l = 0; l < nrowblocks_; ++l)
829 if (j >= introw[l].min && j < introw[l].max)
break;
830 return (block(k, l))(i - introw[k].min, j - introw[l].min);
833 template <
typename CONT>
void resize(
const CONT &c1,
const CONT &c2);
834 template <
typename CONT> block_matrix(
const CONT &c1,
const CONT &c2)
836 block_matrix(
void) {}
840 template <
typename MAT>
struct linalg_traits<block_matrix<MAT> > {
841 typedef block_matrix<MAT> this_type;
842 typedef linalg_false is_reference;
843 typedef abstract_matrix linalg_type;
844 typedef this_type origin_type;
845 typedef typename linalg_traits<MAT>::value_type value_type;
846 typedef typename linalg_traits<MAT>::reference reference;
847 typedef typename linalg_traits<MAT>::storage_type storage_type;
848 typedef abstract_null_type sub_row_type;
849 typedef abstract_null_type const_sub_row_type;
850 typedef abstract_null_type row_iterator;
851 typedef abstract_null_type const_row_iterator;
852 typedef abstract_null_type sub_col_type;
853 typedef abstract_null_type const_sub_col_type;
854 typedef abstract_null_type col_iterator;
855 typedef abstract_null_type const_col_iterator;
856 typedef abstract_null_type sub_orientation;
857 typedef linalg_true index_sorted;
858 static size_type nrows(
const this_type &m) {
return m.nrows(); }
859 static size_type ncols(
const this_type &m) {
return m.ncols(); }
860 static origin_type* origin(this_type &m) {
return &m; }
861 static const origin_type* origin(
const this_type &m) {
return &m; }
862 static void do_clear(this_type &m) { m.do_clear(); }
865 { GMM_ASSERT1(
false,
"Sorry, to be done"); }
867 { GMM_ASSERT1(
false,
"Sorry, to be done"); }
870 template <
typename MAT>
void block_matrix<MAT>::do_clear(
void) {
871 for (
size_type j = 0, l = 0; j < ncolblocks_; ++j)
872 for (
size_type i = 0, k = 0; i < nrowblocks_; ++i)
876 template <
typename MAT>
template <
typename CONT>
877 void block_matrix<MAT>::resize(
const CONT &c1,
const CONT &c2) {
878 nrowblocks_ = c1.size(); ncolblocks_ = c2.size();
879 blocks.resize(nrowblocks_ * ncolblocks_);
880 intcol.resize(ncolblocks_);
881 introw.resize(nrowblocks_);
882 for (
size_type j = 0, l = 0; j < ncolblocks_; ++j) {
883 intcol[j] = sub_interval(l, c2[j]); l += c2[j];
884 for (
size_type i = 0, k = 0; i < nrowblocks_; ++i) {
885 if (j == 0) { introw[i] = sub_interval(k, c1[i]); k += c1[i]; }
886 block(i, j) = MAT(c1[i], c2[j]);
891 template <
typename M1,
typename M2>
892 void copy(
const block_matrix<M1> &m1, M2 &m2) {
893 for (
size_type j = 0; j < m1.ncolblocks(); ++j)
894 for (
size_type i = 0; i < m1.nrowblocks(); ++i)
895 copy(m1.block(i,j), sub_matrix(m2, m1.subrowinterval(i),
896 m1.subcolinterval(j)));
899 template <
typename M1,
typename M2>
900 void copy(
const block_matrix<M1> &m1,
const M2 &m2)
901 {
copy(m1, linalg_const_cast(m2)); }
904 template <
typename MAT,
typename V1,
typename V2>
905 void mult(
const block_matrix<MAT> &m,
const V1 &v1, V2 &v2) {
907 typename sub_vector_type<V2 *, sub_interval>::vector_type sv;
908 for (
size_type i = 0; i < m.nrowblocks() ; ++i)
909 for (
size_type j = 0; j < m.ncolblocks() ; ++j) {
910 sv = sub_vector(v2, m.subrowinterval(i));
912 sub_vector(v1, m.subcolinterval(j)), sv, sv);
916 template <
typename MAT,
typename V1,
typename V2,
typename V3>
917 void mult(
const block_matrix<MAT> &m,
const V1 &v1,
const V2 &v2, V3 &v3) {
918 typename sub_vector_type<V3 *, sub_interval>::vector_type sv;
919 for (
size_type i = 0; i < m.nrowblocks() ; ++i)
920 for (
size_type j = 0; j < m.ncolblocks() ; ++j) {
921 sv = sub_vector(v3, m.subrowinterval(i));
924 sub_vector(v1, m.subcolinterval(j)),
925 sub_vector(v2, m.subrowinterval(i)), sv);
928 sub_vector(v1, m.subcolinterval(j)), sv, sv);
933 template <
typename MAT,
typename V1,
typename V2>
934 void mult(
const block_matrix<MAT> &m,
const V1 &v1,
const V2 &v2)
935 { mult(m, v1, linalg_const_cast(v2)); }
937 template <
typename MAT,
typename V1,
typename V2,
typename V3>
938 void mult(
const block_matrix<MAT> &m,
const V1 &v1,
const V2 &v2,
940 { mult_const(m, v1, v2, linalg_const_cast(v3)); }
956 template <
typename T>
inline MPI_Datatype mpi_type(T)
957 { GMM_ASSERT1(
false,
"Sorry unsupported type");
return MPI_FLOAT; }
958 inline MPI_Datatype mpi_type(
double) {
return MPI_DOUBLE; }
959 inline MPI_Datatype mpi_type(
float) {
return MPI_FLOAT; }
960 inline MPI_Datatype mpi_type(
long double) {
return MPI_LONG_DOUBLE; }
962 inline MPI_Datatype mpi_type(std::complex<float>) {
return MPI_COMPLEX; }
963 inline MPI_Datatype mpi_type(std::complex<double>) {
return MPI_DOUBLE_COMPLEX; }
965 inline MPI_Datatype mpi_type(
int) {
return MPI_INT; }
966 inline MPI_Datatype mpi_type(
unsigned int) {
return MPI_UNSIGNED; }
967 inline MPI_Datatype mpi_type(
long) {
return MPI_LONG; }
968 inline MPI_Datatype mpi_type(
unsigned long) {
return MPI_UNSIGNED_LONG; }
970 template <
typename MAT>
struct mpi_distributed_matrix {
974 mpi_distributed_matrix() {}
976 const MAT &local_matrix(
void)
const {
return M; }
977 MAT &local_matrix(
void) {
return M; }
980 template <
typename MAT>
inline MAT &eff_matrix(MAT &m) {
return m; }
981 template <
typename MAT>
inline
982 const MAT &eff_matrix(
const MAT &m) {
return m; }
983 template <
typename MAT>
inline
984 MAT &eff_matrix(mpi_distributed_matrix<MAT> &m) {
return m.M; }
985 template <
typename MAT>
inline
986 const MAT &eff_matrix(
const mpi_distributed_matrix<MAT> &m) {
return m.M; }
989 template <
typename MAT1,
typename MAT2>
990 inline void copy(
const mpi_distributed_matrix<MAT1> &m1,
991 mpi_distributed_matrix<MAT2> &m2)
992 {
copy(eff_matrix(m1), eff_matrix(m2)); }
993 template <
typename MAT1,
typename MAT2>
994 inline void copy(
const mpi_distributed_matrix<MAT1> &m1,
995 const mpi_distributed_matrix<MAT2> &m2)
996 {
copy(m1.M, m2.M); }
998 template <
typename MAT1,
typename MAT2>
999 inline void copy(
const mpi_distributed_matrix<MAT1> &m1, MAT2 &m2)
1001 template <
typename MAT1,
typename MAT2>
1002 inline void copy(
const mpi_distributed_matrix<MAT1> &m1,
const MAT2 &m2)
1006 template <
typename MATSP,
typename V1,
typename V2>
inline
1007 typename strongest_value_type3<V1,V2,MATSP>::value_type
1008 vect_sp(
const mpi_distributed_matrix<MATSP> &ps,
const V1 &v1,
1010 typedef typename strongest_value_type3<V1,V2,MATSP>::value_type T;
1011 T res =
vect_sp(ps.M, v1, v2), rest;
1012 MPI_Allreduce(&res, &rest, 1, mpi_type(T()), MPI_SUM,MPI_COMM_WORLD);
1016 template <
typename MAT,
typename V1,
typename V2>
1017 inline void mult_add(
const mpi_distributed_matrix<MAT> &m,
const V1 &v1,
1019 typedef typename linalg_traits<V2>::value_type T;
1020 std::vector<T> v3(vect_size(v2)), v4(vect_size(v2));
1021 static double tmult_tot = 0.0;
1022 static double tmult_tot2 = 0.0;
1023 double t_ref = MPI_Wtime();
1024 gmm::mult(m.M, v1, v3);
1025 if (is_sparse(v2)) GMM_WARNING2(
"Using a plain temporary, here.");
1026 double t_ref2 = MPI_Wtime();
1027 MPI_Allreduce(&(v3[0]), &(v4[0]),gmm::vect_size(v2), mpi_type(T()),
1028 MPI_SUM,MPI_COMM_WORLD);
1029 tmult_tot2 = MPI_Wtime()-t_ref2;
1030 cout <<
"reduce mult mpi = " << tmult_tot2 << endl;
1032 tmult_tot = MPI_Wtime()-t_ref;
1033 cout <<
"tmult mpi = " << tmult_tot << endl;
1036 template <
typename MAT,
typename V1,
typename V2>
1037 void mult_add(
const mpi_distributed_matrix<MAT> &m,
const V1 &v1,
1039 {
mult_add(m, v1,
const_cast<V2 &
>(v2_)); }
1041 template <
typename MAT,
typename V1,
typename V2>
1042 inline void mult(
const mpi_distributed_matrix<MAT> &m,
const V1 &v1,
1044 { V2 &v2 =
const_cast<V2 &
>(v2_);
clear(v2);
mult_add(m, v1, v2); }
1046 template <
typename MAT,
typename V1,
typename V2>
1047 inline void mult(
const mpi_distributed_matrix<MAT> &m,
const V1 &v1,
1051 template <
typename MAT,
typename V1,
typename V2,
typename V3>
1052 inline void mult(
const mpi_distributed_matrix<MAT> &m,
const V1 &v1,
1053 const V2 &v2,
const V3 &v3_)
1054 { V3 &v3 =
const_cast<V3 &
>(v3_); gmm::copy(v2, v3);
mult_add(m, v1, v3); }
1056 template <
typename MAT,
typename V1,
typename V2,
typename V3>
1057 inline void mult(
const mpi_distributed_matrix<MAT> &m,
const V1 &v1,
1058 const V2 &v2, V3 &v3)
1059 { gmm::copy(v2, v3);
mult_add(m, v1, v3); }
1062 template <
typename MAT>
inline
1063 size_type mat_nrows(
const mpi_distributed_matrix<MAT> &M)
1064 {
return mat_nrows(M.M); }
1065 template <
typename MAT>
inline
1066 size_type mat_ncols(
const mpi_distributed_matrix<MAT> &M)
1067 {
return mat_nrows(M.M); }
1068 template <
typename MAT>
inline
1071 template <
typename MAT>
inline void clear(mpi_distributed_matrix<MAT> &M)
1076 template <
typename MAT1,
typename MAT2>
inline
1077 void mult(
const MAT1 &M1,
const mpi_distributed_matrix<MAT2> &M2,
1078 mpi_distributed_matrix<MAT2> &M3)
1079 { mult(M1, M2.M, M3.M); }
1080 template <
typename MAT1,
typename MAT2>
inline
1081 void mult(
const mpi_distributed_matrix<MAT2> &M2,
1082 const MAT1 &M1, mpi_distributed_matrix<MAT2> &M3)
1083 { mult(M2.M, M1, M3.M); }
1084 template <
typename MAT1,
typename MAT2,
typename MAT3>
inline
1085 void mult(
const MAT1 &M1,
const mpi_distributed_matrix<MAT2> &M2,
1087 { mult(M1, M2.M, M3); }
1088 template <
typename MAT1,
typename MAT2,
typename MAT3>
inline
1089 void mult(
const MAT1 &M1,
const mpi_distributed_matrix<MAT2> &M2,
1091 { mult(M1, M2.M, M3); }
1093 template <
typename M,
typename SUBI1,
typename SUBI2>
1094 struct sub_matrix_type<const mpi_distributed_matrix<M> *, SUBI1, SUBI2>
1095 {
typedef abstract_null_type matrix_type; };
1097 template <
typename M,
typename SUBI1,
typename SUBI2>
1098 struct sub_matrix_type<mpi_distributed_matrix<M> *, SUBI1, SUBI2>
1099 {
typedef abstract_null_type matrix_type; };
1101 template <
typename M,
typename SUBI1,
typename SUBI2>
inline
1102 typename select_return<typename sub_matrix_type<const M *, SUBI1, SUBI2>
1103 ::matrix_type,
typename sub_matrix_type<M *, SUBI1, SUBI2>::matrix_type,
1105 sub_matrix(mpi_distributed_matrix<M> &m,
const SUBI1 &si1,
const SUBI2 &si2)
1106 {
return sub_matrix(m.M, si1, si2); }
1108 template <
typename MAT,
typename SUBI1,
typename SUBI2>
inline
1109 typename select_return<typename sub_matrix_type<const MAT *, SUBI1, SUBI2>
1110 ::matrix_type,
typename sub_matrix_type<MAT *, SUBI1, SUBI2>::matrix_type,
1111 const MAT *>::return_type
1112 sub_matrix(
const mpi_distributed_matrix<MAT> &m,
const SUBI1 &si1,
1114 {
return sub_matrix(m.M, si1, si2); }
1116 template <
typename M,
typename SUBI1>
inline
1117 typename select_return<typename sub_matrix_type<const M *, SUBI1, SUBI1>
1118 ::matrix_type,
typename sub_matrix_type<M *, SUBI1, SUBI1>::matrix_type,
1120 sub_matrix(mpi_distributed_matrix<M> &m,
const SUBI1 &si1)
1121 {
return sub_matrix(m.M, si1, si1); }
1123 template <
typename M,
typename SUBI1>
inline
1124 typename select_return<typename sub_matrix_type<const M *, SUBI1, SUBI1>
1125 ::matrix_type,
typename sub_matrix_type<M *, SUBI1, SUBI1>::matrix_type,
1126 const M *>::return_type
1127 sub_matrix(
const mpi_distributed_matrix<M> &m,
const SUBI1 &si1)
1128 {
return sub_matrix(m.M, si1, si1); }
1131 template <
typename L>
struct transposed_return<const mpi_distributed_matrix<L> *>
1132 {
typedef abstract_null_type return_type; };
1133 template <
typename L>
struct transposed_return<mpi_distributed_matrix<L> *>
1134 {
typedef abstract_null_type return_type; };
1136 template <
typename L>
inline typename transposed_return<const L *>::return_type
1137 transposed(
const mpi_distributed_matrix<L> &l)
1138 {
return transposed(l.M); }
1140 template <
typename L>
inline typename transposed_return<L *>::return_type
1141 transposed(mpi_distributed_matrix<L> &l)
1142 {
return transposed(l.M); }
1145 template <
typename MAT>
1146 struct linalg_traits<mpi_distributed_matrix<MAT> > {
1147 typedef mpi_distributed_matrix<MAT> this_type;
1148 typedef MAT origin_type;
1149 typedef linalg_false is_reference;
1150 typedef abstract_matrix linalg_type;
1151 typedef typename linalg_traits<MAT>::value_type value_type;
1152 typedef typename linalg_traits<MAT>::reference reference;
1153 typedef typename linalg_traits<MAT>::storage_type storage_type;
1154 typedef abstract_null_type sub_row_type;
1155 typedef abstract_null_type const_sub_row_type;
1156 typedef abstract_null_type row_iterator;
1157 typedef abstract_null_type const_row_iterator;
1158 typedef abstract_null_type sub_col_type;
1159 typedef abstract_null_type const_sub_col_type;
1160 typedef abstract_null_type col_iterator;
1161 typedef abstract_null_type const_col_iterator;
1162 typedef abstract_null_type sub_orientation;
1163 typedef abstract_null_type index_sorted;
1164 static size_type nrows(
const this_type &m) {
return nrows(m.M); }
1165 static size_type ncols(
const this_type &m) {
return ncols(m.M); }
1166 static void do_clear(this_type &m) {
clear(m.M); }
1172 #endif // GMM_USES_MPI
1175 template <
typename V>
1176 void swap(gmm::row_matrix<V> &m1, gmm::row_matrix<V> &m2)
1178 template <
typename V>
1179 void swap(gmm::col_matrix<V> &m1, gmm::col_matrix<V> &m2)
1181 template <
typename T>
1182 void swap(gmm::dense_matrix<T> &m1, gmm::dense_matrix<T> &m2)
1184 template <
typename T,
typename IND_TYPE,
int shift>
void
1185 swap(gmm::csc_matrix<T, IND_TYPE, shift> &m1, gmm::csc_matrix<T, IND_TYPE, shift> &m2)
1187 template <
typename T,
typename IND_TYPE,
int shift>
void
1188 swap(gmm::csr_matrix<T, IND_TYPE, shift> &m1, gmm::csr_matrix<T, IND_TYPE, shift> &m2)