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");
299 typename linalg_traits<V2>::const_iterator
300 it = vect_const_begin(v2), ite = vect_const_end(v2);
301 typename strongest_value_type3<V1,V2,MATSP>::value_type res(0);
302 for (; it != ite; ++it)
303 res +=
vect_sp(mat_const_row(ps, it.index()), v1)* (*it);
307 template <
typename MATSP,
typename V1,
typename V2>
inline
308 typename strongest_value_type3<V1,V2,MATSP>::value_type
309 vect_sp_with_matr(
const MATSP &ps,
const V1 &v1,
const V2 &v2,
311 {
return vect_sp_with_matr(ps, v1, v2, abstract_sparse()); }
313 template <
typename MATSP,
typename V1,
typename V2>
inline
314 typename strongest_value_type3<V1,V2,MATSP>::value_type
315 vect_sp_with_matr(
const MATSP &ps,
const V1 &v1,
const V2 &v2,
317 GMM_ASSERT2(vect_size(v1) == mat_ncols(ps) &&
318 vect_size(v2) == mat_nrows(ps),
"dimensions mismatch");
319 typename linalg_traits<V2>::const_iterator
320 it = vect_const_begin(v2), ite = vect_const_end(v2);
321 typename strongest_value_type3<V1,V2,MATSP>::value_type res(0);
322 for (
size_type i = 0; it != ite; ++i, ++it)
323 res +=
vect_sp(mat_const_row(ps, i), v1) * (*it);
327 template <
typename MATSP,
typename V1,
typename V2>
inline
328 typename strongest_value_type3<V1,V2,MATSP>::value_type
329 vect_sp_with_mat(
const MATSP &ps,
const V1 &v1,
const V2 &v2,row_and_col)
330 {
return vect_sp_with_mat(ps, v1, v2, row_major()); }
332 template <
typename MATSP,
typename V1,
typename V2>
inline
333 typename strongest_value_type3<V1,V2,MATSP>::value_type
334 vect_sp_with_mat(
const MATSP &ps,
const V1 &v1,
const V2 &v2,col_major){
335 return vect_sp_with_matc(ps, v1, v2,
336 typename linalg_traits<V1>::storage_type());
339 template <
typename MATSP,
typename V1,
typename V2>
inline
340 typename strongest_value_type3<V1,V2,MATSP>::value_type
341 vect_sp_with_matc(
const MATSP &ps,
const V1 &v1,
const V2 &v2,
343 GMM_ASSERT2(vect_size(v1) == mat_ncols(ps) &&
344 vect_size(v2) == mat_nrows(ps),
"dimensions mismatch");
345 typename linalg_traits<V1>::const_iterator
346 it = vect_const_begin(v1), ite = vect_const_end(v1);
347 typename strongest_value_type3<V1,V2,MATSP>::value_type res(0);
348 for (; it != ite; ++it)
349 res +=
vect_sp(mat_const_col(ps, it.index()), v2) * (*it);
353 template <
typename MATSP,
typename V1,
typename V2>
inline
354 typename strongest_value_type3<V1,V2,MATSP>::value_type
355 vect_sp_with_matc(
const MATSP &ps,
const V1 &v1,
const V2 &v2,
357 {
return vect_sp_with_matc(ps, v1, v2, abstract_sparse()); }
359 template <
typename MATSP,
typename V1,
typename V2>
inline
360 typename strongest_value_type3<V1,V2,MATSP>::value_type
361 vect_sp_with_matc(
const MATSP &ps,
const V1 &v1,
const V2 &v2,
363 GMM_ASSERT2(vect_size(v1) == mat_ncols(ps) &&
364 vect_size(v2) == mat_nrows(ps),
"dimensions mismatch");
365 typename linalg_traits<V1>::const_iterator
366 it = vect_const_begin(v1), ite = vect_const_end(v1);
367 typename strongest_value_type3<V1,V2,MATSP>::value_type res(0);
368 for (
size_type i = 0; it != ite; ++i, ++it)
369 res +=
vect_sp(mat_const_col(ps, i), v2) * (*it);
373 template <
typename MATSP,
typename V1,
typename V2>
inline
374 typename strongest_value_type3<V1,V2,MATSP>::value_type
375 vect_sp_with_mat(
const MATSP &ps,
const V1 &v1,
const V2 &v2,col_and_row)
376 {
return vect_sp_with_mat(ps, v1, v2, col_major()); }
378 template <
typename MATSP,
typename V1,
typename V2>
inline
379 typename strongest_value_type3<V1,V2,MATSP>::value_type
380 vect_sp_with_mat(
const MATSP &ps,
const V1 &v1,
const V2 &v2,
381 abstract_null_type) {
382 typename temporary_vector<V1>::vector_type w(mat_nrows(ps));
383 GMM_WARNING2(
"Warning, a temporary is used in scalar product\n");
388 template <
typename IT1,
typename IT2>
inline
389 typename strongest_numeric_type<typename std::iterator_traits<IT1>::value_type,
390 typename std::iterator_traits<IT2>::value_type>::T
391 vect_sp_dense_(IT1 it, IT1 ite, IT2 it2) {
392 typename strongest_numeric_type<typename std::iterator_traits<IT1>::value_type,
393 typename std::iterator_traits<IT2>::value_type>::T res(0);
394 for (; it != ite; ++it, ++it2) res += (*it) * (*it2);
398 template <
typename IT1,
typename V>
inline
399 typename strongest_numeric_type<typename std::iterator_traits<IT1>::value_type,
400 typename linalg_traits<V>::value_type>::T
401 vect_sp_sparse_(IT1 it, IT1 ite,
const V &v) {
402 typename strongest_numeric_type<typename std::iterator_traits<IT1>::value_type,
403 typename linalg_traits<V>::value_type>::T res(0);
404 for (; it != ite; ++it) res += (*it) * v[it.index()];
408 template <
typename V1,
typename V2>
inline
409 typename strongest_value_type<V1,V2>::value_type
410 vect_sp(
const V1 &v1,
const V2 &v2, abstract_dense, abstract_dense) {
411 return vect_sp_dense_(vect_const_begin(v1), vect_const_end(v1),
412 vect_const_begin(v2));
415 template <
typename V1,
typename V2>
inline
416 typename strongest_value_type<V1,V2>::value_type
417 vect_sp(
const V1 &v1,
const V2 &v2, abstract_skyline, abstract_dense) {
418 typename linalg_traits<V1>::const_iterator it1 = vect_const_begin(v1),
419 ite = vect_const_end(v1);
420 typename linalg_traits<V2>::const_iterator it2 = vect_const_begin(v2);
421 return vect_sp_dense_(it1, ite, it2 + it1.index());
424 template <
typename V1,
typename V2>
inline
425 typename strongest_value_type<V1,V2>::value_type
426 vect_sp(
const V1 &v1,
const V2 &v2, abstract_dense, abstract_skyline) {
427 typename linalg_traits<V2>::const_iterator it1 = vect_const_begin(v2),
428 ite = vect_const_end(v2);
429 typename linalg_traits<V1>::const_iterator it2 = vect_const_begin(v1);
430 return vect_sp_dense_(it1, ite, it2 + it1.index());
433 template <
typename V1,
typename V2>
inline
434 typename strongest_value_type<V1,V2>::value_type
435 vect_sp(
const V1 &v1,
const V2 &v2, abstract_skyline, abstract_skyline) {
436 typedef typename strongest_value_type<V1,V2>::value_type T;
437 auto it1 = vect_const_begin(v1), ite1 = vect_const_end(v1);
438 auto it2 = vect_const_begin(v2), ite2 = vect_const_end(v2);
439 size_type n = std::min(ite1.index(), ite2.index());
440 size_type l = std::max(it1.index(), it2.index());
443 size_type m = l - it1.index(), p = l - it2.index(), q = m + n - l;
444 return vect_sp_dense_(it1+m, it1+q, it2 + p);
449 template <
typename V1,
typename V2>
inline
450 typename strongest_value_type<V1,V2>::value_type
451 vect_sp(
const V1 &v1,
const V2 &v2,abstract_sparse,abstract_dense) {
452 return vect_sp_sparse_(vect_const_begin(v1), vect_const_end(v1), v2);
455 template <
typename V1,
typename V2>
inline
456 typename strongest_value_type<V1,V2>::value_type
457 vect_sp(
const V1 &v1,
const V2 &v2, abstract_sparse, abstract_skyline) {
458 return vect_sp_sparse_(vect_const_begin(v1), vect_const_end(v1), v2);
461 template <
typename V1,
typename V2>
inline
462 typename strongest_value_type<V1,V2>::value_type
463 vect_sp(
const V1 &v1,
const V2 &v2, abstract_skyline, abstract_sparse) {
464 return vect_sp_sparse_(vect_const_begin(v2), vect_const_end(v2), v1);
467 template <
typename V1,
typename V2>
inline
468 typename strongest_value_type<V1,V2>::value_type
469 vect_sp(
const V1 &v1,
const V2 &v2, abstract_dense,abstract_sparse) {
470 return vect_sp_sparse_(vect_const_begin(v2), vect_const_end(v2), v1);
474 template <
typename V1,
typename V2>
inline
475 typename strongest_value_type<V1,V2>::value_type
476 vect_sp_sparse_sparse(
const V1 &v1,
const V2 &v2, linalg_true) {
477 typename linalg_traits<V1>::const_iterator it1 = vect_const_begin(v1),
478 ite1 = vect_const_end(v1);
479 typename linalg_traits<V2>::const_iterator it2 = vect_const_begin(v2),
480 ite2 = vect_const_end(v2);
481 typename strongest_value_type<V1,V2>::value_type res(0);
483 while (it1 != ite1 && it2 != ite2) {
484 if (it1.index() == it2.index())
485 { res += (*it1) * *it2; ++it1; ++it2; }
486 else if (it1.index() < it2.index()) ++it1;
else ++it2;
491 template <
typename V1,
typename V2>
inline
492 typename strongest_value_type<V1,V2>::value_type
493 vect_sp_sparse_sparse(
const V1 &v1,
const V2 &v2, linalg_false) {
494 return vect_sp_sparse_(vect_const_begin(v1), vect_const_end(v1), v2);
497 template <
typename V1,
typename V2>
inline
498 typename strongest_value_type<V1,V2>::value_type
499 vect_sp(
const V1 &v1,
const V2 &v2,abstract_sparse,abstract_sparse) {
500 return vect_sp_sparse_sparse(v1, v2,
501 typename linalg_and<
typename linalg_traits<V1>::index_sorted,
502 typename linalg_traits<V2>::index_sorted>::bool_type());
510 template <
typename V1,
typename V2>
511 inline typename strongest_value_type<V1,V2>::value_type
516 template <
typename MATSP,
typename V1,
typename V2>
inline
517 typename strongest_value_type3<V1,V2,MATSP>::value_type
518 vect_hp(
const MATSP &ps,
const V1 &v1,
const V2 &v2) {
527 template <
typename M>
528 typename linalg_traits<M>::value_type
530 typedef typename linalg_traits<M>::value_type T;
532 for (size_type i = 0; i < std::min(mat_nrows(m), mat_ncols(m)); ++i)
542 template <
typename V>
543 typename number_traits<typename linalg_traits<V>::value_type>
546 typedef typename linalg_traits<V>::value_type T;
547 typedef typename number_traits<T>::magnitude_type R;
548 auto it = vect_const_begin(v), ite = vect_const_end(v);
550 for (; it != ite; ++it) res += gmm::abs_sqr(*it);
555 template <
typename V>
inline
556 typename number_traits<typename linalg_traits<V>::value_type>
563 template <
typename V1,
typename V2>
inline
564 typename number_traits<typename linalg_traits<V1>::value_type>
567 typedef typename linalg_traits<V1>::value_type T;
568 typedef typename number_traits<T>::magnitude_type R;
569 auto it1 = vect_const_begin(v1), ite1 = vect_const_end(v1);
570 auto it2 = vect_const_begin(v2), ite2 = vect_const_end(v2);
571 size_type k1(0), k2(0);
573 while (it1 != ite1 && it2 != ite2) {
574 size_type i1 = index_of_it(it1, k1,
575 typename linalg_traits<V1>::storage_type());
576 size_type i2 = index_of_it(it2, k2,
577 typename linalg_traits<V2>::storage_type());
580 res += gmm::abs_sqr(*it2 - *it1); ++it1; ++k1; ++it2; ++k2;
583 res += gmm::abs_sqr(*it1); ++it1; ++k1;
586 res += gmm::abs_sqr(*it2); ++it2; ++k2;
589 while (it1 != ite1) { res += gmm::abs_sqr(*it1); ++it1; }
590 while (it2 != ite2) { res += gmm::abs_sqr(*it2); ++it2; }
595 template <
typename V1,
typename V2>
inline
596 typename number_traits<typename linalg_traits<V1>::value_type>
601 template <
typename M>
602 typename number_traits<typename linalg_traits<M>::value_type>
604 mat_euclidean_norm_sqr(
const M &m, row_major) {
605 typename number_traits<typename linalg_traits<M>::value_type>
606 ::magnitude_type res(0);
607 for (
size_type i = 0; i < mat_nrows(m); ++i)
608 res += vect_norm2_sqr(mat_const_row(m, i));
612 template <
typename M>
613 typename number_traits<typename linalg_traits<M>::value_type>
616 typename number_traits<typename linalg_traits<M>::value_type>
617 ::magnitude_type res(0);
618 for (
size_type i = 0; i < mat_ncols(m); ++i)
624 template <
typename M>
inline
625 typename number_traits<typename linalg_traits<M>::value_type>
629 typename principal_orientation_type<
typename
630 linalg_traits<M>::sub_orientation>::potype());
634 template <
typename M>
inline
635 typename number_traits<typename linalg_traits<M>::value_type>
644 template <
typename V>
645 typename number_traits<typename linalg_traits<V>::value_type>
648 auto it = vect_const_begin(v), ite = vect_const_end(v);
649 typename number_traits<typename linalg_traits<V>::value_type>
650 ::magnitude_type res(0);
651 for (; it != ite; ++it) res += gmm::abs(*it);
656 template <
typename V1,
typename V2>
inline
657 typename number_traits<typename linalg_traits<V1>::value_type>
660 typedef typename linalg_traits<V1>::value_type T;
661 typedef typename number_traits<T>::magnitude_type R;
662 auto it1 = vect_const_begin(v1), ite1 = vect_const_end(v1);
663 auto it2 = vect_const_begin(v2), ite2 = vect_const_end(v2);
664 size_type k1(0), k2(0);
666 while (it1 != ite1 && it2 != ite2) {
667 size_type i1 = index_of_it(it1, k1,
668 typename linalg_traits<V1>::storage_type());
669 size_type i2 = index_of_it(it2, k2,
670 typename linalg_traits<V2>::storage_type());
673 res += gmm::abs(*it2 - *it1); ++it1; ++k1; ++it2; ++k2;
676 res += gmm::abs(*it1); ++it1; ++k1;
679 res += gmm::abs(*it2); ++it2; ++k2;
682 while (it1 != ite1) { res += gmm::abs(*it1); ++it1; }
683 while (it2 != ite2) { res += gmm::abs(*it2); ++it2; }
691 template <
typename V>
692 typename number_traits<typename linalg_traits<V>::value_type>
695 auto it = vect_const_begin(v), ite = vect_const_end(v);
696 typename number_traits<typename linalg_traits<V>::value_type>
697 ::magnitude_type res(0);
698 for (; it != ite; ++it) res = std::max(res, gmm::abs(*it));
703 template <
typename V1,
typename V2>
inline
704 typename number_traits<typename linalg_traits<V1>::value_type>
707 typedef typename linalg_traits<V1>::value_type T;
708 typedef typename number_traits<T>::magnitude_type R;
709 auto it1 = vect_const_begin(v1), ite1 = vect_const_end(v1);
710 auto it2 = vect_const_begin(v2), ite2 = vect_const_end(v2);
711 size_type k1(0), k2(0);
713 while (it1 != ite1 && it2 != ite2) {
714 size_type i1 = index_of_it(it1, k1,
715 typename linalg_traits<V1>::storage_type());
716 size_type i2 = index_of_it(it2, k2,
717 typename linalg_traits<V2>::storage_type());
720 res = std::max(res, gmm::abs(*it2 - *it1)); ++it1; ++k1; ++it2; ++k2;
723 res = std::max(res, gmm::abs(*it1)); ++it1; ++k1;
726 res = std::max(res, gmm::abs(*it2)); ++it2; ++k2;
729 while (it1 != ite1) { res = std::max(res, gmm::abs(*it1)); ++it1; }
730 while (it2 != ite2) { res = std::max(res, gmm::abs(*it2)); ++it2; }
738 template <
typename M>
739 typename number_traits<typename linalg_traits<M>::value_type>
741 mat_norm1(
const M &m, col_major) {
742 typename number_traits<typename linalg_traits<M>::value_type>
743 ::magnitude_type res(0);
744 for (
size_type i = 0; i < mat_ncols(m); ++i)
745 res = std::max(res, vect_norm1(mat_const_col(m,i)));
749 template <
typename M>
750 typename number_traits<typename linalg_traits<M>::value_type>
753 typedef typename linalg_traits<M>::value_type T;
754 typedef typename number_traits<T>::magnitude_type R;
755 typedef typename linalg_traits<M>::storage_type store_type;
757 std::vector<R> aux(mat_ncols(m));
758 for (
size_type i = 0; i < mat_nrows(m); ++i) {
759 typename linalg_traits<M>::const_sub_row_type row = mat_const_row(m, i);
760 auto it = vect_const_begin(row), ite = vect_const_end(row);
761 for (
size_type k = 0; it != ite; ++it, ++k)
762 aux[index_of_it(it, k, store_type())] += gmm::abs(*it);
767 template <
typename M>
768 typename number_traits<typename linalg_traits<M>::value_type>
773 template <
typename M>
774 typename number_traits<typename linalg_traits<M>::value_type>
780 template <
typename M>
781 typename number_traits<typename linalg_traits<M>::value_type>
784 return mat_norm1(m,
typename linalg_traits<M>::sub_orientation());
792 template <
typename M>
793 typename number_traits<typename linalg_traits<M>::value_type>
795 mat_norminf(
const M &m, row_major) {
796 typename number_traits<typename linalg_traits<M>::value_type>
797 ::magnitude_type res(0);
798 for (
size_type i = 0; i < mat_nrows(m); ++i)
799 res = std::max(res, vect_norm1(mat_const_row(m,i)));
803 template <
typename M>
804 typename number_traits<typename linalg_traits<M>::value_type>
807 typedef typename linalg_traits<M>::value_type T;
808 typedef typename number_traits<T>::magnitude_type R;
809 typedef typename linalg_traits<M>::storage_type store_type;
811 std::vector<R> aux(mat_nrows(m));
812 for (
size_type i = 0; i < mat_ncols(m); ++i) {
813 typename linalg_traits<M>::const_sub_col_type col = mat_const_col(m, i);
814 auto it = vect_const_begin(col), ite = vect_const_end(col);
815 for (
size_type k = 0; it != ite; ++it, ++k)
816 aux[index_of_it(it, k, store_type())] += gmm::abs(*it);
821 template <
typename M>
822 typename number_traits<typename linalg_traits<M>::value_type>
827 template <
typename M>
828 typename number_traits<typename linalg_traits<M>::value_type>
834 template <
typename M>
835 typename number_traits<typename linalg_traits<M>::value_type>
838 return mat_norminf(m,
typename linalg_traits<M>::sub_orientation());
845 template <
typename M>
846 typename number_traits<typename linalg_traits<M>::value_type>
848 mat_maxnorm(
const M &m, row_major) {
849 typename number_traits<typename linalg_traits<M>::value_type>
850 ::magnitude_type res(0);
851 for (
size_type i = 0; i < mat_nrows(m); ++i)
852 res = std::max(res, vect_norminf(mat_const_row(m,i)));
856 template <
typename M>
857 typename number_traits<typename linalg_traits<M>::value_type>
860 typename number_traits<typename linalg_traits<M>::value_type>
861 ::magnitude_type res(0);
862 for (
size_type i = 0; i < mat_ncols(m); ++i)
868 template <
typename M>
869 typename number_traits<typename linalg_traits<M>::value_type>
873 (m,
typename principal_orientation_type
874 <
typename linalg_traits<M>::sub_orientation>::potype());
882 template <
typename L>
inline void clean(L &l,
double threshold);
886 template <
typename L,
typename T>
887 void clean(L &l,
double threshold, abstract_dense, T) {
888 typedef typename number_traits<T>::magnitude_type R;
889 auto it = vect_begin(l), ite = vect_end(l);
890 for (; it != ite; ++it)
891 if (gmm::abs(*it) < R(threshold)) *it = T(0);
894 template <
typename L,
typename T>
895 void clean(L &l,
double threshold, abstract_skyline, T)
896 { gmm::clean(l, threshold, abstract_dense(), T()); }
898 template <
typename L,
typename T>
899 void clean(L &l,
double threshold, abstract_sparse, T) {
900 typedef typename number_traits<T>::magnitude_type R;
901 auto it = vect_begin(l), ite = vect_end(l);
902 std::vector<size_type> ind;
903 for (; it != ite; ++it)
904 if (gmm::abs(*it) < R(threshold)) ind.push_back(it.index());
905 for (
size_type i = 0; i < ind.size(); ++i) l[ind[i]] = T(0);
908 template <
typename L,
typename T>
909 void clean(L &l,
double threshold, abstract_dense, std::complex<T>) {
910 auto it = vect_begin(l), ite = vect_end(l);
911 for (; it != ite; ++it){
912 if (gmm::abs((*it).real()) < T(threshold))
913 *it = std::complex<T>(T(0), (*it).imag());
914 if (gmm::abs((*it).imag()) < T(threshold))
915 *it = std::complex<T>((*it).real(), T(0));
919 template <
typename L,
typename T>
920 void clean(L &l,
double threshold, abstract_skyline, std::complex<T>)
921 {
gmm::clean(l, threshold, abstract_dense(), std::complex<T>()); }
923 template <
typename L,
typename T>
924 void clean(L &l,
double threshold, abstract_sparse, std::complex<T>) {
925 auto it = vect_begin(l), ite = vect_end(l);
926 std::vector<size_type> ind;
927 for (; it != ite; ++it) {
928 bool r = (gmm::abs((*it).real()) < T(threshold));
929 bool i = (gmm::abs((*it).imag()) < T(threshold));
930 if (r && i) ind.push_back(it.index());
931 else if (r) *it = std::complex<T>(T(0), (*it).imag());
932 else if (i) *it = std::complex<T>((*it).real(), T(0));
934 for (
size_type i = 0; i < ind.size(); ++i)
935 l[ind[i]] = std::complex<T>(T(0),T(0));
938 template <
typename L>
inline void clean(L &l,
double threshold,
940 gmm::clean(l, threshold,
typename linalg_traits<L>::storage_type(),
941 typename linalg_traits<L>::value_type());
944 template <
typename L>
inline void clean(
const L &l,
double threshold);
946 template <
typename L>
void clean(L &l,
double threshold, row_major) {
947 for (
size_type i = 0; i < mat_nrows(l); ++i)
948 gmm::clean(mat_row(l, i), threshold);
951 template <
typename L>
void clean(L &l,
double threshold, col_major) {
952 for (
size_type i = 0; i < mat_ncols(l); ++i)
953 gmm::clean(mat_col(l, i), threshold);
956 template <
typename L>
inline void clean(L &l,
double threshold,
959 typename principal_orientation_type<
typename
960 linalg_traits<L>::sub_orientation>::potype());
963 template <
typename L>
inline void clean(L &l,
double threshold)
964 {
clean(l, threshold,
typename linalg_traits<L>::linalg_type()); }
966 template <
typename L>
inline void clean(
const L &l,
double threshold)
967 {
gmm::clean(linalg_const_cast(l), threshold); }
977 template <
typename L1,
typename L2>
inline
978 void copy(
const L1& l1, L2& l2) {
979 if ((
const void *)(&l1) != (
const void *)(&l2)) {
980 if (same_origin(l1,l2))
981 GMM_WARNING2(
"Warning : a conflict is possible in copy\n");
983 copy(l1, l2,
typename linalg_traits<L1>::linalg_type(),
984 typename linalg_traits<L2>::linalg_type());
989 template <
typename L1,
typename L2>
inline
990 void copy(
const L1& l1,
const L2& l2) { copy(l1, linalg_const_cast(l2)); }
992 template <
typename L1,
typename L2>
inline
993 void copy(
const L1& l1, L2& l2, abstract_vector, abstract_vector) {
994 GMM_ASSERT2(vect_size(l1) == vect_size(l2),
"dimensions mismatch, "
995 << vect_size(l1) <<
" !=" << vect_size(l2));
996 copy_vect(l1, l2,
typename linalg_traits<L1>::storage_type(),
997 typename linalg_traits<L2>::storage_type());
1000 template <
typename L1,
typename L2>
inline
1001 void copy(
const L1& l1, L2& l2, abstract_matrix, abstract_matrix) {
1002 size_type m = mat_nrows(l1), n = mat_ncols(l1);
1003 if (!m || !n)
return;
1004 GMM_ASSERT2(n==mat_ncols(l2) && m==mat_nrows(l2),
"dimensions mismatch");
1005 copy_mat(l1, l2,
typename linalg_traits<L1>::sub_orientation(),
1006 typename linalg_traits<L2>::sub_orientation());
1009 template <
typename V1,
typename V2,
typename C1,
typename C2>
inline
1010 void copy_vect(
const V1 &v1,
const V2 &v2, C1, C2)
1011 { copy_vect(v1,
const_cast<V2 &
>(v2), C1(), C2()); }
1014 template <
typename L1,
typename L2>
1015 void copy_mat_by_row(
const L1& l1, L2& l2) {
1018 copy(mat_const_row(l1, i), mat_row(l2, i));
1021 template <
typename L1,
typename L2>
1022 void copy_mat_by_col(
const L1 &l1, L2 &l2) {
1025 copy(mat_const_col(l1, i), mat_col(l2, i));
1029 template <
typename L1,
typename L2>
inline
1030 void copy_mat(
const L1& l1, L2& l2, row_major, row_major)
1031 { copy_mat_by_row(l1, l2); }
1033 template <
typename L1,
typename L2>
inline
1034 void copy_mat(
const L1& l1, L2& l2, row_major, row_and_col)
1035 { copy_mat_by_row(l1, l2); }
1037 template <
typename L1,
typename L2>
inline
1038 void copy_mat(
const L1& l1, L2& l2, row_and_col, row_and_col)
1039 { copy_mat_by_row(l1, l2); }
1041 template <
typename L1,
typename L2>
inline
1042 void copy_mat(
const L1& l1, L2& l2, row_and_col, row_major)
1043 { copy_mat_by_row(l1, l2); }
1045 template <
typename L1,
typename L2>
inline
1046 void copy_mat(
const L1& l1, L2& l2, col_and_row, row_major)
1047 { copy_mat_by_row(l1, l2); }
1049 template <
typename L1,
typename L2>
inline
1050 void copy_mat(
const L1& l1, L2& l2, row_major, col_and_row)
1051 { copy_mat_by_row(l1, l2); }
1053 template <
typename L1,
typename L2>
inline
1054 void copy_mat(
const L1& l1, L2& l2, col_and_row, row_and_col)
1055 { copy_mat_by_row(l1, l2); }
1057 template <
typename L1,
typename L2>
inline
1058 void copy_mat(
const L1& l1, L2& l2, row_and_col, col_and_row)
1059 { copy_mat_by_row(l1, l2); }
1061 template <
typename L1,
typename L2>
inline
1062 void copy_mat(
const L1& l1, L2& l2, col_major, col_major)
1063 { copy_mat_by_col(l1, l2); }
1065 template <
typename L1,
typename L2>
inline
1066 void copy_mat(
const L1& l1, L2& l2, col_major, col_and_row)
1067 { copy_mat_by_col(l1, l2); }
1069 template <
typename L1,
typename L2>
inline
1070 void copy_mat(
const L1& l1, L2& l2, col_major, row_and_col)
1071 { copy_mat_by_col(l1, l2); }
1073 template <
typename L1,
typename L2>
inline
1074 void copy_mat(
const L1& l1, L2& l2, row_and_col, col_major)
1075 { copy_mat_by_col(l1, l2); }
1077 template <
typename L1,
typename L2>
inline
1078 void copy_mat(
const L1& l1, L2& l2, col_and_row, col_major)
1079 { copy_mat_by_col(l1, l2); }
1081 template <
typename L1,
typename L2>
inline
1082 void copy_mat(
const L1& l1, L2& l2, col_and_row, col_and_row)
1083 { copy_mat_by_col(l1, l2); }
1085 template <
typename L1,
typename L2>
inline
1086 void copy_mat_mixed_rc(
const L1& l1, L2& l2,
size_type i) {
1087 copy_mat_mixed_rc(l1, l2, i,
typename linalg_traits<L1>::storage_type());
1090 template <
typename L1,
typename L2>
1091 void copy_mat_mixed_rc(
const L1& l1, L2& l2,
size_type i, abstract_sparse) {
1092 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1093 for (; it != ite; ++it)
1094 l2(i, it.index()) = *it;
1097 template <
typename L1,
typename L2>
1098 void copy_mat_mixed_rc(
const L1& l1, L2& l2,
size_type i, abstract_skyline) {
1099 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1100 for (; it != ite; ++it)
1101 l2(i, it.index()) = *it;
1104 template <
typename L1,
typename L2>
1105 void copy_mat_mixed_rc(
const L1& l1, L2& l2,
size_type i, abstract_dense) {
1106 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1107 for (
size_type j = 0; it != ite; ++it, ++j) l2(i, j) = *it;
1110 template <
typename L1,
typename L2>
inline
1111 void copy_mat_mixed_cr(
const L1& l1, L2& l2,
size_type i) {
1112 copy_mat_mixed_cr(l1, l2, i,
typename linalg_traits<L1>::storage_type());
1115 template <
typename L1,
typename L2>
1116 void copy_mat_mixed_cr(
const L1& l1, L2& l2,
size_type i, abstract_sparse) {
1117 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1118 for (; it != ite; ++it) l2(it.index(), i) = *it;
1121 template <
typename L1,
typename L2>
1122 void copy_mat_mixed_cr(
const L1& l1, L2& l2,
size_type i, abstract_skyline) {
1123 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1124 for (; it != ite; ++it) l2(it.index(), i) = *it;
1127 template <
typename L1,
typename L2>
1128 void copy_mat_mixed_cr(
const L1& l1, L2& l2,
size_type i, abstract_dense) {
1129 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1130 for (
size_type j = 0; it != ite; ++it, ++j) l2(j, i) = *it;
1133 template <
typename L1,
typename L2>
1134 void copy_mat(
const L1& l1, L2& l2, row_major, col_major) {
1138 copy_mat_mixed_rc(mat_const_row(l1, i), l2, i);
1141 template <
typename L1,
typename L2>
1142 void copy_mat(
const L1& l1, L2& l2, col_major, row_major) {
1146 copy_mat_mixed_cr(mat_const_col(l1, i), l2, i);
1149 template <
typename L1,
typename L2>
inline
1150 void copy_vect(
const L1 &l1, L2 &l2, abstract_dense, abstract_dense) {
1151 std::copy(vect_const_begin(l1), vect_const_end(l1), vect_begin(l2));
1154 template <
typename L1,
typename L2>
inline
1155 void copy_vect(
const L1 &l1, L2 &l2, abstract_skyline, abstract_skyline) {
1156 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1157 while (it1 != ite1 && *it1 ==
typename linalg_traits<L1>::value_type(0))
1160 if (ite1 - it1 > 0) {
1162 auto it2 = vect_begin(l2), ite2 = vect_end(l2);
1163 while (*(ite1-1) ==
typename linalg_traits<L1>::value_type(0))
1167 l2[it1.index()] = *it1;
1169 l2[ite1.index()-1] = *(ite1-1);
1172 it2 = vect_begin(l2);
1174 std::copy(it1, ite1, it2);
1177 ptrdiff_t m = it1.index() - it2.index();
1178 if (m >= 0 && ite1.index() <= ite2.index())
1179 std::copy(it1, ite1, it2 + m);
1182 l2[it1.index()] = *it1;
1183 if (ite1.index() > ite2.index())
1184 l2[ite1.index()-1] = *(ite1-1);
1185 it2 = vect_begin(l2);
1186 ite2 = vect_end(l2);
1187 m = it1.index() - it2.index();
1188 std::copy(it1, ite1, it2 + m);
1194 template <
typename L1,
typename L2>
1195 void copy_vect(
const L1& l1, L2& l2, abstract_sparse, abstract_dense) {
1197 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1198 for (; it != ite; ++it) { l2[it.index()] = *it; }
1201 template <
typename L1,
typename L2>
1202 void copy_vect(
const L1& l1, L2& l2, abstract_sparse, abstract_skyline) {
1204 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1205 for (; it != ite; ++it) l2[it.index()] = *it;
1208 template <
typename L1,
typename L2>
1209 void copy_vect(
const L1& l1, L2& l2, abstract_skyline, abstract_dense) {
1210 typedef typename linalg_traits<L1>::value_type T;
1211 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1215 auto it2 = vect_begin(l2), ite2 = vect_end(l2);
1218 for (j = 0; j < i; ++j, ++it2) *it2 = T(0);
1219 for (; it != ite; ++it, ++it2) *it2 = *it;
1220 for (; it2 != ite2; ++it2) *it2 = T(0);
1224 template <
typename L1,
typename L2>
1225 void copy_vect(
const L1& l1, L2& l2, abstract_sparse, abstract_sparse) {
1226 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1229 for (; it != ite; ++it) {
1232 if (*it != (
typename linalg_traits<L1>::value_type)(0))
1233 l2[it.index()] = *it;
1237 template <
typename L1,
typename L2>
1238 void copy_vect(
const L1& l1, L2& l2, abstract_dense, abstract_sparse) {
1240 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1241 for (
size_type i = 0; it != ite; ++it, ++i)
1242 if (*it != (
typename linalg_traits<L1>::value_type)(0))
1246 template <
typename L1,
typename L2>
1247 void copy_vect(
const L1& l1, L2& l2, abstract_dense, abstract_skyline) {
1249 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1250 for (
size_type i = 0; it != ite; ++it, ++i)
1251 if (*it != (
typename linalg_traits<L1>::value_type)(0))
1256 template <
typename L1,
typename L2>
1257 void copy_vect(
const L1& l1, L2& l2, abstract_skyline, abstract_sparse) {
1259 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1260 for (; it != ite; ++it)
1261 if (*it != (
typename linalg_traits<L1>::value_type)(0))
1262 l2[it.index()] = *it;
1276 template <
typename L1,
typename L2>
inline
1277 void add(
const L1& l1, L2& l2) {
1278 add_spec(l1, l2,
typename linalg_traits<L2>::linalg_type());
1282 template <
typename L1,
typename L2>
inline
1283 void add(
const L1& l1,
const L2& l2) { add(l1, linalg_const_cast(l2)); }
1285 template <
typename L1,
typename L2>
inline
1286 void add_spec(
const L1& l1, L2& l2, abstract_vector) {
1287 GMM_ASSERT2(vect_size(l1) == vect_size(l2),
"dimensions mismatch, "
1288 << vect_size(l1) <<
" !=" << vect_size(l2));
1289 add(l1, l2,
typename linalg_traits<L1>::storage_type(),
1290 typename linalg_traits<L2>::storage_type());
1293 template <
typename L1,
typename L2>
inline
1294 void add_spec(
const L1& l1, L2& l2, abstract_matrix) {
1295 GMM_ASSERT2(mat_nrows(l1)==mat_nrows(l2) && mat_ncols(l1)==mat_ncols(l2),
1296 "dimensions mismatch l1 is " << mat_nrows(l1) <<
"x"
1297 << mat_ncols(l1) <<
" and l2 is " << mat_nrows(l2)
1298 <<
"x" << mat_ncols(l2));
1299 add(l1, l2,
typename linalg_traits<L1>::sub_orientation(),
1300 typename linalg_traits<L2>::sub_orientation());
1303 template <
typename L1,
typename L2>
1304 void add(
const L1& l1, L2& l2, row_major, row_major) {
1305 auto it1 = mat_row_begin(l1), ite = mat_row_end(l1);
1306 auto it2 = mat_row_begin(l2);
1307 for ( ; it1 != ite; ++it1, ++it2)
1308 add(linalg_traits<L1>::row(it1), linalg_traits<L2>::row(it2));
1311 template <
typename L1,
typename L2>
1312 void add(
const L1& l1, L2& l2, col_major, col_major) {
1313 auto it1 = mat_col_const_begin(l1), ite = mat_col_const_end(l1);
1314 typename linalg_traits<L2>::col_iterator it2 = mat_col_begin(l2);
1315 for ( ; it1 != ite; ++it1, ++it2)
1316 add(linalg_traits<L1>::col(it1), linalg_traits<L2>::col(it2));
1319 template <
typename L1,
typename L2>
inline
1320 void add_mat_mixed_rc(
const L1& l1, L2& l2,
size_type i) {
1321 add_mat_mixed_rc(l1, l2, i,
typename linalg_traits<L1>::storage_type());
1324 template <
typename L1,
typename L2>
1325 void add_mat_mixed_rc(
const L1& l1, L2& l2,
size_type i, abstract_sparse) {
1326 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1327 for (; it != ite; ++it) l2(i, it.index()) += *it;
1330 template <
typename L1,
typename L2>
1331 void add_mat_mixed_rc(
const L1& l1, L2& l2,
size_type i, abstract_skyline) {
1332 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1333 for (; it != ite; ++it) l2(i, it.index()) += *it;
1336 template <
typename L1,
typename L2>
1337 void add_mat_mixed_rc(
const L1& l1, L2& l2,
size_type i, abstract_dense) {
1338 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1339 for (
size_type j = 0; it != ite; ++it, ++j) l2(i, j) += *it;
1342 template <
typename L1,
typename L2>
inline
1343 void add_mat_mixed_cr(
const L1& l1, L2& l2,
size_type i) {
1344 add_mat_mixed_cr(l1, l2, i,
typename linalg_traits<L1>::storage_type());
1347 template <
typename L1,
typename L2>
1348 void add_mat_mixed_cr(
const L1& l1, L2& l2,
size_type i, abstract_sparse) {
1349 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1350 for (; it != ite; ++it) l2(it.index(), i) += *it;
1353 template <
typename L1,
typename L2>
1354 void add_mat_mixed_cr(
const L1& l1, L2& l2,
size_type i, abstract_skyline) {
1355 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1356 for (; it != ite; ++it) l2(it.index(), i) += *it;
1359 template <
typename L1,
typename L2>
1360 void add_mat_mixed_cr(
const L1& l1, L2& l2,
size_type i, abstract_dense) {
1361 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1362 for (
size_type j = 0; it != ite; ++it, ++j) l2(j, i) += *it;
1365 template <
typename L1,
typename L2>
1366 void add(
const L1& l1, L2& l2, row_major, col_major) {
1369 add_mat_mixed_rc(mat_const_row(l1, i), l2, i);
1372 template <
typename L1,
typename L2>
1373 void add(
const L1& l1, L2& l2, col_major, row_major) {
1376 add_mat_mixed_cr(mat_const_col(l1, i), l2, i);
1379 template <
typename L1,
typename L2>
inline
1380 void add(
const L1& l1, L2& l2, row_and_col, row_major)
1381 {
add(l1, l2, row_major(), row_major()); }
1383 template <
typename L1,
typename L2>
inline
1384 void add(
const L1& l1, L2& l2, row_and_col, row_and_col)
1385 {
add(l1, l2, row_major(), row_major()); }
1387 template <
typename L1,
typename L2>
inline
1388 void add(
const L1& l1, L2& l2, row_and_col, col_and_row)
1389 {
add(l1, l2, row_major(), row_major()); }
1391 template <
typename L1,
typename L2>
inline
1392 void add(
const L1& l1, L2& l2, col_and_row, row_and_col)
1393 {
add(l1, l2, row_major(), row_major()); }
1395 template <
typename L1,
typename L2>
inline
1396 void add(
const L1& l1, L2& l2, row_major, row_and_col)
1397 {
add(l1, l2, row_major(), row_major()); }
1399 template <
typename L1,
typename L2>
inline
1400 void add(
const L1& l1, L2& l2, col_and_row, row_major)
1401 {
add(l1, l2, row_major(), row_major()); }
1403 template <
typename L1,
typename L2>
inline
1404 void add(
const L1& l1, L2& l2, row_major, col_and_row)
1405 {
add(l1, l2, row_major(), row_major()); }
1407 template <
typename L1,
typename L2>
inline
1408 void add(
const L1& l1, L2& l2, row_and_col, col_major)
1409 {
add(l1, l2, col_major(), col_major()); }
1411 template <
typename L1,
typename L2>
inline
1412 void add(
const L1& l1, L2& l2, col_major, row_and_col)
1413 {
add(l1, l2, col_major(), col_major()); }
1415 template <
typename L1,
typename L2>
inline
1416 void add(
const L1& l1, L2& l2, col_and_row, col_major)
1417 {
add(l1, l2, col_major(), col_major()); }
1419 template <
typename L1,
typename L2>
inline
1420 void add(
const L1& l1, L2& l2, col_and_row, col_and_row)
1421 {
add(l1, l2, col_major(), col_major()); }
1423 template <
typename L1,
typename L2>
inline
1424 void add(
const L1& l1, L2& l2, col_major, col_and_row)
1425 {
add(l1, l2, col_major(), col_major()); }
1433 template <
typename L1,
typename L2,
typename L3>
inline
1434 void add(
const L1& l1,
const L2& l2, L3& l3) {
1435 add_spec(l1, l2, l3,
typename linalg_traits<L2>::linalg_type());
1439 template <
typename L1,
typename L2,
typename L3>
inline
1440 void add(
const L1& l1,
const L2& l2,
const L3& l3)
1441 { add(l1, l2, linalg_const_cast(l3)); }
1443 template <
typename L1,
typename L2,
typename L3>
inline
1444 void add_spec(
const L1& l1,
const L2& l2, L3& l3, abstract_matrix)
1445 {
copy(l2, l3);
add(l1, l3); }
1447 template <
typename L1,
typename L2,
typename L3>
inline
1448 void add_spec(
const L1& l1,
const L2& l2, L3& l3, abstract_vector) {
1449 GMM_ASSERT2(vect_size(l1) == vect_size(l2),
"dimensions mismatch, "
1450 << vect_size(l1) <<
" !=" << vect_size(l2));
1451 GMM_ASSERT2(vect_size(l1) == vect_size(l3),
"dimensions mismatch, "
1452 << vect_size(l1) <<
" !=" << vect_size(l3));
1453 if ((
const void *)(&l1) == (
const void *)(&l3))
1455 else if ((
const void *)(&l2) == (
const void *)(&l3))
1458 add(l1, l2, l3,
typename linalg_traits<L1>::storage_type(),
1459 typename linalg_traits<L2>::storage_type(),
1460 typename linalg_traits<L3>::storage_type());
1463 template <
typename IT1,
typename IT2,
typename IT3>
1464 void add_full_(IT1 it1, IT2 it2, IT3 it3, IT3 ite) {
1465 for (; it3 != ite; ++it3, ++it2, ++it1) *it3 = *it1 + *it2;
1468 template <
typename IT1,
typename IT2,
typename IT3>
1469 void add_almost_full_(IT1 it1, IT1 ite1, IT2 it2, IT3 it3, IT3 ite3) {
1471 for (; it != ite3; ++it, ++it2) *it = *it2;
1472 for (; it1 != ite1; ++it1)
1473 *(it3 + it1.index()) += *it1;
1476 template <
typename IT1,
typename IT2,
typename IT3>
1477 void add_to_full_(IT1 it1, IT1 ite1, IT2 it2, IT2 ite2,
1478 IT3 it3, IT3 ite3) {
1479 typedef typename std::iterator_traits<IT3>::value_type T;
1481 for (; it != ite3; ++it) *it = T(0);
1482 for (; it1 != ite1; ++it1) *(it3 + it1.index()) = *it1;
1483 for (; it2 != ite2; ++it2) *(it3 + it2.index()) += *it2;
1486 template <
typename L1,
typename L2,
typename L3>
inline
1487 void add(
const L1& l1,
const L2& l2, L3& l3,
1488 abstract_dense, abstract_dense, abstract_dense) {
1489 add_full_(vect_const_begin(l1), vect_const_begin(l2),
1490 vect_begin(l3), vect_end(l3));
1495 template <
typename L1,
typename L2,
typename L3,
1496 typename ST1,
typename ST2,
typename ST3>
1497 inline void add(
const L1& l1,
const L2& l2, L3& l3, ST1, ST2, ST3)
1498 {
copy(l2, l3);
add(l1, l3, ST1(), ST3()); }
1500 template <
typename L1,
typename L2,
typename L3>
inline
1501 void add(
const L1& l1,
const L2& l2, L3& l3,
1502 abstract_sparse, abstract_dense, abstract_dense) {
1503 add_almost_full_(vect_const_begin(l1), vect_const_end(l1),
1504 vect_const_begin(l2), vect_begin(l3), vect_end(l3));
1507 template <
typename L1,
typename L2,
typename L3>
inline
1508 void add(
const L1& l1,
const L2& l2, L3& l3,
1509 abstract_dense, abstract_sparse, abstract_dense)
1510 {
add(l2, l1, l3, abstract_sparse(), abstract_dense(), abstract_dense()); }
1512 template <
typename L1,
typename L2,
typename L3>
inline
1513 void add(
const L1& l1,
const L2& l2, L3& l3,
1514 abstract_sparse, abstract_sparse, abstract_dense) {
1515 add_to_full_(vect_const_begin(l1), vect_const_end(l1),
1516 vect_const_begin(l2), vect_const_end(l2),
1517 vect_begin(l3), vect_end(l3));
1521 template <
typename L1,
typename L2,
typename L3>
1522 void add_spspsp(
const L1& l1,
const L2& l2, L3& l3, linalg_true) {
1523 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1524 auto it2 = vect_const_begin(l2), ite2 = vect_const_end(l2);
1526 while (it1 != ite1 && it2 != ite2) {
1527 ptrdiff_t d = it1.index() - it2.index();
1529 { l3[it1.index()] += *it1; ++it1; }
1531 { l3[it2.index()] += *it2; ++it2; }
1533 { l3[it1.index()] = *it1 + *it2; ++it1; ++it2; }
1535 for (; it1 != ite1; ++it1) l3[it1.index()] += *it1;
1536 for (; it2 != ite2; ++it2) l3[it2.index()] += *it2;
1539 template <
typename L1,
typename L2,
typename L3>
1540 void add_spspsp(
const L1& l1,
const L2& l2, L3& l3, linalg_false)
1541 {
copy(l2, l3);
add(l2, l3); }
1543 template <
typename L1,
typename L2,
typename L3>
1544 void add(
const L1& l1,
const L2& l2, L3& l3,
1545 abstract_sparse, abstract_sparse, abstract_sparse) {
1546 add_spspsp(l1, l2, l3,
typename linalg_and<
typename
1547 linalg_traits<L1>::index_sorted,
1548 typename linalg_traits<L2>::index_sorted>::bool_type());
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