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)); }
68 template <
typename L>
inline size_type
nnz(
const L& l)
69 {
return nnz(l,
typename linalg_traits<L>::linalg_type()); }
72 template <
typename L>
inline size_type nnz(
const L& l, abstract_vector) {
73 auto it = vect_const_begin(l), ite = vect_const_end(l);
75 for (; it != ite; ++it) ++res;
79 template <
typename L>
inline size_type nnz(
const L& l, abstract_matrix) {
80 return nnz(l,
typename principal_orientation_type<
typename
81 linalg_traits<L>::sub_orientation>::potype());
84 template <
typename L>
inline size_type nnz(
const L& l, row_major) {
86 for (
size_type i = 0; i < mat_nrows(l); ++i)
87 res +=
nnz(mat_const_row(l, i));
91 template <
typename L>
inline size_type nnz(
const L& l, col_major) {
93 for (
size_type i = 0; i < mat_ncols(l); ++i)
94 res +=
nnz(mat_const_col(l, i));
102 template <
typename L>
inline
103 void fill(L& l,
typename gmm::linalg_traits<L>::value_type x) {
104 typedef typename gmm::linalg_traits<L>::value_type T;
106 fill(l, x,
typename linalg_traits<L>::linalg_type());
109 template <
typename L>
inline
110 void fill(
const L& l,
typename gmm::linalg_traits<L>::value_type x) {
111 fill(linalg_const_cast(l), x);
114 template <
typename L>
inline
115 void fill(L& l,
typename gmm::linalg_traits<L>::value_type x,
117 for (
size_type i = 0; i < vect_size(l); ++i) l[i] = x;
120 template <
typename L>
inline
121 void fill(L& l,
typename gmm::linalg_traits<L>::value_type x,
123 for (
size_type i = 0; i < mat_nrows(l); ++i)
124 for (
size_type j = 0; j < mat_ncols(l); ++j)
130 {
fill_random(l,
typename linalg_traits<L>::linalg_type()); }
133 template <
typename L>
inline void fill_random(
const L& l) {
134 fill_random(linalg_const_cast(l),
135 typename linalg_traits<L>::linalg_type());
138 template <
typename L>
inline void fill_random(L& l, abstract_vector) {
139 for (
size_type i = 0; i < vect_size(l); ++i)
140 l[i] = gmm::random(
typename linalg_traits<L>::value_type());
143 template <
typename L>
inline void fill_random(L& l, abstract_matrix) {
144 for (
size_type i = 0; i < mat_nrows(l); ++i)
145 for (
size_type j = 0; j < mat_ncols(l); ++j)
146 l(i,j) = gmm::random(
typename linalg_traits<L>::value_type());
155 {
fill_random(l, cfill,
typename linalg_traits<L>::linalg_type()); }
158 template <
typename L>
inline void fill_random(
const L& l,
double cfill) {
159 fill_random(linalg_const_cast(l), cfill,
160 typename linalg_traits<L>::linalg_type());
163 template <
typename L>
inline
164 void fill_random(L& l,
double cfill, abstract_vector) {
165 typedef typename linalg_traits<L>::value_type T;
167 size_type(
double(vect_size(l))*cfill) + 1);
169 size_type i = gmm::irandom(vect_size(l));
171 l[i] = gmm::random(
typename linalg_traits<L>::value_type());
177 template <
typename L>
inline
178 void fill_random(L& l,
double cfill, abstract_matrix) {
179 fill_random(l, cfill,
typename principal_orientation_type<
typename
180 linalg_traits<L>::sub_orientation>::potype());
183 template <
typename L>
inline
188 template <
typename L>
inline
194 template <
typename V>
inline
196 { linalg_traits<V>::resize(v, n); }
198 template <
typename V>
inline
200 { GMM_ASSERT1(
false,
"You cannot resize a reference"); }
202 template <
typename V>
inline
204 { GMM_ASSERT1(
false,
"You cannot resize a reference"); }
208 template <
typename V>
inline
210 resize(v, n,
typename linalg_traits<V>::is_reference());
215 template <
typename M>
inline
217 linalg_traits<M>::resize(v, m, n);
220 template <
typename M>
inline
222 { GMM_ASSERT1(
false,
"You cannot resize a reference"); }
224 template <
typename M>
inline
226 { GMM_ASSERT1(
false,
"You cannot resize a reference"); }
230 template <
typename M>
inline
231 void resize(M &v, size_type m, size_type n)
232 {
resize(v, m, n,
typename linalg_traits<M>::is_reference()); }
235 template <
typename M>
inline
237 { linalg_traits<M>::reshape(v, m, n); }
239 template <
typename M>
inline
241 { GMM_ASSERT1(
false,
"You cannot reshape a reference"); }
243 template <
typename M>
inline
245 { GMM_ASSERT1(
false,
"You cannot reshape a reference"); }
249 template <
typename M>
inline
251 {
reshape(v, m, n,
typename linalg_traits<M>::is_reference()); }
261 template <
typename V1,
typename V2>
inline
262 typename strongest_value_type<V1,V2>::value_type
264 GMM_ASSERT2(vect_size(v1) == vect_size(v2),
"dimensions mismatch, "
265 << vect_size(v1) <<
" !=" << vect_size(v2));
267 typename linalg_traits<V1>::storage_type(),
268 typename linalg_traits<V2>::storage_type());
276 template <
typename MATSP,
typename V1,
typename V2>
inline
277 typename strongest_value_type3<V1,V2,MATSP>::value_type
278 vect_sp(
const MATSP &ps,
const V1 &v1,
const V2 &v2) {
279 return vect_sp_with_mat(ps, v1, v2,
280 typename linalg_traits<MATSP>::sub_orientation());
284 template <
typename MATSP,
typename V1,
typename V2>
inline
285 typename strongest_value_type3<V1,V2,MATSP>::value_type
286 vect_sp_with_mat(
const MATSP &ps,
const V1 &v1,
const V2 &v2, row_major) {
287 return vect_sp_with_matr(ps, v1, v2,
288 typename linalg_traits<V2>::storage_type());
291 template <
typename MATSP,
typename V1,
typename V2>
inline
292 typename strongest_value_type3<V1,V2,MATSP>::value_type
293 vect_sp_with_matr(
const MATSP &ps,
const V1 &v1,
const V2 &v2,
295 GMM_ASSERT2(vect_size(v1) == mat_ncols(ps) &&
296 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 typename principal_orientation_type<
typename
873 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,
957 gmm::clean(l, 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)) ite1--;
1165 l2[it1.index()] = *it1; ++it1;
1166 l2[ite1.index()-1] = *(ite1-1); --ite1;
1168 { it2 = vect_begin(l2); ++it2; std::copy(it1, ite1, it2); }
1171 ptrdiff_t m = it1.index() - it2.index();
1172 if (m >= 0 && ite1.index() <= ite2.index())
1173 std::copy(it1, ite1, it2 + m);
1175 if (m < 0) l2[it1.index()] = *it1;
1176 if (ite1.index() > ite2.index()) l2[ite1.index()-1] = *(ite1-1);
1177 it2 = vect_begin(l2); ite2 = vect_end(l2);
1178 m = it1.index() - it2.index();
1179 std::copy(it1, ite1, it2 + m);
1185 template <
typename L1,
typename L2>
1186 void copy_vect(
const L1& l1, L2& l2, abstract_sparse, abstract_dense) {
1188 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1189 for (; it != ite; ++it) { l2[it.index()] = *it; }
1192 template <
typename L1,
typename L2>
1193 void copy_vect(
const L1& l1, L2& l2, abstract_sparse, abstract_skyline) {
1195 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1196 for (; it != ite; ++it) l2[it.index()] = *it;
1199 template <
typename L1,
typename L2>
1200 void copy_vect(
const L1& l1, L2& l2, abstract_skyline, abstract_dense) {
1201 typedef typename linalg_traits<L1>::value_type T;
1202 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1206 auto it2 = vect_begin(l2), ite2 = vect_end(l2);
1209 for (j = 0; j < i; ++j, ++it2) *it2 = T(0);
1210 for (; it != ite; ++it, ++it2) *it2 = *it;
1211 for (; it2 != ite2; ++it2) *it2 = T(0);
1215 template <
typename L1,
typename L2>
1216 void copy_vect(
const L1& l1, L2& l2, abstract_sparse, abstract_sparse) {
1217 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1220 for (; it != ite; ++it) {
1223 if (*it != (
typename linalg_traits<L1>::value_type)(0))
1224 l2[it.index()] = *it;
1228 template <
typename L1,
typename L2>
1229 void copy_vect(
const L1& l1, L2& l2, abstract_dense, abstract_sparse) {
1231 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1232 for (
size_type i = 0; it != ite; ++it, ++i)
1233 if (*it != (
typename linalg_traits<L1>::value_type)(0))
1237 template <
typename L1,
typename L2>
1238 void copy_vect(
const L1& l1, L2& l2, abstract_dense, abstract_skyline) {
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))
1247 template <
typename L1,
typename L2>
1248 void copy_vect(
const L1& l1, L2& l2, abstract_skyline, abstract_sparse) {
1250 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1251 for (; it != ite; ++it)
1252 if (*it != (
typename linalg_traits<L1>::value_type)(0))
1253 l2[it.index()] = *it;
1267 template <
typename L1,
typename L2>
inline
1268 void add(
const L1& l1, L2& l2) {
1269 add_spec(l1, l2,
typename linalg_traits<L2>::linalg_type());
1273 template <
typename L1,
typename L2>
inline
1274 void add(
const L1& l1,
const L2& l2) { add(l1, linalg_const_cast(l2)); }
1276 template <
typename L1,
typename L2>
inline
1277 void add_spec(
const L1& l1, L2& l2, abstract_vector) {
1278 GMM_ASSERT2(vect_size(l1) == vect_size(l2),
"dimensions mismatch, "
1279 << vect_size(l1) <<
" !=" << vect_size(l2));
1280 add(l1, l2,
typename linalg_traits<L1>::storage_type(),
1281 typename linalg_traits<L2>::storage_type());
1284 template <
typename L1,
typename L2>
inline
1285 void add_spec(
const L1& l1, L2& l2, abstract_matrix) {
1286 GMM_ASSERT2(mat_nrows(l1)==mat_nrows(l2) && mat_ncols(l1)==mat_ncols(l2),
1287 "dimensions mismatch l1 is " << mat_nrows(l1) <<
"x"
1288 << mat_ncols(l1) <<
" and l2 is " << mat_nrows(l2)
1289 <<
"x" << mat_ncols(l2));
1290 add(l1, l2,
typename linalg_traits<L1>::sub_orientation(),
1291 typename linalg_traits<L2>::sub_orientation());
1294 template <
typename L1,
typename L2>
1295 void add(
const L1& l1, L2& l2, row_major, row_major) {
1296 auto it1 = mat_row_begin(l1), ite = mat_row_end(l1);
1297 auto it2 = mat_row_begin(l2);
1298 for ( ; it1 != ite; ++it1, ++it2)
1299 add(linalg_traits<L1>::row(it1), linalg_traits<L2>::row(it2));
1302 template <
typename L1,
typename L2>
1303 void add(
const L1& l1, L2& l2, col_major, col_major) {
1304 auto it1 = mat_col_const_begin(l1), ite = mat_col_const_end(l1);
1305 typename linalg_traits<L2>::col_iterator it2 = mat_col_begin(l2);
1306 for ( ; it1 != ite; ++it1, ++it2)
1307 add(linalg_traits<L1>::col(it1), linalg_traits<L2>::col(it2));
1310 template <
typename L1,
typename L2>
inline
1311 void add_mat_mixed_rc(
const L1& l1, L2& l2,
size_type i) {
1312 add_mat_mixed_rc(l1, l2, i,
typename linalg_traits<L1>::storage_type());
1315 template <
typename L1,
typename L2>
1316 void add_mat_mixed_rc(
const L1& l1, L2& l2,
size_type i, abstract_sparse) {
1317 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1318 for (; it != ite; ++it) l2(i, it.index()) += *it;
1321 template <
typename L1,
typename L2>
1322 void add_mat_mixed_rc(
const L1& l1, L2& l2,
size_type i, abstract_skyline) {
1323 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1324 for (; it != ite; ++it) l2(i, it.index()) += *it;
1327 template <
typename L1,
typename L2>
1328 void add_mat_mixed_rc(
const L1& l1, L2& l2,
size_type i, abstract_dense) {
1329 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1330 for (
size_type j = 0; it != ite; ++it, ++j) l2(i, j) += *it;
1333 template <
typename L1,
typename L2>
inline
1334 void add_mat_mixed_cr(
const L1& l1, L2& l2,
size_type i) {
1335 add_mat_mixed_cr(l1, l2, i,
typename linalg_traits<L1>::storage_type());
1338 template <
typename L1,
typename L2>
1339 void add_mat_mixed_cr(
const L1& l1, L2& l2,
size_type i, abstract_sparse) {
1340 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1341 for (; it != ite; ++it) l2(it.index(), i) += *it;
1344 template <
typename L1,
typename L2>
1345 void add_mat_mixed_cr(
const L1& l1, L2& l2,
size_type i, abstract_skyline) {
1346 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1347 for (; it != ite; ++it) l2(it.index(), i) += *it;
1350 template <
typename L1,
typename L2>
1351 void add_mat_mixed_cr(
const L1& l1, L2& l2,
size_type i, abstract_dense) {
1352 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1353 for (
size_type j = 0; it != ite; ++it, ++j) l2(j, i) += *it;
1356 template <
typename L1,
typename L2>
1357 void add(
const L1& l1, L2& l2, row_major, col_major) {
1360 add_mat_mixed_rc(mat_const_row(l1, i), l2, i);
1363 template <
typename L1,
typename L2>
1364 void add(
const L1& l1, L2& l2, col_major, row_major) {
1367 add_mat_mixed_cr(mat_const_col(l1, i), l2, i);
1370 template <
typename L1,
typename L2>
inline
1371 void add(
const L1& l1, L2& l2, row_and_col, row_major)
1372 {
add(l1, l2, row_major(), row_major()); }
1374 template <
typename L1,
typename L2>
inline
1375 void add(
const L1& l1, L2& l2, row_and_col, row_and_col)
1376 {
add(l1, l2, row_major(), row_major()); }
1378 template <
typename L1,
typename L2>
inline
1379 void add(
const L1& l1, L2& l2, row_and_col, col_and_row)
1380 {
add(l1, l2, row_major(), row_major()); }
1382 template <
typename L1,
typename L2>
inline
1383 void add(
const L1& l1, L2& l2, col_and_row, 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_major, row_and_col)
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_major)
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, col_and_row)
1396 {
add(l1, l2, row_major(), row_major()); }
1398 template <
typename L1,
typename L2>
inline
1399 void add(
const L1& l1, L2& l2, row_and_col, col_major)
1400 {
add(l1, l2, col_major(), col_major()); }
1402 template <
typename L1,
typename L2>
inline
1403 void add(
const L1& l1, L2& l2, col_major, row_and_col)
1404 {
add(l1, l2, col_major(), col_major()); }
1406 template <
typename L1,
typename L2>
inline
1407 void add(
const L1& l1, L2& l2, col_and_row, 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_and_row, col_and_row)
1412 {
add(l1, l2, col_major(), col_major()); }
1414 template <
typename L1,
typename L2>
inline
1415 void add(
const L1& l1, L2& l2, col_major, col_and_row)
1416 {
add(l1, l2, col_major(), col_major()); }
1424 template <
typename L1,
typename L2,
typename L3>
inline
1425 void add(
const L1& l1,
const L2& l2, L3& l3) {
1426 add_spec(l1, l2, l3,
typename linalg_traits<L2>::linalg_type());
1430 template <
typename L1,
typename L2,
typename L3>
inline
1431 void add(
const L1& l1,
const L2& l2,
const L3& l3)
1432 { add(l1, l2, linalg_const_cast(l3)); }
1434 template <
typename L1,
typename L2,
typename L3>
inline
1435 void add_spec(
const L1& l1,
const L2& l2, L3& l3, abstract_matrix)
1436 {
copy(l2, l3);
add(l1, l3); }
1438 template <
typename L1,
typename L2,
typename L3>
inline
1439 void add_spec(
const L1& l1,
const L2& l2, L3& l3, abstract_vector) {
1440 GMM_ASSERT2(vect_size(l1) == vect_size(l2),
"dimensions mismatch, "
1441 << vect_size(l1) <<
" !=" << vect_size(l2));
1442 GMM_ASSERT2(vect_size(l1) == vect_size(l3),
"dimensions mismatch, "
1443 << vect_size(l1) <<
" !=" << vect_size(l3));
1444 if ((
const void *)(&l1) == (
const void *)(&l3))
1446 else if ((
const void *)(&l2) == (
const void *)(&l3))
1449 add(l1, l2, l3,
typename linalg_traits<L1>::storage_type(),
1450 typename linalg_traits<L2>::storage_type(),
1451 typename linalg_traits<L3>::storage_type());
1454 template <
typename IT1,
typename IT2,
typename IT3>
1455 void add_full_(IT1 it1, IT2 it2, IT3 it3, IT3 ite) {
1456 for (; it3 != ite; ++it3, ++it2, ++it1) *it3 = *it1 + *it2;
1459 template <
typename IT1,
typename IT2,
typename IT3>
1460 void add_almost_full_(IT1 it1, IT1 ite1, IT2 it2, IT3 it3, IT3 ite3) {
1462 for (; it != ite3; ++it, ++it2) *it = *it2;
1463 for (; it1 != ite1; ++it1)
1464 *(it3 + it1.index()) += *it1;
1467 template <
typename IT1,
typename IT2,
typename IT3>
1468 void add_to_full_(IT1 it1, IT1 ite1, IT2 it2, IT2 ite2,
1469 IT3 it3, IT3 ite3) {
1470 typedef typename std::iterator_traits<IT3>::value_type T;
1472 for (; it != ite3; ++it) *it = T(0);
1473 for (; it1 != ite1; ++it1) *(it3 + it1.index()) = *it1;
1474 for (; it2 != ite2; ++it2) *(it3 + it2.index()) += *it2;
1477 template <
typename L1,
typename L2,
typename L3>
inline
1478 void add(
const L1& l1,
const L2& l2, L3& l3,
1479 abstract_dense, abstract_dense, abstract_dense) {
1480 add_full_(vect_const_begin(l1), vect_const_begin(l2),
1481 vect_begin(l3), vect_end(l3));
1486 template <
typename L1,
typename L2,
typename L3,
1487 typename ST1,
typename ST2,
typename ST3>
1488 inline void add(
const L1& l1,
const L2& l2, L3& l3, ST1, ST2, ST3)
1489 {
copy(l2, l3);
add(l1, l3, ST1(), ST3()); }
1491 template <
typename L1,
typename L2,
typename L3>
inline
1492 void add(
const L1& l1,
const L2& l2, L3& l3,
1493 abstract_sparse, abstract_dense, abstract_dense) {
1494 add_almost_full_(vect_const_begin(l1), vect_const_end(l1),
1495 vect_const_begin(l2), vect_begin(l3), vect_end(l3));
1498 template <
typename L1,
typename L2,
typename L3>
inline
1499 void add(
const L1& l1,
const L2& l2, L3& l3,
1500 abstract_dense, abstract_sparse, abstract_dense)
1501 {
add(l2, l1, l3, abstract_sparse(), abstract_dense(), abstract_dense()); }
1503 template <
typename L1,
typename L2,
typename L3>
inline
1504 void add(
const L1& l1,
const L2& l2, L3& l3,
1505 abstract_sparse, abstract_sparse, abstract_dense) {
1506 add_to_full_(vect_const_begin(l1), vect_const_end(l1),
1507 vect_const_begin(l2), vect_const_end(l2),
1508 vect_begin(l3), vect_end(l3));
1512 template <
typename L1,
typename L2,
typename L3>
1513 void add_spspsp(
const L1& l1,
const L2& l2, L3& l3, linalg_true) {
1514 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1515 auto it2 = vect_const_begin(l2), ite2 = vect_const_end(l2);
1517 while (it1 != ite1 && it2 != ite2) {
1518 ptrdiff_t d = it1.index() - it2.index();
1520 { l3[it1.index()] += *it1; ++it1; }
1522 { l3[it2.index()] += *it2; ++it2; }
1524 { l3[it1.index()] = *it1 + *it2; ++it1; ++it2; }
1526 for (; it1 != ite1; ++it1) l3[it1.index()] += *it1;
1527 for (; it2 != ite2; ++it2) l3[it2.index()] += *it2;
1530 template <
typename L1,
typename L2,
typename L3>
1531 void add_spspsp(
const L1& l1,
const L2& l2, L3& l3, linalg_false)
1532 {
copy(l2, l3);
add(l2, l3); }
1534 template <
typename L1,
typename L2,
typename L3>
1535 void add(
const L1& l1,
const L2& l2, L3& l3,
1536 abstract_sparse, abstract_sparse, abstract_sparse) {
1537 add_spspsp(l1, l2, l3,
typename linalg_and<
typename
1538 linalg_traits<L1>::index_sorted,
1539 typename linalg_traits<L2>::index_sorted>::bool_type());
1542 template <
typename L1,
typename L2>
1543 void add(
const L1& l1, L2& l2, abstract_dense, abstract_dense) {
1544 auto it1 = vect_const_begin(l1);
1545 auto it2 = vect_begin(l2), ite = vect_end(l2);
1546 for (; it2 != ite; ++it2, ++it1) *it2 += *it1;
1549 template <
typename L1,
typename L2>
1550 void add(
const L1& l1, L2& l2, abstract_dense, abstract_skyline) {
1551 typedef typename linalg_traits<L1>::value_type T;
1553 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1555 while (it1 != ite1 && *it1 == T(0)) { ++it1; ++i1; }
1557 auto it2 = vect_begin(l2), ite2 = vect_end(l2);
1558 while (ie1 && *(ite1-1) == T(0)) { ite1--; --ie1; }
1560 if (it2 == ite2 || i1 < it2.index()) {
1561 l2[i1] = *it1; ++i1; ++it1;
1562 if (it1 == ite1)
return;
1563 it2 = vect_begin(l2); ite2 = vect_end(l2);
1565 if (ie1 > ite2.index()) {
1566 --ite1; l2[ie1 - 1] = *ite1;
1567 it2 = vect_begin(l2);
1569 it2 += i1 - it2.index();
1570 for (; it1 != ite1; ++it1, ++it2) { *it2 += *it1; }
1575 template <
typename L1,
typename L2>
1576 void add(
const L1& l1, L2& l2, abstract_skyline, abstract_dense) {
1577 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1579 auto it2 = vect_begin(l2);
1581 for (; it1 != ite1; ++it2, ++it1) *it2 += *it1;
1586 template <
typename L1,
typename L2>
1587 void add(
const L1& l1, L2& l2, abstract_sparse, abstract_dense) {
1588 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1589 for (; it1 != ite1; ++it1) l2[it1.index()] += *it1;
1592 template <
typename L1,
typename L2>
1593 void add(
const L1& l1, L2& l2, abstract_sparse, abstract_sparse) {
1594 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1595 for (; it1 != ite1; ++it1) l2[it1.index()] += *it1;
1598 template <
typename L1,
typename L2>
1599 void add(
const L1& l1, L2& l2, abstract_sparse, abstract_skyline) {
1600 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1601 for (; it1 != ite1; ++it1) l2[it1.index()] += *it1;
1605 template <
typename L1,
typename L2>
1606 void add(
const L1& l1, L2& l2, abstract_skyline, abstract_sparse) {
1607 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1608 for (; it1 != ite1; ++it1)
1609 if (*it1 !=
typename linalg_traits<L1>::value_type(0))
1610 l2[it1.index()] += *it1;
1613 template <
typename L1,
typename L2>
1614 void add(
const L1& l1, L2& l2, abstract_skyline, abstract_skyline) {
1615 typedef typename linalg_traits<L1>::value_type T1;
1616 typedef typename linalg_traits<L2>::value_type T2;
1618 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1620 while (it1 != ite1 && *it1 == T1(0)) ++it1;
1622 auto it2 = vect_begin(l2), ite2 = vect_end(l2);
1623 while (*(ite1-1) == T1(0)) ite1--;
1624 if (it2 == ite2 || it1.index() < it2.index()) {
1625 l2[it1.index()] = T2(0);
1626 it2 = vect_begin(l2); ite2 = vect_end(l2);
1628 if (ite1.index() > ite2.index()) {
1629 l2[ite1.index() - 1] = T2(0);
1630 it2 = vect_begin(l2);
1632 it2 += it1.index() - it2.index();
1633 for (; it1 != ite1; ++it1, ++it2) *it2 += *it1;
1637 template <
typename L1,
typename L2>
1638 void add(
const L1& l1, L2& l2, abstract_dense, abstract_sparse) {
1639 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1640 for (
size_type i = 0; it1 != ite1; ++it1, ++i)
1641 if (*it1 !=
typename linalg_traits<L1>::value_type(0)) l2[i] += *it1;
1653 template <
typename L1,
typename L2,
typename L3>
inline
1654 void mult(
const L1& l1,
const L2& l2, L3& l3) {
1655 mult_dispatch(l1, l2, l3,
typename linalg_traits<L2>::linalg_type());
1659 template <
typename L1,
typename L2,
typename L3>
inline
1660 void mult(
const L1& l1,
const L2& l2,
const L3& l3)
1661 { mult(l1, l2, linalg_const_cast(l3)); }
1663 template <
typename L1,
typename L2,
typename L3>
inline
1664 void mult_dispatch(
const L1& l1,
const L2& l2, L3& l3, abstract_vector) {
1665 size_type m = mat_nrows(l1), n = mat_ncols(l1);
1667 GMM_ASSERT2(n==vect_size(l2) && m==vect_size(l3),
"dimensions mismatch");
1668 if (!same_origin(l2, l3))
1669 mult_spec(l1, l2, l3,
typename principal_orientation_type<
typename
1670 linalg_traits<L1>::sub_orientation>::potype());
1672 GMM_WARNING2(
"Warning, A temporary is used for mult\n");
1673 typename temporary_vector<L3>::vector_type temp(vect_size(l3));
1674 mult_spec(l1, l2, temp,
typename principal_orientation_type<
typename
1675 linalg_traits<L1>::sub_orientation>::potype());
1680 template <
typename L1,
typename L2,
typename L3>
1681 void mult_by_row(
const L1& l1,
const L2& l2, L3& l3, abstract_sparse) {
1682 typedef typename linalg_traits<L3>::value_type T;
1686 T aux =
vect_sp(mat_const_row(l1, i), l2);
1687 if (aux != T(0)) l3[i] = aux;
1691 template <
typename L1,
typename L2,
typename L3>
1692 void mult_by_row(
const L1& l1,
const L2& l2, L3& l3, abstract_skyline) {
1693 typedef typename linalg_traits<L3>::value_type T;
1697 T aux =
vect_sp(mat_const_row(l1, i), l2);
1698 if (aux != T(0)) l3[i] = aux;
1702 template <
typename L1,
typename L2,
typename L3>
1703 void mult_by_row(
const L1& l1,
const L2& l2, L3& l3, abstract_dense) {
1704 typename linalg_traits<L3>::iterator it=vect_begin(l3), ite=vect_end(l3);
1705 auto itr = mat_row_const_begin(l1);
1706 for (; it != ite; ++it, ++itr)
1707 *it =
vect_sp(linalg_traits<L1>::row(itr), l2,
1708 typename linalg_traits<L1>::storage_type(),
1709 typename linalg_traits<L2>::storage_type());
1712 template <
typename L1,
typename L2,
typename L3>
1713 void mult_by_col(
const L1& l1,
const L2& l2, L3& l3, abstract_dense) {
1717 add(scaled(mat_const_col(l1, i), l2[i]), l3);
1720 template <
typename L1,
typename L2,
typename L3>
1721 void mult_by_col(
const L1& l1,
const L2& l2, L3& l3, abstract_sparse) {
1722 typedef typename linalg_traits<L2>::value_type T;
1724 auto it = vect_const_begin(l2), ite = vect_const_end(l2);
1725 for (; it != ite; ++it)
1726 if (*it != T(0))
add(scaled(mat_const_col(l1, it.index()), *it), l3);
1729 template <
typename L1,
typename L2,
typename L3>
1730 void mult_by_col(
const L1& l1,
const L2& l2, L3& l3, abstract_skyline) {
1731 typedef typename linalg_traits<L2>::value_type T;
1733 auto it = vect_const_begin(l2), ite = vect_const_end(l2);
1734 for (; it != ite; ++it)
1735 if (*it != T(0))
add(scaled(mat_const_col(l1, it.index()), *it), l3);
1738 template <
typename L1,
typename L2,
typename L3>
inline
1739 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, row_major)
1740 { mult_by_row(l1, l2, l3,
typename linalg_traits<L3>::storage_type()); }
1742 template <
typename L1,
typename L2,
typename L3>
inline
1743 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, col_major)
1744 { mult_by_col(l1, l2, l3,
typename linalg_traits<L2>::storage_type()); }
1746 template <
typename L1,
typename L2,
typename L3>
inline
1747 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, abstract_null_type)
1748 { mult_ind(l1, l2, l3,
typename linalg_traits<L1>::storage_type()); }
1750 template <
typename L1,
typename L2,
typename L3>
1751 void mult_ind(
const L1& l1,
const L2& l2, L3& l3, abstract_indirect) {
1752 GMM_ASSERT1(
false,
"gmm::mult(m, ., .) undefined for this kind of matrix");
1755 template <
typename L1,
typename L2,
typename L3,
typename L4>
inline
1756 void mult(
const L1& l1,
const L2& l2,
const L3& l3, L4& l4) {
1757 size_type m = mat_nrows(l1), n = mat_ncols(l1);
1759 if (!m || !n) { gmm::copy(l3, l4);
return; }
1760 GMM_ASSERT2(n==vect_size(l2) && m==vect_size(l4),
"dimensions mismatch");
1761 if (!same_origin(l2, l4)) {
1762 mult_add_spec(l1, l2, l4,
typename principal_orientation_type<
typename
1763 linalg_traits<L1>::sub_orientation>::potype());
1766 GMM_WARNING2(
"Warning, A temporary is used for mult\n");
1767 typename temporary_vector<L2>::vector_type temp(vect_size(l2));
1769 mult_add_spec(l1,temp, l4,
typename principal_orientation_type<
typename
1770 linalg_traits<L1>::sub_orientation>::potype());
1774 template <
typename L1,
typename L2,
typename L3,
typename L4>
inline
1775 void mult(
const L1& l1,
const L2& l2,
const L3& l3,
const L4& l4)
1776 { mult(l1, l2, l3, linalg_const_cast(l4)); }
1780 template <
typename L1,
typename L2,
typename L3>
inline
1782 size_type m = mat_nrows(l1), n = mat_ncols(l1);
1783 if (!m || !n)
return;
1784 GMM_ASSERT2(n==vect_size(l2) && m==vect_size(l3),
"dimensions mismatch");
1785 if (!same_origin(l2, l3)) {
1786 mult_add_spec(l1, l2, l3,
typename principal_orientation_type<
typename
1787 linalg_traits<L1>::sub_orientation>::potype());
1790 GMM_WARNING2(
"Warning, A temporary is used for mult\n");
1791 typename temporary_vector<L3>::vector_type temp(vect_size(l2));
1793 mult_add_spec(l1,temp, l3,
typename principal_orientation_type<
typename
1794 linalg_traits<L1>::sub_orientation>::potype());
1799 template <
typename L1,
typename L2,
typename L3>
inline
1800 void mult_add(
const L1& l1,
const L2& l2,
const L3& l3)
1801 { mult_add(l1, l2, linalg_const_cast(l3)); }
1803 template <
typename L1,
typename L2,
typename L3>
1804 void mult_add_by_row(
const L1& l1,
const L2& l2, L3& l3, abstract_sparse) {
1805 typedef typename linalg_traits<L3>::value_type T;
1808 T aux =
vect_sp(mat_const_row(l1, i), l2);
1809 if (aux != T(0)) l3[i] += aux;
1813 template <
typename L1,
typename L2,
typename L3>
1814 void mult_add_by_row(
const L1& l1,
const L2& l2, L3& l3, abstract_skyline) {
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_dense) {
1825 auto it=vect_begin(l3), ite=vect_end(l3);
1826 auto itr = mat_row_const_begin(l1);
1827 for (; it != ite; ++it, ++itr)
1828 *it +=
vect_sp(linalg_traits<L1>::row(itr), l2);
1831 template <
typename L1,
typename L2,
typename L3>
1832 void mult_add_by_col(
const L1& l1,
const L2& l2, L3& l3, abstract_dense) {
1835 add(scaled(mat_const_col(l1, i), l2[i]), l3);
1838 template <
typename L1,
typename L2,
typename L3>
1839 void mult_add_by_col(
const L1& l1,
const L2& l2, L3& l3, abstract_sparse) {
1840 auto it = vect_const_begin(l2), ite = vect_const_end(l2);
1841 for (; it != ite; ++it)
1842 if (*it !=
typename linalg_traits<L2>::value_type(0))
1843 add(scaled(mat_const_col(l1, it.index()), *it), l3);
1846 template <
typename L1,
typename L2,
typename L3>
1847 void mult_add_by_col(
const L1& l1,
const L2& l2, L3& l3, abstract_skyline) {
1848 auto it = vect_const_begin(l2), ite = vect_const_end(l2);
1849 for (; it != ite; ++it)
1850 if (*it !=
typename linalg_traits<L2>::value_type(0))
1851 add(scaled(mat_const_col(l1, it.index()), *it), l3);
1854 template <
typename L1,
typename L2,
typename L3>
inline
1855 void mult_add_spec(
const L1& l1,
const L2& l2, L3& l3, row_major)
1856 { mult_add_by_row(l1, l2, l3,
typename linalg_traits<L3>::storage_type()); }
1858 template <
typename L1,
typename L2,
typename L3>
inline
1859 void mult_add_spec(
const L1& l1,
const L2& l2, L3& l3, col_major)
1860 { mult_add_by_col(l1, l2, l3,
typename linalg_traits<L2>::storage_type()); }
1862 template <
typename L1,
typename L2,
typename L3>
inline
1863 void mult_add_spec(
const L1& l1,
const L2& l2, L3& l3, abstract_null_type)
1864 { mult_ind(l1, l2, l3,
typename linalg_traits<L1>::storage_type()); }
1866 template <
typename L1,
typename L2,
typename L3>
1867 void transposed_mult(
const L1& l1,
const L2& l2,
const L3& l3)
1868 { mult(gmm::transposed(l1), l2, l3); }
1883 template<
typename SO1,
typename SO2,
typename SO3>
struct mult_t;
1884 #define DEFMU__ template<> struct mult_t
1885 DEFMU__<row_major , row_major , row_major > {
typedef r_mult t; };
1886 DEFMU__<row_major , row_major , col_major > {
typedef g_mult t; };
1887 DEFMU__<row_major , row_major , col_and_row> {
typedef r_mult t; };
1888 DEFMU__<row_major , row_major , row_and_col> {
typedef r_mult t; };
1889 DEFMU__<row_major , col_major , row_major > {
typedef rcmult t; };
1890 DEFMU__<row_major , col_major , col_major > {
typedef rcmult t; };
1891 DEFMU__<row_major , col_major , col_and_row> {
typedef rcmult t; };
1892 DEFMU__<row_major , col_major , row_and_col> {
typedef rcmult t; };
1893 DEFMU__<row_major , col_and_row, row_major > {
typedef r_mult t; };
1894 DEFMU__<row_major , col_and_row, col_major > {
typedef rcmult t; };
1895 DEFMU__<row_major , col_and_row, col_and_row> {
typedef rcmult t; };
1896 DEFMU__<row_major , col_and_row, row_and_col> {
typedef rcmult t; };
1897 DEFMU__<row_major , row_and_col, row_major > {
typedef r_mult t; };
1898 DEFMU__<row_major , row_and_col, col_major > {
typedef rcmult t; };
1899 DEFMU__<row_major , row_and_col, col_and_row> {
typedef r_mult t; };
1900 DEFMU__<row_major , row_and_col, row_and_col> {
typedef r_mult t; };
1901 DEFMU__<col_major , row_major , row_major > {
typedef crmult t; };
1902 DEFMU__<col_major , row_major , col_major > {
typedef g_mult t; };
1903 DEFMU__<col_major , row_major , col_and_row> {
typedef crmult t; };
1904 DEFMU__<col_major , row_major , row_and_col> {
typedef crmult t; };
1905 DEFMU__<col_major , col_major , row_major > {
typedef g_mult t; };
1906 DEFMU__<col_major , col_major , col_major > {
typedef c_mult t; };
1907 DEFMU__<col_major , col_major , col_and_row> {
typedef c_mult t; };
1908 DEFMU__<col_major , col_major , row_and_col> {
typedef c_mult t; };
1909 DEFMU__<col_major , col_and_row, row_major > {
typedef crmult t; };
1910 DEFMU__<col_major , col_and_row, col_major > {
typedef c_mult t; };
1911 DEFMU__<col_major , col_and_row, col_and_row> {
typedef c_mult t; };
1912 DEFMU__<col_major , col_and_row, row_and_col> {
typedef c_mult t; };
1913 DEFMU__<col_major , row_and_col, row_major > {
typedef crmult t; };
1914 DEFMU__<col_major , row_and_col, col_major > {
typedef c_mult t; };
1915 DEFMU__<col_major , row_and_col, col_and_row> {
typedef c_mult t; };
1916 DEFMU__<col_major , row_and_col, row_and_col> {
typedef c_mult t; };
1917 DEFMU__<col_and_row, row_major , row_major > {
typedef r_mult t; };
1918 DEFMU__<col_and_row, row_major , col_major > {
typedef c_mult t; };
1919 DEFMU__<col_and_row, row_major , col_and_row> {
typedef r_mult t; };
1920 DEFMU__<col_and_row, row_major , row_and_col> {
typedef r_mult t; };
1921 DEFMU__<col_and_row, col_major , row_major > {
typedef rcmult t; };
1922 DEFMU__<col_and_row, col_major , col_major > {
typedef c_mult t; };
1923 DEFMU__<col_and_row, col_major , col_and_row> {
typedef c_mult t; };
1924 DEFMU__<col_and_row, col_major , row_and_col> {
typedef c_mult t; };
1925 DEFMU__<col_and_row, col_and_row, row_major > {
typedef r_mult t; };
1926 DEFMU__<col_and_row, col_and_row, col_major > {
typedef c_mult t; };
1927 DEFMU__<col_and_row, col_and_row, col_and_row> {
typedef c_mult t; };
1928 DEFMU__<col_and_row, col_and_row, row_and_col> {
typedef c_mult t; };
1929 DEFMU__<col_and_row, row_and_col, row_major > {
typedef r_mult t; };
1930 DEFMU__<col_and_row, row_and_col, col_major > {
typedef c_mult t; };
1931 DEFMU__<col_and_row, row_and_col, col_and_row> {
typedef c_mult t; };
1932 DEFMU__<col_and_row, row_and_col, row_and_col> {
typedef r_mult t; };
1933 DEFMU__<row_and_col, row_major , row_major > {
typedef r_mult t; };
1934 DEFMU__<row_and_col, row_major , col_major > {
typedef c_mult t; };
1935 DEFMU__<row_and_col, row_major , col_and_row> {
typedef r_mult t; };
1936 DEFMU__<row_and_col, row_major , row_and_col> {
typedef r_mult t; };
1937 DEFMU__<row_and_col, col_major , row_major > {
typedef rcmult t; };
1938 DEFMU__<row_and_col, col_major , col_major > {
typedef c_mult t; };
1939 DEFMU__<row_and_col, col_major , col_and_row> {
typedef c_mult t; };
1940 DEFMU__<row_and_col, col_major , row_and_col> {
typedef c_mult t; };
1941 DEFMU__<row_and_col, col_and_row, row_major > {
typedef rcmult t; };
1942 DEFMU__<row_and_col, col_and_row, col_major > {
typedef rcmult t; };
1943 DEFMU__<row_and_col, col_and_row, col_and_row> {
typedef rcmult t; };
1944 DEFMU__<row_and_col, col_and_row, row_and_col> {
typedef rcmult t; };
1945 DEFMU__<row_and_col, row_and_col, row_major > {
typedef r_mult t; };
1946 DEFMU__<row_and_col, row_and_col, col_major > {
typedef c_mult t; };
1947 DEFMU__<row_and_col, row_and_col, col_and_row> {
typedef r_mult t; };
1948 DEFMU__<row_and_col, row_and_col, row_and_col> {
typedef r_mult t; };
1950 template <
typename L1,
typename L2,
typename L3>
1951 void mult_dispatch(
const L1& l1,
const L2& l2, L3& l3, abstract_matrix) {
1952 typedef typename temporary_matrix<L3>::matrix_type temp_mat_type;
1955 GMM_ASSERT2(n == mat_nrows(l2) && mat_nrows(l1) == mat_nrows(l3) &&
1956 mat_ncols(l2) == mat_ncols(l3),
"dimensions mismatch");
1958 if (same_origin(l2, l3) || same_origin(l1, l3)) {
1959 GMM_WARNING2(
"A temporary is used for mult");
1960 temp_mat_type temp(mat_nrows(l3), mat_ncols(l3));
1961 mult_spec(l1, l2, temp,
typename mult_t<
1962 typename linalg_traits<L1>::sub_orientation,
1963 typename linalg_traits<L2>::sub_orientation,
1964 typename linalg_traits<temp_mat_type>::sub_orientation>::t());
1968 mult_spec(l1, l2, l3,
typename mult_t<
1969 typename linalg_traits<L1>::sub_orientation,
1970 typename linalg_traits<L2>::sub_orientation,
1971 typename linalg_traits<L3>::sub_orientation>::t());
1976 template <
typename L1,
typename L2,
typename L3>
1977 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, g_mult) {
1978 typedef typename linalg_traits<L3>::value_type T;
1979 GMM_WARNING2(
"Inefficient generic matrix-matrix mult is used");
1980 for (
size_type i = 0; i < mat_nrows(l3) ; ++i)
1981 for (
size_type j = 0; j < mat_ncols(l3) ; ++j) {
1983 for (
size_type k = 0; k < mat_nrows(l2) ; ++k) a += l1(i, k)*l2(k, j);
1990 template <
typename L1,
typename L2,
typename L3>
1991 void mult_row_col_with_temp(
const L1& l1,
const L2& l2, L3& l3, col_major) {
1992 typedef typename temporary_col_matrix<L1>::matrix_type temp_col_mat;
1993 temp_col_mat temp(mat_nrows(l1), mat_ncols(l1));
1998 template <
typename L1,
typename L2,
typename L3>
1999 void mult_row_col_with_temp(
const L1& l1,
const L2& l2, L3& l3, row_major) {
2000 typedef typename temporary_row_matrix<L2>::matrix_type temp_row_mat;
2001 temp_row_mat temp(mat_nrows(l2), mat_ncols(l2));
2006 template <
typename L1,
typename L2,
typename L3>
2007 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, rcmult) {
2008 if (is_sparse(l1) && is_sparse(l2)) {
2009 GMM_WARNING3(
"Inefficient row matrix - col matrix mult for "
2010 "sparse matrices, using temporary");
2011 mult_row_col_with_temp(l1, l2, l3,
2012 typename principal_orientation_type<
typename
2013 linalg_traits<L3>::sub_orientation>::potype());
2016 auto it2b = linalg_traits<L2>::col_begin(l2), it2 = it2b,
2017 ite = linalg_traits<L2>::col_end(l2);
2020 for (i = 0; i < k; ++i) {
2021 typename linalg_traits<L1>::const_sub_row_type r1=mat_const_row(l1, i);
2022 for (it2 = it2b, j = 0; it2 != ite; ++it2, ++j)
2023 l3(i,j) =
vect_sp(r1, linalg_traits<L2>::col(it2));
2030 template <
typename L1,
typename L2,
typename L3>
inline
2031 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, r_mult) {
2032 mult_spec(l1, l2, l3,r_mult(),
typename linalg_traits<L1>::storage_type());
2035 template <
typename L1,
typename L2,
typename L3>
2036 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, r_mult, abstract_dense) {
2039 size_type nn = mat_nrows(l3), mm = mat_nrows(l2);
2042 add(scaled(mat_const_row(l2, j), l1(i, j)), mat_row(l3, i));
2047 template <
typename L1,
typename L2,
typename L3>
2048 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, r_mult, abstract_sparse) {
2053 typename linalg_traits<L1>::const_sub_row_type rl1=mat_const_row(l1, i);
2054 auto it = vect_const_begin(rl1), ite = vect_const_end(rl1);
2055 for (; it != ite; ++it)
2056 add(scaled(mat_const_row(l2, it.index()), *it), mat_row(l3, i));
2060 template <
typename L1,
typename L2,
typename L3>
2061 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, r_mult, abstract_skyline)
2062 { mult_spec(l1, l2, l3, r_mult(), abstract_sparse()); }
2066 template <
typename L1,
typename L2,
typename L3>
inline
2067 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, c_mult) {
2068 mult_spec(l1, l2,l3,c_mult(),
typename linalg_traits<L2>::storage_type(),
2069 typename linalg_traits<L2>::sub_orientation());
2073 template <
typename L1,
typename L2,
typename L3,
typename ORIEN>
2074 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, c_mult,
2075 abstract_dense, ORIEN) {
2076 typedef typename linalg_traits<L2>::value_type T;
2077 size_type nn = mat_ncols(l3), mm = mat_ncols(l1);
2080 clear(mat_col(l3, i));
2083 if (b != T(0))
add(scaled(mat_const_col(l1, j), b), mat_col(l3, i));
2088 template <
typename L1,
typename L2,
typename L3,
typename ORIEN>
2089 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, c_mult,
2090 abstract_sparse, ORIEN) {
2095 typename linalg_traits<L2>::const_sub_col_type rc2 = mat_const_col(l2, i);
2096 auto it = vect_const_begin(rc2), ite = vect_const_end(rc2);
2097 for (; it != ite; ++it)
2098 add(scaled(mat_const_col(l1, it.index()), *it), mat_col(l3, i));
2102 template <
typename L1,
typename L2,
typename L3>
2103 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, c_mult,
2104 abstract_sparse, row_major) {
2105 typedef typename linalg_traits<L2>::value_type T;
2106 GMM_WARNING3(
"Inefficient matrix-matrix mult for sparse matrices");
2108 size_type mm = mat_nrows(l2), nn = mat_ncols(l3);
2112 if (a != T(0))
add(scaled(mat_const_col(l1, j), a), mat_col(l3, i));
2116 template <
typename L1,
typename L2,
typename L3,
typename ORIEN>
inline
2117 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, c_mult,
2118 abstract_skyline, ORIEN)
2119 { mult_spec(l1, l2, l3, c_mult(), abstract_sparse(), ORIEN()); }
2124 template <
typename L1,
typename L2,
typename L3>
inline
2125 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, crmult)
2126 { mult_spec(l1,l2,l3,crmult(),
typename linalg_traits<L1>::storage_type()); }
2129 template <
typename L1,
typename L2,
typename L3>
2130 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, crmult, abstract_dense) {
2133 size_type nn = mat_ncols(l1), mm = mat_nrows(l1);
2136 add(scaled(mat_const_row(l2, i), l1(j, i)), mat_row(l3, j));
2140 template <
typename L1,
typename L2,
typename L3>
2141 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, crmult, abstract_sparse) {
2146 typename linalg_traits<L1>::const_sub_col_type rc1 = mat_const_col(l1, i);
2147 auto it = vect_const_begin(rc1), ite = vect_const_end(rc1);
2148 for (; it != ite; ++it)
2149 add(scaled(mat_const_row(l2, i), *it), mat_row(l3, it.index()));
2153 template <
typename L1,
typename L2,
typename L3>
inline
2154 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, crmult, abstract_skyline)
2155 { mult_spec(l1, l2, l3, crmult(), abstract_sparse()); }
2167 template <
typename MAT>
inline
2169 = magnitude_of_linalg(MAT)(-1)) {
2170 typedef magnitude_of_linalg(MAT) R;
2171 if (tol < R(0)) tol = default_tol(R()) *
mat_maxnorm(A);
2172 if (mat_nrows(A) != mat_ncols(A))
return false;
2173 return is_symmetric(A, tol,
typename linalg_traits<MAT>::storage_type());
2177 template <
typename MAT>
2178 bool is_symmetric(
const MAT &A, magnitude_of_linalg(MAT) tol,
2183 if (gmm::abs(A(i, j)-A(j, i)) > tol)
return false;
2187 template <
typename MAT>
2188 bool is_symmetric(
const MAT &A, magnitude_of_linalg(MAT) tol,
2190 return is_symmetric(A, tol,
typename principal_orientation_type<
typename
2191 linalg_traits<MAT>::sub_orientation>::potype());
2194 template <
typename MAT>
2195 bool is_symmetric(
const MAT &A, magnitude_of_linalg(MAT) tol,
2197 for (
size_type i = 0; i < mat_nrows(A); ++i) {
2198 typename linalg_traits<MAT>::const_sub_row_type row = mat_const_row(A, i);
2199 auto it = vect_const_begin(row), ite = vect_const_end(row);
2200 for (; it != ite; ++it)
2201 if (gmm::abs(*it - A(it.index(), i)) > tol)
return false;
2206 template <
typename MAT>
2207 bool is_symmetric(
const MAT &A, magnitude_of_linalg(MAT) tol,
2209 for (
size_type i = 0; i < mat_ncols(A); ++i) {
2210 typename linalg_traits<MAT>::const_sub_col_type col = mat_const_col(A, i);
2211 auto it = vect_const_begin(col), ite = vect_const_end(col);
2212 for (; it != ite; ++it)
2213 if (gmm::abs(*it - A(i, it.index())) > tol)
return false;
2218 template <
typename MAT>
2219 bool is_symmetric(
const MAT &A, magnitude_of_linalg(MAT) tol,
2228 template <
typename MAT>
inline
2230 = magnitude_of_linalg(MAT)(-1)) {
2231 typedef magnitude_of_linalg(MAT) R;
2232 if (tol < R(0)) tol = default_tol(R()) *
mat_maxnorm(A);
2233 if (mat_nrows(A) != mat_ncols(A))
return false;
2234 return is_hermitian(A, tol,
typename linalg_traits<MAT>::storage_type());
2238 template <
typename MAT>
2239 bool is_hermitian(
const MAT &A, magnitude_of_linalg(MAT) tol,
2244 if (gmm::abs(A(i, j)-gmm::conj(A(j, i))) > tol)
return false;
2248 template <
typename MAT>
2249 bool is_hermitian(
const MAT &A, magnitude_of_linalg(MAT) tol,
2251 return is_hermitian(A, tol,
typename principal_orientation_type<
typename
2252 linalg_traits<MAT>::sub_orientation>::potype());
2255 template <
typename MAT>
2256 bool is_hermitian(
const MAT &A, magnitude_of_linalg(MAT) tol,
2258 for (
size_type i = 0; i < mat_nrows(A); ++i) {
2259 typename linalg_traits<MAT>::const_sub_row_type row = mat_const_row(A, i);
2260 auto it = vect_const_begin(row), ite = vect_const_end(row);
2261 for (; it != ite; ++it)
2262 if (gmm::abs(gmm::conj(*it) - A(it.index(), i)) > tol)
return false;
2267 template <
typename MAT>
2268 bool is_hermitian(
const MAT &A, magnitude_of_linalg(MAT) tol,
2270 for (
size_type i = 0; i < mat_ncols(A); ++i) {
2271 typename linalg_traits<MAT>::const_sub_col_type col = mat_const_col(A, i);
2272 auto it = vect_const_begin(col), ite = vect_const_end(col);
2273 for (; it != ite; ++it)
2274 if (gmm::abs(gmm::conj(*it) - A(i, it.index())) > tol)
return false;
2279 template <
typename MAT>
2280 bool is_hermitian(
const MAT &A, magnitude_of_linalg(MAT) tol,
2287 #endif // GMM_BLAS_H__