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;
359 inline const_reference operator ()(size_type l, size_type c)
const {
360 GMM_ASSERT2(l < nbl && c < nbc,
"out of range");
361 return *(this->begin() + c*nbl+l);
363 inline reference operator ()(size_type l, size_type c) {
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; }
371 void resize(size_type, size_type);
372 void base_resize(size_type, size_type);
373 void reshape(size_type, size_type);
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); }
381 dense_matrix(size_type l, size_type c)
382 :
std::vector<T>(c*l), nbc(c), nbl(l) {}
383 dense_matrix(
void) { nbl = nbc = 0; }
386 template<
typename T>
void dense_matrix<T>::reshape(size_type m,size_type n) {
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; }
395 template<
typename T>
void dense_matrix<T>::resize(size_type m, size_type 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);
417 size_type n = std::min(nbl, nbc);
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]; }
484 static void resize(this_type &v, size_type m, size_type n)
486 static void reshape(this_type &v, size_type m, size_type n)
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,
int shift = 0>
502 typedef unsigned int IND_TYPE;
505 std::vector<IND_TYPE> ir;
506 std::vector<IND_TYPE> jc;
509 typedef T value_type;
510 typedef T& access_type;
512 template <
typename Matrix>
void init_with_good_format(
const Matrix &B);
513 template <
typename Matrix>
void init_with(
const Matrix &A);
515 { init_with_good_format(B); }
516 void init_with(
const col_matrix<wsvector<T> > &B)
517 { init_with_good_format(B); }
518 template <
typename PT1,
typename PT2,
typename PT3,
int cshift>
519 void init_with(
const csc_matrix_ref<PT1,PT2,PT3,cshift>& B)
520 { init_with_good_format(B); }
521 template <
typename U,
int cshift>
522 void init_with(
const csc_matrix<U, cshift>& B)
523 { init_with_good_format(B); }
525 void init_with_identity(size_type n);
527 csc_matrix(
void) : nc(0), nr(0) {}
528 csc_matrix(size_type nnr, size_type nnc);
530 size_type nrows(
void)
const {
return nr; }
531 size_type ncols(
void)
const {
return nc; }
532 void swap(csc_matrix<T, shift> &m) {
534 std::swap(ir, m.ir); std::swap(jc, m.jc);
535 std::swap(nc, m.nc); std::swap(nr, m.nr);
537 value_type operator()(size_type i, size_type j)
const 538 {
return mat_col(*
this, j)[i]; }
541 template <
typename T,
int shift>
template<
typename Matrix>
542 void csc_matrix<T, shift>::init_with_good_format(
const Matrix &B) {
543 typedef typename linalg_traits<Matrix>::const_sub_col_type col_type;
544 nc = mat_ncols(B); nr = mat_nrows(B);
547 for (size_type j = 0; j < nc; ++j) {
548 jc[j+1] = IND_TYPE(jc[j] +
nnz(mat_const_col(B, j)));
552 for (size_type j = 0; j < nc; ++j) {
553 col_type col = mat_const_col(B, j);
554 typename linalg_traits<typename org_type<col_type>::t>::const_iterator
555 it = vect_const_begin(col), ite = vect_const_end(col);
556 for (size_type k = 0; it != ite; ++it, ++k) {
557 pr[jc[j]-shift+k] = *it;
558 ir[jc[j]-shift+k] = IND_TYPE(it.index() + shift);
563 template <
typename T,
int shift>
template <
typename Matrix>
564 void csc_matrix<T, 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,
int shift>
571 void csc_matrix<T, shift>::init_with_identity(size_type n) {
573 pr.resize(nc); ir.resize(nc); jc.resize(nc+1);
574 for (size_type j = 0; j < nc; ++j)
575 { ir[j] = jc[j] = shift + j; pr[j] = T(1); }
579 template <
typename T,
int shift>
580 csc_matrix<T, shift>::csc_matrix(size_type nnr, size_type nnc)
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,
int shift>
587 struct linalg_traits<csc_matrix<T, shift> > {
588 typedef csc_matrix<T, shift> this_type;
589 typedef typename this_type::IND_TYPE IND_TYPE;
590 typedef linalg_const is_reference;
591 typedef abstract_matrix linalg_type;
592 typedef T value_type;
593 typedef T origin_type;
595 typedef abstract_sparse storage_type;
596 typedef abstract_null_type sub_row_type;
597 typedef abstract_null_type const_sub_row_type;
598 typedef abstract_null_type row_iterator;
599 typedef abstract_null_type const_row_iterator;
600 typedef abstract_null_type sub_col_type;
601 typedef cs_vector_ref<const T *, const IND_TYPE *, shift>
603 typedef sparse_compressed_iterator<
const T *,
const IND_TYPE *,
604 const IND_TYPE *, shift>
606 typedef abstract_null_type col_iterator;
607 typedef col_major sub_orientation;
608 typedef linalg_true index_sorted;
609 static size_type nrows(
const this_type &m) {
return m.nrows(); }
610 static size_type ncols(
const this_type &m) {
return m.ncols(); }
611 static const_col_iterator col_begin(
const this_type &m)
612 {
return const_col_iterator(&m.pr[0],&m.ir[0],&m.jc[0], m.nr, &m.pr[0]); }
613 static const_col_iterator col_end(
const this_type &m) {
614 return const_col_iterator(&m.pr[0],&m.ir[0],&m.jc[0]+m.nc,
617 static const_sub_col_type col(
const const_col_iterator &it) {
618 return const_sub_col_type(it.pr + *(it.jc) - shift,
619 it.ir + *(it.jc) - shift,
620 *(it.jc + 1) - *(it.jc), it.n);
622 static const origin_type* origin(
const this_type &m) {
return &m.pr[0]; }
623 static void do_clear(this_type &m) { m.do_clear(); }
624 static value_type access(
const const_col_iterator &itcol, size_type j)
625 {
return col(itcol)[j]; }
628 template <
typename T,
int shift>
629 std::ostream &
operator <<
630 (std::ostream &o,
const csc_matrix<T, shift>& m)
631 { gmm::write(o,m);
return o; }
633 template <
typename T,
int shift>
634 inline void copy(
const identity_matrix &, csc_matrix<T, shift>& M)
635 { M.init_with_identity(mat_nrows(M)); }
637 template <
typename Matrix,
typename T,
int shift>
638 inline void copy(
const Matrix &A, csc_matrix<T, shift>& M)
647 template <
typename T,
int shift = 0>
650 typedef unsigned int IND_TYPE;
653 std::vector<IND_TYPE> ir;
654 std::vector<IND_TYPE> jc;
657 typedef T value_type;
658 typedef T& access_type;
661 template <
typename Matrix>
void init_with_good_format(
const Matrix &B);
662 void init_with(
const row_matrix<wsvector<T> > &B)
663 { init_with_good_format(B); }
664 void init_with(
const row_matrix<rsvector<T> > &B)
665 { init_with_good_format(B); }
666 template <
typename PT1,
typename PT2,
typename PT3,
int cshift>
667 void init_with(
const csr_matrix_ref<PT1,PT2,PT3,cshift>& B)
668 { init_with_good_format(B); }
669 template <
typename U,
int cshift>
670 void init_with(
const csr_matrix<U, cshift>& B)
671 { init_with_good_format(B); }
673 template <
typename Matrix>
void init_with(
const Matrix &A);
674 void init_with_identity(size_type n);
676 csr_matrix(
void) : nc(0), nr(0) {}
677 csr_matrix(size_type nnr, size_type nnc);
679 size_type nrows(
void)
const {
return nr; }
680 size_type ncols(
void)
const {
return nc; }
681 void swap(csr_matrix<T, shift> &m) {
683 std::swap(ir,m.ir); std::swap(jc, m.jc);
684 std::swap(nc, m.nc); std::swap(nr,m.nr);
687 value_type operator()(size_type i, size_type j)
const 688 {
return mat_row(*
this, i)[j]; }
691 template <
typename T,
int shift>
template <
typename Matrix>
692 void csr_matrix<T, shift>::init_with_good_format(
const Matrix &B) {
693 typedef typename linalg_traits<Matrix>::const_sub_row_type row_type;
694 nc = mat_ncols(B); nr = mat_nrows(B);
697 for (size_type j = 0; j < nr; ++j) {
698 jc[j+1] = IND_TYPE(jc[j] +
nnz(mat_const_row(B, j)));
702 for (size_type j = 0; j < nr; ++j) {
703 row_type row = mat_const_row(B, j);
704 typename linalg_traits<typename org_type<row_type>::t>::const_iterator
705 it = vect_const_begin(row), ite = vect_const_end(row);
706 for (size_type k = 0; it != ite; ++it, ++k) {
707 pr[jc[j]-shift+k] = *it;
708 ir[jc[j]-shift+k] = IND_TYPE(it.index()+shift);
713 template <
typename T,
int shift>
template <
typename Matrix>
714 void csr_matrix<T, shift>::init_with(
const Matrix &A) {
715 row_matrix<wsvector<T> > B(mat_nrows(A), mat_ncols(A));
717 init_with_good_format(B);
720 template <
typename T,
int shift>
721 void csr_matrix<T, shift>::init_with_identity(size_type n) {
723 pr.resize(nr); ir.resize(nr); jc.resize(nr+1);
724 for (size_type j = 0; j < nr; ++j)
725 { ir[j] = jc[j] = shift + j; pr[j] = T(1); }
729 template <
typename T,
int shift>
730 csr_matrix<T, shift>::csr_matrix(size_type nnr, size_type nnc)
732 pr.resize(1); ir.resize(1); jc.resize(nr+1);
733 for (size_type j = 0; j < nr; ++j) jc[j] = shift;
738 template <
typename T,
int shift>
739 struct linalg_traits<csr_matrix<T, shift> > {
740 typedef csr_matrix<T, shift> this_type;
741 typedef typename this_type::IND_TYPE IND_TYPE;
742 typedef linalg_const is_reference;
743 typedef abstract_matrix linalg_type;
744 typedef T value_type;
745 typedef T origin_type;
747 typedef abstract_sparse storage_type;
748 typedef abstract_null_type sub_col_type;
749 typedef abstract_null_type const_sub_col_type;
750 typedef abstract_null_type col_iterator;
751 typedef abstract_null_type const_col_iterator;
752 typedef abstract_null_type sub_row_type;
753 typedef cs_vector_ref<const T *, const IND_TYPE *, shift>
755 typedef sparse_compressed_iterator<
const T *,
const IND_TYPE *,
756 const IND_TYPE *, shift>
758 typedef abstract_null_type row_iterator;
759 typedef row_major sub_orientation;
760 typedef linalg_true index_sorted;
761 static size_type nrows(
const this_type &m) {
return m.nrows(); }
762 static size_type ncols(
const this_type &m) {
return m.ncols(); }
763 static const_row_iterator row_begin(
const this_type &m)
764 {
return const_row_iterator(&m.pr[0], &m.ir[0], &m.jc[0], m.nc, &m.pr[0]); }
765 static const_row_iterator row_end(
const this_type &m)
766 {
return const_row_iterator(&m.pr[0], &m.ir[0], &m.jc[0] + m.nr, m.nc, &m.pr[0]); }
767 static const_sub_row_type row(
const const_row_iterator &it) {
768 return const_sub_row_type(it.pr + *(it.jc) - shift,
769 it.ir + *(it.jc) - shift,
770 *(it.jc + 1) - *(it.jc), it.n);
772 static const origin_type* origin(
const this_type &m) {
return &m.pr[0]; }
773 static void do_clear(this_type &m) { m.do_clear(); }
774 static value_type access(
const const_row_iterator &itrow, size_type j)
775 {
return row(itrow)[j]; }
778 template <
typename T,
int shift>
779 std::ostream &
operator <<
780 (std::ostream &o,
const csr_matrix<T, shift>& m)
781 { gmm::write(o,m);
return o; }
783 template <
typename T,
int shift>
784 inline void copy(
const identity_matrix &, csr_matrix<T, shift>& M)
785 { M.init_with_identity(mat_nrows(M)); }
787 template <
typename Matrix,
typename T,
int shift>
788 inline void copy(
const Matrix &A, csr_matrix<T, shift>& M)
797 template <
typename MAT>
class block_matrix {
799 std::vector<MAT> blocks;
800 size_type nrowblocks_;
801 size_type ncolblocks_;
802 std::vector<sub_interval> introw, intcol;
805 typedef typename linalg_traits<MAT>::value_type value_type;
806 typedef typename linalg_traits<MAT>::reference reference;
808 size_type nrows(
void)
const {
return introw[nrowblocks_-1].max; }
809 size_type ncols(
void)
const {
return intcol[ncolblocks_-1].max; }
810 size_type nrowblocks(
void)
const {
return nrowblocks_; }
811 size_type ncolblocks(
void)
const {
return ncolblocks_; }
812 const sub_interval &subrowinterval(size_type i)
const {
return introw[i]; }
813 const sub_interval &subcolinterval(size_type i)
const {
return intcol[i]; }
814 const MAT &block(size_type i, size_type j)
const 815 {
return blocks[j*ncolblocks_+i]; }
816 MAT &block(size_type i, size_type j)
817 {
return blocks[j*ncolblocks_+i]; }
820 value_type operator() (size_type i, size_type j)
const {
822 for (k = 0; k < nrowblocks_; ++k)
823 if (i >= introw[k].min && i < introw[k].max)
break;
824 for (l = 0; l < nrowblocks_; ++l)
825 if (j >= introw[l].min && j < introw[l].max)
break;
826 return (block(k, l))(i - introw[k].min, j - introw[l].min);
828 reference operator() (size_type i, size_type j) {
830 for (k = 0; k < nrowblocks_; ++k)
831 if (i >= introw[k].min && i < introw[k].max)
break;
832 for (l = 0; l < nrowblocks_; ++l)
833 if (j >= introw[l].min && j < introw[l].max)
break;
834 return (block(k, l))(i - introw[k].min, j - introw[l].min);
837 template <
typename CONT>
void resize(
const CONT &c1,
const CONT &c2);
838 template <
typename CONT> block_matrix(
const CONT &c1,
const CONT &c2)
840 block_matrix(
void) {}
844 template <
typename MAT>
struct linalg_traits<block_matrix<MAT> > {
845 typedef block_matrix<MAT> this_type;
846 typedef linalg_false is_reference;
847 typedef abstract_matrix linalg_type;
848 typedef this_type origin_type;
849 typedef typename linalg_traits<MAT>::value_type value_type;
850 typedef typename linalg_traits<MAT>::reference reference;
851 typedef typename linalg_traits<MAT>::storage_type storage_type;
852 typedef abstract_null_type sub_row_type;
853 typedef abstract_null_type const_sub_row_type;
854 typedef abstract_null_type row_iterator;
855 typedef abstract_null_type const_row_iterator;
856 typedef abstract_null_type sub_col_type;
857 typedef abstract_null_type const_sub_col_type;
858 typedef abstract_null_type col_iterator;
859 typedef abstract_null_type const_col_iterator;
860 typedef abstract_null_type sub_orientation;
861 typedef linalg_true index_sorted;
862 static size_type nrows(
const this_type &m) {
return m.nrows(); }
863 static size_type ncols(
const this_type &m) {
return m.ncols(); }
864 static origin_type* origin(this_type &m) {
return &m; }
865 static const origin_type* origin(
const this_type &m) {
return &m; }
866 static void do_clear(this_type &m) { m.do_clear(); }
868 static void resize(this_type &, size_type , size_type)
869 { GMM_ASSERT1(
false,
"Sorry, to be done"); }
870 static void reshape(this_type &, size_type , size_type)
871 { GMM_ASSERT1(
false,
"Sorry, to be done"); }
874 template <
typename MAT>
void block_matrix<MAT>::do_clear(
void) {
875 for (size_type j = 0, l = 0; j < ncolblocks_; ++j)
876 for (size_type i = 0, k = 0; i < nrowblocks_; ++i)
880 template <
typename MAT>
template <
typename CONT>
881 void block_matrix<MAT>::resize(
const CONT &c1,
const CONT &c2) {
882 nrowblocks_ = c1.size(); ncolblocks_ = c2.size();
883 blocks.resize(nrowblocks_ * ncolblocks_);
884 intcol.resize(ncolblocks_);
885 introw.resize(nrowblocks_);
886 for (size_type j = 0, l = 0; j < ncolblocks_; ++j) {
887 intcol[j] = sub_interval(l, c2[j]); l += c2[j];
888 for (size_type i = 0, k = 0; i < nrowblocks_; ++i) {
889 if (j == 0) { introw[i] = sub_interval(k, c1[i]); k += c1[i]; }
890 block(i, j) = MAT(c1[i], c2[j]);
895 template <
typename M1,
typename M2>
896 void copy(
const block_matrix<M1> &m1, M2 &m2) {
897 for (size_type j = 0; j < m1.ncolblocks(); ++j)
898 for (size_type i = 0; i < m1.nrowblocks(); ++i)
899 copy(m1.block(i,j), sub_matrix(m2, m1.subrowinterval(i),
900 m1.subcolinterval(j)));
903 template <
typename M1,
typename M2>
904 void copy(
const block_matrix<M1> &m1,
const M2 &m2)
905 {
copy(m1, linalg_const_cast(m2)); }
908 template <
typename MAT,
typename V1,
typename V2>
909 void mult(
const block_matrix<MAT> &m,
const V1 &v1, V2 &v2) {
911 typename sub_vector_type<V2 *, sub_interval>::vector_type sv;
912 for (size_type i = 0; i < m.nrowblocks() ; ++i)
913 for (size_type j = 0; j < m.ncolblocks() ; ++j) {
914 sv = sub_vector(v2, m.subrowinterval(i));
916 sub_vector(v1, m.subcolinterval(j)), sv, sv);
920 template <
typename MAT,
typename V1,
typename V2,
typename V3>
921 void mult(
const block_matrix<MAT> &m,
const V1 &v1,
const V2 &v2, V3 &v3) {
922 typename sub_vector_type<V3 *, sub_interval>::vector_type sv;
923 for (size_type i = 0; i < m.nrowblocks() ; ++i)
924 for (size_type j = 0; j < m.ncolblocks() ; ++j) {
925 sv = sub_vector(v3, m.subrowinterval(i));
928 sub_vector(v1, m.subcolinterval(j)),
929 sub_vector(v2, m.subrowinterval(i)), sv);
932 sub_vector(v1, m.subcolinterval(j)), sv, sv);
937 template <
typename MAT,
typename V1,
typename V2>
938 void mult(
const block_matrix<MAT> &m,
const V1 &v1,
const V2 &v2)
939 { mult(m, v1, linalg_const_cast(v2)); }
941 template <
typename MAT,
typename V1,
typename V2,
typename V3>
942 void mult(
const block_matrix<MAT> &m,
const V1 &v1,
const V2 &v2,
944 { mult_const(m, v1, v2, linalg_const_cast(v3)); }
960 template <
typename T>
inline MPI_Datatype mpi_type(T)
961 { GMM_ASSERT1(
false,
"Sorry unsupported type");
return MPI_FLOAT; }
962 inline MPI_Datatype mpi_type(
double) {
return MPI_DOUBLE; }
963 inline MPI_Datatype mpi_type(
float) {
return MPI_FLOAT; }
964 inline MPI_Datatype mpi_type(
long double) {
return MPI_LONG_DOUBLE; }
966 inline MPI_Datatype mpi_type(std::complex<float>) {
return MPI_COMPLEX; }
967 inline MPI_Datatype mpi_type(std::complex<double>) {
return MPI_DOUBLE_COMPLEX; }
969 inline MPI_Datatype mpi_type(
int) {
return MPI_INT; }
970 inline MPI_Datatype mpi_type(
unsigned int) {
return MPI_UNSIGNED; }
971 inline MPI_Datatype mpi_type(
long) {
return MPI_LONG; }
972 inline MPI_Datatype mpi_type(
unsigned long) {
return MPI_UNSIGNED_LONG; }
974 template <
typename MAT>
struct mpi_distributed_matrix {
977 mpi_distributed_matrix(size_type n, size_type m) : M(n, m) {}
978 mpi_distributed_matrix() {}
980 const MAT &local_matrix(
void)
const {
return M; }
981 MAT &local_matrix(
void) {
return M; }
984 template <
typename MAT>
inline MAT &eff_matrix(MAT &m) {
return m; }
985 template <
typename MAT>
inline 986 const MAT &eff_matrix(
const MAT &m) {
return m; }
987 template <
typename MAT>
inline 988 MAT &eff_matrix(mpi_distributed_matrix<MAT> &m) {
return m.M; }
989 template <
typename MAT>
inline 990 const MAT &eff_matrix(
const mpi_distributed_matrix<MAT> &m) {
return m.M; }
993 template <
typename MAT1,
typename MAT2>
994 inline void copy(
const mpi_distributed_matrix<MAT1> &m1,
995 mpi_distributed_matrix<MAT2> &m2)
996 {
copy(eff_matrix(m1), eff_matrix(m2)); }
997 template <
typename MAT1,
typename MAT2>
998 inline void copy(
const mpi_distributed_matrix<MAT1> &m1,
999 const mpi_distributed_matrix<MAT2> &m2)
1000 {
copy(m1.M, m2.M); }
1002 template <
typename MAT1,
typename MAT2>
1003 inline void copy(
const mpi_distributed_matrix<MAT1> &m1, MAT2 &m2)
1005 template <
typename MAT1,
typename MAT2>
1006 inline void copy(
const mpi_distributed_matrix<MAT1> &m1,
const MAT2 &m2)
1010 template <
typename MATSP,
typename V1,
typename V2>
inline 1011 typename strongest_value_type3<V1,V2,MATSP>::value_type
1012 vect_sp(
const mpi_distributed_matrix<MATSP> &ps,
const V1 &v1,
1014 typedef typename strongest_value_type3<V1,V2,MATSP>::value_type T;
1015 T res =
vect_sp(ps.M, v1, v2), rest;
1016 MPI_Allreduce(&res, &rest, 1, mpi_type(T()), MPI_SUM,MPI_COMM_WORLD);
1020 template <
typename MAT,
typename V1,
typename V2>
1021 inline void mult_add(
const mpi_distributed_matrix<MAT> &m,
const V1 &v1,
1023 typedef typename linalg_traits<V2>::value_type T;
1024 std::vector<T> v3(vect_size(v2)), v4(vect_size(v2));
1025 static double tmult_tot = 0.0;
1026 static double tmult_tot2 = 0.0;
1027 double t_ref = MPI_Wtime();
1028 gmm::mult(m.M, v1, v3);
1029 if (is_sparse(v2)) GMM_WARNING2(
"Using a plain temporary, here.");
1030 double t_ref2 = MPI_Wtime();
1031 MPI_Allreduce(&(v3[0]), &(v4[0]),gmm::vect_size(v2), mpi_type(T()),
1032 MPI_SUM,MPI_COMM_WORLD);
1033 tmult_tot2 = MPI_Wtime()-t_ref2;
1034 cout <<
"reduce mult mpi = " << tmult_tot2 << endl;
1036 tmult_tot = MPI_Wtime()-t_ref;
1037 cout <<
"tmult mpi = " << tmult_tot << endl;
1040 template <
typename MAT,
typename V1,
typename V2>
1041 void mult_add(
const mpi_distributed_matrix<MAT> &m,
const V1 &v1,
1043 {
mult_add(m, v1, const_cast<V2 &>(v2_)); }
1045 template <
typename MAT,
typename V1,
typename V2>
1046 inline void mult(
const mpi_distributed_matrix<MAT> &m,
const V1 &v1,
1048 { V2 &v2 =
const_cast<V2 &
>(v2_);
clear(v2);
mult_add(m, v1, v2); }
1050 template <
typename MAT,
typename V1,
typename V2>
1051 inline void mult(
const mpi_distributed_matrix<MAT> &m,
const V1 &v1,
1055 template <
typename MAT,
typename V1,
typename V2,
typename V3>
1056 inline void mult(
const mpi_distributed_matrix<MAT> &m,
const V1 &v1,
1057 const V2 &v2,
const V3 &v3_)
1058 { V3 &v3 =
const_cast<V3 &
>(v3_); gmm::copy(v2, v3);
mult_add(m, v1, v3); }
1060 template <
typename MAT,
typename V1,
typename V2,
typename V3>
1061 inline void mult(
const mpi_distributed_matrix<MAT> &m,
const V1 &v1,
1062 const V2 &v2, V3 &v3)
1063 { gmm::copy(v2, v3);
mult_add(m, v1, v3); }
1066 template <
typename MAT>
inline 1067 size_type mat_nrows(
const mpi_distributed_matrix<MAT> &M)
1068 {
return mat_nrows(M.M); }
1069 template <
typename MAT>
inline 1070 size_type mat_ncols(
const mpi_distributed_matrix<MAT> &M)
1071 {
return mat_nrows(M.M); }
1072 template <
typename MAT>
inline 1073 void resize(mpi_distributed_matrix<MAT> &M, size_type m, size_type n)
1075 template <
typename MAT>
inline void clear(mpi_distributed_matrix<MAT> &M)
1080 template <
typename MAT1,
typename MAT2>
inline 1081 void mult(
const MAT1 &M1,
const mpi_distributed_matrix<MAT2> &M2,
1082 mpi_distributed_matrix<MAT2> &M3)
1083 { mult(M1, M2.M, M3.M); }
1084 template <
typename MAT1,
typename MAT2>
inline 1085 void mult(
const mpi_distributed_matrix<MAT2> &M2,
1086 const MAT1 &M1, mpi_distributed_matrix<MAT2> &M3)
1087 { mult(M2.M, M1, M3.M); }
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); }
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); }
1097 template <
typename M,
typename SUBI1,
typename SUBI2>
1098 struct sub_matrix_type<const mpi_distributed_matrix<M> *, SUBI1, SUBI2>
1099 {
typedef abstract_null_type matrix_type; };
1101 template <
typename M,
typename SUBI1,
typename SUBI2>
1102 struct sub_matrix_type<mpi_distributed_matrix<M> *, SUBI1, SUBI2>
1103 {
typedef abstract_null_type matrix_type; };
1105 template <
typename M,
typename SUBI1,
typename SUBI2>
inline 1106 typename select_return<typename sub_matrix_type<const M *, SUBI1, SUBI2>
1107 ::matrix_type,
typename sub_matrix_type<M *, SUBI1, SUBI2>::matrix_type,
1109 sub_matrix(mpi_distributed_matrix<M> &m,
const SUBI1 &si1,
const SUBI2 &si2)
1110 {
return sub_matrix(m.M, si1, si2); }
1112 template <
typename MAT,
typename SUBI1,
typename SUBI2>
inline 1113 typename select_return<typename sub_matrix_type<const MAT *, SUBI1, SUBI2>
1114 ::matrix_type,
typename sub_matrix_type<MAT *, SUBI1, SUBI2>::matrix_type,
1115 const MAT *>::return_type
1116 sub_matrix(
const mpi_distributed_matrix<MAT> &m,
const SUBI1 &si1,
1118 {
return sub_matrix(m.M, si1, si2); }
1120 template <
typename M,
typename SUBI1>
inline 1121 typename select_return<typename sub_matrix_type<const M *, SUBI1, SUBI1>
1122 ::matrix_type,
typename sub_matrix_type<M *, SUBI1, SUBI1>::matrix_type,
1124 sub_matrix(mpi_distributed_matrix<M> &m,
const SUBI1 &si1)
1125 {
return sub_matrix(m.M, si1, si1); }
1127 template <
typename M,
typename SUBI1>
inline 1128 typename select_return<typename sub_matrix_type<const M *, SUBI1, SUBI1>
1129 ::matrix_type,
typename sub_matrix_type<M *, SUBI1, SUBI1>::matrix_type,
1130 const M *>::return_type
1131 sub_matrix(
const mpi_distributed_matrix<M> &m,
const SUBI1 &si1)
1132 {
return sub_matrix(m.M, si1, si1); }
1135 template <
typename L>
struct transposed_return<const mpi_distributed_matrix<L> *>
1136 {
typedef abstract_null_type return_type; };
1137 template <
typename L>
struct transposed_return<mpi_distributed_matrix<L> *>
1138 {
typedef abstract_null_type return_type; };
1140 template <
typename L>
inline typename transposed_return<const L *>::return_type
1141 transposed(
const mpi_distributed_matrix<L> &l)
1142 {
return transposed(l.M); }
1144 template <
typename L>
inline typename transposed_return<L *>::return_type
1145 transposed(mpi_distributed_matrix<L> &l)
1146 {
return transposed(l.M); }
1149 template <
typename MAT>
1150 struct linalg_traits<mpi_distributed_matrix<MAT> > {
1151 typedef mpi_distributed_matrix<MAT> this_type;
1152 typedef MAT origin_type;
1153 typedef linalg_false is_reference;
1154 typedef abstract_matrix linalg_type;
1155 typedef typename linalg_traits<MAT>::value_type value_type;
1156 typedef typename linalg_traits<MAT>::reference reference;
1157 typedef typename linalg_traits<MAT>::storage_type storage_type;
1158 typedef abstract_null_type sub_row_type;
1159 typedef abstract_null_type const_sub_row_type;
1160 typedef abstract_null_type row_iterator;
1161 typedef abstract_null_type const_row_iterator;
1162 typedef abstract_null_type sub_col_type;
1163 typedef abstract_null_type const_sub_col_type;
1164 typedef abstract_null_type col_iterator;
1165 typedef abstract_null_type const_col_iterator;
1166 typedef abstract_null_type sub_orientation;
1167 typedef abstract_null_type index_sorted;
1168 static size_type nrows(
const this_type &m) {
return nrows(m.M); }
1169 static size_type ncols(
const this_type &m) {
return ncols(m.M); }
1170 static void do_clear(this_type &m) {
clear(m.M); }
1176 #endif // GMM_USES_MPI 1179 template <
typename V>
1180 void swap(gmm::row_matrix<V> &m1, gmm::row_matrix<V> &m2)
1182 template <
typename V>
1183 void swap(gmm::col_matrix<V> &m1, gmm::col_matrix<V> &m2)
1185 template <
typename T>
1186 void swap(gmm::dense_matrix<T> &m1, gmm::dense_matrix<T> &m2)
1188 template <
typename T,
int shift>
void 1189 swap(gmm::csc_matrix<T,shift> &m1, gmm::csc_matrix<T,shift> &m2)
1191 template <
typename T,
int shift>
void 1192 swap(gmm::csr_matrix<T,shift> &m1, gmm::csr_matrix<T,shift> &m2)
size_t size_type
used as the common size type in the library
void copy(const L1 &l1, L2 &l2)
*/
void resize(V &v, size_type n)
*/
Declaration of the vector types (gmm::rsvector, gmm::wsvector, gmm::slvector ,..) ...
sparse vector built upon std::vector.
void fill(L &l, typename gmm::linalg_traits< L >::value_type x)
*/
strongest_value_type< V1, V2 >::value_type vect_sp(const V1 &v1, const V2 &v2)
*/
void reshape(M &v, size_type m, size_type n)
*/
void clear(L &l)
clear (fill with zeros) a vector or matrix.
void mult_add(const L1 &l1, const L2 &l2, L3 &l3)
*/
strongest_value_type< V1, V2 >::value_type vect_hp(const V1 &v1, const V2 &v2)
*/
size_type nnz(const L &l)
count the number of non-zero entries of a vector or matrix.
Generic transposed matrices.
void add(const L1 &l1, L2 &l2)
*/