|
@ -1858,6 +1858,25 @@ namespace gmm { |
|
|
linalg_traits<L1>::sub_orientation>::potype()); |
|
|
linalg_traits<L1>::sub_orientation>::potype()); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** Multiply-accumulate. l4 = l1*l2 + l3; */ |
|
|
|
|
|
template <typename L1, typename L2, typename L3, typename L4> inline |
|
|
|
|
|
void mult_add(const L1& l1, const L2& l2, const L3& l3, L4& l4) { |
|
|
|
|
|
size_type m = mat_nrows(l1), n = mat_ncols(l1); |
|
|
|
|
|
if (!m || !n) return; |
|
|
|
|
|
GMM_ASSERT2(n==vect_size(l2) && m==vect_size(l3) && vect_size(l3) == vect_size(l4), "dimensions mismatch"); |
|
|
|
|
|
if (!same_origin(l2, l3)) { |
|
|
|
|
|
mult_add_spec(l1, l2, l3, l4, typename principal_orientation_type<typename |
|
|
|
|
|
linalg_traits<L1>::sub_orientation>::potype()); |
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
GMM_WARNING2("Warning, A temporary is used for mult\n"); |
|
|
|
|
|
typename temporary_vector<L3>::vector_type temp(vect_size(l2)); |
|
|
|
|
|
copy(l2, temp); |
|
|
|
|
|
mult_add_spec(l1, temp, l3, l4, typename principal_orientation_type<typename |
|
|
|
|
|
linalg_traits<L1>::sub_orientation>::potype()); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
///@cond DOXY_SHOW_ALL_FUNCTIONS |
|
|
///@cond DOXY_SHOW_ALL_FUNCTIONS |
|
|
|
|
|
|
|
|
template <typename L1, typename L2, typename L3> inline |
|
|
template <typename L1, typename L2, typename L3> inline |
|
@ -1893,6 +1912,16 @@ namespace gmm { |
|
|
*it += vect_sp(linalg_traits<L1>::row(itr), l2); |
|
|
*it += vect_sp(linalg_traits<L1>::row(itr), l2); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
template <typename L1, typename L2, typename L3, typename L4> |
|
|
|
|
|
void mult_add_by_row(const L1& l1, const L2& l2, const L3& l3, L4& l4, abstract_dense) { |
|
|
|
|
|
typename linalg_traits<L3>::const_iterator add_it=vect_begin(l3), add_ite=vect_end(l3); |
|
|
|
|
|
typename linalg_traits<L4>::iterator target_it=vect_begin(l4), target_ite=vect_end(l4); |
|
|
|
|
|
typename linalg_traits<L1>::const_row_iterator |
|
|
|
|
|
itr = mat_row_const_begin(l1); |
|
|
|
|
|
for (; add_it != add_ite; ++add_it, ++target_it, ++itr) |
|
|
|
|
|
*target_it = vect_sp(linalg_traits<L1>::row(itr), l2) + *add_it; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
template <typename L1, typename L2, typename L3> |
|
|
template <typename L1, typename L2, typename L3> |
|
|
void mult_add_by_col(const L1& l1, const L2& l2, L3& l3, abstract_dense) { |
|
|
void mult_add_by_col(const L1& l1, const L2& l2, L3& l3, abstract_dense) { |
|
|
size_type nc = mat_ncols(l1); |
|
|
size_type nc = mat_ncols(l1); |
|
@ -1922,6 +1951,10 @@ namespace gmm { |
|
|
void mult_add_spec(const L1& l1, const L2& l2, L3& l3, row_major) |
|
|
void mult_add_spec(const L1& l1, const L2& l2, L3& l3, row_major) |
|
|
{ mult_add_by_row(l1, l2, l3, typename linalg_traits<L3>::storage_type()); } |
|
|
{ mult_add_by_row(l1, l2, l3, typename linalg_traits<L3>::storage_type()); } |
|
|
|
|
|
|
|
|
|
|
|
template <typename L1, typename L2, typename L3, typename L4> inline |
|
|
|
|
|
void mult_add_spec(const L1& l1, const L2& l2, const L3& l3, L4& l4, row_major) |
|
|
|
|
|
{ mult_add_by_row(l1, l2, l3, l4, typename linalg_traits<L3>::storage_type()); } |
|
|
|
|
|
|
|
|
template <typename L1, typename L2, typename L3> inline |
|
|
template <typename L1, typename L2, typename L3> inline |
|
|
void mult_add_spec(const L1& l1, const L2& l2, L3& l3, col_major) |
|
|
void mult_add_spec(const L1& l1, const L2& l2, L3& l3, col_major) |
|
|
{ mult_add_by_col(l1, l2, l3, typename linalg_traits<L2>::storage_type()); } |
|
|
{ mult_add_by_col(l1, l2, l3, typename linalg_traits<L2>::storage_type()); } |
|
|