59 template <
typename L>
inline void clear(L &l)
60 { linalg_traits<L>::do_clear(l); }
64 template <
typename L>
inline void clear(
const L &l)
65 { linalg_traits<L>::do_clear(linalg_const_cast(l)); }
69 template <
typename L>
inline size_type
nnz(
const L& l)
70 {
return nnz(l,
typename linalg_traits<L>::linalg_type()); }
73 template <
typename L>
inline size_type nnz(
const L& l, abstract_vector) {
74 auto it = vect_const_begin(l), ite = vect_const_end(l);
76 for (; it != ite; ++it) ++res;
80 template <
typename L>
inline size_type nnz(
const L& l, abstract_matrix) {
81 return nnz(l,
typename principal_orientation_type<
typename
82 linalg_traits<L>::sub_orientation>::potype());
85 template <
typename L>
inline size_type nnz(
const L& l, row_major) {
87 for (
size_type i = 0; i < mat_nrows(l); ++i)
88 res +=
nnz(mat_const_row(l, i));
92 template <
typename L>
inline size_type nnz(
const L& l, col_major) {
94 for (
size_type i = 0; i < mat_ncols(l); ++i)
95 res +=
nnz(mat_const_col(l, i));
103 template <
typename L>
inline
104 void fill(L& l,
typename gmm::linalg_traits<L>::value_type x) {
105 typedef typename gmm::linalg_traits<L>::value_type T;
107 fill(l, x,
typename linalg_traits<L>::linalg_type());
110 template <
typename L>
inline
111 void fill(
const L& l,
typename gmm::linalg_traits<L>::value_type x) {
112 fill(linalg_const_cast(l), x);
115 template <
typename L>
inline
116 void fill(L& l,
typename gmm::linalg_traits<L>::value_type x,
118 for (
size_type i = 0; i < vect_size(l); ++i) l[i] = x;
121 template <
typename L>
inline
122 void fill(L& l,
typename gmm::linalg_traits<L>::value_type x,
124 for (
size_type i = 0; i < mat_nrows(l); ++i)
125 for (
size_type j = 0; j < mat_ncols(l); ++j)
131 {
fill_random(l,
typename linalg_traits<L>::linalg_type()); }
134 template <
typename L>
inline void fill_random(
const L& l) {
135 fill_random(linalg_const_cast(l),
136 typename linalg_traits<L>::linalg_type());
139 template <
typename L>
inline void fill_random(L& l, abstract_vector) {
140 for (
size_type i = 0; i < vect_size(l); ++i)
141 l[i] = gmm::random(
typename linalg_traits<L>::value_type());
144 template <
typename L>
inline void fill_random(L& l, abstract_matrix) {
145 for (
size_type i = 0; i < mat_nrows(l); ++i)
146 for (
size_type j = 0; j < mat_ncols(l); ++j)
147 l(i,j) = gmm::random(
typename linalg_traits<L>::value_type());
156 {
fill_random(l, cfill,
typename linalg_traits<L>::linalg_type()); }
159 template <
typename L>
inline void fill_random(
const L& l,
double cfill) {
160 fill_random(linalg_const_cast(l), cfill,
161 typename linalg_traits<L>::linalg_type());
164 template <
typename L>
inline
165 void fill_random(L& l,
double cfill, abstract_vector) {
166 typedef typename linalg_traits<L>::value_type T;
168 size_type(
double(vect_size(l))*cfill) + 1);
170 size_type i = gmm::irandom(vect_size(l));
172 l[i] = gmm::random(
typename linalg_traits<L>::value_type());
178 template <
typename L>
inline
179 void fill_random(L& l,
double cfill, abstract_matrix) {
180 fill_random(l, cfill,
typename principal_orientation_type<
typename
181 linalg_traits<L>::sub_orientation>::potype());
184 template <
typename L>
inline
189 template <
typename L>
inline
195 template <
typename V>
inline
197 { linalg_traits<V>::resize(v, n); }
199 template <
typename V>
inline
201 { GMM_ASSERT1(
false,
"You cannot resize a reference"); }
203 template <
typename V>
inline
205 { GMM_ASSERT1(
false,
"You cannot resize a reference"); }
209 template <
typename V>
inline
211 resize(v, n,
typename linalg_traits<V>::is_reference());
216 template <
typename M>
inline
218 linalg_traits<M>::resize(v, m, n);
221 template <
typename M>
inline
223 { GMM_ASSERT1(
false,
"You cannot resize a reference"); }
225 template <
typename M>
inline
227 { GMM_ASSERT1(
false,
"You cannot resize a reference"); }
231 template <
typename M>
inline
232 void resize(M &v, size_type m, size_type n)
233 {
resize(v, m, n,
typename linalg_traits<M>::is_reference()); }
236 template <
typename M>
inline
238 { linalg_traits<M>::reshape(v, m, n); }
240 template <
typename M>
inline
242 { GMM_ASSERT1(
false,
"You cannot reshape a reference"); }
244 template <
typename M>
inline
246 { GMM_ASSERT1(
false,
"You cannot reshape a reference"); }
250 template <
typename M>
inline
252 {
reshape(v, m, n,
typename linalg_traits<M>::is_reference()); }
262 template <
typename V1,
typename V2>
inline
263 typename strongest_value_type<V1,V2>::value_type
265 GMM_ASSERT2(vect_size(v1) == vect_size(v2),
"dimensions mismatch, "
266 << vect_size(v1) <<
" !=" << vect_size(v2));
268 typename linalg_traits<V1>::storage_type(),
269 typename linalg_traits<V2>::storage_type());
277 template <
typename MATSP,
typename V1,
typename V2>
inline
278 typename strongest_value_type3<V1,V2,MATSP>::value_type
279 vect_sp(
const MATSP &ps,
const V1 &v1,
const V2 &v2) {
280 return vect_sp_with_mat(ps, v1, v2,
281 typename linalg_traits<MATSP>::sub_orientation());
285 template <
typename MATSP,
typename V1,
typename V2>
inline
286 typename strongest_value_type3<V1,V2,MATSP>::value_type
287 vect_sp_with_mat(
const MATSP &ps,
const V1 &v1,
const V2 &v2, row_major) {
288 return vect_sp_with_matr(ps, v1, v2,
289 typename linalg_traits<V2>::storage_type());
292 template <
typename MATSP,
typename V1,
typename V2>
inline
293 typename strongest_value_type3<V1,V2,MATSP>::value_type
294 vect_sp_with_matr(
const MATSP &ps,
const V1 &v1,
const V2 &v2,
296 GMM_ASSERT2(vect_size(v1) == mat_ncols(ps) &&
297 vect_size(v2) == mat_nrows(ps),
"dimensions mismatch");
298 typename linalg_traits<V2>::const_iterator
299 it = vect_const_begin(v2), ite = vect_const_end(v2);
300 typename strongest_value_type3<V1,V2,MATSP>::value_type res(0);
301 for (; it != ite; ++it)
302 res +=
vect_sp(mat_const_row(ps, it.index()), v1)* (*it);
306 template <
typename MATSP,
typename V1,
typename V2>
inline
307 typename strongest_value_type3<V1,V2,MATSP>::value_type
308 vect_sp_with_matr(
const MATSP &ps,
const V1 &v1,
const V2 &v2,
310 {
return vect_sp_with_matr(ps, v1, v2, abstract_sparse()); }
312 template <
typename MATSP,
typename V1,
typename V2>
inline
313 typename strongest_value_type3<V1,V2,MATSP>::value_type
314 vect_sp_with_matr(
const MATSP &ps,
const V1 &v1,
const V2 &v2,
316 GMM_ASSERT2(vect_size(v1) == mat_ncols(ps) &&
317 vect_size(v2) == mat_nrows(ps),
"dimensions mismatch");
318 typename linalg_traits<V2>::const_iterator
319 it = vect_const_begin(v2), ite = vect_const_end(v2);
320 typename strongest_value_type3<V1,V2,MATSP>::value_type res(0);
321 for (
size_type i = 0; it != ite; ++i, ++it)
322 res +=
vect_sp(mat_const_row(ps, i), v1) * (*it);
326 template <
typename MATSP,
typename V1,
typename V2>
inline
327 typename strongest_value_type3<V1,V2,MATSP>::value_type
328 vect_sp_with_mat(
const MATSP &ps,
const V1 &v1,
const V2 &v2,row_and_col)
329 {
return vect_sp_with_mat(ps, v1, v2, row_major()); }
331 template <
typename MATSP,
typename V1,
typename V2>
inline
332 typename strongest_value_type3<V1,V2,MATSP>::value_type
333 vect_sp_with_mat(
const MATSP &ps,
const V1 &v1,
const V2 &v2,col_major){
334 return vect_sp_with_matc(ps, v1, v2,
335 typename linalg_traits<V1>::storage_type());
338 template <
typename MATSP,
typename V1,
typename V2>
inline
339 typename strongest_value_type3<V1,V2,MATSP>::value_type
340 vect_sp_with_matc(
const MATSP &ps,
const V1 &v1,
const V2 &v2,
342 GMM_ASSERT2(vect_size(v1) == mat_ncols(ps) &&
343 vect_size(v2) == mat_nrows(ps),
"dimensions mismatch");
344 typename linalg_traits<V1>::const_iterator
345 it = vect_const_begin(v1), ite = vect_const_end(v1);
346 typename strongest_value_type3<V1,V2,MATSP>::value_type res(0);
347 for (; it != ite; ++it)
348 res +=
vect_sp(mat_const_col(ps, it.index()), v2) * (*it);
352 template <
typename MATSP,
typename V1,
typename V2>
inline
353 typename strongest_value_type3<V1,V2,MATSP>::value_type
354 vect_sp_with_matc(
const MATSP &ps,
const V1 &v1,
const V2 &v2,
356 {
return vect_sp_with_matc(ps, v1, v2, abstract_sparse()); }
358 template <
typename MATSP,
typename V1,
typename V2>
inline
359 typename strongest_value_type3<V1,V2,MATSP>::value_type
360 vect_sp_with_matc(
const MATSP &ps,
const V1 &v1,
const V2 &v2,
362 GMM_ASSERT2(vect_size(v1) == mat_ncols(ps) &&
363 vect_size(v2) == mat_nrows(ps),
"dimensions mismatch");
364 typename linalg_traits<V1>::const_iterator
365 it = vect_const_begin(v1), ite = vect_const_end(v1);
366 typename strongest_value_type3<V1,V2,MATSP>::value_type res(0);
367 for (
size_type i = 0; it != ite; ++i, ++it)
368 res +=
vect_sp(mat_const_col(ps, i), v2) * (*it);
372 template <
typename MATSP,
typename V1,
typename V2>
inline
373 typename strongest_value_type3<V1,V2,MATSP>::value_type
374 vect_sp_with_mat(
const MATSP &ps,
const V1 &v1,
const V2 &v2,col_and_row)
375 {
return vect_sp_with_mat(ps, v1, v2, col_major()); }
377 template <
typename MATSP,
typename V1,
typename V2>
inline
378 typename strongest_value_type3<V1,V2,MATSP>::value_type
379 vect_sp_with_mat(
const MATSP &ps,
const V1 &v1,
const V2 &v2,
380 abstract_null_type) {
381 typename temporary_vector<V1>::vector_type w(mat_nrows(ps));
382 GMM_WARNING2(
"Warning, a temporary is used in scalar product\n");
387 template <
typename IT1,
typename IT2>
inline
388 typename strongest_numeric_type<typename std::iterator_traits<IT1>::value_type,
389 typename std::iterator_traits<IT2>::value_type>::T
390 vect_sp_dense_(IT1 it, IT1 ite, IT2 it2) {
391 typename strongest_numeric_type<typename std::iterator_traits<IT1>::value_type,
392 typename std::iterator_traits<IT2>::value_type>::T res(0);
393 for (; it != ite; ++it, ++it2) res += (*it) * (*it2);
397 template <
typename IT1,
typename V>
inline
398 typename strongest_numeric_type<typename std::iterator_traits<IT1>::value_type,
399 typename linalg_traits<V>::value_type>::T
400 vect_sp_sparse_(IT1 it, IT1 ite,
const V &v) {
401 typename strongest_numeric_type<typename std::iterator_traits<IT1>::value_type,
402 typename linalg_traits<V>::value_type>::T res(0);
403 for (; it != ite; ++it) res += (*it) * v[it.index()];
407 template <
typename V1,
typename V2>
inline
408 typename strongest_value_type<V1,V2>::value_type
409 vect_sp(
const V1 &v1,
const V2 &v2, abstract_dense, abstract_dense) {
410 return vect_sp_dense_(vect_const_begin(v1), vect_const_end(v1),
411 vect_const_begin(v2));
414 template <
typename V1,
typename V2>
inline
415 typename strongest_value_type<V1,V2>::value_type
416 vect_sp(
const V1 &v1,
const V2 &v2, abstract_skyline, abstract_dense) {
417 typename linalg_traits<V1>::const_iterator it1 = vect_const_begin(v1),
418 ite = vect_const_end(v1);
419 typename linalg_traits<V2>::const_iterator it2 = vect_const_begin(v2);
420 return vect_sp_dense_(it1, ite, it2 + it1.index());
423 template <
typename V1,
typename V2>
inline
424 typename strongest_value_type<V1,V2>::value_type
425 vect_sp(
const V1 &v1,
const V2 &v2, abstract_dense, abstract_skyline) {
426 typename linalg_traits<V2>::const_iterator it1 = vect_const_begin(v2),
427 ite = vect_const_end(v2);
428 typename linalg_traits<V1>::const_iterator it2 = vect_const_begin(v1);
429 return vect_sp_dense_(it1, ite, it2 + it1.index());
432 template <
typename V1,
typename V2>
inline
433 typename strongest_value_type<V1,V2>::value_type
434 vect_sp(
const V1 &v1,
const V2 &v2, abstract_skyline, abstract_skyline) {
435 typedef typename strongest_value_type<V1,V2>::value_type T;
436 auto it1 = vect_const_begin(v1), ite1 = vect_const_end(v1);
437 auto it2 = vect_const_begin(v2), ite2 = vect_const_end(v2);
438 size_type n = std::min(ite1.index(), ite2.index());
439 size_type l = std::max(it1.index(), it2.index());
442 size_type m = l - it1.index(), p = l - it2.index(), q = m + n - l;
443 return vect_sp_dense_(it1+m, it1+q, it2 + p);
448 template <
typename V1,
typename V2>
inline
449 typename strongest_value_type<V1,V2>::value_type
450 vect_sp(
const V1 &v1,
const V2 &v2,abstract_sparse,abstract_dense) {
451 return vect_sp_sparse_(vect_const_begin(v1), vect_const_end(v1), v2);
454 template <
typename V1,
typename V2>
inline
455 typename strongest_value_type<V1,V2>::value_type
456 vect_sp(
const V1 &v1,
const V2 &v2, abstract_sparse, abstract_skyline) {
457 return vect_sp_sparse_(vect_const_begin(v1), vect_const_end(v1), v2);
460 template <
typename V1,
typename V2>
inline
461 typename strongest_value_type<V1,V2>::value_type
462 vect_sp(
const V1 &v1,
const V2 &v2, abstract_skyline, abstract_sparse) {
463 return vect_sp_sparse_(vect_const_begin(v2), vect_const_end(v2), v1);
466 template <
typename V1,
typename V2>
inline
467 typename strongest_value_type<V1,V2>::value_type
468 vect_sp(
const V1 &v1,
const V2 &v2, abstract_dense,abstract_sparse) {
469 return vect_sp_sparse_(vect_const_begin(v2), vect_const_end(v2), v1);
473 template <
typename V1,
typename V2>
inline
474 typename strongest_value_type<V1,V2>::value_type
475 vect_sp_sparse_sparse(
const V1 &v1,
const V2 &v2, linalg_true) {
476 typename linalg_traits<V1>::const_iterator it1 = vect_const_begin(v1),
477 ite1 = vect_const_end(v1);
478 typename linalg_traits<V2>::const_iterator it2 = vect_const_begin(v2),
479 ite2 = vect_const_end(v2);
480 typename strongest_value_type<V1,V2>::value_type res(0);
482 while (it1 != ite1 && it2 != ite2) {
483 if (it1.index() == it2.index())
484 { res += (*it1) * *it2; ++it1; ++it2; }
485 else if (it1.index() < it2.index()) ++it1;
else ++it2;
490 template <
typename V1,
typename V2>
inline
491 typename strongest_value_type<V1,V2>::value_type
492 vect_sp_sparse_sparse(
const V1 &v1,
const V2 &v2, linalg_false) {
493 return vect_sp_sparse_(vect_const_begin(v1), vect_const_end(v1), v2);
496 template <
typename V1,
typename V2>
inline
497 typename strongest_value_type<V1,V2>::value_type
498 vect_sp(
const V1 &v1,
const V2 &v2,abstract_sparse,abstract_sparse) {
499 return vect_sp_sparse_sparse(v1, v2,
500 typename linalg_and<
typename linalg_traits<V1>::index_sorted,
501 typename linalg_traits<V2>::index_sorted>::bool_type());
509 template <
typename V1,
typename V2>
510 inline typename strongest_value_type<V1,V2>::value_type
515 template <
typename MATSP,
typename V1,
typename V2>
inline
516 typename strongest_value_type3<V1,V2,MATSP>::value_type
517 vect_hp(
const MATSP &ps,
const V1 &v1,
const V2 &v2) {
526 template <
typename M>
527 typename linalg_traits<M>::value_type
529 typedef typename linalg_traits<M>::value_type T;
531 for (size_type i = 0; i < std::min(mat_nrows(m), mat_ncols(m)); ++i)
541 template <
typename V>
542 typename number_traits<typename linalg_traits<V>::value_type>
545 typedef typename linalg_traits<V>::value_type T;
546 typedef typename number_traits<T>::magnitude_type R;
547 auto it = vect_const_begin(v), ite = vect_const_end(v);
549 for (; it != ite; ++it) res += gmm::abs_sqr(*it);
554 template <
typename V>
inline
555 typename number_traits<typename linalg_traits<V>::value_type>
562 template <
typename V1,
typename V2>
inline
563 typename number_traits<typename linalg_traits<V1>::value_type>
566 typedef typename linalg_traits<V1>::value_type T;
567 typedef typename number_traits<T>::magnitude_type R;
568 auto it1 = vect_const_begin(v1), ite1 = vect_const_end(v1);
569 auto it2 = vect_const_begin(v2), ite2 = vect_const_end(v2);
570 size_type k1(0), k2(0);
572 while (it1 != ite1 && it2 != ite2) {
573 size_type i1 = index_of_it(it1, k1,
574 typename linalg_traits<V1>::storage_type());
575 size_type i2 = index_of_it(it2, k2,
576 typename linalg_traits<V2>::storage_type());
579 res += gmm::abs_sqr(*it2 - *it1); ++it1; ++k1; ++it2; ++k2;
582 res += gmm::abs_sqr(*it1); ++it1; ++k1;
585 res += gmm::abs_sqr(*it2); ++it2; ++k2;
588 while (it1 != ite1) { res += gmm::abs_sqr(*it1); ++it1; }
589 while (it2 != ite2) { res += gmm::abs_sqr(*it2); ++it2; }
594 template <
typename V1,
typename V2>
inline
595 typename number_traits<typename linalg_traits<V1>::value_type>
600 template <
typename M>
601 typename number_traits<typename linalg_traits<M>::value_type>
603 mat_euclidean_norm_sqr(
const M &m, row_major) {
604 typename number_traits<typename linalg_traits<M>::value_type>
605 ::magnitude_type res(0);
606 for (
size_type i = 0; i < mat_nrows(m); ++i)
607 res += vect_norm2_sqr(mat_const_row(m, i));
611 template <
typename M>
612 typename number_traits<typename linalg_traits<M>::value_type>
615 typename number_traits<typename linalg_traits<M>::value_type>
616 ::magnitude_type res(0);
617 for (
size_type i = 0; i < mat_ncols(m); ++i)
623 template <
typename M>
inline
624 typename number_traits<typename linalg_traits<M>::value_type>
628 typename principal_orientation_type<
typename
629 linalg_traits<M>::sub_orientation>::potype());
633 template <
typename M>
inline
634 typename number_traits<typename linalg_traits<M>::value_type>
643 template <
typename V>
644 typename number_traits<typename linalg_traits<V>::value_type>
647 auto it = vect_const_begin(v), ite = vect_const_end(v);
648 typename number_traits<typename linalg_traits<V>::value_type>
649 ::magnitude_type res(0);
650 for (; it != ite; ++it) res += gmm::abs(*it);
655 template <
typename V1,
typename V2>
inline
656 typename number_traits<typename linalg_traits<V1>::value_type>
659 typedef typename linalg_traits<V1>::value_type T;
660 typedef typename number_traits<T>::magnitude_type R;
661 auto it1 = vect_const_begin(v1), ite1 = vect_const_end(v1);
662 auto it2 = vect_const_begin(v2), ite2 = vect_const_end(v2);
663 size_type k1(0), k2(0);
665 while (it1 != ite1 && it2 != ite2) {
666 size_type i1 = index_of_it(it1, k1,
667 typename linalg_traits<V1>::storage_type());
668 size_type i2 = index_of_it(it2, k2,
669 typename linalg_traits<V2>::storage_type());
672 res += gmm::abs(*it2 - *it1); ++it1; ++k1; ++it2; ++k2;
675 res += gmm::abs(*it1); ++it1; ++k1;
678 res += gmm::abs(*it2); ++it2; ++k2;
681 while (it1 != ite1) { res += gmm::abs(*it1); ++it1; }
682 while (it2 != ite2) { res += gmm::abs(*it2); ++it2; }
690 template <
typename V>
691 typename number_traits<typename linalg_traits<V>::value_type>
694 auto it = vect_const_begin(v), ite = vect_const_end(v);
695 typename number_traits<typename linalg_traits<V>::value_type>
696 ::magnitude_type res(0);
697 for (; it != ite; ++it) res = std::max(res, gmm::abs(*it));
702 template <
typename V1,
typename V2>
inline
703 typename number_traits<typename linalg_traits<V1>::value_type>
706 typedef typename linalg_traits<V1>::value_type T;
707 typedef typename number_traits<T>::magnitude_type R;
708 auto it1 = vect_const_begin(v1), ite1 = vect_const_end(v1);
709 auto it2 = vect_const_begin(v2), ite2 = vect_const_end(v2);
710 size_type k1(0), k2(0);
712 while (it1 != ite1 && it2 != ite2) {
713 size_type i1 = index_of_it(it1, k1,
714 typename linalg_traits<V1>::storage_type());
715 size_type i2 = index_of_it(it2, k2,
716 typename linalg_traits<V2>::storage_type());
719 res = std::max(res, gmm::abs(*it2 - *it1)); ++it1; ++k1; ++it2; ++k2;
722 res = std::max(res, gmm::abs(*it1)); ++it1; ++k1;
725 res = std::max(res, gmm::abs(*it2)); ++it2; ++k2;
728 while (it1 != ite1) { res = std::max(res, gmm::abs(*it1)); ++it1; }
729 while (it2 != ite2) { res = std::max(res, gmm::abs(*it2)); ++it2; }
737 template <
typename M>
738 typename number_traits<typename linalg_traits<M>::value_type>
740 mat_norm1(
const M &m, col_major) {
741 typename number_traits<typename linalg_traits<M>::value_type>
742 ::magnitude_type res(0);
743 for (
size_type i = 0; i < mat_ncols(m); ++i)
744 res = std::max(res, vect_norm1(mat_const_col(m,i)));
748 template <
typename M>
749 typename number_traits<typename linalg_traits<M>::value_type>
752 typedef typename linalg_traits<M>::value_type T;
753 typedef typename number_traits<T>::magnitude_type R;
754 typedef typename linalg_traits<M>::storage_type store_type;
756 std::vector<R> aux(mat_ncols(m));
757 for (
size_type i = 0; i < mat_nrows(m); ++i) {
758 typename linalg_traits<M>::const_sub_row_type row = mat_const_row(m, i);
759 auto it = vect_const_begin(row), ite = vect_const_end(row);
760 for (
size_type k = 0; it != ite; ++it, ++k)
761 aux[index_of_it(it, k, store_type())] += gmm::abs(*it);
766 template <
typename M>
767 typename number_traits<typename linalg_traits<M>::value_type>
772 template <
typename M>
773 typename number_traits<typename linalg_traits<M>::value_type>
779 template <
typename M>
780 typename number_traits<typename linalg_traits<M>::value_type>
783 return mat_norm1(m,
typename linalg_traits<M>::sub_orientation());
791 template <
typename M>
792 typename number_traits<typename linalg_traits<M>::value_type>
794 mat_norminf(
const M &m, row_major) {
795 typename number_traits<typename linalg_traits<M>::value_type>
796 ::magnitude_type res(0);
797 for (
size_type i = 0; i < mat_nrows(m); ++i)
798 res = std::max(res, vect_norm1(mat_const_row(m,i)));
802 template <
typename M>
803 typename number_traits<typename linalg_traits<M>::value_type>
806 typedef typename linalg_traits<M>::value_type T;
807 typedef typename number_traits<T>::magnitude_type R;
808 typedef typename linalg_traits<M>::storage_type store_type;
810 std::vector<R> aux(mat_nrows(m));
811 for (
size_type i = 0; i < mat_ncols(m); ++i) {
812 typename linalg_traits<M>::const_sub_col_type col = mat_const_col(m, i);
813 auto it = vect_const_begin(col), ite = vect_const_end(col);
814 for (
size_type k = 0; it != ite; ++it, ++k)
815 aux[index_of_it(it, k, store_type())] += gmm::abs(*it);
820 template <
typename M>
821 typename number_traits<typename linalg_traits<M>::value_type>
826 template <
typename M>
827 typename number_traits<typename linalg_traits<M>::value_type>
833 template <
typename M>
834 typename number_traits<typename linalg_traits<M>::value_type>
837 return mat_norminf(m,
typename linalg_traits<M>::sub_orientation());
844 template <
typename M>
845 typename number_traits<typename linalg_traits<M>::value_type>
847 mat_maxnorm(
const M &m, row_major) {
848 typename number_traits<typename linalg_traits<M>::value_type>
849 ::magnitude_type res(0);
850 for (
size_type i = 0; i < mat_nrows(m); ++i)
851 res = std::max(res, vect_norminf(mat_const_row(m,i)));
855 template <
typename M>
856 typename number_traits<typename linalg_traits<M>::value_type>
859 typename number_traits<typename linalg_traits<M>::value_type>
860 ::magnitude_type res(0);
861 for (
size_type i = 0; i < mat_ncols(m); ++i)
867 template <
typename M>
868 typename number_traits<typename linalg_traits<M>::value_type>
872 (m,
typename principal_orientation_type
873 <
typename linalg_traits<M>::sub_orientation>::potype());
881 template <
typename L>
inline void clean(L &l,
double threshold);
885 template <
typename L,
typename T>
886 void clean(L &l,
double threshold, abstract_dense, T) {
887 typedef typename number_traits<T>::magnitude_type R;
888 auto it = vect_begin(l), ite = vect_end(l);
889 for (; it != ite; ++it)
890 if (gmm::abs(*it) < R(threshold)) *it = T(0);
893 template <
typename L,
typename T>
894 void clean(L &l,
double threshold, abstract_skyline, T)
895 { gmm::clean(l, threshold, abstract_dense(), T()); }
897 template <
typename L,
typename T>
898 void clean(L &l,
double threshold, abstract_sparse, T) {
899 typedef typename number_traits<T>::magnitude_type R;
900 auto it = vect_begin(l), ite = vect_end(l);
901 std::vector<size_type> ind;
902 for (; it != ite; ++it)
903 if (gmm::abs(*it) < R(threshold)) ind.push_back(it.index());
904 for (
size_type i = 0; i < ind.size(); ++i) l[ind[i]] = T(0);
907 template <
typename L,
typename T>
908 void clean(L &l,
double threshold, abstract_dense, std::complex<T>) {
909 auto it = vect_begin(l), ite = vect_end(l);
910 for (; it != ite; ++it){
911 if (gmm::abs((*it).real()) < T(threshold))
912 *it = std::complex<T>(T(0), (*it).imag());
913 if (gmm::abs((*it).imag()) < T(threshold))
914 *it = std::complex<T>((*it).real(), T(0));
918 template <
typename L,
typename T>
919 void clean(L &l,
double threshold, abstract_skyline, std::complex<T>)
920 {
gmm::clean(l, threshold, abstract_dense(), std::complex<T>()); }
922 template <
typename L,
typename T>
923 void clean(L &l,
double threshold, abstract_sparse, std::complex<T>) {
924 auto it = vect_begin(l), ite = vect_end(l);
925 std::vector<size_type> ind;
926 for (; it != ite; ++it) {
927 bool r = (gmm::abs((*it).real()) < T(threshold));
928 bool i = (gmm::abs((*it).imag()) < T(threshold));
929 if (r && i) ind.push_back(it.index());
930 else if (r) *it = std::complex<T>(T(0), (*it).imag());
931 else if (i) *it = std::complex<T>((*it).real(), T(0));
933 for (
size_type i = 0; i < ind.size(); ++i)
934 l[ind[i]] = std::complex<T>(T(0),T(0));
937 template <
typename L>
inline void clean(L &l,
double threshold,
939 gmm::clean(l, threshold,
typename linalg_traits<L>::storage_type(),
940 typename linalg_traits<L>::value_type());
943 template <
typename L>
inline void clean(
const L &l,
double threshold);
945 template <
typename L>
void clean(L &l,
double threshold, row_major) {
946 for (
size_type i = 0; i < mat_nrows(l); ++i)
947 gmm::clean(mat_row(l, i), threshold);
950 template <
typename L>
void clean(L &l,
double threshold, col_major) {
951 for (
size_type i = 0; i < mat_ncols(l); ++i)
952 gmm::clean(mat_col(l, i), threshold);
955 template <
typename L>
inline void clean(L &l,
double threshold,
958 typename principal_orientation_type<
typename
959 linalg_traits<L>::sub_orientation>::potype());
962 template <
typename L>
inline void clean(L &l,
double threshold)
963 {
clean(l, threshold,
typename linalg_traits<L>::linalg_type()); }
965 template <
typename L>
inline void clean(
const L &l,
double threshold)
966 {
gmm::clean(linalg_const_cast(l), threshold); }
976 template <
typename L1,
typename L2>
inline
977 void copy(
const L1& l1, L2& l2) {
978 if ((
const void *)(&l1) != (
const void *)(&l2)) {
979 if (same_origin(l1,l2))
980 GMM_WARNING2(
"Warning : a conflict is possible in copy\n");
982 copy(l1, l2,
typename linalg_traits<L1>::linalg_type(),
983 typename linalg_traits<L2>::linalg_type());
988 template <
typename L1,
typename L2>
inline
989 void copy(
const L1& l1,
const L2& l2) { copy(l1, linalg_const_cast(l2)); }
991 template <
typename L1,
typename L2>
inline
992 void copy(
const L1& l1, L2& l2, abstract_vector, abstract_vector) {
993 GMM_ASSERT2(vect_size(l1) == vect_size(l2),
"dimensions mismatch, "
994 << vect_size(l1) <<
" !=" << vect_size(l2));
995 copy_vect(l1, l2,
typename linalg_traits<L1>::storage_type(),
996 typename linalg_traits<L2>::storage_type());
999 template <
typename L1,
typename L2>
inline
1000 void copy(
const L1& l1, L2& l2, abstract_matrix, abstract_matrix) {
1001 size_type m = mat_nrows(l1), n = mat_ncols(l1);
1002 if (!m || !n)
return;
1003 GMM_ASSERT2(n==mat_ncols(l2) && m==mat_nrows(l2),
"dimensions mismatch");
1004 copy_mat(l1, l2,
typename linalg_traits<L1>::sub_orientation(),
1005 typename linalg_traits<L2>::sub_orientation());
1008 template <
typename V1,
typename V2,
typename C1,
typename C2>
inline
1009 void copy_vect(
const V1 &v1,
const V2 &v2, C1, C2)
1010 { copy_vect(v1,
const_cast<V2 &
>(v2), C1(), C2()); }
1013 template <
typename L1,
typename L2>
1014 void copy_mat_by_row(
const L1& l1, L2& l2) {
1017 copy(mat_const_row(l1, i), mat_row(l2, i));
1020 template <
typename L1,
typename L2>
1021 void copy_mat_by_col(
const L1 &l1, L2 &l2) {
1024 copy(mat_const_col(l1, i), mat_col(l2, i));
1028 template <
typename L1,
typename L2>
inline
1029 void copy_mat(
const L1& l1, L2& l2, row_major, row_major)
1030 { copy_mat_by_row(l1, l2); }
1032 template <
typename L1,
typename L2>
inline
1033 void copy_mat(
const L1& l1, L2& l2, row_major, row_and_col)
1034 { copy_mat_by_row(l1, l2); }
1036 template <
typename L1,
typename L2>
inline
1037 void copy_mat(
const L1& l1, L2& l2, row_and_col, row_and_col)
1038 { copy_mat_by_row(l1, l2); }
1040 template <
typename L1,
typename L2>
inline
1041 void copy_mat(
const L1& l1, L2& l2, row_and_col, row_major)
1042 { copy_mat_by_row(l1, l2); }
1044 template <
typename L1,
typename L2>
inline
1045 void copy_mat(
const L1& l1, L2& l2, col_and_row, row_major)
1046 { copy_mat_by_row(l1, l2); }
1048 template <
typename L1,
typename L2>
inline
1049 void copy_mat(
const L1& l1, L2& l2, row_major, col_and_row)
1050 { copy_mat_by_row(l1, l2); }
1052 template <
typename L1,
typename L2>
inline
1053 void copy_mat(
const L1& l1, L2& l2, col_and_row, row_and_col)
1054 { copy_mat_by_row(l1, l2); }
1056 template <
typename L1,
typename L2>
inline
1057 void copy_mat(
const L1& l1, L2& l2, row_and_col, col_and_row)
1058 { copy_mat_by_row(l1, l2); }
1060 template <
typename L1,
typename L2>
inline
1061 void copy_mat(
const L1& l1, L2& l2, col_major, col_major)
1062 { copy_mat_by_col(l1, l2); }
1064 template <
typename L1,
typename L2>
inline
1065 void copy_mat(
const L1& l1, L2& l2, col_major, col_and_row)
1066 { copy_mat_by_col(l1, l2); }
1068 template <
typename L1,
typename L2>
inline
1069 void copy_mat(
const L1& l1, L2& l2, col_major, row_and_col)
1070 { copy_mat_by_col(l1, l2); }
1072 template <
typename L1,
typename L2>
inline
1073 void copy_mat(
const L1& l1, L2& l2, row_and_col, col_major)
1074 { copy_mat_by_col(l1, l2); }
1076 template <
typename L1,
typename L2>
inline
1077 void copy_mat(
const L1& l1, L2& l2, col_and_row, col_major)
1078 { copy_mat_by_col(l1, l2); }
1080 template <
typename L1,
typename L2>
inline
1081 void copy_mat(
const L1& l1, L2& l2, col_and_row, col_and_row)
1082 { copy_mat_by_col(l1, l2); }
1084 template <
typename L1,
typename L2>
inline
1085 void copy_mat_mixed_rc(
const L1& l1, L2& l2,
size_type i) {
1086 copy_mat_mixed_rc(l1, l2, i,
typename linalg_traits<L1>::storage_type());
1089 template <
typename L1,
typename L2>
1090 void copy_mat_mixed_rc(
const L1& l1, L2& l2,
size_type i, abstract_sparse) {
1091 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1092 for (; it != ite; ++it)
1093 l2(i, it.index()) = *it;
1096 template <
typename L1,
typename L2>
1097 void copy_mat_mixed_rc(
const L1& l1, L2& l2,
size_type i, abstract_skyline) {
1098 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1099 for (; it != ite; ++it)
1100 l2(i, it.index()) = *it;
1103 template <
typename L1,
typename L2>
1104 void copy_mat_mixed_rc(
const L1& l1, L2& l2,
size_type i, abstract_dense) {
1105 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1106 for (
size_type j = 0; it != ite; ++it, ++j) l2(i, j) = *it;
1109 template <
typename L1,
typename L2>
inline
1110 void copy_mat_mixed_cr(
const L1& l1, L2& l2,
size_type i) {
1111 copy_mat_mixed_cr(l1, l2, i,
typename linalg_traits<L1>::storage_type());
1114 template <
typename L1,
typename L2>
1115 void copy_mat_mixed_cr(
const L1& l1, L2& l2,
size_type i, abstract_sparse) {
1116 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1117 for (; it != ite; ++it) l2(it.index(), i) = *it;
1120 template <
typename L1,
typename L2>
1121 void copy_mat_mixed_cr(
const L1& l1, L2& l2,
size_type i, abstract_skyline) {
1122 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1123 for (; it != ite; ++it) l2(it.index(), i) = *it;
1126 template <
typename L1,
typename L2>
1127 void copy_mat_mixed_cr(
const L1& l1, L2& l2,
size_type i, abstract_dense) {
1128 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1129 for (
size_type j = 0; it != ite; ++it, ++j) l2(j, i) = *it;
1132 template <
typename L1,
typename L2>
1133 void copy_mat(
const L1& l1, L2& l2, row_major, col_major) {
1137 copy_mat_mixed_rc(mat_const_row(l1, i), l2, i);
1140 template <
typename L1,
typename L2>
1141 void copy_mat(
const L1& l1, L2& l2, col_major, row_major) {
1145 copy_mat_mixed_cr(mat_const_col(l1, i), l2, i);
1148 template <
typename L1,
typename L2>
inline
1149 void copy_vect(
const L1 &l1, L2 &l2, abstract_dense, abstract_dense) {
1150 std::copy(vect_const_begin(l1), vect_const_end(l1), vect_begin(l2));
1153 template <
typename L1,
typename L2>
inline
1154 void copy_vect(
const L1 &l1, L2 &l2, abstract_skyline, abstract_skyline) {
1155 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1156 while (it1 != ite1 && *it1 ==
typename linalg_traits<L1>::value_type(0))
1159 if (ite1 - it1 > 0) {
1161 auto it2 = vect_begin(l2), ite2 = vect_end(l2);
1162 while (*(ite1-1) ==
typename linalg_traits<L1>::value_type(0))
1166 l2[it1.index()] = *it1;
1168 l2[ite1.index()-1] = *(ite1-1);
1171 it2 = vect_begin(l2);
1173 std::copy(it1, ite1, it2);
1176 ptrdiff_t m = it1.index() - it2.index();
1177 if (m >= 0 && ite1.index() <= ite2.index())
1178 std::copy(it1, ite1, it2 + m);
1181 l2[it1.index()] = *it1;
1182 if (ite1.index() > ite2.index())
1183 l2[ite1.index()-1] = *(ite1-1);
1184 it2 = vect_begin(l2);
1185 ite2 = vect_end(l2);
1186 m = it1.index() - it2.index();
1187 std::copy(it1, ite1, it2 + m);
1193 template <
typename L1,
typename L2>
1194 void copy_vect(
const L1& l1, L2& l2, abstract_sparse, abstract_dense) {
1196 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1197 for (; it != ite; ++it) { l2[it.index()] = *it; }
1200 template <
typename L1,
typename L2>
1201 void copy_vect(
const L1& l1, L2& l2, abstract_sparse, abstract_skyline) {
1203 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1204 for (; it != ite; ++it) l2[it.index()] = *it;
1207 template <
typename L1,
typename L2>
1208 void copy_vect(
const L1& l1, L2& l2, abstract_skyline, abstract_dense) {
1209 typedef typename linalg_traits<L1>::value_type T;
1210 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1214 auto it2 = vect_begin(l2), ite2 = vect_end(l2);
1217 for (j = 0; j < i; ++j, ++it2) *it2 = T(0);
1218 for (; it != ite; ++it, ++it2) *it2 = *it;
1219 for (; it2 != ite2; ++it2) *it2 = T(0);
1223 template <
typename L1,
typename L2>
1224 void copy_vect(
const L1& l1, L2& l2, abstract_sparse, abstract_sparse) {
1225 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1228 for (; it != ite; ++it) {
1231 if (*it != (
typename linalg_traits<L1>::value_type)(0))
1232 l2[it.index()] = *it;
1236 template <
typename L1,
typename L2>
1237 void copy_vect(
const L1& l1, L2& l2, abstract_dense, abstract_sparse) {
1239 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1240 for (
size_type i = 0; it != ite; ++it, ++i)
1241 if (*it != (
typename linalg_traits<L1>::value_type)(0))
1245 template <
typename L1,
typename L2>
1246 void copy_vect(
const L1& l1, L2& l2, abstract_dense, abstract_skyline) {
1248 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1249 for (
size_type i = 0; it != ite; ++it, ++i)
1250 if (*it != (
typename linalg_traits<L1>::value_type)(0))
1255 template <
typename L1,
typename L2>
1256 void copy_vect(
const L1& l1, L2& l2, abstract_skyline, abstract_sparse) {
1258 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1259 for (; it != ite; ++it)
1260 if (*it != (
typename linalg_traits<L1>::value_type)(0))
1261 l2[it.index()] = *it;
1275 template <
typename L1,
typename L2>
inline
1276 void add(
const L1& l1, L2& l2) {
1277 add_spec(l1, l2,
typename linalg_traits<L2>::linalg_type());
1281 template <
typename L1,
typename L2>
inline
1282 void add(
const L1& l1,
const L2& l2) { add(l1, linalg_const_cast(l2)); }
1284 template <
typename L1,
typename L2>
inline
1285 void add_spec(
const L1& l1, L2& l2, abstract_vector) {
1286 GMM_ASSERT2(vect_size(l1) == vect_size(l2),
"dimensions mismatch, "
1287 << vect_size(l1) <<
" !=" << vect_size(l2));
1288 add(l1, l2,
typename linalg_traits<L1>::storage_type(),
1289 typename linalg_traits<L2>::storage_type());
1292 template <
typename L1,
typename L2>
inline
1293 void add_spec(
const L1& l1, L2& l2, abstract_matrix) {
1294 GMM_ASSERT2(mat_nrows(l1)==mat_nrows(l2) && mat_ncols(l1)==mat_ncols(l2),
1295 "dimensions mismatch l1 is " << mat_nrows(l1) <<
"x"
1296 << mat_ncols(l1) <<
" and l2 is " << mat_nrows(l2)
1297 <<
"x" << mat_ncols(l2));
1298 add(l1, l2,
typename linalg_traits<L1>::sub_orientation(),
1299 typename linalg_traits<L2>::sub_orientation());
1302 template <
typename L1,
typename L2>
1303 void add(
const L1& l1, L2& l2, row_major, row_major) {
1304 auto it1 = mat_row_begin(l1), ite = mat_row_end(l1);
1305 auto it2 = mat_row_begin(l2);
1306 for ( ; it1 != ite; ++it1, ++it2)
1307 add(linalg_traits<L1>::row(it1), linalg_traits<L2>::row(it2));
1310 template <
typename L1,
typename L2>
1311 void add(
const L1& l1, L2& l2, col_major, col_major) {
1312 auto it1 = mat_col_const_begin(l1), ite = mat_col_const_end(l1);
1313 typename linalg_traits<L2>::col_iterator it2 = mat_col_begin(l2);
1314 for ( ; it1 != ite; ++it1, ++it2)
1315 add(linalg_traits<L1>::col(it1), linalg_traits<L2>::col(it2));
1318 template <
typename L1,
typename L2>
inline
1319 void add_mat_mixed_rc(
const L1& l1, L2& l2,
size_type i) {
1320 add_mat_mixed_rc(l1, l2, i,
typename linalg_traits<L1>::storage_type());
1323 template <
typename L1,
typename L2>
1324 void add_mat_mixed_rc(
const L1& l1, L2& l2,
size_type i, abstract_sparse) {
1325 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1326 for (; it != ite; ++it) l2(i, it.index()) += *it;
1329 template <
typename L1,
typename L2>
1330 void add_mat_mixed_rc(
const L1& l1, L2& l2,
size_type i, abstract_skyline) {
1331 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1332 for (; it != ite; ++it) l2(i, it.index()) += *it;
1335 template <
typename L1,
typename L2>
1336 void add_mat_mixed_rc(
const L1& l1, L2& l2,
size_type i, abstract_dense) {
1337 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1338 for (
size_type j = 0; it != ite; ++it, ++j) l2(i, j) += *it;
1341 template <
typename L1,
typename L2>
inline
1342 void add_mat_mixed_cr(
const L1& l1, L2& l2,
size_type i) {
1343 add_mat_mixed_cr(l1, l2, i,
typename linalg_traits<L1>::storage_type());
1346 template <
typename L1,
typename L2>
1347 void add_mat_mixed_cr(
const L1& l1, L2& l2,
size_type i, abstract_sparse) {
1348 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1349 for (; it != ite; ++it) l2(it.index(), i) += *it;
1352 template <
typename L1,
typename L2>
1353 void add_mat_mixed_cr(
const L1& l1, L2& l2,
size_type i, abstract_skyline) {
1354 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1355 for (; it != ite; ++it) l2(it.index(), i) += *it;
1358 template <
typename L1,
typename L2>
1359 void add_mat_mixed_cr(
const L1& l1, L2& l2,
size_type i, abstract_dense) {
1360 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1361 for (
size_type j = 0; it != ite; ++it, ++j) l2(j, i) += *it;
1364 template <
typename L1,
typename L2>
1365 void add(
const L1& l1, L2& l2, row_major, col_major) {
1368 add_mat_mixed_rc(mat_const_row(l1, i), l2, i);
1371 template <
typename L1,
typename L2>
1372 void add(
const L1& l1, L2& l2, col_major, row_major) {
1375 add_mat_mixed_cr(mat_const_col(l1, i), l2, i);
1378 template <
typename L1,
typename L2>
inline
1379 void add(
const L1& l1, L2& l2, row_and_col, row_major)
1380 {
add(l1, l2, row_major(), row_major()); }
1382 template <
typename L1,
typename L2>
inline
1383 void add(
const L1& l1, L2& l2, row_and_col, row_and_col)
1384 {
add(l1, l2, row_major(), row_major()); }
1386 template <
typename L1,
typename L2>
inline
1387 void add(
const L1& l1, L2& l2, row_and_col, col_and_row)
1388 {
add(l1, l2, row_major(), row_major()); }
1390 template <
typename L1,
typename L2>
inline
1391 void add(
const L1& l1, L2& l2, col_and_row, row_and_col)
1392 {
add(l1, l2, row_major(), row_major()); }
1394 template <
typename L1,
typename L2>
inline
1395 void add(
const L1& l1, L2& l2, row_major, row_and_col)
1396 {
add(l1, l2, row_major(), row_major()); }
1398 template <
typename L1,
typename L2>
inline
1399 void add(
const L1& l1, L2& l2, col_and_row, row_major)
1400 {
add(l1, l2, row_major(), row_major()); }
1402 template <
typename L1,
typename L2>
inline
1403 void add(
const L1& l1, L2& l2, row_major, col_and_row)
1404 {
add(l1, l2, row_major(), row_major()); }
1406 template <
typename L1,
typename L2>
inline
1407 void add(
const L1& l1, L2& l2, row_and_col, col_major)
1408 {
add(l1, l2, col_major(), col_major()); }
1410 template <
typename L1,
typename L2>
inline
1411 void add(
const L1& l1, L2& l2, col_major, row_and_col)
1412 {
add(l1, l2, col_major(), col_major()); }
1414 template <
typename L1,
typename L2>
inline
1415 void add(
const L1& l1, L2& l2, col_and_row, col_major)
1416 {
add(l1, l2, col_major(), col_major()); }
1418 template <
typename L1,
typename L2>
inline
1419 void add(
const L1& l1, L2& l2, col_and_row, col_and_row)
1420 {
add(l1, l2, col_major(), col_major()); }
1422 template <
typename L1,
typename L2>
inline
1423 void add(
const L1& l1, L2& l2, col_major, col_and_row)
1424 {
add(l1, l2, col_major(), col_major()); }
1432 template <
typename L1,
typename L2,
typename L3>
inline
1433 void add(
const L1& l1,
const L2& l2, L3& l3) {
1434 add_spec(l1, l2, l3,
typename linalg_traits<L2>::linalg_type());
1438 template <
typename L1,
typename L2,
typename L3>
inline
1439 void add(
const L1& l1,
const L2& l2,
const L3& l3)
1440 { add(l1, l2, linalg_const_cast(l3)); }
1442 template <
typename L1,
typename L2,
typename L3>
inline
1443 void add_spec(
const L1& l1,
const L2& l2, L3& l3, abstract_matrix)
1444 {
copy(l2, l3);
add(l1, l3); }
1446 template <
typename L1,
typename L2,
typename L3>
inline
1447 void add_spec(
const L1& l1,
const L2& l2, L3& l3, abstract_vector) {
1448 GMM_ASSERT2(vect_size(l1) == vect_size(l2),
"dimensions mismatch, "
1449 << vect_size(l1) <<
" !=" << vect_size(l2));
1450 GMM_ASSERT2(vect_size(l1) == vect_size(l3),
"dimensions mismatch, "
1451 << vect_size(l1) <<
" !=" << vect_size(l3));
1452 if ((
const void *)(&l1) == (
const void *)(&l3))
1454 else if ((
const void *)(&l2) == (
const void *)(&l3))
1457 add(l1, l2, l3,
typename linalg_traits<L1>::storage_type(),
1458 typename linalg_traits<L2>::storage_type(),
1459 typename linalg_traits<L3>::storage_type());
1462 template <
typename IT1,
typename IT2,
typename IT3>
1463 void add_full_(IT1 it1, IT2 it2, IT3 it3, IT3 ite) {
1464 for (; it3 != ite; ++it3, ++it2, ++it1) *it3 = *it1 + *it2;
1467 template <
typename IT1,
typename IT2,
typename IT3>
1468 void add_almost_full_(IT1 it1, IT1 ite1, IT2 it2, IT3 it3, IT3 ite3) {
1470 for (; it != ite3; ++it, ++it2) *it = *it2;
1471 for (; it1 != ite1; ++it1)
1472 *(it3 + it1.index()) += *it1;
1475 template <
typename IT1,
typename IT2,
typename IT3>
1476 void add_to_full_(IT1 it1, IT1 ite1, IT2 it2, IT2 ite2,
1477 IT3 it3, IT3 ite3) {
1478 typedef typename std::iterator_traits<IT3>::value_type T;
1480 for (; it != ite3; ++it) *it = T(0);
1481 for (; it1 != ite1; ++it1) *(it3 + it1.index()) = *it1;
1482 for (; it2 != ite2; ++it2) *(it3 + it2.index()) += *it2;
1485 template <
typename L1,
typename L2,
typename L3>
inline
1486 void add(
const L1& l1,
const L2& l2, L3& l3,
1487 abstract_dense, abstract_dense, abstract_dense) {
1488 add_full_(vect_const_begin(l1), vect_const_begin(l2),
1489 vect_begin(l3), vect_end(l3));
1494 template <
typename L1,
typename L2,
typename L3,
1495 typename ST1,
typename ST2,
typename ST3>
1496 inline void add(
const L1& l1,
const L2& l2, L3& l3, ST1, ST2, ST3)
1497 {
copy(l2, l3);
add(l1, l3, ST1(), ST3()); }
1499 template <
typename L1,
typename L2,
typename L3>
inline
1500 void add(
const L1& l1,
const L2& l2, L3& l3,
1501 abstract_sparse, abstract_dense, abstract_dense) {
1502 add_almost_full_(vect_const_begin(l1), vect_const_end(l1),
1503 vect_const_begin(l2), vect_begin(l3), vect_end(l3));
1506 template <
typename L1,
typename L2,
typename L3>
inline
1507 void add(
const L1& l1,
const L2& l2, L3& l3,
1508 abstract_dense, abstract_sparse, abstract_dense)
1509 {
add(l2, l1, l3, abstract_sparse(), abstract_dense(), abstract_dense()); }
1511 template <
typename L1,
typename L2,
typename L3>
inline
1512 void add(
const L1& l1,
const L2& l2, L3& l3,
1513 abstract_sparse, abstract_sparse, abstract_dense) {
1514 add_to_full_(vect_const_begin(l1), vect_const_end(l1),
1515 vect_const_begin(l2), vect_const_end(l2),
1516 vect_begin(l3), vect_end(l3));
1520 template <
typename L1,
typename L2,
typename L3>
1521 void add_spspsp(
const L1& l1,
const L2& l2, L3& l3, linalg_true) {
1522 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1523 auto it2 = vect_const_begin(l2), ite2 = vect_const_end(l2);
1525 while (it1 != ite1 && it2 != ite2) {
1526 ptrdiff_t d = it1.index() - it2.index();
1528 { l3[it1.index()] += *it1; ++it1; }
1530 { l3[it2.index()] += *it2; ++it2; }
1532 { l3[it1.index()] = *it1 + *it2; ++it1; ++it2; }
1534 for (; it1 != ite1; ++it1) l3[it1.index()] += *it1;
1535 for (; it2 != ite2; ++it2) l3[it2.index()] += *it2;
1538 template <
typename L1,
typename L2,
typename L3>
1539 void add_spspsp(
const L1& l1,
const L2& l2, L3& l3, linalg_false)
1540 {
copy(l1, l3);
add(l2, l3); }
1542 template <
typename L1,
typename L2,
typename L3>
1543 void add(
const L1& l1,
const L2& l2, L3& l3,
1544 abstract_sparse, abstract_sparse, abstract_sparse) {
1545 add_spspsp(l1, l2, l3,
1546 typename linalg_and<
typename linalg_traits<L1>::index_sorted,
1547 typename linalg_traits<L2>::index_sorted>
1551 template <
typename L1,
typename L2>
1552 void add(
const L1& l1, L2& l2, abstract_dense, abstract_dense) {
1553 auto it1 = vect_const_begin(l1);
1554 auto it2 = vect_begin(l2), ite = vect_end(l2);
1555 for (; it2 != ite; ++it2, ++it1) *it2 += *it1;
1558 template <
typename L1,
typename L2>
1559 void add(
const L1& l1, L2& l2, abstract_dense, abstract_skyline) {
1560 typedef typename linalg_traits<L1>::value_type T;
1562 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1564 while (it1 != ite1 && *it1 == T(0)) { ++it1; ++i1; }
1566 auto it2 = vect_begin(l2), ite2 = vect_end(l2);
1567 while (ie1 && *(ite1-1) == T(0)) { ite1--; --ie1; }
1569 if (it2 == ite2 || i1 < it2.index()) {
1570 l2[i1] = *it1; ++i1; ++it1;
1571 if (it1 == ite1)
return;
1572 it2 = vect_begin(l2);
1573 ite2 = vect_end(l2);
1575 if (ie1 > ite2.index()) {
1576 --ite1; l2[ie1 - 1] = *ite1;
1577 it2 = vect_begin(l2);
1579 it2 += i1 - it2.index();
1580 for (; it1 != ite1; ++it1, ++it2) { *it2 += *it1; }
1585 template <
typename L1,
typename L2>
1586 void add(
const L1& l1, L2& l2, abstract_skyline, abstract_dense) {
1587 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1589 auto it2 = vect_begin(l2);
1591 for (; it1 != ite1; ++it2, ++it1) *it2 += *it1;
1596 template <
typename L1,
typename L2>
1597 void add(
const L1& l1, L2& l2, abstract_sparse, abstract_dense) {
1598 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1599 for (; it1 != ite1; ++it1) l2[it1.index()] += *it1;
1602 template <
typename L1,
typename L2>
1603 void add(
const L1& l1, L2& l2, abstract_sparse, abstract_sparse) {
1604 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1605 for (; it1 != ite1; ++it1) l2[it1.index()] += *it1;
1608 template <
typename L1,
typename L2>
1609 void add(
const L1& l1, L2& l2, abstract_sparse, abstract_skyline) {
1610 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1611 for (; it1 != ite1; ++it1) l2[it1.index()] += *it1;
1615 template <
typename L1,
typename L2>
1616 void add(
const L1& l1, L2& l2, abstract_skyline, abstract_sparse) {
1617 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1618 for (; it1 != ite1; ++it1)
1619 if (*it1 !=
typename linalg_traits<L1>::value_type(0))
1620 l2[it1.index()] += *it1;
1623 template <
typename L1,
typename L2>
1624 void add(
const L1& l1, L2& l2, abstract_skyline, abstract_skyline) {
1625 typedef typename linalg_traits<L1>::value_type T1;
1626 typedef typename linalg_traits<L2>::value_type T2;
1628 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1630 while (it1 != ite1 && *it1 == T1(0)) ++it1;
1632 auto it2 = vect_begin(l2), ite2 = vect_end(l2);
1633 while (*(ite1-1) == T1(0)) ite1--;
1634 if (it2 == ite2 || it1.index() < it2.index()) {
1635 l2[it1.index()] = T2(0);
1636 it2 = vect_begin(l2); ite2 = vect_end(l2);
1638 if (ite1.index() > ite2.index()) {
1639 l2[ite1.index() - 1] = T2(0);
1640 it2 = vect_begin(l2);
1642 it2 += it1.index() - it2.index();
1643 for (; it1 != ite1; ++it1, ++it2) *it2 += *it1;
1647 template <
typename L1,
typename L2>
1648 void add(
const L1& l1, L2& l2, abstract_dense, abstract_sparse) {
1649 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1650 for (
size_type i = 0; it1 != ite1; ++it1, ++i)
1651 if (*it1 !=
typename linalg_traits<L1>::value_type(0)) l2[i] += *it1;
1663 template <
typename L1,
typename L2,
typename L3>
inline
1664 void mult(
const L1& l1,
const L2& l2, L3& l3) {
1665 mult_dispatch(l1, l2, l3,
typename linalg_traits<L2>::linalg_type());
1669 template <
typename L1,
typename L2,
typename L3>
inline
1670 void mult(
const L1& l1,
const L2& l2,
const L3& l3)
1671 { mult(l1, l2, linalg_const_cast(l3)); }
1673 template <
typename L1,
typename L2,
typename L3>
inline
1674 void mult_dispatch(
const L1& l1,
const L2& l2, L3& l3, abstract_vector) {
1675 size_type m = mat_nrows(l1), n = mat_ncols(l1);
1677 GMM_ASSERT2(n==vect_size(l2) && m==vect_size(l3),
"dimensions mismatch");
1678 if (!same_origin(l2, l3))
1679 mult_spec(l1, l2, l3,
typename principal_orientation_type<
typename
1680 linalg_traits<L1>::sub_orientation>::potype());
1682 GMM_WARNING2(
"Warning, A temporary is used for mult\n");
1683 typename temporary_vector<L3>::vector_type temp(vect_size(l3));
1684 mult_spec(l1, l2, temp,
typename principal_orientation_type<
typename
1685 linalg_traits<L1>::sub_orientation>::potype());
1690 template <
typename L1,
typename L2,
typename L3>
1691 void mult_by_row(
const L1& l1,
const L2& l2, L3& l3, abstract_sparse) {
1692 typedef typename linalg_traits<L3>::value_type T;
1696 T aux =
vect_sp(mat_const_row(l1, i), l2);
1697 if (aux != T(0)) l3[i] = aux;
1701 template <
typename L1,
typename L2,
typename L3>
1702 void mult_by_row(
const L1& l1,
const L2& l2, L3& l3, abstract_skyline) {
1703 typedef typename linalg_traits<L3>::value_type T;
1707 T aux =
vect_sp(mat_const_row(l1, i), l2);
1708 if (aux != T(0)) l3[i] = aux;
1712 template <
typename L1,
typename L2,
typename L3>
1713 void mult_by_row(
const L1& l1,
const L2& l2, L3& l3, abstract_dense) {
1714 typename linalg_traits<L3>::iterator it=vect_begin(l3), ite=vect_end(l3);
1715 auto itr = mat_row_const_begin(l1);
1716 for (; it != ite; ++it, ++itr)
1717 *it =
vect_sp(linalg_traits<L1>::row(itr), l2,
1718 typename linalg_traits<L1>::storage_type(),
1719 typename linalg_traits<L2>::storage_type());
1722 template <
typename L1,
typename L2,
typename L3>
1723 void mult_by_col(
const L1& l1,
const L2& l2, L3& l3, abstract_dense) {
1727 add(scaled(mat_const_col(l1, i), l2[i]), l3);
1730 template <
typename L1,
typename L2,
typename L3>
1731 void mult_by_col(
const L1& l1,
const L2& l2, L3& l3, abstract_sparse) {
1732 typedef typename linalg_traits<L2>::value_type T;
1734 auto it = vect_const_begin(l2), ite = vect_const_end(l2);
1735 for (; it != ite; ++it)
1736 if (*it != T(0))
add(scaled(mat_const_col(l1, it.index()), *it), l3);
1739 template <
typename L1,
typename L2,
typename L3>
1740 void mult_by_col(
const L1& l1,
const L2& l2, L3& l3, abstract_skyline) {
1741 typedef typename linalg_traits<L2>::value_type T;
1743 auto it = vect_const_begin(l2), ite = vect_const_end(l2);
1744 for (; it != ite; ++it)
1745 if (*it != T(0))
add(scaled(mat_const_col(l1, it.index()), *it), l3);
1748 template <
typename L1,
typename L2,
typename L3>
inline
1749 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, row_major)
1750 { mult_by_row(l1, l2, l3,
typename linalg_traits<L3>::storage_type()); }
1752 template <
typename L1,
typename L2,
typename L3>
inline
1753 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, col_major)
1754 { mult_by_col(l1, l2, l3,
typename linalg_traits<L2>::storage_type()); }
1756 template <
typename L1,
typename L2,
typename L3>
inline
1757 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, abstract_null_type)
1758 { mult_ind(l1, l2, l3,
typename linalg_traits<L1>::storage_type()); }
1760 template <
typename L1,
typename L2,
typename L3>
1761 void mult_ind(
const L1& l1,
const L2& l2, L3& l3, abstract_indirect) {
1762 GMM_ASSERT1(
false,
"gmm::mult(m, ., .) undefined for this kind of matrix");
1765 template <
typename L1,
typename L2,
typename L3,
typename L4>
inline
1766 void mult(
const L1& l1,
const L2& l2,
const L3& l3, L4& l4) {
1767 size_type m = mat_nrows(l1), n = mat_ncols(l1);
1769 if (!m || !n) {
gmm::copy(l3, l4);
return; }
1770 GMM_ASSERT2(n==vect_size(l2) && m==vect_size(l4),
"dimensions mismatch");
1771 if (!same_origin(l2, l4)) {
1772 mult_add_spec(l1, l2, l4,
typename principal_orientation_type<
typename
1773 linalg_traits<L1>::sub_orientation>::potype());
1776 GMM_WARNING2(
"Warning, A temporary is used for mult\n");
1777 typename temporary_vector<L2>::vector_type temp(vect_size(l2));
1779 mult_add_spec(l1,temp, l4,
typename principal_orientation_type<
typename
1780 linalg_traits<L1>::sub_orientation>::potype());
1784 template <
typename L1,
typename L2,
typename L3,
typename L4>
inline
1785 void mult(
const L1& l1,
const L2& l2,
const L3& l3,
const L4& l4)
1786 {
mult(l1, l2, l3, linalg_const_cast(l4)); }
1790 template <
typename L1,
typename L2,
typename L3>
inline
1792 size_type m = mat_nrows(l1), n = mat_ncols(l1);
1793 if (!m || !n)
return;
1794 GMM_ASSERT2(n==vect_size(l2) && m==vect_size(l3),
"dimensions mismatch");
1795 if (!same_origin(l2, l3)) {
1796 mult_add_spec(l1, l2, l3,
typename principal_orientation_type<
typename
1797 linalg_traits<L1>::sub_orientation>::potype());
1800 GMM_WARNING2(
"Warning, A temporary is used for mult\n");
1801 typename temporary_vector<L3>::vector_type temp(vect_size(l2));
1803 mult_add_spec(l1,temp, l3,
typename principal_orientation_type<
typename
1804 linalg_traits<L1>::sub_orientation>::potype());
1809 template <
typename L1,
typename L2,
typename L3>
inline
1810 void mult_add(
const L1& l1,
const L2& l2,
const L3& l3)
1811 { mult_add(l1, l2, linalg_const_cast(l3)); }
1813 template <
typename L1,
typename L2,
typename L3>
1814 void mult_add_by_row(
const L1& l1,
const L2& l2, L3& l3, abstract_sparse) {
1815 typedef typename linalg_traits<L3>::value_type T;
1818 T aux =
vect_sp(mat_const_row(l1, i), l2);
1819 if (aux != T(0)) l3[i] += aux;
1823 template <
typename L1,
typename L2,
typename L3>
1824 void mult_add_by_row(
const L1& l1,
const L2& l2, L3& l3, abstract_skyline) {
1825 typedef typename linalg_traits<L3>::value_type T;
1828 T aux =
vect_sp(mat_const_row(l1, i), l2);
1829 if (aux != T(0)) l3[i] += aux;
1833 template <
typename L1,
typename L2,
typename L3>
1834 void mult_add_by_row(
const L1& l1,
const L2& l2, L3& l3, abstract_dense) {
1835 auto it=vect_begin(l3), ite=vect_end(l3);
1836 auto itr = mat_row_const_begin(l1);
1837 for (; it != ite; ++it, ++itr)
1838 *it +=
vect_sp(linalg_traits<L1>::row(itr), l2);
1841 template <
typename L1,
typename L2,
typename L3>
1842 void mult_add_by_col(
const L1& l1,
const L2& l2, L3& l3, abstract_dense) {
1845 add(scaled(mat_const_col(l1, i), l2[i]), l3);
1848 template <
typename L1,
typename L2,
typename L3>
1849 void mult_add_by_col(
const L1& l1,
const L2& l2, L3& l3, abstract_sparse) {
1850 auto it = vect_const_begin(l2), ite = vect_const_end(l2);
1851 for (; it != ite; ++it)
1852 if (*it !=
typename linalg_traits<L2>::value_type(0))
1853 add(scaled(mat_const_col(l1, it.index()), *it), l3);
1856 template <
typename L1,
typename L2,
typename L3>
1857 void mult_add_by_col(
const L1& l1,
const L2& l2, L3& l3, abstract_skyline) {
1858 auto it = vect_const_begin(l2), ite = vect_const_end(l2);
1859 for (; it != ite; ++it)
1860 if (*it !=
typename linalg_traits<L2>::value_type(0))
1861 add(scaled(mat_const_col(l1, it.index()), *it), l3);
1864 template <
typename L1,
typename L2,
typename L3>
inline
1865 void mult_add_spec(
const L1& l1,
const L2& l2, L3& l3, row_major)
1866 { mult_add_by_row(l1, l2, l3,
typename linalg_traits<L3>::storage_type()); }
1868 template <
typename L1,
typename L2,
typename L3>
inline
1869 void mult_add_spec(
const L1& l1,
const L2& l2, L3& l3, col_major)
1870 { mult_add_by_col(l1, l2, l3,
typename linalg_traits<L2>::storage_type()); }
1872 template <
typename L1,
typename L2,
typename L3>
inline
1873 void mult_add_spec(
const L1& l1,
const L2& l2, L3& l3, abstract_null_type)
1874 { mult_ind(l1, l2, l3,
typename linalg_traits<L1>::storage_type()); }
1876 template <
typename L1,
typename L2,
typename L3>
1877 void transposed_mult(
const L1& l1,
const L2& l2,
const L3& l3)
1878 {
mult(gmm::transposed(l1), l2, l3); }
1893 template<
typename SO1,
typename SO2,
typename SO3>
struct mult_t;
1894 #define DEFMU__ template<> struct mult_t
1895 DEFMU__<row_major , row_major , row_major > {
typedef r_mult t; };
1896 DEFMU__<row_major , row_major , col_major > {
typedef g_mult t; };
1897 DEFMU__<row_major , row_major , col_and_row> {
typedef r_mult t; };
1898 DEFMU__<row_major , row_major , row_and_col> {
typedef r_mult t; };
1899 DEFMU__<row_major , col_major , row_major > {
typedef rcmult t; };
1900 DEFMU__<row_major , col_major , col_major > {
typedef rcmult t; };
1901 DEFMU__<row_major , col_major , col_and_row> {
typedef rcmult t; };
1902 DEFMU__<row_major , col_major , row_and_col> {
typedef rcmult t; };
1903 DEFMU__<row_major , col_and_row, row_major > {
typedef r_mult t; };
1904 DEFMU__<row_major , col_and_row, col_major > {
typedef rcmult t; };
1905 DEFMU__<row_major , col_and_row, col_and_row> {
typedef rcmult t; };
1906 DEFMU__<row_major , col_and_row, row_and_col> {
typedef rcmult t; };
1907 DEFMU__<row_major , row_and_col, row_major > {
typedef r_mult t; };
1908 DEFMU__<row_major , row_and_col, col_major > {
typedef rcmult t; };
1909 DEFMU__<row_major , row_and_col, col_and_row> {
typedef r_mult t; };
1910 DEFMU__<row_major , row_and_col, row_and_col> {
typedef r_mult t; };
1911 DEFMU__<col_major , row_major , row_major > {
typedef crmult t; };
1912 DEFMU__<col_major , row_major , col_major > {
typedef g_mult t; };
1913 DEFMU__<col_major , row_major , col_and_row> {
typedef crmult t; };
1914 DEFMU__<col_major , row_major , row_and_col> {
typedef crmult t; };
1915 DEFMU__<col_major , col_major , row_major > {
typedef g_mult t; };
1916 DEFMU__<col_major , col_major , col_major > {
typedef c_mult t; };
1917 DEFMU__<col_major , col_major , col_and_row> {
typedef c_mult t; };
1918 DEFMU__<col_major , col_major , row_and_col> {
typedef c_mult t; };
1919 DEFMU__<col_major , col_and_row, row_major > {
typedef crmult t; };
1920 DEFMU__<col_major , col_and_row, col_major > {
typedef c_mult t; };
1921 DEFMU__<col_major , col_and_row, col_and_row> {
typedef c_mult t; };
1922 DEFMU__<col_major , col_and_row, row_and_col> {
typedef c_mult t; };
1923 DEFMU__<col_major , row_and_col, row_major > {
typedef crmult t; };
1924 DEFMU__<col_major , row_and_col, col_major > {
typedef c_mult t; };
1925 DEFMU__<col_major , row_and_col, col_and_row> {
typedef c_mult t; };
1926 DEFMU__<col_major , row_and_col, row_and_col> {
typedef c_mult t; };
1927 DEFMU__<col_and_row, row_major , row_major > {
typedef r_mult t; };
1928 DEFMU__<col_and_row, row_major , col_major > {
typedef c_mult t; };
1929 DEFMU__<col_and_row, row_major , col_and_row> {
typedef r_mult t; };
1930 DEFMU__<col_and_row, row_major , row_and_col> {
typedef r_mult t; };
1931 DEFMU__<col_and_row, col_major , row_major > {
typedef rcmult t; };
1932 DEFMU__<col_and_row, col_major , col_major > {
typedef c_mult t; };
1933 DEFMU__<col_and_row, col_major , col_and_row> {
typedef c_mult t; };
1934 DEFMU__<col_and_row, col_major , row_and_col> {
typedef c_mult t; };
1935 DEFMU__<col_and_row, col_and_row, row_major > {
typedef r_mult t; };
1936 DEFMU__<col_and_row, col_and_row, col_major > {
typedef c_mult t; };
1937 DEFMU__<col_and_row, col_and_row, col_and_row> {
typedef c_mult t; };
1938 DEFMU__<col_and_row, col_and_row, row_and_col> {
typedef c_mult t; };
1939 DEFMU__<col_and_row, row_and_col, row_major > {
typedef r_mult t; };
1940 DEFMU__<col_and_row, row_and_col, col_major > {
typedef c_mult t; };
1941 DEFMU__<col_and_row, row_and_col, col_and_row> {
typedef c_mult t; };
1942 DEFMU__<col_and_row, row_and_col, row_and_col> {
typedef r_mult t; };
1943 DEFMU__<row_and_col, row_major , row_major > {
typedef r_mult t; };
1944 DEFMU__<row_and_col, row_major , col_major > {
typedef c_mult t; };
1945 DEFMU__<row_and_col, row_major , col_and_row> {
typedef r_mult t; };
1946 DEFMU__<row_and_col, row_major , row_and_col> {
typedef r_mult t; };
1947 DEFMU__<row_and_col, col_major , row_major > {
typedef rcmult t; };
1948 DEFMU__<row_and_col, col_major , col_major > {
typedef c_mult t; };
1949 DEFMU__<row_and_col, col_major , col_and_row> {
typedef c_mult t; };
1950 DEFMU__<row_and_col, col_major , row_and_col> {
typedef c_mult t; };
1951 DEFMU__<row_and_col, col_and_row, row_major > {
typedef rcmult t; };
1952 DEFMU__<row_and_col, col_and_row, col_major > {
typedef rcmult t; };
1953 DEFMU__<row_and_col, col_and_row, col_and_row> {
typedef rcmult t; };
1954 DEFMU__<row_and_col, col_and_row, row_and_col> {
typedef rcmult t; };
1955 DEFMU__<row_and_col, row_and_col, row_major > {
typedef r_mult t; };
1956 DEFMU__<row_and_col, row_and_col, col_major > {
typedef c_mult t; };
1957 DEFMU__<row_and_col, row_and_col, col_and_row> {
typedef r_mult t; };
1958 DEFMU__<row_and_col, row_and_col, row_and_col> {
typedef r_mult t; };
1960 template <
typename L1,
typename L2,
typename L3>
1961 void mult_dispatch(
const L1& l1,
const L2& l2, L3& l3, abstract_matrix) {
1962 typedef typename temporary_matrix<L3>::matrix_type temp_mat_type;
1965 GMM_ASSERT2(n == mat_nrows(l2) && mat_nrows(l1) == mat_nrows(l3) &&
1966 mat_ncols(l2) == mat_ncols(l3),
"dimensions mismatch");
1968 if (same_origin(l2, l3) || same_origin(l1, l3)) {
1969 GMM_WARNING2(
"A temporary is used for mult");
1970 temp_mat_type temp(mat_nrows(l3), mat_ncols(l3));
1971 mult_spec(l1, l2, temp,
typename mult_t<
1972 typename linalg_traits<L1>::sub_orientation,
1973 typename linalg_traits<L2>::sub_orientation,
1974 typename linalg_traits<temp_mat_type>::sub_orientation>::t());
1978 mult_spec(l1, l2, l3,
typename mult_t<
1979 typename linalg_traits<L1>::sub_orientation,
1980 typename linalg_traits<L2>::sub_orientation,
1981 typename linalg_traits<L3>::sub_orientation>::t());
1986 template <
typename L1,
typename L2,
typename L3>
1987 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, g_mult) {
1988 typedef typename linalg_traits<L3>::value_type T;
1989 GMM_WARNING2(
"Inefficient generic matrix-matrix mult is used");
1990 for (
size_type i = 0; i < mat_nrows(l3) ; ++i)
1991 for (
size_type j = 0; j < mat_ncols(l3) ; ++j) {
1993 for (
size_type k = 0; k < mat_nrows(l2) ; ++k)
1994 a += l1(i, k)*l2(k, j);
2001 template <
typename L1,
typename L2,
typename L3>
2002 void mult_row_col_with_temp(
const L1& l1,
const L2& l2, L3& l3, col_major) {
2003 typedef typename temporary_col_matrix<L1>::matrix_type temp_col_mat;
2004 temp_col_mat temp(mat_nrows(l1), mat_ncols(l1));
2009 template <
typename L1,
typename L2,
typename L3>
2010 void mult_row_col_with_temp(
const L1& l1,
const L2& l2, L3& l3, row_major) {
2011 typedef typename temporary_row_matrix<L2>::matrix_type temp_row_mat;
2012 temp_row_mat temp(mat_nrows(l2), mat_ncols(l2));
2017 template <
typename L1,
typename L2,
typename L3>
2018 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, rcmult) {
2019 if (is_sparse(l1) && is_sparse(l2)) {
2020 GMM_WARNING3(
"Inefficient row matrix - col matrix mult for "
2021 "sparse matrices, using temporary");
2022 mult_row_col_with_temp
2023 (l1, l2, l3,
typename principal_orientation_type
2024 <
typename linalg_traits<L3>::sub_orientation>::potype());
2027 auto it2b = linalg_traits<L2>::col_begin(l2), it2 = it2b,
2028 ite = linalg_traits<L2>::col_end(l2);
2031 for (i = 0; i < k; ++i) {
2032 typename linalg_traits<L1>::const_sub_row_type r1=mat_const_row(l1, i);
2033 for (it2 = it2b, j = 0; it2 != ite; ++it2, ++j)
2034 l3(i,j) =
vect_sp(r1, linalg_traits<L2>::col(it2));
2041 template <
typename L1,
typename L2,
typename L3>
inline
2042 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, r_mult) {
2043 mult_spec(l1, l2, l3,r_mult(),
typename linalg_traits<L1>::storage_type());
2046 template <
typename L1,
typename L2,
typename L3>
2047 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, r_mult, abstract_dense) {
2050 size_type nn = mat_nrows(l3), mm = mat_nrows(l2);
2053 add(scaled(mat_const_row(l2, j), l1(i, j)), mat_row(l3, i));
2058 template <
typename L1,
typename L2,
typename L3>
2059 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, r_mult, abstract_sparse) {
2064 typename linalg_traits<L1>::const_sub_row_type rl1=mat_const_row(l1, i);
2065 auto it = vect_const_begin(rl1), ite = vect_const_end(rl1);
2066 for (; it != ite; ++it)
2067 add(scaled(mat_const_row(l2, it.index()), *it), mat_row(l3, i));
2071 template <
typename L1,
typename L2,
typename L3>
2072 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, r_mult, abstract_skyline)
2073 { mult_spec(l1, l2, l3, r_mult(), abstract_sparse()); }
2077 template <
typename L1,
typename L2,
typename L3>
inline
2078 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, c_mult) {
2079 mult_spec(l1, l2, l3, c_mult(),
typename linalg_traits<L2>::storage_type(),
2080 typename linalg_traits<L2>::sub_orientation());
2084 template <
typename L1,
typename L2,
typename L3,
typename ORIEN>
2085 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, c_mult,
2086 abstract_dense, ORIEN) {
2087 typedef typename linalg_traits<L2>::value_type T;
2088 size_type nn = mat_ncols(l3), mm = mat_ncols(l1);
2091 clear(mat_col(l3, i));
2094 if (b != T(0))
add(scaled(mat_const_col(l1, j), b), mat_col(l3, i));
2099 template <
typename L1,
typename L2,
typename L3,
typename ORIEN>
2100 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, c_mult,
2101 abstract_sparse, ORIEN) {
2106 typename linalg_traits<L2>::const_sub_col_type rc2 = mat_const_col(l2, i);
2107 auto it = vect_const_begin(rc2), ite = vect_const_end(rc2);
2108 for (; it != ite; ++it)
2109 add(scaled(mat_const_col(l1, it.index()), *it), mat_col(l3, i));
2113 template <
typename L1,
typename L2,
typename L3>
2114 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, c_mult,
2115 abstract_sparse, row_major) {
2116 typedef typename linalg_traits<L2>::value_type T;
2117 GMM_WARNING3(
"Inefficient matrix-matrix mult for sparse matrices");
2119 size_type mm = mat_nrows(l2), nn = mat_ncols(l3);
2123 if (a != T(0))
add(scaled(mat_const_col(l1, j), a), mat_col(l3, i));
2127 template <
typename L1,
typename L2,
typename L3,
typename ORIEN>
inline
2128 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, c_mult,
2129 abstract_skyline, ORIEN)
2130 { mult_spec(l1, l2, l3, c_mult(), abstract_sparse(), ORIEN()); }
2135 template <
typename L1,
typename L2,
typename L3>
inline
2136 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, crmult)
2137 { mult_spec(l1,l2,l3,crmult(),
typename linalg_traits<L1>::storage_type()); }
2140 template <
typename L1,
typename L2,
typename L3>
2141 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, crmult, abstract_dense) {
2144 size_type nn = mat_ncols(l1), mm = mat_nrows(l1);
2147 add(scaled(mat_const_row(l2, i), l1(j, i)), mat_row(l3, j));
2151 template <
typename L1,
typename L2,
typename L3>
2152 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, crmult, abstract_sparse) {
2157 typename linalg_traits<L1>::const_sub_col_type rc1 = mat_const_col(l1, i);
2158 auto it = vect_const_begin(rc1), ite = vect_const_end(rc1);
2159 for (; it != ite; ++it)
2160 add(scaled(mat_const_row(l2, i), *it), mat_row(l3, it.index()));
2164 template <
typename L1,
typename L2,
typename L3>
inline
2165 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, crmult, abstract_skyline)
2166 { mult_spec(l1, l2, l3, crmult(), abstract_sparse()); }
2178 template <
typename MAT>
inline
2180 magnitude_of_linalg(MAT) tol = magnitude_of_linalg(MAT)(-1))
2182 typedef magnitude_of_linalg(MAT) R;
2183 if (tol < R(0)) tol = default_tol(R()) *
mat_maxnorm(A);
2184 if (mat_nrows(A) != mat_ncols(A))
return false;
2185 return is_symmetric(A, tol,
typename linalg_traits<MAT>::storage_type());
2189 template <
typename MAT>
2190 bool is_symmetric(
const MAT &A, magnitude_of_linalg(MAT) tol,
2195 if (gmm::abs(A(i, j)-A(j, i)) > tol)
return false;
2199 template <
typename MAT>
2200 bool is_symmetric(
const MAT &A, magnitude_of_linalg(MAT) tol,
2202 return is_symmetric(A, tol,
typename principal_orientation_type<
typename
2203 linalg_traits<MAT>::sub_orientation>::potype());
2206 template <
typename MAT>
2207 bool is_symmetric(
const MAT &A, magnitude_of_linalg(MAT) tol,
2209 for (
size_type i = 0; i < mat_nrows(A); ++i) {
2210 typename linalg_traits<MAT>::const_sub_row_type row = mat_const_row(A, i);
2211 auto it = vect_const_begin(row), ite = vect_const_end(row);
2212 for (; it != ite; ++it)
2213 if (gmm::abs(*it - A(it.index(), i)) > tol)
return false;
2218 template <
typename MAT>
2219 bool is_symmetric(
const MAT &A, magnitude_of_linalg(MAT) tol,
2221 for (
size_type i = 0; i < mat_ncols(A); ++i) {
2222 typename linalg_traits<MAT>::const_sub_col_type col = mat_const_col(A, i);
2223 auto it = vect_const_begin(col), ite = vect_const_end(col);
2224 for (; it != ite; ++it)
2225 if (gmm::abs(*it - A(i, it.index())) > tol)
return false;
2230 template <
typename MAT>
2231 bool is_symmetric(
const MAT &A, magnitude_of_linalg(MAT) tol,
2240 template <
typename MAT>
inline
2242 magnitude_of_linalg(MAT) tol = magnitude_of_linalg(MAT)(-1))
2244 typedef magnitude_of_linalg(MAT) R;
2245 if (tol < R(0)) tol = default_tol(R()) *
mat_maxnorm(A);
2246 if (mat_nrows(A) != mat_ncols(A))
return false;
2247 return is_hermitian(A, tol,
typename linalg_traits<MAT>::storage_type());
2251 template <
typename MAT>
2252 bool is_hermitian(
const MAT &A, magnitude_of_linalg(MAT) tol,
2257 if (gmm::abs(A(i, j)-gmm::conj(A(j, i))) > tol)
return false;
2261 template <
typename MAT>
2262 bool is_hermitian(
const MAT &A, magnitude_of_linalg(MAT) tol,
2264 return is_hermitian(A, tol,
typename principal_orientation_type<
typename
2265 linalg_traits<MAT>::sub_orientation>::potype());
2268 template <
typename MAT>
2269 bool is_hermitian(
const MAT &A, magnitude_of_linalg(MAT) tol,
2271 for (
size_type i = 0; i < mat_nrows(A); ++i) {
2272 typename linalg_traits<MAT>::const_sub_row_type row = mat_const_row(A, i);
2273 auto it = vect_const_begin(row), ite = vect_const_end(row);
2274 for (; it != ite; ++it)
2275 if (gmm::abs(gmm::conj(*it) - A(it.index(), i)) > tol)
return false;
2280 template <
typename MAT>
2281 bool is_hermitian(
const MAT &A, magnitude_of_linalg(MAT) tol,
2283 for (
size_type i = 0; i < mat_ncols(A); ++i) {
2284 typename linalg_traits<MAT>::const_sub_col_type col = mat_const_col(A, i);
2285 auto it = vect_const_begin(col), ite = vect_const_end(col);
2286 for (; it != ite; ++it)
2287 if (gmm::abs(gmm::conj(*it) - A(i, it.index())) > tol)
return false;
2292 template <
typename MAT>
2293 bool is_hermitian(
const MAT &A, magnitude_of_linalg(MAT) tol,
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)
*/
number_traits< typename linalg_traits< M >::value_type >::magnitude_type mat_norm1(const M &m)
*/
number_traits< typename linalg_traits< V >::value_type >::magnitude_type vect_norm2(const V &v)
Euclidean norm of a vector.
void fill(L &l, typename gmm::linalg_traits< L >::value_type x)
*/
void fill_random(L &l)
fill a vector or matrix with random value (uniform [-1,1]).
number_traits< typename linalg_traits< V1 >::value_type >::magnitude_type vect_dist1(const V1 &v1, const V2 &v2)
1-distance between two vectors
number_traits< typename linalg_traits< M >::value_type >::magnitude_type mat_maxnorm(const M &m)
*/
strongest_value_type< V1, V2 >::value_type vect_hp(const V1 &v1, const V2 &v2)
*/
linalg_traits< M >::value_type mat_trace(const M &m)
Trace of a matrix.
number_traits< typename linalg_traits< M >::value_type >::magnitude_type mat_euclidean_norm(const M &m)
Euclidean norm of a matrix.
number_traits< typename linalg_traits< V1 >::value_type >::magnitude_type vect_distinf(const V1 &v1, const V2 &v2)
Infinity distance between two vectors.
number_traits< typename linalg_traits< V1 >::value_type >::magnitude_type vect_dist2_sqr(const V1 &v1, const V2 &v2)
squared Euclidean distance between two vectors
number_traits< typename linalg_traits< V >::value_type >::magnitude_type vect_norm2_sqr(const V &v)
squared Euclidean norm of a vector.
number_traits< typename linalg_traits< V >::value_type >::magnitude_type vect_norminf(const V &v)
Infinity norm of a vector.
void clear(L &l)
clear (fill with zeros) a vector or matrix.
number_traits< typename linalg_traits< V1 >::value_type >::magnitude_type vect_dist2(const V1 &v1, const V2 &v2)
Euclidean distance between two vectors.
void resize(V &v, size_type n)
*/
void clean(L &l, double threshold)
Clean a vector or matrix (replace near-zero entries with zeroes).
void mult(const L1 &l1, const L2 &l2, L3 &l3)
*/
bool is_hermitian(const MAT &A, magnitude_of_linalg(MAT) tol=magnitude_of_linalg(MAT)(-1))
*/
number_traits< typename linalg_traits< V >::value_type >::magnitude_type vect_norm1(const V &v)
1-norm of a vector
strongest_value_type< V1, V2 >::value_type vect_sp(const V1 &v1, const V2 &v2)
*/
void add(const L1 &l1, L2 &l2)
*/
number_traits< typename linalg_traits< M >::value_type >::magnitude_type mat_euclidean_norm_sqr(const M &m)
*/
number_traits< typename linalg_traits< M >::value_type >::magnitude_type mat_norminf(const M &m)
*/
bool is_symmetric(const MAT &A, magnitude_of_linalg(MAT) tol=magnitude_of_linalg(MAT)(-1))
*/
handle conjugation of complex matrices/vectors.
conjugated_return< L >::return_type conjugated(const L &v)
return a conjugated view of the input matrix or vector.
get a scaled view of a vector/matrix.
Generic transposed matrices.
size_t size_type
used as the common size type in the library