58 template <
typename L>
inline void clear(L &l)
59 { linalg_traits<L>::do_clear(l); }
63 template <
typename L>
inline void clear(
const L &l)
64 { 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");
297 typename linalg_traits<V2>::const_iterator
298 it = vect_const_begin(v2), ite = vect_const_end(v2);
299 typename strongest_value_type3<V1,V2,MATSP>::value_type res(0);
300 for (; it != ite; ++it)
301 res +=
vect_sp(mat_const_row(ps, it.index()), v1)* (*it);
305 template <
typename MATSP,
typename V1,
typename V2>
inline
306 typename strongest_value_type3<V1,V2,MATSP>::value_type
307 vect_sp_with_matr(
const MATSP &ps,
const V1 &v1,
const V2 &v2,
309 {
return vect_sp_with_matr(ps, v1, v2, abstract_sparse()); }
311 template <
typename MATSP,
typename V1,
typename V2>
inline
312 typename strongest_value_type3<V1,V2,MATSP>::value_type
313 vect_sp_with_matr(
const MATSP &ps,
const V1 &v1,
const V2 &v2,
315 GMM_ASSERT2(vect_size(v1) == mat_ncols(ps) &&
316 vect_size(v2) == mat_nrows(ps),
"dimensions mismatch");
317 typename linalg_traits<V2>::const_iterator
318 it = vect_const_begin(v2), ite = vect_const_end(v2);
319 typename strongest_value_type3<V1,V2,MATSP>::value_type res(0);
320 for (
size_type i = 0; it != ite; ++i, ++it)
321 res +=
vect_sp(mat_const_row(ps, i), v1) * (*it);
325 template <
typename MATSP,
typename V1,
typename V2>
inline
326 typename strongest_value_type3<V1,V2,MATSP>::value_type
327 vect_sp_with_mat(
const MATSP &ps,
const V1 &v1,
const V2 &v2,row_and_col)
328 {
return vect_sp_with_mat(ps, v1, v2, row_major()); }
330 template <
typename MATSP,
typename V1,
typename V2>
inline
331 typename strongest_value_type3<V1,V2,MATSP>::value_type
332 vect_sp_with_mat(
const MATSP &ps,
const V1 &v1,
const V2 &v2,col_major){
333 return vect_sp_with_matc(ps, v1, v2,
334 typename linalg_traits<V1>::storage_type());
337 template <
typename MATSP,
typename V1,
typename V2>
inline
338 typename strongest_value_type3<V1,V2,MATSP>::value_type
339 vect_sp_with_matc(
const MATSP &ps,
const V1 &v1,
const V2 &v2,
341 GMM_ASSERT2(vect_size(v1) == mat_ncols(ps) &&
342 vect_size(v2) == mat_nrows(ps),
"dimensions mismatch");
343 typename linalg_traits<V1>::const_iterator
344 it = vect_const_begin(v1), ite = vect_const_end(v1);
345 typename strongest_value_type3<V1,V2,MATSP>::value_type res(0);
346 for (; it != ite; ++it)
347 res +=
vect_sp(mat_const_col(ps, it.index()), v2) * (*it);
351 template <
typename MATSP,
typename V1,
typename V2>
inline
352 typename strongest_value_type3<V1,V2,MATSP>::value_type
353 vect_sp_with_matc(
const MATSP &ps,
const V1 &v1,
const V2 &v2,
355 {
return vect_sp_with_matc(ps, v1, v2, abstract_sparse()); }
357 template <
typename MATSP,
typename V1,
typename V2>
inline
358 typename strongest_value_type3<V1,V2,MATSP>::value_type
359 vect_sp_with_matc(
const MATSP &ps,
const V1 &v1,
const V2 &v2,
361 GMM_ASSERT2(vect_size(v1) == mat_ncols(ps) &&
362 vect_size(v2) == mat_nrows(ps),
"dimensions mismatch");
363 typename linalg_traits<V1>::const_iterator
364 it = vect_const_begin(v1), ite = vect_const_end(v1);
365 typename strongest_value_type3<V1,V2,MATSP>::value_type res(0);
366 for (
size_type i = 0; it != ite; ++i, ++it)
367 res +=
vect_sp(mat_const_col(ps, i), v2) * (*it);
371 template <
typename MATSP,
typename V1,
typename V2>
inline
372 typename strongest_value_type3<V1,V2,MATSP>::value_type
373 vect_sp_with_mat(
const MATSP &ps,
const V1 &v1,
const V2 &v2,col_and_row)
374 {
return vect_sp_with_mat(ps, v1, v2, col_major()); }
376 template <
typename MATSP,
typename V1,
typename V2>
inline
377 typename strongest_value_type3<V1,V2,MATSP>::value_type
378 vect_sp_with_mat(
const MATSP &ps,
const V1 &v1,
const V2 &v2,
379 abstract_null_type) {
380 typename temporary_vector<V1>::vector_type w(mat_nrows(ps));
381 GMM_WARNING2(
"Warning, a temporary is used in scalar product\n");
386 template <
typename IT1,
typename IT2>
inline
387 typename strongest_numeric_type<typename std::iterator_traits<IT1>::value_type,
388 typename std::iterator_traits<IT2>::value_type>::T
389 vect_sp_dense_(IT1 it, IT1 ite, IT2 it2) {
390 typename strongest_numeric_type<typename std::iterator_traits<IT1>::value_type,
391 typename std::iterator_traits<IT2>::value_type>::T res(0);
392 for (; it != ite; ++it, ++it2) res += (*it) * (*it2);
396 template <
typename IT1,
typename V>
inline
397 typename strongest_numeric_type<typename std::iterator_traits<IT1>::value_type,
398 typename linalg_traits<V>::value_type>::T
399 vect_sp_sparse_(IT1 it, IT1 ite,
const V &v) {
400 typename strongest_numeric_type<typename std::iterator_traits<IT1>::value_type,
401 typename linalg_traits<V>::value_type>::T res(0);
402 for (; it != ite; ++it) res += (*it) * v[it.index()];
406 template <
typename V1,
typename V2>
inline
407 typename strongest_value_type<V1,V2>::value_type
408 vect_sp(
const V1 &v1,
const V2 &v2, abstract_dense, abstract_dense) {
409 return vect_sp_dense_(vect_const_begin(v1), vect_const_end(v1),
410 vect_const_begin(v2));
413 template <
typename V1,
typename V2>
inline
414 typename strongest_value_type<V1,V2>::value_type
415 vect_sp(
const V1 &v1,
const V2 &v2, abstract_skyline, abstract_dense) {
416 typename linalg_traits<V1>::const_iterator it1 = vect_const_begin(v1),
417 ite = vect_const_end(v1);
418 typename linalg_traits<V2>::const_iterator it2 = vect_const_begin(v2);
419 return vect_sp_dense_(it1, ite, it2 + it1.index());
422 template <
typename V1,
typename V2>
inline
423 typename strongest_value_type<V1,V2>::value_type
424 vect_sp(
const V1 &v1,
const V2 &v2, abstract_dense, abstract_skyline) {
425 typename linalg_traits<V2>::const_iterator it1 = vect_const_begin(v2),
426 ite = vect_const_end(v2);
427 typename linalg_traits<V1>::const_iterator it2 = vect_const_begin(v1);
428 return vect_sp_dense_(it1, ite, it2 + it1.index());
431 template <
typename V1,
typename V2>
inline
432 typename strongest_value_type<V1,V2>::value_type
433 vect_sp(
const V1 &v1,
const V2 &v2, abstract_skyline, abstract_skyline) {
434 typedef typename strongest_value_type<V1,V2>::value_type T;
435 auto it1 = vect_const_begin(v1), ite1 = vect_const_end(v1);
436 auto it2 = vect_const_begin(v2), ite2 = vect_const_end(v2);
437 size_type n = std::min(ite1.index(), ite2.index());
438 size_type l = std::max(it1.index(), it2.index());
441 size_type m = l - it1.index(), p = l - it2.index(), q = m + n - l;
442 return vect_sp_dense_(it1+m, it1+q, it2 + p);
447 template <
typename V1,
typename V2>
inline
448 typename strongest_value_type<V1,V2>::value_type
449 vect_sp(
const V1 &v1,
const V2 &v2,abstract_sparse,abstract_dense) {
450 return vect_sp_sparse_(vect_const_begin(v1), vect_const_end(v1), v2);
453 template <
typename V1,
typename V2>
inline
454 typename strongest_value_type<V1,V2>::value_type
455 vect_sp(
const V1 &v1,
const V2 &v2, abstract_sparse, abstract_skyline) {
456 return vect_sp_sparse_(vect_const_begin(v1), vect_const_end(v1), v2);
459 template <
typename V1,
typename V2>
inline
460 typename strongest_value_type<V1,V2>::value_type
461 vect_sp(
const V1 &v1,
const V2 &v2, abstract_skyline, abstract_sparse) {
462 return vect_sp_sparse_(vect_const_begin(v2), vect_const_end(v2), v1);
465 template <
typename V1,
typename V2>
inline
466 typename strongest_value_type<V1,V2>::value_type
467 vect_sp(
const V1 &v1,
const V2 &v2, abstract_dense,abstract_sparse) {
468 return vect_sp_sparse_(vect_const_begin(v2), vect_const_end(v2), v1);
472 template <
typename V1,
typename V2>
inline
473 typename strongest_value_type<V1,V2>::value_type
474 vect_sp_sparse_sparse(
const V1 &v1,
const V2 &v2, linalg_true) {
475 typename linalg_traits<V1>::const_iterator it1 = vect_const_begin(v1),
476 ite1 = vect_const_end(v1);
477 typename linalg_traits<V2>::const_iterator it2 = vect_const_begin(v2),
478 ite2 = vect_const_end(v2);
479 typename strongest_value_type<V1,V2>::value_type res(0);
481 while (it1 != ite1 && it2 != ite2) {
482 if (it1.index() == it2.index())
483 { res += (*it1) * *it2; ++it1; ++it2; }
484 else if (it1.index() < it2.index()) ++it1;
else ++it2;
489 template <
typename V1,
typename V2>
inline
490 typename strongest_value_type<V1,V2>::value_type
491 vect_sp_sparse_sparse(
const V1 &v1,
const V2 &v2, linalg_false) {
492 return vect_sp_sparse_(vect_const_begin(v1), vect_const_end(v1), v2);
495 template <
typename V1,
typename V2>
inline
496 typename strongest_value_type<V1,V2>::value_type
497 vect_sp(
const V1 &v1,
const V2 &v2,abstract_sparse,abstract_sparse) {
498 return vect_sp_sparse_sparse(v1, v2,
499 typename linalg_and<
typename linalg_traits<V1>::index_sorted,
500 typename linalg_traits<V2>::index_sorted>::bool_type());
508 template <
typename V1,
typename V2>
509 inline typename strongest_value_type<V1,V2>::value_type
514 template <
typename MATSP,
typename V1,
typename V2>
inline
515 typename strongest_value_type3<V1,V2,MATSP>::value_type
516 vect_hp(
const MATSP &ps,
const V1 &v1,
const V2 &v2) {
525 template <
typename M>
526 typename linalg_traits<M>::value_type
528 typedef typename linalg_traits<M>::value_type T;
530 for (size_type i = 0; i < std::min(mat_nrows(m), mat_ncols(m)); ++i)
540 template <
typename V>
541 typename number_traits<typename linalg_traits<V>::value_type>
544 typedef typename linalg_traits<V>::value_type T;
545 typedef typename number_traits<T>::magnitude_type R;
546 auto it = vect_const_begin(v), ite = vect_const_end(v);
548 for (; it != ite; ++it) res += gmm::abs_sqr(*it);
553 template <
typename V>
inline
554 typename number_traits<typename linalg_traits<V>::value_type>
561 template <
typename V1,
typename V2>
inline
562 typename number_traits<typename linalg_traits<V1>::value_type>
565 typedef typename linalg_traits<V1>::value_type T;
566 typedef typename number_traits<T>::magnitude_type R;
567 auto it1 = vect_const_begin(v1), ite1 = vect_const_end(v1);
568 auto it2 = vect_const_begin(v2), ite2 = vect_const_end(v2);
569 size_type k1(0), k2(0);
571 while (it1 != ite1 && it2 != ite2) {
572 size_type i1 = index_of_it(it1, k1,
573 typename linalg_traits<V1>::storage_type());
574 size_type i2 = index_of_it(it2, k2,
575 typename linalg_traits<V2>::storage_type());
578 res += gmm::abs_sqr(*it2 - *it1); ++it1; ++k1; ++it2; ++k2;
581 res += gmm::abs_sqr(*it1); ++it1; ++k1;
584 res += gmm::abs_sqr(*it2); ++it2; ++k2;
587 while (it1 != ite1) { res += gmm::abs_sqr(*it1); ++it1; }
588 while (it2 != ite2) { res += gmm::abs_sqr(*it2); ++it2; }
593 template <
typename V1,
typename V2>
inline
594 typename number_traits<typename linalg_traits<V1>::value_type>
599 template <
typename M>
600 typename number_traits<typename linalg_traits<M>::value_type>
602 mat_euclidean_norm_sqr(
const M &m, row_major) {
603 typename number_traits<typename linalg_traits<M>::value_type>
604 ::magnitude_type res(0);
605 for (
size_type i = 0; i < mat_nrows(m); ++i)
606 res += vect_norm2_sqr(mat_const_row(m, i));
610 template <
typename M>
611 typename number_traits<typename linalg_traits<M>::value_type>
614 typename number_traits<typename linalg_traits<M>::value_type>
615 ::magnitude_type res(0);
616 for (
size_type i = 0; i < mat_ncols(m); ++i)
622 template <
typename M>
inline
623 typename number_traits<typename linalg_traits<M>::value_type>
627 typename principal_orientation_type<
typename
628 linalg_traits<M>::sub_orientation>::potype());
632 template <
typename M>
inline
633 typename number_traits<typename linalg_traits<M>::value_type>
642 template <
typename V>
643 typename number_traits<typename linalg_traits<V>::value_type>
646 auto it = vect_const_begin(v), ite = vect_const_end(v);
647 typename number_traits<typename linalg_traits<V>::value_type>
648 ::magnitude_type res(0);
649 for (; it != ite; ++it) res += gmm::abs(*it);
654 template <
typename V1,
typename V2>
inline
655 typename number_traits<typename linalg_traits<V1>::value_type>
658 typedef typename linalg_traits<V1>::value_type T;
659 typedef typename number_traits<T>::magnitude_type R;
660 auto it1 = vect_const_begin(v1), ite1 = vect_const_end(v1);
661 auto it2 = vect_const_begin(v2), ite2 = vect_const_end(v2);
662 size_type k1(0), k2(0);
664 while (it1 != ite1 && it2 != ite2) {
665 size_type i1 = index_of_it(it1, k1,
666 typename linalg_traits<V1>::storage_type());
667 size_type i2 = index_of_it(it2, k2,
668 typename linalg_traits<V2>::storage_type());
671 res += gmm::abs(*it2 - *it1); ++it1; ++k1; ++it2; ++k2;
674 res += gmm::abs(*it1); ++it1; ++k1;
677 res += gmm::abs(*it2); ++it2; ++k2;
680 while (it1 != ite1) { res += gmm::abs(*it1); ++it1; }
681 while (it2 != ite2) { res += gmm::abs(*it2); ++it2; }
689 template <
typename V>
690 typename number_traits<typename linalg_traits<V>::value_type>
693 auto it = vect_const_begin(v), ite = vect_const_end(v);
694 typename number_traits<typename linalg_traits<V>::value_type>
695 ::magnitude_type res(0);
696 for (; it != ite; ++it) res = std::max(res, gmm::abs(*it));
701 template <
typename V1,
typename V2>
inline
702 typename number_traits<typename linalg_traits<V1>::value_type>
705 typedef typename linalg_traits<V1>::value_type T;
706 typedef typename number_traits<T>::magnitude_type R;
707 auto it1 = vect_const_begin(v1), ite1 = vect_const_end(v1);
708 auto it2 = vect_const_begin(v2), ite2 = vect_const_end(v2);
709 size_type k1(0), k2(0);
711 while (it1 != ite1 && it2 != ite2) {
712 size_type i1 = index_of_it(it1, k1,
713 typename linalg_traits<V1>::storage_type());
714 size_type i2 = index_of_it(it2, k2,
715 typename linalg_traits<V2>::storage_type());
718 res = std::max(res, gmm::abs(*it2 - *it1)); ++it1; ++k1; ++it2; ++k2;
721 res = std::max(res, gmm::abs(*it1)); ++it1; ++k1;
724 res = std::max(res, gmm::abs(*it2)); ++it2; ++k2;
727 while (it1 != ite1) { res = std::max(res, gmm::abs(*it1)); ++it1; }
728 while (it2 != ite2) { res = std::max(res, gmm::abs(*it2)); ++it2; }
736 template <
typename M>
737 typename number_traits<typename linalg_traits<M>::value_type>
739 mat_norm1(
const M &m, col_major) {
740 typename number_traits<typename linalg_traits<M>::value_type>
741 ::magnitude_type res(0);
742 for (
size_type i = 0; i < mat_ncols(m); ++i)
743 res = std::max(res, vect_norm1(mat_const_col(m,i)));
747 template <
typename M>
748 typename number_traits<typename linalg_traits<M>::value_type>
751 typedef typename linalg_traits<M>::value_type T;
752 typedef typename number_traits<T>::magnitude_type R;
753 typedef typename linalg_traits<M>::storage_type store_type;
755 std::vector<R> aux(mat_ncols(m));
756 for (
size_type i = 0; i < mat_nrows(m); ++i) {
757 typename linalg_traits<M>::const_sub_row_type row = mat_const_row(m, i);
758 auto it = vect_const_begin(row), ite = vect_const_end(row);
759 for (
size_type k = 0; it != ite; ++it, ++k)
760 aux[index_of_it(it, k, store_type())] += gmm::abs(*it);
765 template <
typename M>
766 typename number_traits<typename linalg_traits<M>::value_type>
771 template <
typename M>
772 typename number_traits<typename linalg_traits<M>::value_type>
778 template <
typename M>
779 typename number_traits<typename linalg_traits<M>::value_type>
782 return mat_norm1(m,
typename linalg_traits<M>::sub_orientation());
790 template <
typename M>
791 typename number_traits<typename linalg_traits<M>::value_type>
793 mat_norminf(
const M &m, row_major) {
794 typename number_traits<typename linalg_traits<M>::value_type>
795 ::magnitude_type res(0);
796 for (
size_type i = 0; i < mat_nrows(m); ++i)
797 res = std::max(res, vect_norm1(mat_const_row(m,i)));
801 template <
typename M>
802 typename number_traits<typename linalg_traits<M>::value_type>
805 typedef typename linalg_traits<M>::value_type T;
806 typedef typename number_traits<T>::magnitude_type R;
807 typedef typename linalg_traits<M>::storage_type store_type;
809 std::vector<R> aux(mat_nrows(m));
810 for (
size_type i = 0; i < mat_ncols(m); ++i) {
811 typename linalg_traits<M>::const_sub_col_type col = mat_const_col(m, i);
812 auto it = vect_const_begin(col), ite = vect_const_end(col);
813 for (
size_type k = 0; it != ite; ++it, ++k)
814 aux[index_of_it(it, k, store_type())] += gmm::abs(*it);
819 template <
typename M>
820 typename number_traits<typename linalg_traits<M>::value_type>
825 template <
typename M>
826 typename number_traits<typename linalg_traits<M>::value_type>
832 template <
typename M>
833 typename number_traits<typename linalg_traits<M>::value_type>
836 return mat_norminf(m,
typename linalg_traits<M>::sub_orientation());
843 template <
typename M>
844 typename number_traits<typename linalg_traits<M>::value_type>
846 mat_maxnorm(
const M &m, row_major) {
847 typename number_traits<typename linalg_traits<M>::value_type>
848 ::magnitude_type res(0);
849 for (
size_type i = 0; i < mat_nrows(m); ++i)
850 res = std::max(res, vect_norminf(mat_const_row(m,i)));
854 template <
typename M>
855 typename number_traits<typename linalg_traits<M>::value_type>
858 typename number_traits<typename linalg_traits<M>::value_type>
859 ::magnitude_type res(0);
860 for (
size_type i = 0; i < mat_ncols(m); ++i)
866 template <
typename M>
867 typename number_traits<typename linalg_traits<M>::value_type>
871 (m,
typename principal_orientation_type
872 <
typename linalg_traits<M>::sub_orientation>::potype());
880 template <
typename L>
inline void clean(L &l,
double threshold);
884 template <
typename L,
typename T>
885 void clean(L &l,
double threshold, abstract_dense, T) {
886 typedef typename number_traits<T>::magnitude_type R;
887 auto it = vect_begin(l), ite = vect_end(l);
888 for (; it != ite; ++it)
889 if (gmm::abs(*it) < R(threshold)) *it = T(0);
892 template <
typename L,
typename T>
893 void clean(L &l,
double threshold, abstract_skyline, T)
894 { gmm::clean(l, threshold, abstract_dense(), T()); }
896 template <
typename L,
typename T>
897 void clean(L &l,
double threshold, abstract_sparse, T) {
898 typedef typename number_traits<T>::magnitude_type R;
899 auto it = vect_begin(l), ite = vect_end(l);
900 std::vector<size_type> ind;
901 for (; it != ite; ++it)
902 if (gmm::abs(*it) < R(threshold)) ind.push_back(it.index());
903 for (
size_type i = 0; i < ind.size(); ++i) l[ind[i]] = T(0);
906 template <
typename L,
typename T>
907 void clean(L &l,
double threshold, abstract_dense, std::complex<T>) {
908 auto it = vect_begin(l), ite = vect_end(l);
909 for (; it != ite; ++it){
910 if (gmm::abs((*it).real()) < T(threshold))
911 *it = std::complex<T>(T(0), (*it).imag());
912 if (gmm::abs((*it).imag()) < T(threshold))
913 *it = std::complex<T>((*it).real(), T(0));
917 template <
typename L,
typename T>
918 void clean(L &l,
double threshold, abstract_skyline, std::complex<T>)
919 {
gmm::clean(l, threshold, abstract_dense(), std::complex<T>()); }
921 template <
typename L,
typename T>
922 void clean(L &l,
double threshold, abstract_sparse, std::complex<T>) {
923 auto it = vect_begin(l), ite = vect_end(l);
924 std::vector<size_type> ind;
925 for (; it != ite; ++it) {
926 bool r = (gmm::abs((*it).real()) < T(threshold));
927 bool i = (gmm::abs((*it).imag()) < T(threshold));
928 if (r && i) ind.push_back(it.index());
929 else if (r) *it = std::complex<T>(T(0), (*it).imag());
930 else if (i) *it = std::complex<T>((*it).real(), T(0));
932 for (
size_type i = 0; i < ind.size(); ++i)
933 l[ind[i]] = std::complex<T>(T(0),T(0));
936 template <
typename L>
inline void clean(L &l,
double threshold,
938 gmm::clean(l, threshold,
typename linalg_traits<L>::storage_type(),
939 typename linalg_traits<L>::value_type());
942 template <
typename L>
inline void clean(
const L &l,
double threshold);
944 template <
typename L>
void clean(L &l,
double threshold, row_major) {
945 for (
size_type i = 0; i < mat_nrows(l); ++i)
946 gmm::clean(mat_row(l, i), threshold);
949 template <
typename L>
void clean(L &l,
double threshold, col_major) {
950 for (
size_type i = 0; i < mat_ncols(l); ++i)
951 gmm::clean(mat_col(l, i), threshold);
954 template <
typename L>
inline void clean(L &l,
double threshold,
957 typename principal_orientation_type<
typename
958 linalg_traits<L>::sub_orientation>::potype());
961 template <
typename L>
inline void clean(L &l,
double threshold)
962 {
clean(l, threshold,
typename linalg_traits<L>::linalg_type()); }
964 template <
typename L>
inline void clean(
const L &l,
double threshold)
965 {
gmm::clean(linalg_const_cast(l), threshold); }
975 template <
typename L1,
typename L2>
inline
976 void copy(
const L1& l1, L2& l2) {
977 if ((
const void *)(&l1) != (
const void *)(&l2)) {
978 if (same_origin(l1,l2))
979 GMM_WARNING2(
"Warning : a conflict is possible in copy\n");
981 copy(l1, l2,
typename linalg_traits<L1>::linalg_type(),
982 typename linalg_traits<L2>::linalg_type());
987 template <
typename L1,
typename L2>
inline
988 void copy(
const L1& l1,
const L2& l2) { copy(l1, linalg_const_cast(l2)); }
990 template <
typename L1,
typename L2>
inline
991 void copy(
const L1& l1, L2& l2, abstract_vector, abstract_vector) {
992 GMM_ASSERT2(vect_size(l1) == vect_size(l2),
"dimensions mismatch, "
993 << vect_size(l1) <<
" !=" << vect_size(l2));
994 copy_vect(l1, l2,
typename linalg_traits<L1>::storage_type(),
995 typename linalg_traits<L2>::storage_type());
998 template <
typename L1,
typename L2>
inline
999 void copy(
const L1& l1, L2& l2, abstract_matrix, abstract_matrix) {
1000 size_type m = mat_nrows(l1), n = mat_ncols(l1);
1001 if (!m || !n)
return;
1002 GMM_ASSERT2(n==mat_ncols(l2) && m==mat_nrows(l2),
"dimensions mismatch");
1003 copy_mat(l1, l2,
typename linalg_traits<L1>::sub_orientation(),
1004 typename linalg_traits<L2>::sub_orientation());
1007 template <
typename V1,
typename V2,
typename C1,
typename C2>
inline
1008 void copy_vect(
const V1 &v1,
const V2 &v2, C1, C2)
1009 { copy_vect(v1,
const_cast<V2 &
>(v2), C1(), C2()); }
1012 template <
typename L1,
typename L2>
1013 void copy_mat_by_row(
const L1& l1, L2& l2) {
1016 copy(mat_const_row(l1, i), mat_row(l2, i));
1019 template <
typename L1,
typename L2>
1020 void copy_mat_by_col(
const L1 &l1, L2 &l2) {
1023 copy(mat_const_col(l1, i), mat_col(l2, i));
1027 template <
typename L1,
typename L2>
inline
1028 void copy_mat(
const L1& l1, L2& l2, row_major, row_major)
1029 { copy_mat_by_row(l1, l2); }
1031 template <
typename L1,
typename L2>
inline
1032 void copy_mat(
const L1& l1, L2& l2, row_major, row_and_col)
1033 { copy_mat_by_row(l1, l2); }
1035 template <
typename L1,
typename L2>
inline
1036 void copy_mat(
const L1& l1, L2& l2, row_and_col, row_and_col)
1037 { copy_mat_by_row(l1, l2); }
1039 template <
typename L1,
typename L2>
inline
1040 void copy_mat(
const L1& l1, L2& l2, row_and_col, row_major)
1041 { copy_mat_by_row(l1, l2); }
1043 template <
typename L1,
typename L2>
inline
1044 void copy_mat(
const L1& l1, L2& l2, col_and_row, row_major)
1045 { copy_mat_by_row(l1, l2); }
1047 template <
typename L1,
typename L2>
inline
1048 void copy_mat(
const L1& l1, L2& l2, row_major, col_and_row)
1049 { copy_mat_by_row(l1, l2); }
1051 template <
typename L1,
typename L2>
inline
1052 void copy_mat(
const L1& l1, L2& l2, col_and_row, row_and_col)
1053 { copy_mat_by_row(l1, l2); }
1055 template <
typename L1,
typename L2>
inline
1056 void copy_mat(
const L1& l1, L2& l2, row_and_col, col_and_row)
1057 { copy_mat_by_row(l1, l2); }
1059 template <
typename L1,
typename L2>
inline
1060 void copy_mat(
const L1& l1, L2& l2, col_major, col_major)
1061 { copy_mat_by_col(l1, l2); }
1063 template <
typename L1,
typename L2>
inline
1064 void copy_mat(
const L1& l1, L2& l2, col_major, col_and_row)
1065 { copy_mat_by_col(l1, l2); }
1067 template <
typename L1,
typename L2>
inline
1068 void copy_mat(
const L1& l1, L2& l2, col_major, row_and_col)
1069 { copy_mat_by_col(l1, l2); }
1071 template <
typename L1,
typename L2>
inline
1072 void copy_mat(
const L1& l1, L2& l2, row_and_col, col_major)
1073 { copy_mat_by_col(l1, l2); }
1075 template <
typename L1,
typename L2>
inline
1076 void copy_mat(
const L1& l1, L2& l2, col_and_row, col_major)
1077 { copy_mat_by_col(l1, l2); }
1079 template <
typename L1,
typename L2>
inline
1080 void copy_mat(
const L1& l1, L2& l2, col_and_row, col_and_row)
1081 { copy_mat_by_col(l1, l2); }
1083 template <
typename L1,
typename L2>
inline
1084 void copy_mat_mixed_rc(
const L1& l1, L2& l2,
size_type i) {
1085 copy_mat_mixed_rc(l1, l2, i,
typename linalg_traits<L1>::storage_type());
1088 template <
typename L1,
typename L2>
1089 void copy_mat_mixed_rc(
const L1& l1, L2& l2,
size_type i, abstract_sparse) {
1090 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1091 for (; it != ite; ++it)
1092 l2(i, it.index()) = *it;
1095 template <
typename L1,
typename L2>
1096 void copy_mat_mixed_rc(
const L1& l1, L2& l2,
size_type i, abstract_skyline) {
1097 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1098 for (; it != ite; ++it)
1099 l2(i, it.index()) = *it;
1102 template <
typename L1,
typename L2>
1103 void copy_mat_mixed_rc(
const L1& l1, L2& l2,
size_type i, abstract_dense) {
1104 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1105 for (
size_type j = 0; it != ite; ++it, ++j) l2(i, j) = *it;
1108 template <
typename L1,
typename L2>
inline
1109 void copy_mat_mixed_cr(
const L1& l1, L2& l2,
size_type i) {
1110 copy_mat_mixed_cr(l1, l2, i,
typename linalg_traits<L1>::storage_type());
1113 template <
typename L1,
typename L2>
1114 void copy_mat_mixed_cr(
const L1& l1, L2& l2,
size_type i, abstract_sparse) {
1115 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1116 for (; it != ite; ++it) l2(it.index(), i) = *it;
1119 template <
typename L1,
typename L2>
1120 void copy_mat_mixed_cr(
const L1& l1, L2& l2,
size_type i, abstract_skyline) {
1121 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1122 for (; it != ite; ++it) l2(it.index(), i) = *it;
1125 template <
typename L1,
typename L2>
1126 void copy_mat_mixed_cr(
const L1& l1, L2& l2,
size_type i, abstract_dense) {
1127 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1128 for (
size_type j = 0; it != ite; ++it, ++j) l2(j, i) = *it;
1131 template <
typename L1,
typename L2>
1132 void copy_mat(
const L1& l1, L2& l2, row_major, col_major) {
1136 copy_mat_mixed_rc(mat_const_row(l1, i), l2, i);
1139 template <
typename L1,
typename L2>
1140 void copy_mat(
const L1& l1, L2& l2, col_major, row_major) {
1144 copy_mat_mixed_cr(mat_const_col(l1, i), l2, i);
1147 template <
typename L1,
typename L2>
inline
1148 void copy_vect(
const L1 &l1, L2 &l2, abstract_dense, abstract_dense) {
1149 std::copy(vect_const_begin(l1), vect_const_end(l1), vect_begin(l2));
1152 template <
typename L1,
typename L2>
inline
1153 void copy_vect(
const L1 &l1, L2 &l2, abstract_skyline, abstract_skyline) {
1154 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1155 while (it1 != ite1 && *it1 ==
typename linalg_traits<L1>::value_type(0))
1158 if (ite1 - it1 > 0) {
1160 auto it2 = vect_begin(l2), ite2 = vect_end(l2);
1161 while (*(ite1-1) ==
typename linalg_traits<L1>::value_type(0))
1165 l2[it1.index()] = *it1;
1167 l2[ite1.index()-1] = *(ite1-1);
1170 it2 = vect_begin(l2);
1172 std::copy(it1, ite1, it2);
1175 ptrdiff_t m = it1.index() - it2.index();
1176 if (m >= 0 && ite1.index() <= ite2.index())
1177 std::copy(it1, ite1, it2 + m);
1180 l2[it1.index()] = *it1;
1181 if (ite1.index() > ite2.index())
1182 l2[ite1.index()-1] = *(ite1-1);
1183 it2 = vect_begin(l2);
1184 ite2 = vect_end(l2);
1185 m = it1.index() - it2.index();
1186 std::copy(it1, ite1, it2 + m);
1192 template <
typename L1,
typename L2>
1193 void copy_vect(
const L1& l1, L2& l2, abstract_sparse, abstract_dense) {
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_sparse, abstract_skyline) {
1202 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1203 for (; it != ite; ++it) l2[it.index()] = *it;
1206 template <
typename L1,
typename L2>
1207 void copy_vect(
const L1& l1, L2& l2, abstract_skyline, abstract_dense) {
1208 typedef typename linalg_traits<L1>::value_type T;
1209 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1213 auto it2 = vect_begin(l2), ite2 = vect_end(l2);
1216 for (j = 0; j < i; ++j, ++it2) *it2 = T(0);
1217 for (; it != ite; ++it, ++it2) *it2 = *it;
1218 for (; it2 != ite2; ++it2) *it2 = T(0);
1222 template <
typename L1,
typename L2>
1223 void copy_vect(
const L1& l1, L2& l2, abstract_sparse, abstract_sparse) {
1224 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1227 for (; it != ite; ++it) {
1230 if (*it != (
typename linalg_traits<L1>::value_type)(0))
1231 l2[it.index()] = *it;
1235 template <
typename L1,
typename L2>
1236 void copy_vect(
const L1& l1, L2& l2, abstract_dense, abstract_sparse) {
1238 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1239 for (
size_type i = 0; it != ite; ++it, ++i)
1240 if (*it != (
typename linalg_traits<L1>::value_type)(0))
1244 template <
typename L1,
typename L2>
1245 void copy_vect(
const L1& l1, L2& l2, abstract_dense, abstract_skyline) {
1247 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1248 for (
size_type i = 0; it != ite; ++it, ++i)
1249 if (*it != (
typename linalg_traits<L1>::value_type)(0))
1254 template <
typename L1,
typename L2>
1255 void copy_vect(
const L1& l1, L2& l2, abstract_skyline, abstract_sparse) {
1257 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1258 for (; it != ite; ++it)
1259 if (*it != (
typename linalg_traits<L1>::value_type)(0))
1260 l2[it.index()] = *it;
1274 template <
typename L1,
typename L2>
inline
1275 void add(
const L1& l1, L2& l2) {
1276 add_spec(l1, l2,
typename linalg_traits<L2>::linalg_type());
1280 template <
typename L1,
typename L2>
inline
1281 void add(
const L1& l1,
const L2& l2) { add(l1, linalg_const_cast(l2)); }
1283 template <
typename L1,
typename L2>
inline
1284 void add_spec(
const L1& l1, L2& l2, abstract_vector) {
1285 GMM_ASSERT2(vect_size(l1) == vect_size(l2),
"dimensions mismatch, "
1286 << vect_size(l1) <<
" !=" << vect_size(l2));
1287 add(l1, l2,
typename linalg_traits<L1>::storage_type(),
1288 typename linalg_traits<L2>::storage_type());
1291 template <
typename L1,
typename L2>
inline
1292 void add_spec(
const L1& l1, L2& l2, abstract_matrix) {
1293 GMM_ASSERT2(mat_nrows(l1)==mat_nrows(l2) && mat_ncols(l1)==mat_ncols(l2),
1294 "dimensions mismatch l1 is " << mat_nrows(l1) <<
"x"
1295 << mat_ncols(l1) <<
" and l2 is " << mat_nrows(l2)
1296 <<
"x" << mat_ncols(l2));
1297 add(l1, l2,
typename linalg_traits<L1>::sub_orientation(),
1298 typename linalg_traits<L2>::sub_orientation());
1301 template <
typename L1,
typename L2>
1302 void add(
const L1& l1, L2& l2, row_major, row_major) {
1303 auto it1 = mat_row_begin(l1), ite = mat_row_end(l1);
1304 auto it2 = mat_row_begin(l2);
1305 for ( ; it1 != ite; ++it1, ++it2)
1306 add(linalg_traits<L1>::row(it1), linalg_traits<L2>::row(it2));
1309 template <
typename L1,
typename L2>
1310 void add(
const L1& l1, L2& l2, col_major, col_major) {
1311 auto it1 = mat_col_const_begin(l1), ite = mat_col_const_end(l1);
1312 typename linalg_traits<L2>::col_iterator it2 = mat_col_begin(l2);
1313 for ( ; it1 != ite; ++it1, ++it2)
1314 add(linalg_traits<L1>::col(it1), linalg_traits<L2>::col(it2));
1317 template <
typename L1,
typename L2>
inline
1318 void add_mat_mixed_rc(
const L1& l1, L2& l2,
size_type i) {
1319 add_mat_mixed_rc(l1, l2, i,
typename linalg_traits<L1>::storage_type());
1322 template <
typename L1,
typename L2>
1323 void add_mat_mixed_rc(
const L1& l1, L2& l2,
size_type i, abstract_sparse) {
1324 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1325 for (; it != ite; ++it) l2(i, it.index()) += *it;
1328 template <
typename L1,
typename L2>
1329 void add_mat_mixed_rc(
const L1& l1, L2& l2,
size_type i, abstract_skyline) {
1330 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1331 for (; it != ite; ++it) l2(i, it.index()) += *it;
1334 template <
typename L1,
typename L2>
1335 void add_mat_mixed_rc(
const L1& l1, L2& l2,
size_type i, abstract_dense) {
1336 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1337 for (
size_type j = 0; it != ite; ++it, ++j) l2(i, j) += *it;
1340 template <
typename L1,
typename L2>
inline
1341 void add_mat_mixed_cr(
const L1& l1, L2& l2,
size_type i) {
1342 add_mat_mixed_cr(l1, l2, i,
typename linalg_traits<L1>::storage_type());
1345 template <
typename L1,
typename L2>
1346 void add_mat_mixed_cr(
const L1& l1, L2& l2,
size_type i, abstract_sparse) {
1347 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1348 for (; it != ite; ++it) l2(it.index(), i) += *it;
1351 template <
typename L1,
typename L2>
1352 void add_mat_mixed_cr(
const L1& l1, L2& l2,
size_type i, abstract_skyline) {
1353 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1354 for (; it != ite; ++it) l2(it.index(), i) += *it;
1357 template <
typename L1,
typename L2>
1358 void add_mat_mixed_cr(
const L1& l1, L2& l2,
size_type i, abstract_dense) {
1359 auto it = vect_const_begin(l1), ite = vect_const_end(l1);
1360 for (
size_type j = 0; it != ite; ++it, ++j) l2(j, i) += *it;
1363 template <
typename L1,
typename L2>
1364 void add(
const L1& l1, L2& l2, row_major, col_major) {
1367 add_mat_mixed_rc(mat_const_row(l1, i), l2, i);
1370 template <
typename L1,
typename L2>
1371 void add(
const L1& l1, L2& l2, col_major, row_major) {
1374 add_mat_mixed_cr(mat_const_col(l1, i), l2, i);
1377 template <
typename L1,
typename L2>
inline
1378 void add(
const L1& l1, L2& l2, row_and_col, row_major)
1379 {
add(l1, l2, row_major(), row_major()); }
1381 template <
typename L1,
typename L2>
inline
1382 void add(
const L1& l1, L2& l2, row_and_col, row_and_col)
1383 {
add(l1, l2, row_major(), row_major()); }
1385 template <
typename L1,
typename L2>
inline
1386 void add(
const L1& l1, L2& l2, row_and_col, col_and_row)
1387 {
add(l1, l2, row_major(), row_major()); }
1389 template <
typename L1,
typename L2>
inline
1390 void add(
const L1& l1, L2& l2, col_and_row, row_and_col)
1391 {
add(l1, l2, row_major(), row_major()); }
1393 template <
typename L1,
typename L2>
inline
1394 void add(
const L1& l1, L2& l2, row_major, row_and_col)
1395 {
add(l1, l2, row_major(), row_major()); }
1397 template <
typename L1,
typename L2>
inline
1398 void add(
const L1& l1, L2& l2, col_and_row, row_major)
1399 {
add(l1, l2, row_major(), row_major()); }
1401 template <
typename L1,
typename L2>
inline
1402 void add(
const L1& l1, L2& l2, row_major, col_and_row)
1403 {
add(l1, l2, row_major(), row_major()); }
1405 template <
typename L1,
typename L2>
inline
1406 void add(
const L1& l1, L2& l2, row_and_col, col_major)
1407 {
add(l1, l2, col_major(), col_major()); }
1409 template <
typename L1,
typename L2>
inline
1410 void add(
const L1& l1, L2& l2, col_major, row_and_col)
1411 {
add(l1, l2, col_major(), col_major()); }
1413 template <
typename L1,
typename L2>
inline
1414 void add(
const L1& l1, L2& l2, col_and_row, col_major)
1415 {
add(l1, l2, col_major(), col_major()); }
1417 template <
typename L1,
typename L2>
inline
1418 void add(
const L1& l1, L2& l2, col_and_row, col_and_row)
1419 {
add(l1, l2, col_major(), col_major()); }
1421 template <
typename L1,
typename L2>
inline
1422 void add(
const L1& l1, L2& l2, col_major, col_and_row)
1423 {
add(l1, l2, col_major(), col_major()); }
1431 template <
typename L1,
typename L2,
typename L3>
inline
1432 void add(
const L1& l1,
const L2& l2, L3& l3) {
1433 add_spec(l1, l2, l3,
typename linalg_traits<L2>::linalg_type());
1437 template <
typename L1,
typename L2,
typename L3>
inline
1438 void add(
const L1& l1,
const L2& l2,
const L3& l3)
1439 { add(l1, l2, linalg_const_cast(l3)); }
1441 template <
typename L1,
typename L2,
typename L3>
inline
1442 void add_spec(
const L1& l1,
const L2& l2, L3& l3, abstract_matrix)
1443 {
copy(l2, l3);
add(l1, l3); }
1445 template <
typename L1,
typename L2,
typename L3>
inline
1446 void add_spec(
const L1& l1,
const L2& l2, L3& l3, abstract_vector) {
1447 GMM_ASSERT2(vect_size(l1) == vect_size(l2),
"dimensions mismatch, "
1448 << vect_size(l1) <<
" !=" << vect_size(l2));
1449 GMM_ASSERT2(vect_size(l1) == vect_size(l3),
"dimensions mismatch, "
1450 << vect_size(l1) <<
" !=" << vect_size(l3));
1451 if ((
const void *)(&l1) == (
const void *)(&l3))
1453 else if ((
const void *)(&l2) == (
const void *)(&l3))
1456 add(l1, l2, l3,
typename linalg_traits<L1>::storage_type(),
1457 typename linalg_traits<L2>::storage_type(),
1458 typename linalg_traits<L3>::storage_type());
1461 template <
typename IT1,
typename IT2,
typename IT3>
1462 void add_full_(IT1 it1, IT2 it2, IT3 it3, IT3 ite) {
1463 for (; it3 != ite; ++it3, ++it2, ++it1) *it3 = *it1 + *it2;
1466 template <
typename IT1,
typename IT2,
typename IT3>
1467 void add_almost_full_(IT1 it1, IT1 ite1, IT2 it2, IT3 it3, IT3 ite3) {
1469 for (; it != ite3; ++it, ++it2) *it = *it2;
1470 for (; it1 != ite1; ++it1)
1471 *(it3 + it1.index()) += *it1;
1474 template <
typename IT1,
typename IT2,
typename IT3>
1475 void add_to_full_(IT1 it1, IT1 ite1, IT2 it2, IT2 ite2,
1476 IT3 it3, IT3 ite3) {
1477 typedef typename std::iterator_traits<IT3>::value_type T;
1479 for (; it != ite3; ++it) *it = T(0);
1480 for (; it1 != ite1; ++it1) *(it3 + it1.index()) = *it1;
1481 for (; it2 != ite2; ++it2) *(it3 + it2.index()) += *it2;
1484 template <
typename L1,
typename L2,
typename L3>
inline
1485 void add(
const L1& l1,
const L2& l2, L3& l3,
1486 abstract_dense, abstract_dense, abstract_dense) {
1487 add_full_(vect_const_begin(l1), vect_const_begin(l2),
1488 vect_begin(l3), vect_end(l3));
1493 template <
typename L1,
typename L2,
typename L3,
1494 typename ST1,
typename ST2,
typename ST3>
1495 inline void add(
const L1& l1,
const L2& l2, L3& l3, ST1, ST2, ST3)
1496 {
copy(l2, l3);
add(l1, l3, ST1(), ST3()); }
1498 template <
typename L1,
typename L2,
typename L3>
inline
1499 void add(
const L1& l1,
const L2& l2, L3& l3,
1500 abstract_sparse, abstract_dense, abstract_dense) {
1501 add_almost_full_(vect_const_begin(l1), vect_const_end(l1),
1502 vect_const_begin(l2), vect_begin(l3), vect_end(l3));
1505 template <
typename L1,
typename L2,
typename L3>
inline
1506 void add(
const L1& l1,
const L2& l2, L3& l3,
1507 abstract_dense, abstract_sparse, abstract_dense)
1508 {
add(l2, l1, l3, abstract_sparse(), abstract_dense(), abstract_dense()); }
1510 template <
typename L1,
typename L2,
typename L3>
inline
1511 void add(
const L1& l1,
const L2& l2, L3& l3,
1512 abstract_sparse, abstract_sparse, abstract_dense) {
1513 add_to_full_(vect_const_begin(l1), vect_const_end(l1),
1514 vect_const_begin(l2), vect_const_end(l2),
1515 vect_begin(l3), vect_end(l3));
1519 template <
typename L1,
typename L2,
typename L3>
1520 void add_spspsp(
const L1& l1,
const L2& l2, L3& l3, linalg_true) {
1521 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1522 auto it2 = vect_const_begin(l2), ite2 = vect_const_end(l2);
1524 while (it1 != ite1 && it2 != ite2) {
1525 ptrdiff_t d = it1.index() - it2.index();
1527 { l3[it1.index()] += *it1; ++it1; }
1529 { l3[it2.index()] += *it2; ++it2; }
1531 { l3[it1.index()] = *it1 + *it2; ++it1; ++it2; }
1533 for (; it1 != ite1; ++it1) l3[it1.index()] += *it1;
1534 for (; it2 != ite2; ++it2) l3[it2.index()] += *it2;
1537 template <
typename L1,
typename L2,
typename L3>
1538 void add_spspsp(
const L1& l1,
const L2& l2, L3& l3, linalg_false)
1539 {
copy(l1, l3);
add(l2, l3); }
1541 template <
typename L1,
typename L2,
typename L3>
1542 void add(
const L1& l1,
const L2& l2, L3& l3,
1543 abstract_sparse, abstract_sparse, abstract_sparse) {
1544 add_spspsp(l1, l2, l3,
1545 typename linalg_and<
typename linalg_traits<L1>::index_sorted,
1546 typename linalg_traits<L2>::index_sorted>
1550 template <
typename L1,
typename L2>
1551 void add(
const L1& l1, L2& l2, abstract_dense, abstract_dense) {
1552 auto it1 = vect_const_begin(l1);
1553 auto it2 = vect_begin(l2), ite = vect_end(l2);
1554 for (; it2 != ite; ++it2, ++it1) *it2 += *it1;
1557 template <
typename L1,
typename L2>
1558 void add(
const L1& l1, L2& l2, abstract_dense, abstract_skyline) {
1559 typedef typename linalg_traits<L1>::value_type T;
1561 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1563 while (it1 != ite1 && *it1 == T(0)) { ++it1; ++i1; }
1565 auto it2 = vect_begin(l2), ite2 = vect_end(l2);
1566 while (ie1 && *(ite1-1) == T(0)) { ite1--; --ie1; }
1568 if (it2 == ite2 || i1 < it2.index()) {
1569 l2[i1] = *it1; ++i1; ++it1;
1570 if (it1 == ite1)
return;
1571 it2 = vect_begin(l2);
1572 ite2 = vect_end(l2);
1574 if (ie1 > ite2.index()) {
1575 --ite1; l2[ie1 - 1] = *ite1;
1576 it2 = vect_begin(l2);
1578 it2 += i1 - it2.index();
1579 for (; it1 != ite1; ++it1, ++it2) { *it2 += *it1; }
1584 template <
typename L1,
typename L2>
1585 void add(
const L1& l1, L2& l2, abstract_skyline, abstract_dense) {
1586 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1588 auto it2 = vect_begin(l2);
1590 for (; it1 != ite1; ++it2, ++it1) *it2 += *it1;
1595 template <
typename L1,
typename L2>
1596 void add(
const L1& l1, L2& l2, abstract_sparse, abstract_dense) {
1597 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1598 for (; it1 != ite1; ++it1) l2[it1.index()] += *it1;
1601 template <
typename L1,
typename L2>
1602 void add(
const L1& l1, L2& l2, abstract_sparse, abstract_sparse) {
1603 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1604 for (; it1 != ite1; ++it1) l2[it1.index()] += *it1;
1607 template <
typename L1,
typename L2>
1608 void add(
const L1& l1, L2& l2, abstract_sparse, abstract_skyline) {
1609 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1610 for (; it1 != ite1; ++it1) l2[it1.index()] += *it1;
1614 template <
typename L1,
typename L2>
1615 void add(
const L1& l1, L2& l2, abstract_skyline, abstract_sparse) {
1616 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1617 for (; it1 != ite1; ++it1)
1618 if (*it1 !=
typename linalg_traits<L1>::value_type(0))
1619 l2[it1.index()] += *it1;
1622 template <
typename L1,
typename L2>
1623 void add(
const L1& l1, L2& l2, abstract_skyline, abstract_skyline) {
1624 typedef typename linalg_traits<L1>::value_type T1;
1625 typedef typename linalg_traits<L2>::value_type T2;
1627 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1629 while (it1 != ite1 && *it1 == T1(0)) ++it1;
1631 auto it2 = vect_begin(l2), ite2 = vect_end(l2);
1632 while (*(ite1-1) == T1(0)) ite1--;
1633 if (it2 == ite2 || it1.index() < it2.index()) {
1634 l2[it1.index()] = T2(0);
1635 it2 = vect_begin(l2); ite2 = vect_end(l2);
1637 if (ite1.index() > ite2.index()) {
1638 l2[ite1.index() - 1] = T2(0);
1639 it2 = vect_begin(l2);
1641 it2 += it1.index() - it2.index();
1642 for (; it1 != ite1; ++it1, ++it2) *it2 += *it1;
1646 template <
typename L1,
typename L2>
1647 void add(
const L1& l1, L2& l2, abstract_dense, abstract_sparse) {
1648 auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1);
1649 for (
size_type i = 0; it1 != ite1; ++it1, ++i)
1650 if (*it1 !=
typename linalg_traits<L1>::value_type(0)) l2[i] += *it1;
1662 template <
typename L1,
typename L2,
typename L3>
inline
1663 void mult(
const L1& l1,
const L2& l2, L3& l3) {
1664 mult_dispatch(l1, l2, l3,
typename linalg_traits<L2>::linalg_type());
1668 template <
typename L1,
typename L2,
typename L3>
inline
1669 void mult(
const L1& l1,
const L2& l2,
const L3& l3)
1670 { mult(l1, l2, linalg_const_cast(l3)); }
1672 template <
typename L1,
typename L2,
typename L3>
inline
1673 void mult_dispatch(
const L1& l1,
const L2& l2, L3& l3, abstract_vector) {
1674 size_type m = mat_nrows(l1), n = mat_ncols(l1);
1676 GMM_ASSERT2(n==vect_size(l2) && m==vect_size(l3),
"dimensions mismatch");
1677 if (!same_origin(l2, l3))
1678 mult_spec(l1, l2, l3,
typename principal_orientation_type<
typename
1679 linalg_traits<L1>::sub_orientation>::potype());
1681 GMM_WARNING2(
"Warning, A temporary is used for mult\n");
1682 typename temporary_vector<L3>::vector_type temp(vect_size(l3));
1683 mult_spec(l1, l2, temp,
typename principal_orientation_type<
typename
1684 linalg_traits<L1>::sub_orientation>::potype());
1689 template <
typename L1,
typename L2,
typename L3>
1690 void mult_by_row(
const L1& l1,
const L2& l2, L3& l3, abstract_sparse) {
1691 typedef typename linalg_traits<L3>::value_type T;
1695 T aux =
vect_sp(mat_const_row(l1, i), l2);
1696 if (aux != T(0)) l3[i] = aux;
1700 template <
typename L1,
typename L2,
typename L3>
1701 void mult_by_row(
const L1& l1,
const L2& l2, L3& l3, abstract_skyline) {
1702 typedef typename linalg_traits<L3>::value_type T;
1706 T aux =
vect_sp(mat_const_row(l1, i), l2);
1707 if (aux != T(0)) l3[i] = aux;
1711 template <
typename L1,
typename L2,
typename L3>
1712 void mult_by_row(
const L1& l1,
const L2& l2, L3& l3, abstract_dense) {
1713 typename linalg_traits<L3>::iterator it=vect_begin(l3), ite=vect_end(l3);
1714 auto itr = mat_row_const_begin(l1);
1715 for (; it != ite; ++it, ++itr)
1716 *it =
vect_sp(linalg_traits<L1>::row(itr), l2,
1717 typename linalg_traits<L1>::storage_type(),
1718 typename linalg_traits<L2>::storage_type());
1721 template <
typename L1,
typename L2,
typename L3>
1722 void mult_by_col(
const L1& l1,
const L2& l2, L3& l3, abstract_dense) {
1726 add(scaled(mat_const_col(l1, i), l2[i]), l3);
1729 template <
typename L1,
typename L2,
typename L3>
1730 void mult_by_col(
const L1& l1,
const L2& l2, L3& l3, abstract_sparse) {
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>
1739 void mult_by_col(
const L1& l1,
const L2& l2, L3& l3, abstract_skyline) {
1740 typedef typename linalg_traits<L2>::value_type T;
1742 auto it = vect_const_begin(l2), ite = vect_const_end(l2);
1743 for (; it != ite; ++it)
1744 if (*it != T(0))
add(scaled(mat_const_col(l1, it.index()), *it), l3);
1747 template <
typename L1,
typename L2,
typename L3>
inline
1748 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, row_major)
1749 { mult_by_row(l1, l2, l3,
typename linalg_traits<L3>::storage_type()); }
1751 template <
typename L1,
typename L2,
typename L3>
inline
1752 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, col_major)
1753 { mult_by_col(l1, l2, l3,
typename linalg_traits<L2>::storage_type()); }
1755 template <
typename L1,
typename L2,
typename L3>
inline
1756 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, abstract_null_type)
1757 { mult_ind(l1, l2, l3,
typename linalg_traits<L1>::storage_type()); }
1759 template <
typename L1,
typename L2,
typename L3>
1760 void mult_ind(
const L1& l1,
const L2& l2, L3& l3, abstract_indirect) {
1761 GMM_ASSERT1(
false,
"gmm::mult(m, ., .) undefined for this kind of matrix");
1764 template <
typename L1,
typename L2,
typename L3,
typename L4>
inline
1765 void mult(
const L1& l1,
const L2& l2,
const L3& l3, L4& l4) {
1766 size_type m = mat_nrows(l1), n = mat_ncols(l1);
1768 if (!m || !n) {
gmm::copy(l3, l4);
return; }
1769 GMM_ASSERT2(n==vect_size(l2) && m==vect_size(l4),
"dimensions mismatch");
1770 if (!same_origin(l2, l4)) {
1771 mult_add_spec(l1, l2, l4,
typename principal_orientation_type<
typename
1772 linalg_traits<L1>::sub_orientation>::potype());
1775 GMM_WARNING2(
"Warning, A temporary is used for mult\n");
1776 typename temporary_vector<L2>::vector_type temp(vect_size(l2));
1778 mult_add_spec(l1,temp, l4,
typename principal_orientation_type<
typename
1779 linalg_traits<L1>::sub_orientation>::potype());
1783 template <
typename L1,
typename L2,
typename L3,
typename L4>
inline
1784 void mult(
const L1& l1,
const L2& l2,
const L3& l3,
const L4& l4)
1785 {
mult(l1, l2, l3, linalg_const_cast(l4)); }
1789 template <
typename L1,
typename L2,
typename L3>
inline
1791 size_type m = mat_nrows(l1), n = mat_ncols(l1);
1792 if (!m || !n)
return;
1793 GMM_ASSERT2(n==vect_size(l2) && m==vect_size(l3),
"dimensions mismatch");
1794 if (!same_origin(l2, l3)) {
1795 mult_add_spec(l1, l2, l3,
typename principal_orientation_type<
typename
1796 linalg_traits<L1>::sub_orientation>::potype());
1799 GMM_WARNING2(
"Warning, A temporary is used for mult\n");
1800 typename temporary_vector<L3>::vector_type temp(vect_size(l2));
1802 mult_add_spec(l1,temp, l3,
typename principal_orientation_type<
typename
1803 linalg_traits<L1>::sub_orientation>::potype());
1808 template <
typename L1,
typename L2,
typename L3>
inline
1809 void mult_add(
const L1& l1,
const L2& l2,
const L3& l3)
1810 { mult_add(l1, l2, linalg_const_cast(l3)); }
1812 template <
typename L1,
typename L2,
typename L3>
1813 void mult_add_by_row(
const L1& l1,
const L2& l2, L3& l3, abstract_sparse) {
1814 typedef typename linalg_traits<L3>::value_type T;
1817 T aux =
vect_sp(mat_const_row(l1, i), l2);
1818 if (aux != T(0)) l3[i] += aux;
1822 template <
typename L1,
typename L2,
typename L3>
1823 void mult_add_by_row(
const L1& l1,
const L2& l2, L3& l3, abstract_skyline) {
1824 typedef typename linalg_traits<L3>::value_type T;
1827 T aux =
vect_sp(mat_const_row(l1, i), l2);
1828 if (aux != T(0)) l3[i] += aux;
1832 template <
typename L1,
typename L2,
typename L3>
1833 void mult_add_by_row(
const L1& l1,
const L2& l2, L3& l3, abstract_dense) {
1834 auto it=vect_begin(l3), ite=vect_end(l3);
1835 auto itr = mat_row_const_begin(l1);
1836 for (; it != ite; ++it, ++itr)
1837 *it +=
vect_sp(linalg_traits<L1>::row(itr), l2);
1840 template <
typename L1,
typename L2,
typename L3>
1841 void mult_add_by_col(
const L1& l1,
const L2& l2, L3& l3, abstract_dense) {
1844 add(scaled(mat_const_col(l1, i), l2[i]), l3);
1847 template <
typename L1,
typename L2,
typename L3>
1848 void mult_add_by_col(
const L1& l1,
const L2& l2, L3& l3, abstract_sparse) {
1849 auto it = vect_const_begin(l2), ite = vect_const_end(l2);
1850 for (; it != ite; ++it)
1851 if (*it !=
typename linalg_traits<L2>::value_type(0))
1852 add(scaled(mat_const_col(l1, it.index()), *it), l3);
1855 template <
typename L1,
typename L2,
typename L3>
1856 void mult_add_by_col(
const L1& l1,
const L2& l2, L3& l3, abstract_skyline) {
1857 auto it = vect_const_begin(l2), ite = vect_const_end(l2);
1858 for (; it != ite; ++it)
1859 if (*it !=
typename linalg_traits<L2>::value_type(0))
1860 add(scaled(mat_const_col(l1, it.index()), *it), l3);
1863 template <
typename L1,
typename L2,
typename L3>
inline
1864 void mult_add_spec(
const L1& l1,
const L2& l2, L3& l3, row_major)
1865 { mult_add_by_row(l1, l2, l3,
typename linalg_traits<L3>::storage_type()); }
1867 template <
typename L1,
typename L2,
typename L3>
inline
1868 void mult_add_spec(
const L1& l1,
const L2& l2, L3& l3, col_major)
1869 { mult_add_by_col(l1, l2, l3,
typename linalg_traits<L2>::storage_type()); }
1871 template <
typename L1,
typename L2,
typename L3>
inline
1872 void mult_add_spec(
const L1& l1,
const L2& l2, L3& l3, abstract_null_type)
1873 { mult_ind(l1, l2, l3,
typename linalg_traits<L1>::storage_type()); }
1875 template <
typename L1,
typename L2,
typename L3>
1876 void transposed_mult(
const L1& l1,
const L2& l2,
const L3& l3)
1877 {
mult(gmm::transposed(l1), l2, l3); }
1892 template<
typename SO1,
typename SO2,
typename SO3>
struct mult_t;
1893 #define DEFMU__ template<> struct mult_t
1894 DEFMU__<row_major , row_major , row_major > {
typedef r_mult t; };
1895 DEFMU__<row_major , row_major , col_major > {
typedef g_mult t; };
1896 DEFMU__<row_major , row_major , col_and_row> {
typedef r_mult t; };
1897 DEFMU__<row_major , row_major , row_and_col> {
typedef r_mult t; };
1898 DEFMU__<row_major , col_major , row_major > {
typedef rcmult t; };
1899 DEFMU__<row_major , col_major , col_major > {
typedef rcmult t; };
1900 DEFMU__<row_major , col_major , col_and_row> {
typedef rcmult t; };
1901 DEFMU__<row_major , col_major , row_and_col> {
typedef rcmult t; };
1902 DEFMU__<row_major , col_and_row, row_major > {
typedef r_mult t; };
1903 DEFMU__<row_major , col_and_row, col_major > {
typedef rcmult t; };
1904 DEFMU__<row_major , col_and_row, col_and_row> {
typedef rcmult t; };
1905 DEFMU__<row_major , col_and_row, row_and_col> {
typedef rcmult t; };
1906 DEFMU__<row_major , row_and_col, row_major > {
typedef r_mult t; };
1907 DEFMU__<row_major , row_and_col, col_major > {
typedef rcmult t; };
1908 DEFMU__<row_major , row_and_col, col_and_row> {
typedef r_mult t; };
1909 DEFMU__<row_major , row_and_col, row_and_col> {
typedef r_mult t; };
1910 DEFMU__<col_major , row_major , row_major > {
typedef crmult t; };
1911 DEFMU__<col_major , row_major , col_major > {
typedef g_mult t; };
1912 DEFMU__<col_major , row_major , col_and_row> {
typedef crmult t; };
1913 DEFMU__<col_major , row_major , row_and_col> {
typedef crmult t; };
1914 DEFMU__<col_major , col_major , row_major > {
typedef g_mult t; };
1915 DEFMU__<col_major , col_major , col_major > {
typedef c_mult t; };
1916 DEFMU__<col_major , col_major , col_and_row> {
typedef c_mult t; };
1917 DEFMU__<col_major , col_major , row_and_col> {
typedef c_mult t; };
1918 DEFMU__<col_major , col_and_row, row_major > {
typedef crmult t; };
1919 DEFMU__<col_major , col_and_row, col_major > {
typedef c_mult t; };
1920 DEFMU__<col_major , col_and_row, col_and_row> {
typedef c_mult t; };
1921 DEFMU__<col_major , col_and_row, row_and_col> {
typedef c_mult t; };
1922 DEFMU__<col_major , row_and_col, row_major > {
typedef crmult t; };
1923 DEFMU__<col_major , row_and_col, col_major > {
typedef c_mult t; };
1924 DEFMU__<col_major , row_and_col, col_and_row> {
typedef c_mult t; };
1925 DEFMU__<col_major , row_and_col, row_and_col> {
typedef c_mult t; };
1926 DEFMU__<col_and_row, row_major , row_major > {
typedef r_mult t; };
1927 DEFMU__<col_and_row, row_major , col_major > {
typedef c_mult t; };
1928 DEFMU__<col_and_row, row_major , col_and_row> {
typedef r_mult t; };
1929 DEFMU__<col_and_row, row_major , row_and_col> {
typedef r_mult t; };
1930 DEFMU__<col_and_row, col_major , row_major > {
typedef rcmult t; };
1931 DEFMU__<col_and_row, col_major , col_major > {
typedef c_mult t; };
1932 DEFMU__<col_and_row, col_major , col_and_row> {
typedef c_mult t; };
1933 DEFMU__<col_and_row, col_major , row_and_col> {
typedef c_mult t; };
1934 DEFMU__<col_and_row, col_and_row, row_major > {
typedef r_mult t; };
1935 DEFMU__<col_and_row, col_and_row, col_major > {
typedef c_mult t; };
1936 DEFMU__<col_and_row, col_and_row, col_and_row> {
typedef c_mult t; };
1937 DEFMU__<col_and_row, col_and_row, row_and_col> {
typedef c_mult t; };
1938 DEFMU__<col_and_row, row_and_col, row_major > {
typedef r_mult t; };
1939 DEFMU__<col_and_row, row_and_col, col_major > {
typedef c_mult t; };
1940 DEFMU__<col_and_row, row_and_col, col_and_row> {
typedef c_mult t; };
1941 DEFMU__<col_and_row, row_and_col, row_and_col> {
typedef r_mult t; };
1942 DEFMU__<row_and_col, row_major , row_major > {
typedef r_mult t; };
1943 DEFMU__<row_and_col, row_major , col_major > {
typedef c_mult t; };
1944 DEFMU__<row_and_col, row_major , col_and_row> {
typedef r_mult t; };
1945 DEFMU__<row_and_col, row_major , row_and_col> {
typedef r_mult t; };
1946 DEFMU__<row_and_col, col_major , row_major > {
typedef rcmult t; };
1947 DEFMU__<row_and_col, col_major , col_major > {
typedef c_mult t; };
1948 DEFMU__<row_and_col, col_major , col_and_row> {
typedef c_mult t; };
1949 DEFMU__<row_and_col, col_major , row_and_col> {
typedef c_mult t; };
1950 DEFMU__<row_and_col, col_and_row, row_major > {
typedef rcmult t; };
1951 DEFMU__<row_and_col, col_and_row, col_major > {
typedef rcmult t; };
1952 DEFMU__<row_and_col, col_and_row, col_and_row> {
typedef rcmult t; };
1953 DEFMU__<row_and_col, col_and_row, row_and_col> {
typedef rcmult t; };
1954 DEFMU__<row_and_col, row_and_col, row_major > {
typedef r_mult t; };
1955 DEFMU__<row_and_col, row_and_col, col_major > {
typedef c_mult t; };
1956 DEFMU__<row_and_col, row_and_col, col_and_row> {
typedef r_mult t; };
1957 DEFMU__<row_and_col, row_and_col, row_and_col> {
typedef r_mult t; };
1959 template <
typename L1,
typename L2,
typename L3>
1960 void mult_dispatch(
const L1& l1,
const L2& l2, L3& l3, abstract_matrix) {
1961 typedef typename temporary_matrix<L3>::matrix_type temp_mat_type;
1964 GMM_ASSERT2(n == mat_nrows(l2) && mat_nrows(l1) == mat_nrows(l3) &&
1965 mat_ncols(l2) == mat_ncols(l3),
"dimensions mismatch");
1967 if (same_origin(l2, l3) || same_origin(l1, l3)) {
1968 GMM_WARNING2(
"A temporary is used for mult");
1969 temp_mat_type temp(mat_nrows(l3), mat_ncols(l3));
1970 mult_spec(l1, l2, temp,
typename mult_t<
1971 typename linalg_traits<L1>::sub_orientation,
1972 typename linalg_traits<L2>::sub_orientation,
1973 typename linalg_traits<temp_mat_type>::sub_orientation>::t());
1977 mult_spec(l1, l2, l3,
typename mult_t<
1978 typename linalg_traits<L1>::sub_orientation,
1979 typename linalg_traits<L2>::sub_orientation,
1980 typename linalg_traits<L3>::sub_orientation>::t());
1985 template <
typename L1,
typename L2,
typename L3>
1986 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, g_mult) {
1987 typedef typename linalg_traits<L3>::value_type T;
1988 GMM_WARNING2(
"Inefficient generic matrix-matrix mult is used");
1989 for (
size_type i = 0; i < mat_nrows(l3) ; ++i)
1990 for (
size_type j = 0; j < mat_ncols(l3) ; ++j) {
1992 for (
size_type k = 0; k < mat_nrows(l2) ; ++k)
1993 a += l1(i, k)*l2(k, j);
2000 template <
typename L1,
typename L2,
typename L3>
2001 void mult_row_col_with_temp(
const L1& l1,
const L2& l2, L3& l3, col_major) {
2002 typedef typename temporary_col_matrix<L1>::matrix_type temp_col_mat;
2003 temp_col_mat temp(mat_nrows(l1), mat_ncols(l1));
2008 template <
typename L1,
typename L2,
typename L3>
2009 void mult_row_col_with_temp(
const L1& l1,
const L2& l2, L3& l3, row_major) {
2010 typedef typename temporary_row_matrix<L2>::matrix_type temp_row_mat;
2011 temp_row_mat temp(mat_nrows(l2), mat_ncols(l2));
2016 template <
typename L1,
typename L2,
typename L3>
2017 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, rcmult) {
2018 if (is_sparse(l1) && is_sparse(l2)) {
2019 GMM_WARNING3(
"Inefficient row matrix - col matrix mult for "
2020 "sparse matrices, using temporary");
2021 mult_row_col_with_temp
2022 (l1, l2, l3,
typename principal_orientation_type
2023 <
typename linalg_traits<L3>::sub_orientation>::potype());
2026 auto it2b = linalg_traits<L2>::col_begin(l2), it2 = it2b,
2027 ite = linalg_traits<L2>::col_end(l2);
2030 for (i = 0; i < k; ++i) {
2031 typename linalg_traits<L1>::const_sub_row_type r1=mat_const_row(l1, i);
2032 for (it2 = it2b, j = 0; it2 != ite; ++it2, ++j)
2033 l3(i,j) =
vect_sp(r1, linalg_traits<L2>::col(it2));
2040 template <
typename L1,
typename L2,
typename L3>
inline
2041 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, r_mult) {
2042 mult_spec(l1, l2, l3,r_mult(),
typename linalg_traits<L1>::storage_type());
2045 template <
typename L1,
typename L2,
typename L3>
2046 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, r_mult, abstract_dense) {
2049 size_type nn = mat_nrows(l3), mm = mat_nrows(l2);
2052 add(scaled(mat_const_row(l2, j), l1(i, j)), mat_row(l3, i));
2057 template <
typename L1,
typename L2,
typename L3>
2058 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, r_mult, abstract_sparse) {
2063 typename linalg_traits<L1>::const_sub_row_type rl1=mat_const_row(l1, i);
2064 auto it = vect_const_begin(rl1), ite = vect_const_end(rl1);
2065 for (; it != ite; ++it)
2066 add(scaled(mat_const_row(l2, it.index()), *it), mat_row(l3, i));
2070 template <
typename L1,
typename L2,
typename L3>
2071 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, r_mult, abstract_skyline)
2072 { mult_spec(l1, l2, l3, r_mult(), abstract_sparse()); }
2076 template <
typename L1,
typename L2,
typename L3>
inline
2077 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, c_mult) {
2078 mult_spec(l1, l2, l3, c_mult(),
typename linalg_traits<L2>::storage_type(),
2079 typename linalg_traits<L2>::sub_orientation());
2083 template <
typename L1,
typename L2,
typename L3,
typename ORIEN>
2084 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, c_mult,
2085 abstract_dense, ORIEN) {
2086 typedef typename linalg_traits<L2>::value_type T;
2087 size_type nn = mat_ncols(l3), mm = mat_ncols(l1);
2090 clear(mat_col(l3, i));
2093 if (b != T(0))
add(scaled(mat_const_col(l1, j), b), mat_col(l3, i));
2098 template <
typename L1,
typename L2,
typename L3,
typename ORIEN>
2099 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, c_mult,
2100 abstract_sparse, ORIEN) {
2105 typename linalg_traits<L2>::const_sub_col_type rc2 = mat_const_col(l2, i);
2106 auto it = vect_const_begin(rc2), ite = vect_const_end(rc2);
2107 for (; it != ite; ++it)
2108 add(scaled(mat_const_col(l1, it.index()), *it), mat_col(l3, i));
2112 template <
typename L1,
typename L2,
typename L3>
2113 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, c_mult,
2114 abstract_sparse, row_major) {
2115 typedef typename linalg_traits<L2>::value_type T;
2116 GMM_WARNING3(
"Inefficient matrix-matrix mult for sparse matrices");
2118 size_type mm = mat_nrows(l2), nn = mat_ncols(l3);
2122 if (a != T(0))
add(scaled(mat_const_col(l1, j), a), mat_col(l3, i));
2126 template <
typename L1,
typename L2,
typename L3,
typename ORIEN>
inline
2127 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, c_mult,
2128 abstract_skyline, ORIEN)
2129 { mult_spec(l1, l2, l3, c_mult(), abstract_sparse(), ORIEN()); }
2134 template <
typename L1,
typename L2,
typename L3>
inline
2135 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, crmult)
2136 { mult_spec(l1,l2,l3,crmult(),
typename linalg_traits<L1>::storage_type()); }
2139 template <
typename L1,
typename L2,
typename L3>
2140 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, crmult, abstract_dense) {
2143 size_type nn = mat_ncols(l1), mm = mat_nrows(l1);
2146 add(scaled(mat_const_row(l2, i), l1(j, i)), mat_row(l3, j));
2150 template <
typename L1,
typename L2,
typename L3>
2151 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, crmult, abstract_sparse) {
2156 typename linalg_traits<L1>::const_sub_col_type rc1 = mat_const_col(l1, i);
2157 auto it = vect_const_begin(rc1), ite = vect_const_end(rc1);
2158 for (; it != ite; ++it)
2159 add(scaled(mat_const_row(l2, i), *it), mat_row(l3, it.index()));
2163 template <
typename L1,
typename L2,
typename L3>
inline
2164 void mult_spec(
const L1& l1,
const L2& l2, L3& l3, crmult, abstract_skyline)
2165 { mult_spec(l1, l2, l3, crmult(), abstract_sparse()); }
2177 template <
typename MAT>
inline
2179 magnitude_of_linalg(MAT) tol = magnitude_of_linalg(MAT)(-1))
2181 typedef magnitude_of_linalg(MAT) R;
2182 if (tol < R(0)) tol = default_tol(R()) *
mat_maxnorm(A);
2183 if (mat_nrows(A) != mat_ncols(A))
return false;
2184 return is_symmetric(A, tol,
typename linalg_traits<MAT>::storage_type());
2188 template <
typename MAT>
2189 bool is_symmetric(
const MAT &A, magnitude_of_linalg(MAT) tol,
2194 if (gmm::abs(A(i, j)-A(j, i)) > tol)
return false;
2198 template <
typename MAT>
2199 bool is_symmetric(
const MAT &A, magnitude_of_linalg(MAT) tol,
2201 return is_symmetric(A, tol,
typename principal_orientation_type<
typename
2202 linalg_traits<MAT>::sub_orientation>::potype());
2205 template <
typename MAT>
2206 bool is_symmetric(
const MAT &A, magnitude_of_linalg(MAT) tol,
2208 for (
size_type i = 0; i < mat_nrows(A); ++i) {
2209 typename linalg_traits<MAT>::const_sub_row_type row = mat_const_row(A, i);
2210 auto it = vect_const_begin(row), ite = vect_const_end(row);
2211 for (; it != ite; ++it)
2212 if (gmm::abs(*it - A(it.index(), i)) > tol)
return false;
2217 template <
typename MAT>
2218 bool is_symmetric(
const MAT &A, magnitude_of_linalg(MAT) tol,
2220 for (
size_type i = 0; i < mat_ncols(A); ++i) {
2221 typename linalg_traits<MAT>::const_sub_col_type col = mat_const_col(A, i);
2222 auto it = vect_const_begin(col), ite = vect_const_end(col);
2223 for (; it != ite; ++it)
2224 if (gmm::abs(*it - A(i, it.index())) > tol)
return false;
2229 template <
typename MAT>
2230 bool is_symmetric(
const MAT &A, magnitude_of_linalg(MAT) tol,
2239 template <
typename MAT>
inline
2241 magnitude_of_linalg(MAT) tol = magnitude_of_linalg(MAT)(-1))
2243 typedef magnitude_of_linalg(MAT) R;
2244 if (tol < R(0)) tol = default_tol(R()) *
mat_maxnorm(A);
2245 if (mat_nrows(A) != mat_ncols(A))
return false;
2246 return is_hermitian(A, tol,
typename linalg_traits<MAT>::storage_type());
2250 template <
typename MAT>
2251 bool is_hermitian(
const MAT &A, magnitude_of_linalg(MAT) tol,
2256 if (gmm::abs(A(i, j)-gmm::conj(A(j, i))) > tol)
return false;
2260 template <
typename MAT>
2261 bool is_hermitian(
const MAT &A, magnitude_of_linalg(MAT) tol,
2263 return is_hermitian(A, tol,
typename principal_orientation_type<
typename
2264 linalg_traits<MAT>::sub_orientation>::potype());
2267 template <
typename MAT>
2268 bool is_hermitian(
const MAT &A, magnitude_of_linalg(MAT) tol,
2270 for (
size_type i = 0; i < mat_nrows(A); ++i) {
2271 typename linalg_traits<MAT>::const_sub_row_type row = mat_const_row(A, i);
2272 auto it = vect_const_begin(row), ite = vect_const_end(row);
2273 for (; it != ite; ++it)
2274 if (gmm::abs(gmm::conj(*it) - A(it.index(), i)) > tol)
return false;
2279 template <
typename MAT>
2280 bool is_hermitian(
const MAT &A, magnitude_of_linalg(MAT) tol,
2282 for (
size_type i = 0; i < mat_ncols(A); ++i) {
2283 typename linalg_traits<MAT>::const_sub_col_type col = mat_const_col(A, i);
2284 auto it = vect_const_begin(col), ite = vect_const_end(col);
2285 for (; it != ite; ++it)
2286 if (gmm::abs(gmm::conj(*it) - A(i, it.index())) > tol)
return false;
2291 template <
typename MAT>
2292 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