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() : nc(0) {}
152 typename std::vector<V>::iterator begin()
153 {
return li.begin(); }
154 typename std::vector<V>::iterator end()
156 typename std::vector<V>::const_iterator begin()
const
157 {
return li.begin(); }
158 typename std::vector<V>::const_iterator end()
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()
const {
return li.size(); }
168 inline size_type ncols()
const {
return nc; }
170 void swap(row_matrix<V> &m) { std::swap(li, m.li); std::swap(nc, m.nc); }
178 for (
size_type i=nr; i < m; ++i) gmm::resize(li[i], n);
180 for (
size_type i=0; i < nr; ++i) gmm::resize(li[i], n);
187 void row_matrix<V>::clear_mat()
190 template <
typename V>
191 struct linalg_traits<row_matrix<V> > {
192 typedef row_matrix<V> this_type;
193 typedef this_type origin_type;
194 typedef linalg_false is_reference;
195 typedef abstract_matrix linalg_type;
196 typedef typename linalg_traits<V>::value_type value_type;
197 typedef typename linalg_traits<V>::reference reference;
198 typedef typename linalg_traits<V>::storage_type storage_type;
199 typedef V & sub_row_type;
200 typedef const V & const_sub_row_type;
201 typedef typename std::vector<V>::iterator row_iterator;
202 typedef typename std::vector<V>::const_iterator const_row_iterator;
203 typedef abstract_null_type sub_col_type;
204 typedef abstract_null_type const_sub_col_type;
205 typedef abstract_null_type col_iterator;
206 typedef abstract_null_type const_col_iterator;
207 typedef row_major sub_orientation;
208 typedef linalg_true index_sorted;
209 static size_type nrows(
const this_type &m) {
return m.nrows(); }
210 static size_type ncols(
const this_type &m) {
return m.ncols(); }
211 static row_iterator row_begin(this_type &m) {
return m.begin(); }
212 static row_iterator row_end(this_type &m) {
return m.end(); }
213 static const_row_iterator row_begin(
const this_type &m)
214 {
return m.begin(); }
215 static const_row_iterator row_end(
const this_type &m)
217 static const_sub_row_type row(
const const_row_iterator &it)
218 {
return const_sub_row_type(*it); }
219 static sub_row_type row(
const row_iterator &it)
220 {
return sub_row_type(*it); }
221 static origin_type* origin(this_type &m) {
return &m; }
222 static const origin_type* origin(
const this_type &m) {
return &m; }
223 static void do_clear(this_type &m) { m.clear_mat(); }
224 static value_type access(
const const_row_iterator &itrow,
size_type j)
225 {
return (*itrow)[j]; }
226 static reference access(
const row_iterator &itrow,
size_type j)
227 {
return (*itrow)[j]; }
231 { GMM_ASSERT1(
false,
"Sorry, to be done"); }
234 template<
typename V> std::ostream &
operator <<
235 (std::ostream &o,
const row_matrix<V>& m) { gmm::write(o,m);
return o; }
243 template<
typename V>
class col_matrix {
250 typedef typename linalg_traits<V>::reference reference;
251 typedef typename linalg_traits<V>::value_type value_type;
254 col_matrix() : nr(0) {}
264 const V& col(
size_type i)
const {
return li[i]; }
265 V& operator[](
size_type i) {
return li[i]; }
266 const V& operator[](
size_type i)
const {
return li[i]; }
268 typename std::vector<V>::iterator begin()
269 {
return li.begin(); }
270 typename std::vector<V>::iterator end()
272 typename std::vector<V>::const_iterator begin()
const
273 {
return li.begin(); }
274 typename std::vector<V>::const_iterator end()
const
277 inline size_type ncols()
const {
return li.size(); }
278 inline size_type nrows()
const {
return nr; }
280 void swap(col_matrix<V> &m) { std::swap(li, m.li); std::swap(nr, m.nr); }
287 for (
size_type i=nc; i < n; ++i) gmm::resize(li[i], m);
289 for (
size_type i=0; i < nc; ++i) gmm::resize(li[i], m);
294 template<
typename V>
void col_matrix<V>::clear_mat()
297 template <
typename V>
struct linalg_traits<col_matrix<V> > {
298 typedef col_matrix<V> this_type;
299 typedef this_type origin_type;
300 typedef linalg_false is_reference;
301 typedef abstract_matrix linalg_type;
302 typedef typename linalg_traits<V>::value_type value_type;
303 typedef typename linalg_traits<V>::reference reference;
304 typedef typename linalg_traits<V>::storage_type storage_type;
305 typedef V &sub_col_type;
306 typedef const V &const_sub_col_type;
307 typedef typename std::vector<V>::iterator col_iterator;
308 typedef typename std::vector<V>::const_iterator const_col_iterator;
309 typedef abstract_null_type sub_row_type;
310 typedef abstract_null_type const_sub_row_type;
311 typedef abstract_null_type row_iterator;
312 typedef abstract_null_type const_row_iterator;
313 typedef col_major sub_orientation;
314 typedef linalg_true index_sorted;
315 static size_type nrows(
const this_type &m) {
return m.nrows(); }
316 static size_type ncols(
const this_type &m) {
return m.ncols(); }
317 static col_iterator col_begin(this_type &m) {
return m.begin(); }
318 static col_iterator col_end(this_type &m) {
return m.end(); }
319 static const_col_iterator col_begin(
const this_type &m)
320 {
return m.begin(); }
321 static const_col_iterator col_end(
const this_type &m)
323 static const_sub_col_type col(
const const_col_iterator &it)
325 static sub_col_type col(
const col_iterator &it)
327 static origin_type* origin(this_type &m) {
return &m; }
328 static const origin_type* origin(
const this_type &m) {
return &m; }
329 static void do_clear(this_type &m) { m.clear_mat(); }
330 static value_type access(
const const_col_iterator &itcol,
size_type j)
331 {
return (*itcol)[j]; }
332 static reference access(
const col_iterator &itcol,
size_type j)
333 {
return (*itcol)[j]; }
337 { GMM_ASSERT1(
false,
"Sorry, to be done"); }
340 template<
typename V> std::ostream &
operator <<
341 (std::ostream &o,
const col_matrix<V>& m) { gmm::write(o,m);
return o; }
349 template<
typename T>
class dense_matrix :
public std::vector<T> {
352 typedef typename std::vector<T>::iterator iterator;
353 typedef typename std::vector<T>::const_iterator const_iterator;
354 typedef typename std::vector<T>::reference reference;
355 typedef typename std::vector<T>::const_reference const_reference;
363 GMM_ASSERT2(l < nbl && c < nbc,
"out of range");
364 return *(this->begin() + c*nbl+l);
367 GMM_ASSERT2(l < nbl && c < nbc,
"out of range");
368 return *(this->begin() + c*nbl+l);
371 std::vector<T> &as_vector() {
return *
this; }
372 const std::vector<T> &as_vector()
const {
return *
this; }
378 void fill(T a, T b = T(0));
379 inline size_type nrows()
const {
return nbl; }
380 inline size_type ncols()
const {
return nbc; }
381 void swap(dense_matrix<T> &m)
382 { std::vector<T>::swap(m); std::swap(nbc, m.nbc); std::swap(nbl, m.nbl); }
385 : std::vector<T>(c*l), nbc(c), nbl(l) {}
386 dense_matrix() { nbl = nbc = 0; }
391 GMM_ASSERT2(n*m == nbl*nbc,
"dimensions mismatch");
397 { std::vector<T>::resize(n*m); nbl = m; nbc = n; }
401 if (n*m > nbc*nbl) std::vector<T>::resize(n*m);
403 for (
size_type i = 1; i < std::min(nbc, n); ++i)
404 std::copy(this->begin()+i*nbl, this->begin()+(i*nbl+m),
406 for (
size_type i = std::min(nbc, n); i < n; ++i)
407 std::fill(this->begin()+(i*m), this->begin()+(i+1)*m, T(0));
410 for (
size_type i = std::min(nbc, n); i > 1; --i)
411 std::copy(this->begin()+(i-1)*nbl, this->begin()+i*nbl,
412 this->begin()+(i-1)*m);
413 for (
size_type i = 0; i < std::min(nbc, n); ++i)
414 std::fill(this->begin()+(i*m+nbl), this->begin()+(i+1)*m, T(0));
416 if (n*m < nbc*nbl) std::vector<T>::resize(n*m);
421 void dense_matrix<T>::fill(T a, T b) {
422 std::fill(this->begin(), this->end(), b);
424 if (a != b)
for (
size_type i = 0; i < n; ++i) (*
this)(i,i) = a;
427 template <
typename T>
428 struct linalg_traits<dense_matrix<T> > {
429 typedef dense_matrix<T> this_type;
430 typedef this_type origin_type;
431 typedef linalg_false is_reference;
432 typedef abstract_matrix linalg_type;
433 typedef T value_type;
434 typedef T& reference;
435 typedef abstract_dense storage_type;
436 typedef tab_ref_reg_spaced_with_origin<
typename this_type::iterator,
437 this_type> sub_row_type;
438 typedef tab_ref_reg_spaced_with_origin<
typename this_type::const_iterator,
439 this_type> const_sub_row_type;
440 typedef dense_compressed_iterator<
typename this_type::iterator,
441 typename this_type::iterator,
442 this_type *> row_iterator;
443 typedef dense_compressed_iterator<
typename this_type::const_iterator,
444 typename this_type::iterator,
445 const this_type *> const_row_iterator;
446 typedef tab_ref_with_origin<
typename this_type::iterator,
447 this_type> sub_col_type;
448 typedef tab_ref_with_origin<
typename this_type::const_iterator,
449 this_type> const_sub_col_type;
450 typedef dense_compressed_iterator<
typename this_type::iterator,
451 typename this_type::iterator,
452 this_type *> col_iterator;
453 typedef dense_compressed_iterator<
typename this_type::const_iterator,
454 typename this_type::iterator,
455 const this_type *> const_col_iterator;
456 typedef col_and_row sub_orientation;
457 typedef linalg_true index_sorted;
458 static size_type nrows(
const this_type &m) {
return m.nrows(); }
459 static size_type ncols(
const this_type &m) {
return m.ncols(); }
460 static const_sub_row_type row(
const const_row_iterator &it)
461 {
return const_sub_row_type(*it, it.nrows, it.ncols, it.origin); }
462 static const_sub_col_type col(
const const_col_iterator &it)
463 {
return const_sub_col_type(*it, *it + it.nrows, it.origin); }
464 static sub_row_type row(
const row_iterator &it)
465 {
return sub_row_type(*it, it.nrows, it.ncols, it.origin); }
466 static sub_col_type col(
const col_iterator &it)
467 {
return sub_col_type(*it, *it + it.nrows, it.origin); }
468 static row_iterator row_begin(this_type &m)
469 {
return row_iterator(m.begin(), m.size() ? 1 : 0, m.nrows(), m.ncols(), 0, &m); }
470 static row_iterator row_end(this_type &m)
471 {
return row_iterator(m.begin(), m.size() ? 1 : 0, m.nrows(), m.ncols(), m.nrows(), &m); }
472 static const_row_iterator row_begin(
const this_type &m)
473 {
return const_row_iterator(m.begin(), m.size() ? 1 : 0, m.nrows(), m.ncols(), 0, &m); }
474 static const_row_iterator row_end(
const this_type &m)
475 {
return const_row_iterator(m.begin(), m.size() ? 1 : 0, m.nrows(), m.ncols(), m.nrows(), &m); }
476 static col_iterator col_begin(this_type &m)
477 {
return col_iterator(m.begin(), m.nrows(), m.nrows(), m.ncols(), 0, &m); }
478 static col_iterator col_end(this_type &m)
479 {
return col_iterator(m.begin(), m.nrows(), m.nrows(), m.ncols(), m.ncols(), &m); }
480 static const_col_iterator col_begin(
const this_type &m)
481 {
return const_col_iterator(m.begin(), m.nrows(), m.nrows(), m.ncols(), 0, &m); }
482 static const_col_iterator col_end(
const this_type &m)
483 {
return const_col_iterator(m.begin(),m.nrows(),m.nrows(),m.ncols(),m.ncols(), &m); }
484 static origin_type* origin(this_type &m) {
return &m; }
485 static const origin_type* origin(
const this_type &m) {
return &m; }
486 static void do_clear(this_type &m) { m.fill(value_type(0)); }
487 static value_type access(
const const_col_iterator &itcol,
size_type j)
488 {
return (*itcol)[j]; }
489 static reference access(
const col_iterator &itcol,
size_type j)
490 {
return (*itcol)[j]; }
497 template<
typename T> std::ostream &
operator <<
498 (std::ostream &o,
const dense_matrix<T>& m) { gmm::write(o,m);
return o; }
507 template <
typename T,
typename IND_TYPE =
unsigned int,
int shift = 0>
511 std::vector<IND_TYPE> ir;
512 std::vector<IND_TYPE> jc;
515 typedef T value_type;
516 typedef T& access_type;
518 template <
typename Matrix>
void init_with_good_format(
const Matrix &B);
519 template <
typename Matrix>
void init_with(
const Matrix &A);
521 { init_with_good_format(B); }
522 void init_with(
const col_matrix<wsvector<T> > &B)
523 { init_with_good_format(B); }
524 template <
typename PT1,
typename PT2,
typename PT3,
int cshift>
525 void init_with(
const csc_matrix_ref<PT1,PT2,PT3,cshift>& B)
526 { init_with_good_format(B); }
527 template <
typename U,
int cshift>
528 void init_with(
const csc_matrix<U, IND_TYPE, cshift>& B)
529 { init_with_good_format(B); }
533 csc_matrix() : nc(0), nr(0) {}
538 void swap(csc_matrix<T, IND_TYPE, shift> &m) {
540 std::swap(ir, m.ir); std::swap(jc, m.jc);
541 std::swap(nc, m.nc); std::swap(nr, m.nr);
544 {
return mat_col(*
this, j)[i]; }
547 template <
typename T,
typename IND_TYPE,
int shift>
template<
typename Matrix>
548 void csc_matrix<T, IND_TYPE, shift>::init_with_good_format(
const Matrix &B) {
549 typedef typename linalg_traits<Matrix>::const_sub_col_type col_type;
550 nc = mat_ncols(B); nr = mat_nrows(B);
554 jc[j+1] = IND_TYPE(jc[j] +
nnz(mat_const_col(B, j)));
559 col_type col = mat_const_col(B, j);
560 typename linalg_traits<typename org_type<col_type>::t>::const_iterator
561 it = vect_const_begin(col), ite = vect_const_end(col);
562 for (
size_type k = 0; it != ite; ++it, ++k) {
563 pr[jc[j]-shift+k] = *it;
564 ir[jc[j]-shift+k] = IND_TYPE(it.index() + shift);
569 template <
typename T,
typename IND_TYPE,
int shift>
570 template <
typename Matrix>
571 void csc_matrix<T, IND_TYPE, shift>::init_with(
const Matrix &A) {
572 col_matrix<wsvector<T> > B(mat_nrows(A), mat_ncols(A));
574 init_with_good_format(B);
577 template <
typename T,
typename IND_TYPE,
int shift>
578 void csc_matrix<T, IND_TYPE, shift>::init_with_identity(
size_type n) {
580 pr.resize(nc); ir.resize(nc); jc.resize(nc+1);
582 { ir[j] = jc[j] = shift + j; pr[j] = T(1); }
586 template <
typename T,
typename IND_TYPE,
int shift>
589 pr.resize(1); ir.resize(1); jc.resize(nc+1);
590 for (
size_type j = 0; j <= nc; ++j) jc[j] = shift;
593 template <
typename T,
typename IND_TYPE,
int shift>
594 struct linalg_traits<csc_matrix<T, IND_TYPE, shift> > {
595 typedef csc_matrix<T, IND_TYPE, shift> this_type;
596 typedef linalg_const is_reference;
597 typedef abstract_matrix linalg_type;
598 typedef T value_type;
599 typedef T origin_type;
601 typedef abstract_sparse storage_type;
602 typedef abstract_null_type sub_row_type;
603 typedef abstract_null_type const_sub_row_type;
604 typedef abstract_null_type row_iterator;
605 typedef abstract_null_type const_row_iterator;
606 typedef abstract_null_type sub_col_type;
607 typedef cs_vector_ref<const T *, const IND_TYPE *, shift>
609 typedef sparse_compressed_iterator<
const T *,
const IND_TYPE *,
610 const IND_TYPE *, shift>
612 typedef abstract_null_type col_iterator;
613 typedef col_major sub_orientation;
614 typedef linalg_true index_sorted;
615 static size_type nrows(
const this_type &m) {
return m.nrows(); }
616 static size_type ncols(
const this_type &m) {
return m.ncols(); }
617 static const_col_iterator col_begin(
const this_type &m)
618 {
return const_col_iterator(&m.pr[0],&m.ir[0],&m.jc[0], m.nr, &m.pr[0]); }
619 static const_col_iterator col_end(
const this_type &m) {
620 return const_col_iterator(&m.pr[0],&m.ir[0],&m.jc[0]+m.nc,
623 static const_sub_col_type col(
const const_col_iterator &it) {
624 return const_sub_col_type(it.pr + *(it.jc) - shift,
625 it.ir + *(it.jc) - shift,
626 *(it.jc + 1) - *(it.jc), it.n);
628 static const origin_type* origin(
const this_type &m) {
return &m.pr[0]; }
629 static void do_clear(this_type &m) { m.do_clear(); }
630 static value_type access(
const const_col_iterator &itcol,
size_type j)
631 {
return col(itcol)[j]; }
634 template <
typename T,
typename IND_TYPE,
int shift>
635 std::ostream &
operator <<
636 (std::ostream &o,
const csc_matrix<T, IND_TYPE, shift>& m)
637 { gmm::write(o,m);
return o; }
639 template <
typename T,
typename IND_TYPE,
int shift>
640 inline void copy(
const identity_matrix &, csc_matrix<T, IND_TYPE, shift>& M)
641 { M.init_with_identity(mat_nrows(M)); }
643 template <
typename Matrix,
typename T,
typename IND_TYPE,
int shift>
644 inline void copy(
const Matrix &A, csc_matrix<T, IND_TYPE, shift>& M)
653 template <
typename T,
typename IND_TYPE =
unsigned int,
int shift = 0>
657 std::vector<IND_TYPE> ir;
658 std::vector<IND_TYPE> jc;
661 typedef T value_type;
662 typedef T& access_type;
665 template <
typename Matrix>
void init_with_good_format(
const Matrix &B);
666 void init_with(
const row_matrix<wsvector<T> > &B)
667 { init_with_good_format(B); }
668 void init_with(
const row_matrix<rsvector<T> > &B)
669 { init_with_good_format(B); }
670 template <
typename PT1,
typename PT2,
typename PT3,
int cshift>
671 void init_with(
const csr_matrix_ref<PT1,PT2,PT3,cshift>& B)
672 { init_with_good_format(B); }
673 template <
typename U,
int cshift>
674 void init_with(
const csr_matrix<U, IND_TYPE, cshift>& B)
675 { init_with_good_format(B); }
677 template <
typename Matrix>
void init_with(
const Matrix &A);
680 csr_matrix() : nc(0), nr(0) {}
685 void swap(csr_matrix<T, IND_TYPE, shift> &m) {
687 std::swap(ir,m.ir); std::swap(jc, m.jc);
688 std::swap(nc, m.nc); std::swap(nr,m.nr);
692 {
return mat_row(*
this, i)[j]; }
695 template <
typename T,
typename IND_TYPE,
int shift>
template <
typename Matrix>
696 void csr_matrix<T, IND_TYPE, shift>::init_with_good_format(
const Matrix &B) {
697 typedef typename linalg_traits<Matrix>::const_sub_row_type row_type;
698 nc = mat_ncols(B); nr = mat_nrows(B);
702 jc[j+1] = IND_TYPE(jc[j] +
nnz(mat_const_row(B, j)));
707 row_type row = mat_const_row(B, j);
708 typename linalg_traits<typename org_type<row_type>::t>::const_iterator
709 it = vect_const_begin(row), ite = vect_const_end(row);
710 for (
size_type k = 0; it != ite; ++it, ++k) {
711 pr[jc[j]-shift+k] = *it;
712 ir[jc[j]-shift+k] = IND_TYPE(it.index()+shift);
717 template <
typename T,
typename IND_TYPE,
int shift>
template <
typename Matrix>
718 void csr_matrix<T, IND_TYPE, shift>::init_with(
const Matrix &A) {
719 row_matrix<wsvector<T> > B(mat_nrows(A), mat_ncols(A));
721 init_with_good_format(B);
724 template <
typename T,
typename IND_TYPE,
int shift>
725 void csr_matrix<T, IND_TYPE, shift>::init_with_identity(
size_type n) {
727 pr.resize(nr); ir.resize(nr); jc.resize(nr+1);
729 { ir[j] = jc[j] = shift + j; pr[j] = T(1); }
733 template <
typename T,
typename IND_TYPE,
int shift>
736 pr.resize(1); ir.resize(1); jc.resize(nr+1);
737 for (
size_type j = 0; j < nr; ++j) jc[j] = shift;
742 template <
typename T,
typename IND_TYPE,
int shift>
743 struct linalg_traits<csr_matrix<T, IND_TYPE, shift> > {
744 typedef csr_matrix<T, IND_TYPE, shift> this_type;
745 typedef linalg_const is_reference;
746 typedef abstract_matrix linalg_type;
747 typedef T value_type;
748 typedef T origin_type;
750 typedef abstract_sparse storage_type;
751 typedef abstract_null_type sub_col_type;
752 typedef abstract_null_type const_sub_col_type;
753 typedef abstract_null_type col_iterator;
754 typedef abstract_null_type const_col_iterator;
755 typedef abstract_null_type sub_row_type;
756 typedef cs_vector_ref<const T *, const IND_TYPE *, shift>
758 typedef sparse_compressed_iterator<
const T *,
const IND_TYPE *,
759 const IND_TYPE *, shift>
761 typedef abstract_null_type row_iterator;
762 typedef row_major sub_orientation;
763 typedef linalg_true index_sorted;
764 static size_type nrows(
const this_type &m) {
return m.nrows(); }
765 static size_type ncols(
const this_type &m) {
return m.ncols(); }
766 static const_row_iterator row_begin(
const this_type &m)
767 {
return const_row_iterator(&m.pr[0], &m.ir[0], &m.jc[0], m.nc, &m.pr[0]); }
768 static const_row_iterator row_end(
const this_type &m)
769 {
return const_row_iterator(&m.pr[0], &m.ir[0], &m.jc[0] + m.nr, m.nc, &m.pr[0]); }
770 static const_sub_row_type row(
const const_row_iterator &it) {
771 return const_sub_row_type(it.pr + *(it.jc) - shift,
772 it.ir + *(it.jc) - shift,
773 *(it.jc + 1) - *(it.jc), it.n);
775 static const origin_type* origin(
const this_type &m) {
return &m.pr[0]; }
776 static void do_clear(this_type &m) { m.do_clear(); }
777 static value_type access(
const const_row_iterator &itrow,
size_type j)
778 {
return row(itrow)[j]; }
781 template <
typename T,
typename IND_TYPE,
int shift>
782 std::ostream &
operator <<
783 (std::ostream &o,
const csr_matrix<T, IND_TYPE, shift>& m)
784 { gmm::write(o,m);
return o; }
786 template <
typename T,
typename IND_TYPE,
int shift>
787 inline void copy(
const identity_matrix &, csr_matrix<T, IND_TYPE, shift>& M)
788 { M.init_with_identity(mat_nrows(M)); }
790 template <
typename Matrix,
typename T,
typename IND_TYPE,
int shift>
791 inline void copy(
const Matrix &A, csr_matrix<T, IND_TYPE, shift>& M)
800 template <
typename MAT>
class block_matrix {
802 std::vector<MAT> blocks;
805 std::vector<sub_interval> introw, intcol;
808 typedef typename linalg_traits<MAT>::value_type value_type;
809 typedef typename linalg_traits<MAT>::reference reference;
811 size_type nrows()
const {
return introw[nrowblocks_-1].max; }
812 size_type ncols()
const {
return intcol[ncolblocks_-1].max; }
813 size_type nrowblocks()
const {
return nrowblocks_; }
814 size_type ncolblocks()
const {
return ncolblocks_; }
815 const sub_interval &subrowinterval(
size_type i)
const {
return introw[i]; }
816 const sub_interval &subcolinterval(
size_type i)
const {
return intcol[i]; }
818 {
return blocks[j*ncolblocks_+i]; }
820 {
return blocks[j*ncolblocks_+i]; }
825 for (k = 0; k < nrowblocks_; ++k)
826 if (i >= introw[k].min && i < introw[k].max)
break;
827 for (l = 0; l < nrowblocks_; ++l)
828 if (j >= introw[l].min && j < introw[l].max)
break;
829 return (block(k, l))(i - introw[k].min, j - introw[l].min);
833 for (k = 0; k < nrowblocks_; ++k)
834 if (i >= introw[k].min && i < introw[k].max)
break;
835 for (l = 0; l < nrowblocks_; ++l)
836 if (j >= introw[l].min && j < introw[l].max)
break;
837 return (block(k, l))(i - introw[k].min, j - introw[l].min);
840 template <
typename CONT>
void resize(
const CONT &c1,
const CONT &c2);
841 template <
typename CONT> block_matrix(
const CONT &c1,
const CONT &c2)
847 template <
typename MAT>
struct linalg_traits<block_matrix<MAT> > {
848 typedef block_matrix<MAT> this_type;
849 typedef linalg_false is_reference;
850 typedef abstract_matrix linalg_type;
851 typedef this_type origin_type;
852 typedef typename linalg_traits<MAT>::value_type value_type;
853 typedef typename linalg_traits<MAT>::reference reference;
854 typedef typename linalg_traits<MAT>::storage_type storage_type;
855 typedef abstract_null_type sub_row_type;
856 typedef abstract_null_type const_sub_row_type;
857 typedef abstract_null_type row_iterator;
858 typedef abstract_null_type const_row_iterator;
859 typedef abstract_null_type sub_col_type;
860 typedef abstract_null_type const_sub_col_type;
861 typedef abstract_null_type col_iterator;
862 typedef abstract_null_type const_col_iterator;
863 typedef abstract_null_type sub_orientation;
864 typedef linalg_true index_sorted;
865 static size_type nrows(
const this_type &m) {
return m.nrows(); }
866 static size_type ncols(
const this_type &m) {
return m.ncols(); }
867 static origin_type* origin(this_type &m) {
return &m; }
868 static const origin_type* origin(
const this_type &m) {
return &m; }
869 static void do_clear(this_type &m) { m.do_clear(); }
872 { GMM_ASSERT1(
false,
"Sorry, to be done"); }
874 { GMM_ASSERT1(
false,
"Sorry, to be done"); }
877 template <
typename MAT>
878 void block_matrix<MAT>::do_clear() {
879 for (
size_type j = 0; j < ncolblocks_; ++j)
880 for (
size_type i = 0; i < nrowblocks_; ++i)
884 template <
typename MAT>
template <
typename CONT>
885 void block_matrix<MAT>::resize(
const CONT &c1,
const CONT &c2) {
886 nrowblocks_ = c1.size(); ncolblocks_ = c2.size();
887 blocks.resize(nrowblocks_ * ncolblocks_);
888 intcol.resize(ncolblocks_);
889 introw.resize(nrowblocks_);
890 for (
size_type j = 0, l = 0; j < ncolblocks_; ++j) {
891 intcol[j] = sub_interval(l, c2[j]); l += c2[j];
892 for (
size_type i = 0, k = 0; i < nrowblocks_; ++i) {
893 if (j == 0) { introw[i] = sub_interval(k, c1[i]); k += c1[i]; }
894 block(i, j) = MAT(c1[i], c2[j]);
899 template <
typename M1,
typename M2>
900 void copy(
const block_matrix<M1> &m1, M2 &m2) {
901 for (
size_type j = 0; j < m1.ncolblocks(); ++j)
902 for (
size_type i = 0; i < m1.nrowblocks(); ++i)
903 copy(m1.block(i,j), sub_matrix(m2, m1.subrowinterval(i),
904 m1.subcolinterval(j)));
907 template <
typename M1,
typename M2>
908 void copy(
const block_matrix<M1> &m1,
const M2 &m2)
909 {
copy(m1, linalg_const_cast(m2)); }
912 template <
typename MAT,
typename V1,
typename V2>
913 void mult(
const block_matrix<MAT> &m,
const V1 &v1, V2 &v2) {
915 typename sub_vector_type<V2 *, sub_interval>::vector_type sv;
916 for (
size_type i = 0; i < m.nrowblocks() ; ++i)
917 for (
size_type j = 0; j < m.ncolblocks() ; ++j) {
918 sv = sub_vector(v2, m.subrowinterval(i));
920 sub_vector(v1, m.subcolinterval(j)), sv, sv);
924 template <
typename MAT,
typename V1,
typename V2,
typename V3>
925 void mult(
const block_matrix<MAT> &m,
const V1 &v1,
const V2 &v2, V3 &v3) {
926 typename sub_vector_type<V3 *, sub_interval>::vector_type sv;
927 for (
size_type i = 0; i < m.nrowblocks() ; ++i)
928 for (
size_type j = 0; j < m.ncolblocks() ; ++j) {
929 sv = sub_vector(v3, m.subrowinterval(i));
932 sub_vector(v1, m.subcolinterval(j)),
933 sub_vector(v2, m.subrowinterval(i)), sv);
936 sub_vector(v1, m.subcolinterval(j)), sv, sv);
941 template <
typename MAT,
typename V1,
typename V2>
942 void mult(
const block_matrix<MAT> &m,
const V1 &v1,
const V2 &v2)
943 {
mult(m, v1, linalg_const_cast(v2)); }
945 template <
typename MAT,
typename V1,
typename V2,
typename V3>
946 void mult(
const block_matrix<MAT> &m,
const V1 &v1,
const V2 &v2,
948 { mult_const(m, v1, v2, linalg_const_cast(v3)); }
964 template <
typename T>
inline MPI_Datatype mpi_type(T)
965 { GMM_ASSERT1(
false,
"Sorry unsupported type");
return MPI_FLOAT; }
966 inline MPI_Datatype mpi_type(
double) {
return MPI_DOUBLE; }
967 inline MPI_Datatype mpi_type(
float) {
return MPI_FLOAT; }
968 inline MPI_Datatype mpi_type(
long double) {
return MPI_LONG_DOUBLE; }
970 inline MPI_Datatype mpi_type(std::complex<float>) {
return MPI_COMPLEX; }
971 inline MPI_Datatype mpi_type(std::complex<double>) {
return MPI_DOUBLE_COMPLEX; }
973 inline MPI_Datatype mpi_type(
int) {
return MPI_INT; }
974 inline MPI_Datatype mpi_type(
unsigned int) {
return MPI_UNSIGNED; }
975 inline MPI_Datatype mpi_type(
long) {
return MPI_LONG; }
976 inline MPI_Datatype mpi_type(
unsigned long) {
return MPI_UNSIGNED_LONG; }
978 template <
typename MAT>
struct mpi_distributed_matrix {
982 mpi_distributed_matrix() {}
984 const MAT &local_matrix()
const {
return M; }
985 MAT &local_matrix() {
return M; }
988 template <
typename MAT>
inline MAT &eff_matrix(MAT &m) {
return m; }
989 template <
typename MAT>
inline
990 const MAT &eff_matrix(
const MAT &m) {
return m; }
991 template <
typename MAT>
inline
992 MAT &eff_matrix(mpi_distributed_matrix<MAT> &m) {
return m.M; }
993 template <
typename MAT>
inline
994 const MAT &eff_matrix(
const mpi_distributed_matrix<MAT> &m) {
return m.M; }
997 template <
typename MAT1,
typename MAT2>
998 inline void copy(
const mpi_distributed_matrix<MAT1> &m1,
999 mpi_distributed_matrix<MAT2> &m2)
1000 {
copy(eff_matrix(m1), eff_matrix(m2)); }
1001 template <
typename MAT1,
typename MAT2>
1002 inline void copy(
const mpi_distributed_matrix<MAT1> &m1,
1003 const mpi_distributed_matrix<MAT2> &m2)
1004 {
copy(m1.M, m2.M); }
1006 template <
typename MAT1,
typename MAT2>
1007 inline void copy(
const mpi_distributed_matrix<MAT1> &m1, MAT2 &m2)
1009 template <
typename MAT1,
typename MAT2>
1010 inline void copy(
const mpi_distributed_matrix<MAT1> &m1,
const MAT2 &m2)
1014 template <
typename MATSP,
typename V1,
typename V2>
inline
1015 typename strongest_value_type3<V1,V2,MATSP>::value_type
1016 vect_sp(
const mpi_distributed_matrix<MATSP> &ps,
const V1 &v1,
1018 typedef typename strongest_value_type3<V1,V2,MATSP>::value_type T;
1019 T res =
vect_sp(ps.M, v1, v2), rest;
1020 MPI_Allreduce(&res, &rest, 1, mpi_type(T()), MPI_SUM,MPI_COMM_WORLD);
1024 template <
typename MAT,
typename V1,
typename V2>
1025 inline void mult_add(
const mpi_distributed_matrix<MAT> &m,
const V1 &v1,
1027 typedef typename linalg_traits<V2>::value_type T;
1028 std::vector<T> v3(vect_size(v2)), v4(vect_size(v2));
1029 static double tmult_tot = 0.0;
1030 static double tmult_tot2 = 0.0;
1031 double t_ref = MPI_Wtime();
1033 if (is_sparse(v2)) GMM_WARNING2(
"Using a plain temporary, here.");
1034 double t_ref2 = MPI_Wtime();
1035 MPI_Allreduce(&(v3[0]), &(v4[0]),gmm::vect_size(v2), mpi_type(T()),
1036 MPI_SUM,MPI_COMM_WORLD);
1037 tmult_tot2 = MPI_Wtime()-t_ref2;
1038 cout <<
"reduce mult mpi = " << tmult_tot2 << endl;
1040 tmult_tot = MPI_Wtime()-t_ref;
1041 cout <<
"tmult mpi = " << tmult_tot << endl;
1044 template <
typename MAT,
typename V1,
typename V2>
1045 void mult_add(
const mpi_distributed_matrix<MAT> &m,
const V1 &v1,
1047 {
mult_add(m, v1,
const_cast<V2 &
>(v2_)); }
1049 template <
typename MAT,
typename V1,
typename V2>
1050 inline void mult(
const mpi_distributed_matrix<MAT> &m,
const V1 &v1,
1052 { V2 &v2 =
const_cast<V2 &
>(v2_);
clear(v2);
mult_add(m, v1, v2); }
1054 template <
typename MAT,
typename V1,
typename V2>
1055 inline void mult(
const mpi_distributed_matrix<MAT> &m,
const V1 &v1,
1059 template <
typename MAT,
typename V1,
typename V2,
typename V3>
1060 inline void mult(
const mpi_distributed_matrix<MAT> &m,
const V1 &v1,
1061 const V2 &v2,
const V3 &v3_)
1064 template <
typename MAT,
typename V1,
typename V2,
typename V3>
1065 inline void mult(
const mpi_distributed_matrix<MAT> &m,
const V1 &v1,
1066 const V2 &v2, V3 &v3)
1070 template <
typename MAT>
inline
1071 size_type mat_nrows(
const mpi_distributed_matrix<MAT> &M)
1072 {
return mat_nrows(M.M); }
1073 template <
typename MAT>
inline
1074 size_type mat_ncols(
const mpi_distributed_matrix<MAT> &M)
1075 {
return mat_nrows(M.M); }
1076 template <
typename MAT>
inline
1079 template <
typename MAT>
inline void clear(mpi_distributed_matrix<MAT> &M)
1084 template <
typename MAT1,
typename MAT2>
inline
1085 void mult(
const MAT1 &M1,
const mpi_distributed_matrix<MAT2> &M2,
1086 mpi_distributed_matrix<MAT2> &M3)
1087 {
mult(M1, M2.M, M3.M); }
1088 template <
typename MAT1,
typename MAT2>
inline
1089 void mult(
const mpi_distributed_matrix<MAT2> &M2,
1090 const MAT1 &M1, mpi_distributed_matrix<MAT2> &M3)
1091 {
mult(M2.M, M1, M3.M); }
1092 template <
typename MAT1,
typename MAT2,
typename MAT3>
inline
1093 void mult(
const MAT1 &M1,
const mpi_distributed_matrix<MAT2> &M2,
1095 {
mult(M1, M2.M, M3); }
1096 template <
typename MAT1,
typename MAT2,
typename MAT3>
inline
1097 void mult(
const MAT1 &M1,
const mpi_distributed_matrix<MAT2> &M2,
1099 {
mult(M1, M2.M, M3); }
1101 template <
typename M,
typename SUBI1,
typename SUBI2>
1102 struct sub_matrix_type<const mpi_distributed_matrix<M> *, SUBI1, SUBI2>
1103 {
typedef abstract_null_type matrix_type; };
1105 template <
typename M,
typename SUBI1,
typename SUBI2>
1106 struct sub_matrix_type<mpi_distributed_matrix<M> *, SUBI1, SUBI2>
1107 {
typedef abstract_null_type matrix_type; };
1109 template <
typename M,
typename SUBI1,
typename SUBI2>
inline
1110 typename select_return<typename sub_matrix_type<const M *, SUBI1, SUBI2>
1111 ::matrix_type,
typename sub_matrix_type<M *, SUBI1, SUBI2>::matrix_type,
1113 sub_matrix(mpi_distributed_matrix<M> &m,
const SUBI1 &si1,
const SUBI2 &si2)
1114 {
return sub_matrix(m.M, si1, si2); }
1116 template <
typename MAT,
typename SUBI1,
typename SUBI2>
inline
1117 typename select_return<typename sub_matrix_type<const MAT *, SUBI1, SUBI2>
1118 ::matrix_type,
typename sub_matrix_type<MAT *, SUBI1, SUBI2>::matrix_type,
1119 const MAT *>::return_type
1120 sub_matrix(
const mpi_distributed_matrix<MAT> &m,
const SUBI1 &si1,
1122 {
return sub_matrix(m.M, si1, si2); }
1124 template <
typename M,
typename SUBI1>
inline
1125 typename select_return<typename sub_matrix_type<const M *, SUBI1, SUBI1>
1126 ::matrix_type,
typename sub_matrix_type<M *, SUBI1, SUBI1>::matrix_type,
1128 sub_matrix(mpi_distributed_matrix<M> &m,
const SUBI1 &si1)
1129 {
return sub_matrix(m.M, si1, si1); }
1131 template <
typename M,
typename SUBI1>
inline
1132 typename select_return<typename sub_matrix_type<const M *, SUBI1, SUBI1>
1133 ::matrix_type,
typename sub_matrix_type<M *, SUBI1, SUBI1>::matrix_type,
1134 const M *>::return_type
1135 sub_matrix(
const mpi_distributed_matrix<M> &m,
const SUBI1 &si1)
1136 {
return sub_matrix(m.M, si1, si1); }
1139 template <
typename L>
struct transposed_return<const mpi_distributed_matrix<L> *>
1140 {
typedef abstract_null_type return_type; };
1141 template <
typename L>
struct transposed_return<mpi_distributed_matrix<L> *>
1142 {
typedef abstract_null_type return_type; };
1144 template <
typename L>
inline typename transposed_return<const L *>::return_type
1145 transposed(
const mpi_distributed_matrix<L> &l)
1146 {
return transposed(l.M); }
1148 template <
typename L>
inline typename transposed_return<L *>::return_type
1149 transposed(mpi_distributed_matrix<L> &l)
1150 {
return transposed(l.M); }
1153 template <
typename MAT>
1154 struct linalg_traits<mpi_distributed_matrix<MAT> > {
1155 typedef mpi_distributed_matrix<MAT> this_type;
1156 typedef MAT origin_type;
1157 typedef linalg_false is_reference;
1158 typedef abstract_matrix linalg_type;
1159 typedef typename linalg_traits<MAT>::value_type value_type;
1160 typedef typename linalg_traits<MAT>::reference reference;
1161 typedef typename linalg_traits<MAT>::storage_type storage_type;
1162 typedef abstract_null_type sub_row_type;
1163 typedef abstract_null_type const_sub_row_type;
1164 typedef abstract_null_type row_iterator;
1165 typedef abstract_null_type const_row_iterator;
1166 typedef abstract_null_type sub_col_type;
1167 typedef abstract_null_type const_sub_col_type;
1168 typedef abstract_null_type col_iterator;
1169 typedef abstract_null_type const_col_iterator;
1170 typedef abstract_null_type sub_orientation;
1171 typedef abstract_null_type index_sorted;
1172 static size_type nrows(
const this_type &m) {
return nrows(m.M); }
1173 static size_type ncols(
const this_type &m) {
return ncols(m.M); }
1174 static void do_clear(this_type &m) {
clear(m.M); }
1183 template <
typename V>
1184 void swap(gmm::row_matrix<V> &m1, gmm::row_matrix<V> &m2)
1186 template <
typename V>
1187 void swap(gmm::col_matrix<V> &m1, gmm::col_matrix<V> &m2)
1189 template <
typename T>
1190 void swap(gmm::dense_matrix<T> &m1, gmm::dense_matrix<T> &m2)
1192 template <
typename T,
typename IND_TYPE,
int shift>
void
1193 swap(gmm::csc_matrix<T, IND_TYPE, shift> &m1, gmm::csc_matrix<T, IND_TYPE, shift> &m2)
1195 template <
typename T,
typename IND_TYPE,
int shift>
void
1196 swap(gmm::csr_matrix<T, IND_TYPE, shift> &m1, gmm::csr_matrix<T, IND_TYPE, shift> &m2)
sparse vector built upon std::vector.
size_type nnz(const L &l)
count the number of non-zero entries of a vector or matrix.
void mult_add(const L1 &l1, const L2 &l2, L3 &l3)
*/
void reshape(M &v, size_type m, size_type n)
*/
void copy(const L1 &l1, L2 &l2)
*/
void fill(L &l, typename gmm::linalg_traits< L >::value_type x)
*/
strongest_value_type< V1, V2 >::value_type vect_hp(const V1 &v1, const V2 &v2)
*/
void clear(L &l)
clear (fill with zeros) a vector or matrix.
void resize(V &v, size_type n)
*/
void mult(const L1 &l1, const L2 &l2, L3 &l3)
*/
strongest_value_type< V1, V2 >::value_type vect_sp(const V1 &v1, const V2 &v2)
*/
void add(const L1 &l1, L2 &l2)
*/
Generic transposed matrices.
Declaration of the vector types (gmm::rsvector, gmm::wsvector, gmm::slvector ,..)
size_t size_type
used as the common size type in the library