Mat_meat.hpp | Mat_meat.hpp | |||
---|---|---|---|---|
skipping to change at line 1833 | skipping to change at line 1833 | |||
const SpProxy<T1> p(m.get_ref()); | const SpProxy<T1> p(m.get_ref()); | |||
access::rw(n_rows) = p.get_n_rows(); | access::rw(n_rows) = p.get_n_rows(); | |||
access::rw(n_cols) = p.get_n_cols(); | access::rw(n_cols) = p.get_n_cols(); | |||
access::rw(n_elem) = p.get_n_elem(); | access::rw(n_elem) = p.get_n_elem(); | |||
init_cold(); | init_cold(); | |||
fill(eT(0)); | fill(eT(0)); | |||
// Iterate over each nonzero element and set it. | typename SpProxy<T1>::const_iterator_type it = p.begin(); | |||
for(typename SpProxy<T1>::const_iterator_type it = p.begin(); it != p.end | typename SpProxy<T1>::const_iterator_type it_end = p.end(); | |||
(); ++it) | ||||
while(it != it_end) | ||||
{ | { | |||
at(it.row(), it.col()) = (*it); | at(it.row(), it.col()) = (*it); | |||
++it; | ||||
} | } | |||
} | } | |||
template<typename eT> | template<typename eT> | |||
template<typename T1> | template<typename T1> | |||
inline | inline | |||
const Mat<eT>& | const Mat<eT>& | |||
Mat<eT>::operator=(const SpBase<eT, T1>& m) | Mat<eT>::operator=(const SpBase<eT, T1>& m) | |||
{ | { | |||
arma_extra_debug_sigprint(); | arma_extra_debug_sigprint(); | |||
const SpProxy<T1> p(m.get_ref()); | const SpProxy<T1> p(m.get_ref()); | |||
init_warm(p.get_n_rows(), p.get_n_cols()); | init_warm(p.get_n_rows(), p.get_n_cols()); | |||
fill(eT(0)); | fill(eT(0)); | |||
for(typename SpProxy<T1>::const_iterator_type it = p.begin(); it != p.end | typename SpProxy<T1>::const_iterator_type it = p.begin(); | |||
(); ++it) | typename SpProxy<T1>::const_iterator_type it_end = p.end(); | |||
while(it != it_end) | ||||
{ | { | |||
at(it.row(), it.col()) = (*it); | at(it.row(), it.col()) = (*it); | |||
++it; | ||||
} | } | |||
return *this; | return *this; | |||
} | } | |||
template<typename eT> | template<typename eT> | |||
template<typename T1> | template<typename T1> | |||
inline | inline | |||
const Mat<eT>& | const Mat<eT>& | |||
Mat<eT>::operator+=(const SpBase<eT, T1>& m) | Mat<eT>::operator+=(const SpBase<eT, T1>& m) | |||
{ | { | |||
arma_extra_debug_sigprint(); | arma_extra_debug_sigprint(); | |||
const SpProxy<T1> p(m.get_ref()); | const SpProxy<T1> p(m.get_ref()); | |||
arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols( ), "addition"); | arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols( ), "addition"); | |||
for(typename SpProxy<T1>::const_iterator_type it = p.begin(); it != p.end | typename SpProxy<T1>::const_iterator_type it = p.begin(); | |||
(); ++it) | typename SpProxy<T1>::const_iterator_type it_end = p.end(); | |||
while(it != it_end) | ||||
{ | { | |||
at(it.row(), it.col()) += (*it); | at(it.row(), it.col()) += (*it); | |||
++it; | ||||
} | } | |||
return *this; | return *this; | |||
} | } | |||
template<typename eT> | template<typename eT> | |||
template<typename T1> | template<typename T1> | |||
inline | inline | |||
const Mat<eT>& | const Mat<eT>& | |||
Mat<eT>::operator-=(const SpBase<eT, T1>& m) | Mat<eT>::operator-=(const SpBase<eT, T1>& m) | |||
{ | { | |||
arma_extra_debug_sigprint(); | arma_extra_debug_sigprint(); | |||
const SpProxy<T1> p(m.get_ref()); | const SpProxy<T1> p(m.get_ref()); | |||
arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols( ), "subtraction"); | arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols( ), "subtraction"); | |||
for(typename SpProxy<T1>::const_iterator_type it = p.begin(); it != p.end | typename SpProxy<T1>::const_iterator_type it = p.begin(); | |||
(); ++it) | typename SpProxy<T1>::const_iterator_type it_end = p.end(); | |||
while(it != it_end) | ||||
{ | { | |||
at(it.row(), it.col()) -= (*it); | at(it.row(), it.col()) -= (*it); | |||
++it; | ||||
} | } | |||
return *this; | return *this; | |||
} | } | |||
template<typename eT> | template<typename eT> | |||
template<typename T1> | template<typename T1> | |||
inline | inline | |||
const Mat<eT>& | const Mat<eT>& | |||
Mat<eT>::operator*=(const SpBase<eT, T1>& m) | Mat<eT>::operator*=(const SpBase<eT, T1>& m) | |||
skipping to change at line 1929 | skipping to change at line 1944 | |||
inline | inline | |||
const Mat<eT>& | const Mat<eT>& | |||
Mat<eT>::operator%=(const SpBase<eT, T1>& m) | Mat<eT>::operator%=(const SpBase<eT, T1>& m) | |||
{ | { | |||
arma_extra_debug_sigprint(); | arma_extra_debug_sigprint(); | |||
const SpProxy<T1> p(m.get_ref()); | const SpProxy<T1> p(m.get_ref()); | |||
arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols( ), "element-wise multiplication"); | arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols( ), "element-wise multiplication"); | |||
typename SpProxy<T1>::const_iterator_type it = p.begin(); | typename SpProxy<T1>::const_iterator_type it = p.begin(); | |||
typename SpProxy<T1>::const_iterator_type it_end = p.end(); | ||||
// We have to zero everything that isn't being used. | // We have to zero everything that isn't being used. | |||
arrayops::inplace_set(memptr(), eT(0), (it.col() * n_rows) + it.row()); | arrayops::inplace_set(memptr(), eT(0), (it.col() * n_rows) + it.row()); | |||
while(it != p.end()) | while(it != it_end) | |||
{ | { | |||
const uword cur_loc = (it.col() * n_rows) + it.row(); | const uword cur_loc = (it.col() * n_rows) + it.row(); | |||
access::rw(mem[cur_loc]) *= (*it); | access::rw(mem[cur_loc]) *= (*it); | |||
++it; | ++it; | |||
const uword next_loc = (it == p.end()) | const uword next_loc = (it == it_end) | |||
? (p.get_n_cols() * n_rows) | ? (p.get_n_cols() * n_rows) | |||
: (it.col() * n_rows) + it.row(); | : (it.col() * n_rows) + it.row(); | |||
arrayops::inplace_set(memptr() + cur_loc + 1, eT(0), (next_loc - cur_lo c - 1)); | arrayops::inplace_set(memptr() + cur_loc + 1, eT(0), (next_loc - cur_lo c - 1)); | |||
} | } | |||
return *this; | return *this; | |||
} | } | |||
template<typename eT> | template<typename eT> | |||
skipping to change at line 1967 | skipping to change at line 1983 | |||
{ | { | |||
arma_extra_debug_sigprint(); | arma_extra_debug_sigprint(); | |||
const SpProxy<T1> p(m.get_ref()); | const SpProxy<T1> p(m.get_ref()); | |||
arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols( ), "element-wise division"); | arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols( ), "element-wise division"); | |||
// If you use this method, you are probably stupid or misguided, but for completeness it is implemented. | // If you use this method, you are probably stupid or misguided, but for completeness it is implemented. | |||
// Unfortunately the best way to do this is loop over every element. | // Unfortunately the best way to do this is loop over every element. | |||
for(uword c = 0; c < n_cols; ++c) | for(uword c = 0; c < n_cols; ++c) | |||
for(uword r = 0; r < n_rows; ++r) | ||||
{ | { | |||
for(uword r = 0; r < n_rows; ++r) | at(r, c) /= p.at(r, c); | |||
{ | ||||
at(r, c) /= p.at(r, c); | ||||
} | ||||
} | } | |||
return *this; | return *this; | |||
} | } | |||
template<typename eT> | template<typename eT> | |||
inline | inline | |||
mat_injector< Mat<eT> > | mat_injector< Mat<eT> > | |||
Mat<eT>::operator<<(const eT val) | Mat<eT>::operator<<(const eT val) | |||
{ | { | |||
End of changes. 13 change blocks. | ||||
16 lines changed or deleted | 26 lines changed or added | |||
Op_bones.hpp | Op_bones.hpp | |||
---|---|---|---|---|
skipping to change at line 35 | skipping to change at line 35 | |||
template<typename T1, typename op_type> | template<typename T1, typename op_type> | |||
class Op : public Base<typename T1::elem_type, Op<T1, op_type> > | class Op : public Base<typename T1::elem_type, Op<T1, op_type> > | |||
{ | { | |||
public: | public: | |||
typedef typename T1::elem_type elem_type; | typedef typename T1::elem_type elem_type; | |||
typedef typename get_pod_type<elem_type>::result pod_type; | typedef typename get_pod_type<elem_type>::result pod_type; | |||
static const bool is_row = ( T1::is_col && (is_same_type<op_type, op_stra ns>::value || is_same_type<op_type, op_htrans>::value || is_same_type<op_ty pe, op_htrans2>::value) ); | static const bool is_row = ( T1::is_col && (is_same_type<op_type, op_stra ns>::value || is_same_type<op_type, op_htrans>::value || is_same_type<op_ty pe, op_htrans2>::value) ); | |||
static const bool is_col = ( T1::is_row && (is_same_type<op_type, op_stra ns>::value || is_same_type<op_type, op_htrans>::value || is_same_type<op_ty pe, op_htrans2>::value) ); | static const bool is_col = ( T1::is_row && (is_same_type<op_type, op_stra ns>::value || is_same_type<op_type, op_htrans>::value || is_same_type<op_ty pe, op_htrans2>::value) ) || (is_same_type<op_type, op_diagvec>::value); | |||
inline explicit Op(const T1& in_m); | inline explicit Op(const T1& in_m); | |||
inline Op(const T1& in_m, const elem_type in_aux); | inline Op(const T1& in_m, const elem_type in_aux); | |||
inline Op(const T1& in_m, const elem_type in_aux, const uword in_aux_uword_a, const uword in_aux_uword_b); | inline Op(const T1& in_m, const elem_type in_aux, const uword in_aux_uword_a, const uword in_aux_uword_b); | |||
inline Op(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b); | inline Op(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b); | |||
inline Op(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c, const char junk); | inline Op(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c, const char junk); | |||
inline ~Op(); | inline ~Op(); | |||
arma_aligned const T1& m; //!< storage of reference to t he operand (eg. a matrix) | arma_aligned const T1& m; //!< storage of reference to t he operand (eg. a matrix) | |||
arma_aligned elem_type aux; //!< storage of auxiliary data , user defined format | arma_aligned elem_type aux; //!< storage of auxiliary data , user defined format | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
Proxy.hpp | Proxy.hpp | |||
---|---|---|---|---|
skipping to change at line 280 | skipping to change at line 280 | |||
arma_inline elem_type operator[] (const uword i) const { return Q[i]; } | arma_inline elem_type operator[] (const uword i) const { return Q[i]; } | |||
arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row, col); } | arma_inline elem_type at (const uword row, const uword col) const { return Q.at(row, col); } | |||
arma_inline ea_type get_ea() const { return Q.memptr(); } | arma_inline ea_type get_ea() const { return Q.memptr(); } | |||
template<typename eT2> | template<typename eT2> | |||
arma_inline bool is_alias(const Mat<eT2>&) const { return false; } | arma_inline bool is_alias(const Mat<eT2>&) const { return false; } | |||
}; | }; | |||
template<typename T1> | template<typename T1> | |||
class Proxy_diagvec_mat | ||||
{ | ||||
inline Proxy_diagvec_mat(const T1&) {} | ||||
}; | ||||
template<typename T1> | ||||
class Proxy_diagvec_mat< Op<T1, op_diagvec> > | ||||
{ | ||||
public: | ||||
typedef typename T1::elem_type elem_type; | ||||
typedef typename get_pod_type<elem_type>::result pod_type; | ||||
typedef diagview<elem_type> stored_type; | ||||
typedef const diagview<elem_type>& ea_type; | ||||
static const bool prefer_at_accessor = false; | ||||
static const bool has_subview = true; | ||||
static const bool is_fixed = false; | ||||
static const bool fake_mat = false; | ||||
static const bool is_row = false; | ||||
static const bool is_col = true; | ||||
arma_aligned const Mat<elem_type>& R; | ||||
arma_aligned const diagview<elem_type> Q; | ||||
inline explicit Proxy_diagvec_mat(const Op<T1, op_diagvec>& A) | ||||
: R(A.m), Q( R.diag( (A.aux_uword_b > 0) ? -sword(A.aux_uword_a) : swor | ||||
d(A.aux_uword_a) ) ) | ||||
{ | ||||
arma_extra_debug_sigprint(); | ||||
} | ||||
arma_inline uword get_n_rows() const { return Q.n_rows; } | ||||
arma_inline uword get_n_cols() const { return 1; } | ||||
arma_inline uword get_n_elem() const { return Q.n_elem; } | ||||
arma_inline elem_type operator[] (const uword i) const { r | ||||
eturn Q[i]; } | ||||
arma_inline elem_type at (const uword row, const uword) const { r | ||||
eturn Q.at(row, 0); } | ||||
arma_inline ea_type get_ea() const { return Q; } | ||||
template<typename eT2> | ||||
arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&R) | ||||
== void_ptr(&X)); } | ||||
}; | ||||
template<typename T1> | ||||
class Proxy_diagvec_expr | ||||
{ | ||||
inline Proxy_diagvec_expr(const T1&) {} | ||||
}; | ||||
template<typename T1> | ||||
class Proxy_diagvec_expr< Op<T1, op_diagvec> > | ||||
{ | ||||
public: | ||||
typedef typename T1::elem_type elem_type; | ||||
typedef typename get_pod_type<elem_type>::result pod_type; | ||||
typedef Mat<elem_type> stored_type; | ||||
typedef const elem_type* ea_type; | ||||
static const bool prefer_at_accessor = false; | ||||
static const bool has_subview = false; | ||||
static const bool is_fixed = false; | ||||
static const bool fake_mat = false; | ||||
static const bool is_row = false; | ||||
static const bool is_col = true; | ||||
arma_aligned const Mat<elem_type> Q; | ||||
inline explicit Proxy_diagvec_expr(const Op<T1, op_diagvec>& A) | ||||
: Q(A) | ||||
{ | ||||
arma_extra_debug_sigprint(); | ||||
} | ||||
arma_inline uword get_n_rows() const { return Q.n_rows; } | ||||
arma_inline uword get_n_cols() const { return 1; } | ||||
arma_inline uword get_n_elem() const { return Q.n_elem; } | ||||
arma_inline elem_type operator[] (const uword i) const { r | ||||
eturn Q[i]; } | ||||
arma_inline elem_type at (const uword row, const uword) const { r | ||||
eturn Q.at(row, 0); } | ||||
arma_inline ea_type get_ea() const { return Q.memptr(); } | ||||
template<typename eT2> | ||||
arma_inline bool is_alias(const Mat<eT2>&) const { return false; } | ||||
}; | ||||
template<typename T1, bool condition> | ||||
struct Proxy_diagvec_redirect {}; | ||||
template<typename T1> | ||||
struct Proxy_diagvec_redirect< Op<T1, op_diagvec>, true > { typedef Proxy_d | ||||
iagvec_mat < Op<T1, op_diagvec> > result; }; | ||||
template<typename T1> | ||||
struct Proxy_diagvec_redirect< Op<T1, op_diagvec>, false> { typedef Proxy_d | ||||
iagvec_expr< Op<T1, op_diagvec> > result; }; | ||||
template<typename T1> | ||||
class Proxy< Op<T1, op_diagvec> > | ||||
: public Proxy_diagvec_redirect< Op<T1, op_diagvec>, is_Mat<T1>::value >: | ||||
:result | ||||
{ | ||||
public: | ||||
typedef typename Proxy_diagvec_redirect< Op<T1, op_diagvec>, is_Mat<T1>:: | ||||
value >::result Proxy_diagvec; | ||||
inline explicit Proxy(const Op<T1, op_diagvec>& A) | ||||
: Proxy_diagvec(A) | ||||
{ | ||||
arma_extra_debug_sigprint(); | ||||
} | ||||
}; | ||||
template<typename T1> | ||||
struct Proxy_xtrans_default | struct Proxy_xtrans_default | |||
{ | { | |||
typedef typename T1::elem_type eT; | typedef typename T1::elem_type eT; | |||
static const bool prefer_at_accessor = false; | static const bool prefer_at_accessor = false; | |||
static const bool has_subview = false; | static const bool has_subview = false; | |||
static const bool is_fixed = false; | static const bool is_fixed = false; | |||
static const bool fake_mat = false; | static const bool fake_mat = false; | |||
arma_aligned const Mat<eT> Q; | arma_aligned const Mat<eT> Q; | |||
End of changes. 1 change blocks. | ||||
0 lines changed or deleted | 125 lines changed or added | |||
SpMat_meat.hpp | SpMat_meat.hpp | |||
---|---|---|---|---|
skipping to change at line 178 | skipping to change at line 178 | |||
// Resize to 1x1 then set that to the right value. | // Resize to 1x1 then set that to the right value. | |||
init(1, 1); // Sets col_ptrs to 0. | init(1, 1); // Sets col_ptrs to 0. | |||
mem_resize(1); // One element. | mem_resize(1); // One element. | |||
// Manually set element. | // Manually set element. | |||
access::rw(values[0]) = val; | access::rw(values[0]) = val; | |||
access::rw(row_indices[0]) = 0; | access::rw(row_indices[0]) = 0; | |||
access::rw(col_ptrs[1]) = 1; | access::rw(col_ptrs[1]) = 1; | |||
return *this; | return *this; | |||
} | } | |||
template<typename eT> | template<typename eT> | |||
inline | inline | |||
const SpMat<eT>& | const SpMat<eT>& | |||
SpMat<eT>::operator*=(const eT val) | SpMat<eT>::operator*=(const eT val) | |||
{ | { | |||
arma_extra_debug_sigprint(); | arma_extra_debug_sigprint(); | |||
if(val == eT(0)) | if(val == eT(0)) | |||
{ | { | |||
// Everything will be zero. | // Everything will be zero. | |||
init(n_rows, n_cols); | init(n_rows, n_cols); | |||
return *this; | return *this; | |||
} | } | |||
// Iterate over nonzero values, which is a lot faster. | ||||
// for(uword i = 0; i < n_nonzero; ++i) | ||||
// { | ||||
// access::rw(values[i]) *= val; | ||||
// } | ||||
arrayops::inplace_mul( access::rwp(values), val, n_nonzero ); | arrayops::inplace_mul( access::rwp(values), val, n_nonzero ); | |||
return *this; | return *this; | |||
} | } | |||
template<typename eT> | template<typename eT> | |||
inline | inline | |||
const SpMat<eT>& | const SpMat<eT>& | |||
SpMat<eT>::operator/=(const eT val) | SpMat<eT>::operator/=(const eT val) | |||
{ | { | |||
arma_extra_debug_sigprint(); | arma_extra_debug_sigprint(); | |||
arma_debug_check( (val == eT(0)), "element-wise division: division by zer o" ); | arma_debug_check( (val == eT(0)), "element-wise division: division by zer o" ); | |||
// We only have to loop over nonzero values. | arrayops::inplace_div( access::rwp(values), val, n_nonzero ); | |||
for (uword i = 0; i < n_nonzero; ++i) | ||||
{ | ||||
access::rw(values[i]) /= val; | ||||
} | ||||
return *this; | return *this; | |||
} | } | |||
template<typename eT> | template<typename eT> | |||
inline | inline | |||
const SpMat<eT>& | const SpMat<eT>& | |||
SpMat<eT>::operator=(const SpMat<eT>& x) | SpMat<eT>::operator=(const SpMat<eT>& x) | |||
{ | { | |||
arma_extra_debug_sigprint(); | arma_extra_debug_sigprint(); | |||
skipping to change at line 502 | skipping to change at line 490 | |||
const uword x_n_cols = p.get_n_cols(); | const uword x_n_cols = p.get_n_cols(); | |||
const uword x_n_elem = p.get_n_elem(); | const uword x_n_elem = p.get_n_elem(); | |||
init(x_n_rows, x_n_cols); | init(x_n_rows, x_n_cols); | |||
// Count number of nonzero elements in base object. | // Count number of nonzero elements in base object. | |||
uword n = 0; | uword n = 0; | |||
if(Proxy<T1>::prefer_at_accessor == true) | if(Proxy<T1>::prefer_at_accessor == true) | |||
{ | { | |||
for(uword j = 0; j < x_n_cols; ++j) | for(uword j = 0; j < x_n_cols; ++j) | |||
for(uword i = 0; i < x_n_rows; ++i) | ||||
{ | { | |||
for(uword i = 0; i < x_n_rows; ++i) | if(p.at(i, j) != eT(0)) { ++n; } | |||
{ | ||||
if(p.at(i, j) != eT(0)) | ||||
++n; | ||||
} | ||||
} | } | |||
} | } | |||
else | else | |||
{ | { | |||
for(uword i = 0; i < x_n_elem; ++i) | for(uword i = 0; i < x_n_elem; ++i) | |||
{ | { | |||
if(p[i] != eT(0)) | if(p[i] != eT(0)) { ++n; } | |||
{ | ||||
++n; | ||||
} | ||||
} | } | |||
} | } | |||
mem_resize(n); | mem_resize(n); | |||
// Now the memory is resized correctly; add nonzero elements. | // Now the memory is resized correctly; add nonzero elements. | |||
n = 0; | n = 0; | |||
for(uword j = 0; j < x_n_cols; ++j) | for(uword j = 0; j < x_n_cols; ++j) | |||
for(uword i = 0; i < x_n_rows; ++i) | ||||
{ | { | |||
for(uword i = 0; i < x_n_rows; ++i) | const eT val = p.at(i, j); | |||
if(val != eT(0)) | ||||
{ | { | |||
if(p.at(i, j) != eT(0)) | access::rw(values[n]) = val; | |||
{ | access::rw(row_indices[n]) = i; | |||
access::rw(values[n]) = p.at(i, j); | access::rw(col_ptrs[j + 1])++; | |||
access::rw(row_indices[n]) = i; | ++n; | |||
access::rw(col_ptrs[j + 1])++; | ||||
++n; | ||||
} | ||||
} | } | |||
} | } | |||
// Sum column counts to be column pointers. | // Sum column counts to be column pointers. | |||
for(uword c = 1; c <= n_cols; ++c) | for(uword c = 1; c <= n_cols; ++c) | |||
{ | { | |||
access::rw(col_ptrs[c]) += col_ptrs[c - 1]; | access::rw(col_ptrs[c]) += col_ptrs[c - 1]; | |||
} | } | |||
return *this; | return *this; | |||
skipping to change at line 640 | skipping to change at line 622 | |||
// Resize to final correct size. | // Resize to final correct size. | |||
z.mem_resize(z.col_ptrs[z.n_cols]); | z.mem_resize(z.col_ptrs[z.n_cols]); | |||
// Now take the memory of the temporary matrix. | // Now take the memory of the temporary matrix. | |||
steal_mem(z); | steal_mem(z); | |||
return *this; | return *this; | |||
} | } | |||
/** | ||||
* Don't use this function. It's not mathematically well-defined and waste | ||||
s | ||||
* cycles to trash all your data. This is dumb. | ||||
*/ | ||||
template<typename eT> | template<typename eT> | |||
template<typename T1> | template<typename T1> | |||
inline | inline | |||
const SpMat<eT>& | const SpMat<eT>& | |||
SpMat<eT>::operator/=(const Base<eT, T1>& x) | SpMat<eT>::operator/=(const Base<eT, T1>& x) | |||
{ | { | |||
arma_extra_debug_sigprint(); | arma_extra_debug_sigprint(); | |||
const Proxy<T1> p(x.get_ref()); | SpMat<eT> tmp = (*this) / x.get_ref(); | |||
/** | ||||
* Don't use this function. It's not mathematically well-defined and was | ||||
tes | ||||
* cycles to trash all your data. This is dumb. | ||||
*/ | ||||
arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols( | ||||
), "element-wise division"); | ||||
for(uword j = 0; j < n_cols; j++) | steal_mem(tmp); | |||
for(uword i = 0; i < n_rows; i++) | ||||
{ | ||||
at(i, j) /= p.at(i, j); | ||||
} | ||||
return *this; | return *this; | |||
} | } | |||
template<typename eT> | template<typename eT> | |||
template<typename T1> | template<typename T1> | |||
inline | inline | |||
const SpMat<eT>& | const SpMat<eT>& | |||
SpMat<eT>::operator%=(const Base<eT, T1>& x) | SpMat<eT>::operator%=(const Base<eT, T1>& x) | |||
{ | { | |||
End of changes. 12 change blocks. | ||||
44 lines changed or deleted | 19 lines changed or added | |||
arma_version.hpp | arma_version.hpp | |||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
// Lesser General Public License (LGPL) as published | // Lesser General Public License (LGPL) as published | |||
// by the Free Software Foundation, either version 3 | // by the Free Software Foundation, either version 3 | |||
// of the License or (at your option) any later version. | // of the License or (at your option) any later version. | |||
// (see http://www.opensource.org/licenses for more info) | // (see http://www.opensource.org/licenses for more info) | |||
//! \addtogroup arma_version | //! \addtogroup arma_version | |||
//! @{ | //! @{ | |||
#define ARMA_VERSION_MAJOR 3 | #define ARMA_VERSION_MAJOR 3 | |||
#define ARMA_VERSION_MINOR 6 | #define ARMA_VERSION_MINOR 6 | |||
#define ARMA_VERSION_PATCH 0 | #define ARMA_VERSION_PATCH 1 | |||
#define ARMA_VERSION_NAME "Piazza del Duomo" | #define ARMA_VERSION_NAME "Piazza del Duomo" | |||
struct arma_version | struct arma_version | |||
{ | { | |||
static const unsigned int major = ARMA_VERSION_MAJOR; | static const unsigned int major = ARMA_VERSION_MAJOR; | |||
static const unsigned int minor = ARMA_VERSION_MINOR; | static const unsigned int minor = ARMA_VERSION_MINOR; | |||
static const unsigned int patch = ARMA_VERSION_PATCH; | static const unsigned int patch = ARMA_VERSION_PATCH; | |||
static | static | |||
inline | inline | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
compiler_setup.hpp | compiler_setup.hpp | |||
---|---|---|---|---|
skipping to change at line 22 | skipping to change at line 22 | |||
#define arma_hot | #define arma_hot | |||
#define arma_cold | #define arma_cold | |||
#define arma_pure | #define arma_pure | |||
#define arma_const | #define arma_const | |||
#define arma_aligned | #define arma_aligned | |||
#define arma_warn_unused | #define arma_warn_unused | |||
#define arma_deprecated | #define arma_deprecated | |||
#define arma_malloc | #define arma_malloc | |||
#define arma_inline inline | #define arma_inline inline | |||
#define arma_noinline | ||||
#define arma_ignore(variable) ((void)(variable)) | #define arma_ignore(variable) ((void)(variable)) | |||
#if defined(ARMA_BLAS_UNDERSCORE) | #if defined(ARMA_BLAS_UNDERSCORE) | |||
#define arma_fortran2_noprefix(function) function##_ | #define arma_fortran2_noprefix(function) function##_ | |||
#define arma_fortran2_prefix(function) wrapper_##function##_ | #define arma_fortran2_prefix(function) wrapper_##function##_ | |||
#else | #else | |||
#define arma_fortran2_prefix(function) wrapper_##function | ||||
#define arma_fortran2_noprefix(function) function | #define arma_fortran2_noprefix(function) function | |||
#define arma_fortran2_prefix(function) wrapper_##function | ||||
#endif | #endif | |||
#if defined(ARMA_USE_WRAPPER) | #if defined(ARMA_USE_WRAPPER) | |||
#define arma_fortran(function) arma_fortran2_prefix(function) | #define arma_fortran(function) arma_fortran2_prefix(function) | |||
#define arma_atlas(function) wrapper_##function | #define arma_atlas(function) wrapper_##function | |||
#else | #else | |||
#define arma_fortran(function) arma_fortran2_noprefix(function) | #define arma_fortran(function) arma_fortran2_noprefix(function) | |||
#define arma_atlas(function) function | #define arma_atlas(function) function | |||
#endif | #endif | |||
skipping to change at line 69 | skipping to change at line 70 | |||
#if (__GNUC__ < 4) | #if (__GNUC__ < 4) | |||
#error "*** Need a newer compiler ***" | #error "*** Need a newer compiler ***" | |||
#endif | #endif | |||
#define ARMA_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNU C_PATCHLEVEL__) | #define ARMA_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNU C_PATCHLEVEL__) | |||
#define ARMA_GOOD_COMPILER | #define ARMA_GOOD_COMPILER | |||
#undef ARMA_HAVE_STD_TR1 | #undef ARMA_HAVE_STD_TR1 | |||
#undef arma_cold | ||||
#undef arma_pure | #undef arma_pure | |||
#undef arma_const | #undef arma_const | |||
#undef arma_aligned | #undef arma_aligned | |||
#undef arma_warn_unused | #undef arma_warn_unused | |||
#undef arma_deprecated | #undef arma_deprecated | |||
#undef arma_malloc | #undef arma_malloc | |||
#undef arma_inline | #undef arma_inline | |||
#undef arma_noinline | ||||
#define arma_cold __attribute__((__noinline__)) | ||||
#define arma_pure __attribute__((__pure__)) | #define arma_pure __attribute__((__pure__)) | |||
#define arma_const __attribute__((__const__)) | #define arma_const __attribute__((__const__)) | |||
#define arma_aligned __attribute__((__aligned__)) | #define arma_aligned __attribute__((__aligned__)) | |||
#define arma_warn_unused __attribute__((__warn_unused_result__)) | #define arma_warn_unused __attribute__((__warn_unused_result__)) | |||
#define arma_deprecated __attribute__((__deprecated__)) | #define arma_deprecated __attribute__((__deprecated__)) | |||
#define arma_malloc __attribute__((__malloc__)) | #define arma_malloc __attribute__((__malloc__)) | |||
#define arma_inline inline __attribute__((__always_inline__)) | #define arma_inline inline __attribute__((__always_inline__)) | |||
#define arma_noinline __attribute__((__noinline__)) | ||||
#if (ARMA_GCC_VERSION >= 40300) | #if (ARMA_GCC_VERSION >= 40300) | |||
#undef arma_hot | #undef arma_hot | |||
#undef arma_cold | #undef arma_cold | |||
#define arma_hot __attribute__((__hot__)) | #define arma_hot __attribute__((__hot__)) | |||
#define arma_cold __attribute__((__cold__,__noinline__)) | #define arma_cold __attribute__((__cold__)) | |||
#endif | #endif | |||
#if (ARMA_GCC_VERSION >= 40200) | #if (ARMA_GCC_VERSION >= 40200) | |||
#if defined(_GLIBCXX_USE_C99_MATH_TR1) && defined(_GLIBCXX_USE_C99_COMP LEX_TR1) | #if defined(_GLIBCXX_USE_C99_MATH_TR1) && defined(_GLIBCXX_USE_C99_COMP LEX_TR1) | |||
#define ARMA_HAVE_STD_TR1 | #define ARMA_HAVE_STD_TR1 | |||
#endif | #endif | |||
#endif | #endif | |||
#if defined(__GXX_EXPERIMENTAL_CXX0X__) | #if defined(__GXX_EXPERIMENTAL_CXX0X__) | |||
#undef ARMA_HAVE_STD_TR1 | #undef ARMA_HAVE_STD_TR1 | |||
End of changes. 8 change blocks. | ||||
4 lines changed or deleted | 5 lines changed or added | |||
debug.hpp | debug.hpp | |||
---|---|---|---|---|
skipping to change at line 81 | skipping to change at line 81 | |||
{ | { | |||
return arma_stream_err2<char>(NULL); | return arma_stream_err2<char>(NULL); | |||
} | } | |||
// | // | |||
// arma_stop | // arma_stop | |||
//! print a message to get_stream_err1() and/or throw a logic_error excepti on | //! print a message to get_stream_err1() and/or throw a logic_error excepti on | |||
template<typename T1> | template<typename T1> | |||
arma_cold | arma_cold | |||
arma_noinline | ||||
static | static | |||
void | void | |||
arma_stop(const T1& x) | arma_stop(const T1& x) | |||
{ | { | |||
#if defined(ARMA_PRINT_LOGIC_ERRORS) | #if defined(ARMA_PRINT_LOGIC_ERRORS) | |||
{ | { | |||
std::ostream& out = get_stream_err1(); | std::ostream& out = get_stream_err1(); | |||
out.flush(); | out.flush(); | |||
skipping to change at line 107 | skipping to change at line 108 | |||
{ | { | |||
arma_ignore(x); | arma_ignore(x); | |||
} | } | |||
#endif | #endif | |||
throw std::logic_error(""); | throw std::logic_error(""); | |||
} | } | |||
template<typename T1> | template<typename T1> | |||
arma_cold | arma_cold | |||
arma_noinline | ||||
static | static | |||
void | void | |||
arma_stop_bad_alloc(const T1& x) | arma_stop_bad_alloc(const T1& x) | |||
{ | { | |||
std::ostream& out = get_stream_err1(); | std::ostream& out = get_stream_err1(); | |||
out.flush(); | out.flush(); | |||
out << '\n'; | out << '\n'; | |||
out << "error: " << x << '\n'; | out << "error: " << x << '\n'; | |||
skipping to change at line 129 | skipping to change at line 131 | |||
throw std::bad_alloc(); | throw std::bad_alloc(); | |||
} | } | |||
// | // | |||
// arma_bad | // arma_bad | |||
//! print a message to get_stream_err2() and/or throw a run-time error exce ption | //! print a message to get_stream_err2() and/or throw a run-time error exce ption | |||
template<typename T1> | template<typename T1> | |||
arma_cold | arma_cold | |||
arma_noinline | ||||
static | static | |||
void | void | |||
arma_bad(const T1& x, const bool hurl = true) | arma_bad(const T1& x, const bool hurl = true) | |||
{ | { | |||
#if defined(ARMA_PRINT_RUNTIME_ERRORS) | #if defined(ARMA_PRINT_RUNTIME_ERRORS) | |||
{ | { | |||
std::ostream& out = get_stream_err2(); | std::ostream& out = get_stream_err2(); | |||
out.flush(); | out.flush(); | |||
skipping to change at line 169 | skipping to change at line 172 | |||
arma_cold | arma_cold | |||
inline | inline | |||
void | void | |||
arma_print() | arma_print() | |||
{ | { | |||
get_stream_err1() << std::endl; | get_stream_err1() << std::endl; | |||
} | } | |||
template<typename T1> | template<typename T1> | |||
arma_cold | arma_cold | |||
arma_noinline | ||||
static | static | |||
void | void | |||
arma_print(const T1& x) | arma_print(const T1& x) | |||
{ | { | |||
get_stream_err1() << x << std::endl; | get_stream_err1() << x << std::endl; | |||
} | } | |||
template<typename T1, typename T2> | template<typename T1, typename T2> | |||
arma_cold | arma_cold | |||
arma_noinline | ||||
static | static | |||
void | void | |||
arma_print(const T1& x, const T2& y) | arma_print(const T1& x, const T2& y) | |||
{ | { | |||
get_stream_err1() << x << y << std::endl; | get_stream_err1() << x << y << std::endl; | |||
} | } | |||
template<typename T1, typename T2, typename T3> | template<typename T1, typename T2, typename T3> | |||
arma_cold | arma_cold | |||
arma_noinline | ||||
static | static | |||
void | void | |||
arma_print(const T1& x, const T2& y, const T3& z) | arma_print(const T1& x, const T2& y, const T3& z) | |||
{ | { | |||
get_stream_err1() << x << y << z << std::endl; | get_stream_err1() << x << y << z << std::endl; | |||
} | } | |||
// | // | |||
// arma_sigprint | // arma_sigprint | |||
skipping to change at line 250 | skipping to change at line 256 | |||
{ | { | |||
get_stream_err1() << " [this = " << this_ptr << ']' << std::endl; | get_stream_err1() << " [this = " << this_ptr << ']' << std::endl; | |||
} | } | |||
// | // | |||
// arma_warn | // arma_warn | |||
//! print a message to the warn stream | //! print a message to the warn stream | |||
template<typename T1> | template<typename T1> | |||
arma_cold | arma_cold | |||
arma_noinline | ||||
static | static | |||
void | void | |||
arma_warn(const bool state, const T1& x) | arma_warn(const bool state, const T1& x) | |||
{ | { | |||
if(state==true) | if(state==true) | |||
{ | { | |||
get_stream_err2() << x << std::endl; | get_stream_err2() << x << std::endl; | |||
} | } | |||
} | } | |||
template<typename T1, typename T2> | template<typename T1, typename T2> | |||
arma_cold | arma_cold | |||
arma_noinline | ||||
static | static | |||
void | void | |||
arma_warn(const bool state, const T1& x, const T2& y) | arma_warn(const bool state, const T1& x, const T2& y) | |||
{ | { | |||
if(state==true) | if(state==true) | |||
{ | { | |||
get_stream_err2() << x << y << std::endl; | get_stream_err2() << x << y << std::endl; | |||
} | } | |||
} | } | |||
template<typename T1, typename T2, typename T3> | template<typename T1, typename T2, typename T3> | |||
arma_cold | arma_cold | |||
arma_noinline | ||||
static | static | |||
void | void | |||
arma_warn(const bool state, const T1& x, const T2& y, const T3& z) | arma_warn(const bool state, const T1& x, const T2& y, const T3& z) | |||
{ | { | |||
if(state==true) | if(state==true) | |||
{ | { | |||
get_stream_err2() << x << y << z << std::endl; | get_stream_err2() << x << y << z << std::endl; | |||
} | } | |||
} | } | |||
skipping to change at line 343 | skipping to change at line 352 | |||
{ | { | |||
err_state = true; | err_state = true; | |||
err_msg = const_cast<char*>(message); | err_msg = const_cast<char*>(message); | |||
} | } | |||
} | } | |||
// | // | |||
// functions for generating strings indicating size errors | // functions for generating strings indicating size errors | |||
arma_cold | arma_cold | |||
arma_noinline | ||||
static | static | |||
std::string | std::string | |||
arma_incompat_size_string(const uword A_n_rows, const uword A_n_cols, const uword B_n_rows, const uword B_n_cols, const char* x) | arma_incompat_size_string(const uword A_n_rows, const uword A_n_cols, const uword B_n_rows, const uword B_n_cols, const char* x) | |||
{ | { | |||
std::stringstream tmp; | std::stringstream tmp; | |||
tmp << x << ": incompatible matrix dimensions: " << A_n_rows << 'x' << A_ n_cols << " and " << B_n_rows << 'x' << B_n_cols; | tmp << x << ": incompatible matrix dimensions: " << A_n_rows << 'x' << A_ n_cols << " and " << B_n_rows << 'x' << B_n_cols; | |||
return tmp.str(); | return tmp.str(); | |||
} | } | |||
arma_cold | arma_cold | |||
arma_noinline | ||||
static | static | |||
std::string | std::string | |||
arma_incompat_size_string(const uword A_n_rows, const uword A_n_cols, const uword A_n_slices, const uword B_n_rows, const uword B_n_cols, const uword B_n_slices, const char* x) | arma_incompat_size_string(const uword A_n_rows, const uword A_n_cols, const uword A_n_slices, const uword B_n_rows, const uword B_n_cols, const uword B_n_slices, const char* x) | |||
{ | { | |||
std::stringstream tmp; | std::stringstream tmp; | |||
tmp << x << ": incompatible cube dimensions: " << A_n_rows << 'x' << A_n_ cols << 'x' << A_n_slices << " and " << B_n_rows << 'x' << B_n_cols << 'x' << B_n_slices; | tmp << x << ": incompatible cube dimensions: " << A_n_rows << 'x' << A_n_ cols << 'x' << A_n_slices << " and " << B_n_rows << 'x' << B_n_cols << 'x' << B_n_slices; | |||
return tmp.str(); | return tmp.str(); | |||
} | } | |||
template<typename eT> | template<typename eT> | |||
arma_cold | arma_cold | |||
arma_noinline | ||||
static | static | |||
std::string | std::string | |||
arma_incompat_size_string(const subview_cube<eT>& Q, const Mat<eT>& A, cons t char* x) | arma_incompat_size_string(const subview_cube<eT>& Q, const Mat<eT>& A, cons t char* x) | |||
{ | { | |||
std::stringstream tmp; | std::stringstream tmp; | |||
tmp << x | tmp << x | |||
<< ": interpreting matrix as cube with dimenensions: " | << ": interpreting matrix as cube with dimenensions: " | |||
<< A.n_rows << 'x' << A.n_cols << 'x' << 1 | << A.n_rows << 'x' << A.n_cols << 'x' << 1 | |||
<< " or " | << " or " | |||
End of changes. 12 change blocks. | ||||
0 lines changed or deleted | 12 lines changed or added | |||
fn_dot.hpp | fn_dot.hpp | |||
---|---|---|---|---|
skipping to change at line 122 | skipping to change at line 122 | |||
( | ( | |||
const Op<T1, op_htrans>& A, | const Op<T1, op_htrans>& A, | |||
const T2& B | const T2& B | |||
) | ) | |||
{ | { | |||
arma_extra_debug_sigprint(); | arma_extra_debug_sigprint(); | |||
return cdot(A.m, B); | return cdot(A.m, B); | |||
} | } | |||
//! dot product of two sparse objects | // | |||
template<typename T1, typename T2> | // for sparse matrices | |||
inline | // | |||
arma_warn_unused | ||||
typename | ||||
enable_if2 | ||||
<(is_arma_sparse_type<T1>::value) && (is_arma_sparse_type<T2>::value) && | ||||
(is_same_type<typename T1::elem_type, typename T2::elem_type>::value), | ||||
typename T1::elem_type | ||||
>::result | ||||
dot | ||||
( | ||||
const SpBase<typename T1::elem_type, T1>& x, | ||||
const SpBase<typename T2::elem_type, T2>& y | ||||
) | ||||
{ | ||||
arma_extra_debug_sigprint(); | ||||
const SpProxy<T1> pa(x.get_ref()); | namespace priv | |||
const SpProxy<T2> pb(y.get_ref()); | { | |||
arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_ro | ||||
ws(), pb.get_n_cols(), "dot()"); | ||||
typedef typename T1::elem_type eT; | ||||
if((&(x.get_ref()) == &(y.get_ref())) && (SpProxy<T1>::must_use_iterator | template<typename T1, typename T2> | |||
== false)) | arma_hot | |||
{ | inline | |||
// We can do it directly! | typename T1::elem_type | |||
return op_dot::direct_dot_arma(pa.get_n_nonzero(), pa.get_values(), pa. | dot_helper(const SpProxy<T1>& pa, const SpProxy<T2>& pb) | |||
get_values()); | ||||
} | ||||
else | ||||
{ | { | |||
typedef typename T1::elem_type eT; | ||||
// Iterate over both objects and see when they are the same | // Iterate over both objects and see when they are the same | |||
eT result = eT(0); | eT result = eT(0); | |||
typename SpProxy<T1>::const_iterator_type a_it = pa.begin(); | typename SpProxy<T1>::const_iterator_type a_it = pa.begin(); | |||
typename SpProxy<T2>::const_iterator_type b_it = pb.begin(); | typename SpProxy<T1>::const_iterator_type a_end = pa.end(); | |||
while((a_it != pa.end()) && (b_it != pb.end())) | typename SpProxy<T2>::const_iterator_type b_it = pb.begin(); | |||
typename SpProxy<T2>::const_iterator_type b_end = pb.end(); | ||||
while((a_it != a_end) && (b_it != b_end)) | ||||
{ | { | |||
if(a_it == b_it) | if(a_it == b_it) | |||
{ | { | |||
result += (*a_it) * (*b_it); | result += (*a_it) * (*b_it); | |||
++a_it; | ++a_it; | |||
++b_it; | ++b_it; | |||
} | } | |||
else if((a_it.col() < b_it.col()) || ((a_it.col() == b_it.col()) && ( a_it.row() < b_it.row()))) | else if((a_it.col() < b_it.col()) || ((a_it.col() == b_it.col()) && ( a_it.row() < b_it.row()))) | |||
{ | { | |||
skipping to change at line 182 | skipping to change at line 169 | |||
} | } | |||
else | else | |||
{ | { | |||
// b_it is "behind" | // b_it is "behind" | |||
++b_it; | ++b_it; | |||
} | } | |||
} | } | |||
return result; | return result; | |||
} | } | |||
} | } | |||
//! dot product of one sparse and one dense object | //! dot product of two sparse objects | |||
template<typename T1, typename T2> | template<typename T1, typename T2> | |||
arma_inline | ||||
arma_warn_unused | arma_warn_unused | |||
arma_hot | ||||
inline | ||||
typename | typename | |||
enable_if2 | enable_if2 | |||
<(is_arma_sparse_type<T1>::value) && (is_arma_type<T2>::value) && (is_sam e_type<typename T1::elem_type, typename T2::elem_type>::value), | <(is_arma_sparse_type<T1>::value) && (is_arma_sparse_type<T2>::value) && (is_same_type<typename T1::elem_type, typename T2::elem_type>::value), | |||
typename T1::elem_type | typename T1::elem_type | |||
>::result | >::result | |||
dot | dot | |||
( | ( | |||
const SpBase<typename T1::elem_type, T1>& x, | const T1& x, | |||
const Base<typename T2::elem_type, T2>& y | const T2& y | |||
) | ) | |||
{ | { | |||
// this is commutative | arma_extra_debug_sigprint(); | |||
return dot(y, x); | ||||
const SpProxy<T1> pa(x); | ||||
const SpProxy<T2> pb(y); | ||||
arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_ro | ||||
ws(), pb.get_n_cols(), "dot()"); | ||||
typedef typename T1::elem_type eT; | ||||
typedef typename SpProxy<T1>::stored_type pa_Q_type; | ||||
typedef typename SpProxy<T2>::stored_type pb_Q_type; | ||||
if( | ||||
( (SpProxy<T1>::must_use_iterator == false) && (SpProxy<T2>::must_ | ||||
use_iterator == false) ) | ||||
&& ( (is_SpMat<pa_Q_type>::value == true ) && (is_SpMat<pb_Q_type | ||||
>::value == true ) ) | ||||
) | ||||
{ | ||||
const unwrap_spmat<pa_Q_type> tmp_a(pa.Q); | ||||
const unwrap_spmat<pb_Q_type> tmp_b(pb.Q); | ||||
const SpMat<eT>& A = tmp_a.M; | ||||
const SpMat<eT>& B = tmp_b.M; | ||||
if( &A == &B ) | ||||
{ | ||||
// We can do it directly! | ||||
return op_dot::direct_dot_arma(A.n_nonzero, A.values, A.values); | ||||
} | ||||
else | ||||
{ | ||||
return priv::dot_helper(pa,pb); | ||||
} | ||||
} | ||||
else | ||||
{ | ||||
return priv::dot_helper(pa,pb); | ||||
} | ||||
} | } | |||
//! dot product of one dense and one sparse object | //! dot product of one dense and one sparse object | |||
template<typename T1, typename T2> | template<typename T1, typename T2> | |||
inline | ||||
arma_warn_unused | arma_warn_unused | |||
arma_hot | ||||
inline | ||||
typename | typename | |||
enable_if2 | enable_if2 | |||
<(is_arma_type<T1>::value) && (is_arma_sparse_type<T2>::value) && (is_sam e_type<typename T1::elem_type, typename T2::elem_type>::value), | <(is_arma_type<T1>::value) && (is_arma_sparse_type<T2>::value) && (is_sam e_type<typename T1::elem_type, typename T2::elem_type>::value), | |||
typename T1::elem_type | typename T1::elem_type | |||
>::result | >::result | |||
dot | dot | |||
( | ( | |||
const Base<typename T1::elem_type, T1>& x, | const T1& x, | |||
const SpBase<typename T2::elem_type, T2>& y | const T2& y | |||
) | ) | |||
{ | { | |||
arma_extra_debug_sigprint(); | arma_extra_debug_sigprint(); | |||
const Proxy<T1> pa(x.get_ref()); | const Proxy<T1> pa(x); | |||
const SpProxy<T2> pb(y.get_ref()); | const SpProxy<T2> pb(y); | |||
arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_ro ws(), pb.get_n_cols(), "dot()"); | arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_ro ws(), pb.get_n_cols(), "dot()"); | |||
typedef typename T1::elem_type eT; | typedef typename T1::elem_type eT; | |||
eT result = eT(0); | eT result = eT(0); | |||
typename SpProxy<T2>::const_iterator_type it = pb.begin(); | typename SpProxy<T2>::const_iterator_type it = pb.begin(); | |||
typename SpProxy<T2>::const_iterator_type it_end = pb.end(); | ||||
// prefer_at_accessor won't save us operations | // prefer_at_accessor won't save us operations | |||
while(it != pb.end()) | while(it != it_end) | |||
{ | { | |||
result += (*it) * pa.at(it.row(), it.col()); | result += (*it) * pa.at(it.row(), it.col()); | |||
++it; | ++it; | |||
} | } | |||
return result; | return result; | |||
} | } | |||
//! dot product of one sparse and one dense object | ||||
template<typename T1, typename T2> | ||||
arma_warn_unused | ||||
arma_hot | ||||
inline | ||||
typename | ||||
enable_if2 | ||||
<(is_arma_sparse_type<T1>::value) && (is_arma_type<T2>::value) && (is_sam | ||||
e_type<typename T1::elem_type, typename T2::elem_type>::value), | ||||
typename T1::elem_type | ||||
>::result | ||||
dot | ||||
( | ||||
const T1& x, | ||||
const T2& y | ||||
) | ||||
{ | ||||
arma_extra_debug_sigprint(); | ||||
// this is commutative | ||||
return dot(y, x); | ||||
} | ||||
//! @} | //! @} | |||
End of changes. 20 change blocks. | ||||
49 lines changed or deleted | 97 lines changed or added | |||
fn_trace.hpp | fn_trace.hpp | |||
---|---|---|---|---|
// Copyright (C) 2008-2010 NICTA (www.nicta.com.au) | // Copyright (C) 2008-2012 NICTA (www.nicta.com.au) | |||
// Copyright (C) 2008-2010 Conrad Sanderson | // Copyright (C) 2008-2012 Conrad Sanderson | |||
// Copyright (C) 2012 Ryan Curtin | // Copyright (C) 2012 Ryan Curtin | |||
// | // | |||
// This file is part of the Armadillo C++ library. | // This file is part of the Armadillo C++ library. | |||
// It is provided without any warranty of fitness | // It is provided without any warranty of fitness | |||
// for any purpose. You can redistribute this file | // for any purpose. You can redistribute this file | |||
// and/or modify it under the terms of the GNU | // and/or modify it under the terms of the GNU | |||
// Lesser General Public License (LGPL) as published | // Lesser General Public License (LGPL) as published | |||
// by the Free Software Foundation, either version 3 | // by the Free Software Foundation, either version 3 | |||
// of the License or (at your option) any later version. | // of the License or (at your option) any later version. | |||
// (see http://www.opensource.org/licenses for more info) | // (see http://www.opensource.org/licenses for more info) | |||
//! \addtogroup fn_trace | //! \addtogroup fn_trace | |||
//! @{ | //! @{ | |||
//! Immediate trace (sum of diagonal elements) of a square dense matrix | //! Immediate trace (sum of diagonal elements) of a square dense matrix | |||
template<typename T1> | template<typename T1> | |||
inline | arma_hot | |||
arma_warn_unused | arma_warn_unused | |||
typename T1::elem_type | inline | |||
trace(const Base<typename T1::elem_type,T1>& X) | typename enable_if2<is_arma_type<T1>::value, typename T1::elem_type>::resul | |||
t | ||||
trace(const T1& X) | ||||
{ | { | |||
arma_extra_debug_sigprint(); | arma_extra_debug_sigprint(); | |||
typedef typename T1::elem_type eT; | typedef typename T1::elem_type eT; | |||
const Proxy<T1> A(X.get_ref()); | const Proxy<T1> A(X); | |||
arma_debug_check( (A.get_n_rows() != A.get_n_cols()), "trace(): matrix mu st be square sized" ); | arma_debug_check( (A.get_n_rows() != A.get_n_cols()), "trace(): matrix mu st be square sized" ); | |||
const uword N = A.get_n_rows(); | const uword N = A.get_n_rows(); | |||
eT val = eT(0); | ||||
for(uword i=0; i<N; ++i) | eT val1 = eT(0); | |||
eT val2 = eT(0); | ||||
uword i,j; | ||||
for(i=0, j=1; j<N; i+=2, j+=2) | ||||
{ | { | |||
val += A.at(i,i); | val1 += A.at(i,i); | |||
val2 += A.at(j,j); | ||||
} | } | |||
return val; | if(i < N) | |||
{ | ||||
val1 += A.at(i,i); | ||||
} | ||||
return val1 + val2; | ||||
} | } | |||
template<typename T1> | template<typename T1> | |||
inline | arma_hot | |||
arma_warn_unused | arma_warn_unused | |||
inline | ||||
typename T1::elem_type | typename T1::elem_type | |||
trace(const Op<T1, op_diagmat>& X) | trace(const Op<T1, op_diagmat>& X) | |||
{ | { | |||
arma_extra_debug_sigprint(); | arma_extra_debug_sigprint(); | |||
typedef typename T1::elem_type eT; | typedef typename T1::elem_type eT; | |||
const diagmat_proxy<T1> A(X.m); | const diagmat_proxy<T1> A(X.m); | |||
const uword N = A.n_elem; | const uword N = A.n_elem; | |||
skipping to change at line 69 | skipping to change at line 80 | |||
for(uword i=0; i<N; ++i) | for(uword i=0; i<N; ++i) | |||
{ | { | |||
val += A[i]; | val += A[i]; | |||
} | } | |||
return val; | return val; | |||
} | } | |||
//! speedup for trace(A*B), where the result of A*B is a square sized matri x | //! speedup for trace(A*B), where the result of A*B is a square sized matri x | |||
template<typename T1, typename T2> | template<typename T1, typename T2> | |||
arma_hot | ||||
inline | inline | |||
arma_warn_unused | ||||
typename T1::elem_type | typename T1::elem_type | |||
trace(const Glue<T1, T2, glue_times>& X) | trace_mul_unwrap(const T1& XA, const T2& XB) | |||
{ | { | |||
arma_extra_debug_sigprint(); | arma_extra_debug_sigprint(); | |||
typedef typename T1::elem_type eT; | typedef typename T1::elem_type eT; | |||
const unwrap<T1> tmp1(X.A); | const Proxy<T1> PA(XA); | |||
const unwrap<T2> tmp2(X.B); | const unwrap<T2> tmpB(XB); | |||
const Mat<eT>& A = tmp1.M; | const Mat<eT>& B = tmpB.M; | |||
const Mat<eT>& B = tmp2.M; | ||||
arma_debug_assert_mul_size(A, B, "matrix multiply"); | arma_debug_assert_mul_size(PA.get_n_rows(), PA.get_n_cols(), B.n_rows, B. n_cols, "matrix multiply"); | |||
arma_debug_check( (A.n_rows != B.n_cols), "trace(): matrix must be square sized" ); | arma_debug_check( (PA.get_n_rows() != B.n_cols), "trace(): matrix must be square sized" ); | |||
const uword N1 = A.n_rows; | const uword N1 = PA.get_n_rows(); // equivalent to B.n_cols, due to squ | |||
const uword N2 = A.n_cols; | are size requirements | |||
eT val = eT(0); | const uword N2 = PA.get_n_cols(); // equivalent to B.n_rows, due to mat | |||
rix multiplication requirements | ||||
eT val = eT(0); | ||||
for(uword i=0; i<N1; ++i) | for(uword i=0; i<N1; ++i) | |||
{ | { | |||
const eT* B_colmem = B.colptr(i); | const eT* B_colmem = B.colptr(i); | |||
eT acc = eT(0); | ||||
for(uword j=0; j<N2; ++j) | eT acc1 = eT(0); | |||
eT acc2 = eT(0); | ||||
uword j,k; | ||||
for(j=0, k=1; k < N2; j+=2, k+=2) | ||||
{ | ||||
const eT tmp_j = B_colmem[j]; | ||||
const eT tmp_k = B_colmem[k]; | ||||
acc1 += PA.at(i,j) * tmp_j; | ||||
acc2 += PA.at(i,k) * tmp_k; | ||||
} | ||||
if(j < N2) | ||||
{ | ||||
acc1 += PA.at(i,j) * B_colmem[j]; | ||||
} | ||||
val += (acc1 + acc2); | ||||
} | ||||
return val; | ||||
} | ||||
//! speedup for trace(A*B), where the result of A*B is a square sized matri | ||||
x | ||||
template<typename T1, typename T2> | ||||
arma_hot | ||||
inline | ||||
typename T1::elem_type | ||||
trace_mul_proxy(const T1& XA, const T2& XB) | ||||
{ | ||||
arma_extra_debug_sigprint(); | ||||
typedef typename T1::elem_type eT; | ||||
const Proxy<T1> PA(XA); | ||||
const Proxy<T2> PB(XB); | ||||
if(is_Mat<typename Proxy<T2>::stored_type>::value == true) | ||||
{ | ||||
return trace_mul_unwrap(PA.Q, PB.Q); | ||||
} | ||||
arma_debug_assert_mul_size(PA.get_n_rows(), PA.get_n_cols(), PB.get_n_row | ||||
s(), PB.get_n_cols(), "matrix multiply"); | ||||
arma_debug_check( (PA.get_n_rows() != PB.get_n_cols()), "trace(): matrix | ||||
must be square sized" ); | ||||
const uword N1 = PA.get_n_rows(); // equivalent to PB.get_n_cols(), due | ||||
to square size requirements | ||||
const uword N2 = PA.get_n_cols(); // equivalent to PB.get_n_rows(), due | ||||
to matrix multiplication requirements | ||||
eT val = eT(0); | ||||
for(uword i=0; i<N1; ++i) | ||||
{ | ||||
eT acc1 = eT(0); | ||||
eT acc2 = eT(0); | ||||
uword j,k; | ||||
for(j=0, k=1; k < N2; j+=2, k+=2) | ||||
{ | { | |||
acc += A.at(i,j) * B_colmem[j]; | const eT tmp_j = PB.at(j,i); | |||
const eT tmp_k = PB.at(k,i); | ||||
acc1 += PA.at(i,j) * tmp_j; | ||||
acc2 += PA.at(i,k) * tmp_k; | ||||
} | } | |||
val += acc; | if(j < N2) | |||
{ | ||||
acc1 += PA.at(i,j) * PB.at(j,i); | ||||
} | ||||
val += (acc1 + acc2); | ||||
} | } | |||
return val; | return val; | |||
} | } | |||
//! speedup for trace(A*B), where the result of A*B is a square sized matri | ||||
x | ||||
template<typename T1, typename T2> | ||||
arma_hot | ||||
arma_warn_unused | ||||
inline | ||||
typename T1::elem_type | ||||
trace(const Glue<T1, T2, glue_times>& X) | ||||
{ | ||||
arma_extra_debug_sigprint(); | ||||
return (is_Mat<T2>::value) ? trace_mul_unwrap(X.A, X.B) : trace_mul_proxy | ||||
(X.A, X.B); | ||||
} | ||||
//! trace of sparse object | //! trace of sparse object | |||
template<typename T1> | template<typename T1> | |||
inline | arma_hot | |||
arma_warn_unused | arma_warn_unused | |||
inline | ||||
typename enable_if2<is_arma_sparse_type<T1>::value, typename T1::elem_type> ::result | typename enable_if2<is_arma_sparse_type<T1>::value, typename T1::elem_type> ::result | |||
trace(const SpBase<typename T1::elem_type, T1>& x) | trace(const T1& x) | |||
{ | { | |||
arma_extra_debug_sigprint(); | arma_extra_debug_sigprint(); | |||
const SpProxy<T1> p(x.get_ref()); | const SpProxy<T1> p(x); | |||
arma_debug_check( (p.get_n_rows() != p.get_n_cols()), "trace(): matrix mu st be square sized" ); | arma_debug_check( (p.get_n_rows() != p.get_n_cols()), "trace(): matrix mu st be square sized" ); | |||
typedef typename T1::elem_type eT; | typedef typename T1::elem_type eT; | |||
eT result = eT(0); | eT result = eT(0); | |||
typename SpProxy<T1>::const_iterator_type it = p.begin(); | typename SpProxy<T1>::const_iterator_type it = p.begin(); | |||
typename SpProxy<T1>::const_iterator_type it_end = p.end(); | ||||
while(it != p.end()) | while(it != it_end) | |||
{ | { | |||
if(it.row() == it.col()) | if(it.row() == it.col()) | |||
{ | { | |||
result += (*it); | result += (*it); | |||
} | } | |||
++it; | ++it; | |||
} | } | |||
return result; | return result; | |||
End of changes. 29 change blocks. | ||||
32 lines changed or deleted | 134 lines changed or added | |||
forward_bones.hpp | forward_bones.hpp | |||
---|---|---|---|---|
skipping to change at line 62 | skipping to change at line 62 | |||
class op_max; | class op_max; | |||
class op_strans; | class op_strans; | |||
class op_htrans; | class op_htrans; | |||
class op_htrans2; | class op_htrans2; | |||
class op_inv; | class op_inv; | |||
class op_sum; | class op_sum; | |||
class op_abs; | class op_abs; | |||
class op_diagmat; | class op_diagmat; | |||
class op_trimat; | class op_trimat; | |||
class op_diagvec; | ||||
class eop_conj; | class eop_conj; | |||
class glue_times; | class glue_times; | |||
class glue_times_diag; | class glue_times_diag; | |||
class glue_rel_lt; | class glue_rel_lt; | |||
class glue_rel_gt; | class glue_rel_gt; | |||
class glue_rel_lteq; | class glue_rel_lteq; | |||
class glue_rel_gteq; | class glue_rel_gteq; | |||
End of changes. 1 change blocks. | ||||
0 lines changed or deleted | 1 lines changed or added | |||
op_diagvec_bones.hpp | op_diagvec_bones.hpp | |||
---|---|---|---|---|
// Copyright (C) 2008-2010 NICTA (www.nicta.com.au) | // Copyright (C) 2008-2012 NICTA (www.nicta.com.au) | |||
// Copyright (C) 2008-2010 Conrad Sanderson | // Copyright (C) 2008-2012 Conrad Sanderson | |||
// | // | |||
// This file is part of the Armadillo C++ library. | // This file is part of the Armadillo C++ library. | |||
// It is provided without any warranty of fitness | // It is provided without any warranty of fitness | |||
// for any purpose. You can redistribute this file | // for any purpose. You can redistribute this file | |||
// and/or modify it under the terms of the GNU | // and/or modify it under the terms of the GNU | |||
// Lesser General Public License (LGPL) as published | // Lesser General Public License (LGPL) as published | |||
// by the Free Software Foundation, either version 3 | // by the Free Software Foundation, either version 3 | |||
// of the License or (at your option) any later version. | // of the License or (at your option) any later version. | |||
// (see http://www.opensource.org/licenses for more info) | // (see http://www.opensource.org/licenses for more info) | |||
//! \addtogroup op_diagvec | //! \addtogroup op_diagvec | |||
//! @{ | //! @{ | |||
class op_diagvec | class op_diagvec | |||
{ | { | |||
public: | public: | |||
template<typename T1> | template<typename T1> | |||
inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op _diagvec>& X); | inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op _diagvec>& X); | |||
template<typename T1> | ||||
arma_hot inline static void apply_unwrap(Mat<typename T1::elem_type>& out | ||||
, const T1& X, const uword row_offset, const uword col_offset, const | ||||
uword len); | ||||
template<typename T1> | ||||
arma_hot inline static void apply_proxy(Mat<typename T1::elem_type>& out, | ||||
const Proxy<T1>& P, const uword row_offset, const uword col_offset, const | ||||
uword len); | ||||
}; | }; | |||
//! @} | //! @} | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 12 lines changed or added | |||
op_diagvec_meat.hpp | op_diagvec_meat.hpp | |||
---|---|---|---|---|
// Copyright (C) 2008-2010 NICTA (www.nicta.com.au) | // Copyright (C) 2008-2012 NICTA (www.nicta.com.au) | |||
// Copyright (C) 2008-2010 Conrad Sanderson | // Copyright (C) 2008-2012 Conrad Sanderson | |||
// | // | |||
// This file is part of the Armadillo C++ library. | // This file is part of the Armadillo C++ library. | |||
// It is provided without any warranty of fitness | // It is provided without any warranty of fitness | |||
// for any purpose. You can redistribute this file | // for any purpose. You can redistribute this file | |||
// and/or modify it under the terms of the GNU | // and/or modify it under the terms of the GNU | |||
// Lesser General Public License (LGPL) as published | // Lesser General Public License (LGPL) as published | |||
// by the Free Software Foundation, either version 3 | // by the Free Software Foundation, either version 3 | |||
// of the License or (at your option) any later version. | // of the License or (at your option) any later version. | |||
// (see http://www.opensource.org/licenses for more info) | // (see http://www.opensource.org/licenses for more info) | |||
skipping to change at line 25 | skipping to change at line 25 | |||
template<typename T1> | template<typename T1> | |||
inline | inline | |||
void | void | |||
op_diagvec::apply(Mat<typename T1::elem_type>& out, const Op<T1, op_diagvec >& X) | op_diagvec::apply(Mat<typename T1::elem_type>& out, const Op<T1, op_diagvec >& X) | |||
{ | { | |||
arma_extra_debug_sigprint(); | arma_extra_debug_sigprint(); | |||
typedef typename T1::elem_type eT; | typedef typename T1::elem_type eT; | |||
const sword id = (X.aux_uword_b > 0) ? -sword(X.aux_uword_a) : sword(X.au | const uword a = X.aux_uword_a; | |||
x_uword_a); | const uword b = X.aux_uword_b; | |||
const unwrap_check<T1> tmp(X.m, out); | const uword row_offset = (b > 0) ? a : 0; | |||
const Mat<eT>& A = tmp.M; | const uword col_offset = (b == 0) ? a : 0; | |||
out = A.diag(id); | const Proxy<T1> P(X.m); | |||
const uword n_rows = P.get_n_rows(); | ||||
const uword n_cols = P.get_n_cols(); | ||||
arma_debug_check | ||||
( | ||||
((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (c | ||||
ol_offset >= n_cols)), | ||||
"diagvec(): requested diagonal is out of bounds" | ||||
); | ||||
const uword len = (std::min)(n_rows - row_offset, n_cols - col_offset); | ||||
if(is_Mat<typename Proxy<T1>::stored_type>::value) | ||||
{ | ||||
op_diagvec::apply_unwrap(out, P.Q, row_offset, col_offset, len); | ||||
} | ||||
else | ||||
{ | ||||
if(P.is_alias(out) == false) | ||||
{ | ||||
op_diagvec::apply_proxy(out, P, row_offset, col_offset, len); | ||||
} | ||||
else | ||||
{ | ||||
Mat<eT> tmp; | ||||
op_diagvec::apply_proxy(tmp, P, row_offset, col_offset, len); | ||||
out.steal_mem(tmp); | ||||
} | ||||
} | ||||
} | ||||
template<typename T1> | ||||
arma_hot | ||||
inline | ||||
void | ||||
op_diagvec::apply_unwrap(Mat<typename T1::elem_type>& out, const T1& X, con | ||||
st uword row_offset, const uword col_offset, const uword len) | ||||
{ | ||||
arma_extra_debug_sigprint(); | ||||
typedef typename T1::elem_type eT; | ||||
const unwrap_check<T1> tmp_A(X, out); | ||||
const Mat<eT>& A = tmp_A.M; | ||||
out.set_size(len, 1); | ||||
eT* out_mem = out.memptr(); | ||||
uword i,j; | ||||
for(i=0, j=1; j < len; i+=2, j+=2) | ||||
{ | ||||
const eT tmp_i = A.at( i + row_offset, i + col_offset ); | ||||
const eT tmp_j = A.at( j + row_offset, j + col_offset ); | ||||
out_mem[i] = tmp_i; | ||||
out_mem[j] = tmp_j; | ||||
} | ||||
if(i < len) | ||||
{ | ||||
out_mem[i] = A.at( i + row_offset, i + col_offset ); | ||||
} | ||||
} | ||||
template<typename T1> | ||||
arma_hot | ||||
inline | ||||
void | ||||
op_diagvec::apply_proxy(Mat<typename T1::elem_type>& out, const Proxy<T1>& | ||||
P, const uword row_offset, const uword col_offset, const uword len) | ||||
{ | ||||
arma_extra_debug_sigprint(); | ||||
typedef typename T1::elem_type eT; | ||||
out.set_size(len, 1); | ||||
eT* out_mem = out.memptr(); | ||||
uword i,j; | ||||
for(i=0, j=1; j < len; i+=2, j+=2) | ||||
{ | ||||
const eT tmp_i = P.at( i + row_offset, i + col_offset ); | ||||
const eT tmp_j = P.at( j + row_offset, j + col_offset ); | ||||
out_mem[i] = tmp_i; | ||||
out_mem[j] = tmp_j; | ||||
} | ||||
if(i < len) | ||||
{ | ||||
out_mem[i] = P.at( i + row_offset, i + col_offset ); | ||||
} | ||||
} | } | |||
//! @} | //! @} | |||
End of changes. 4 change blocks. | ||||
7 lines changed or deleted | 104 lines changed or added | |||
operator_div.hpp | operator_div.hpp | |||
---|---|---|---|---|
skipping to change at line 143 | skipping to change at line 143 | |||
return mtGlue<out_eT, T1, T2, glue_mixed_div>( X, Y ); | return mtGlue<out_eT, T1, T2, glue_mixed_div>( X, Y ); | |||
} | } | |||
//! element-wise division of sparse matrix by scalar | //! element-wise division of sparse matrix by scalar | |||
template<typename T1> | template<typename T1> | |||
inline | inline | |||
typename | typename | |||
enable_if2<is_arma_sparse_type<T1>::value, SpMat<typename T1::elem_type> >: :result | enable_if2<is_arma_sparse_type<T1>::value, SpMat<typename T1::elem_type> >: :result | |||
operator/ | operator/ | |||
( | ( | |||
const SpBase<typename T1::elem_type, T1>& X, | const T1& X, | |||
const typename T1::elem_type y | const typename T1::elem_type y | |||
) | ) | |||
{ | { | |||
arma_extra_debug_sigprint(); | arma_extra_debug_sigprint(); | |||
arma_debug_check(y == typename T1::elem_type(0), "element-wise division: division by zero"); | SpMat<typename T1::elem_type> result(X); | |||
SpMat<typename T1::elem_type> result(X.get_ref()); | result /= y; | |||
for(uword i = 0; i < result.n_nonzero; ++i) | ||||
{ | ||||
access::rw(result.values[i]) /= y; | ||||
} | ||||
return result; | return result; | |||
} | } | |||
// //! element-wise division of two sparse objects. what a bad idea | ||||
// template<typename T1, typename T2> | ||||
// inline | ||||
// typename | ||||
// enable_if2 | ||||
// < | ||||
// (is_arma_sparse_type<T1>::value && is_arma_sparse_type<T2>::value && | ||||
// is_same_type<typename T1::elem_type, typename T2::elem_type>::value), | ||||
// SpMat<typename T1::elem_type> | ||||
// >::result | ||||
// operator/ | ||||
// ( | ||||
// const SpBase<typename T1::elem_type, T1>& x, | ||||
// const SpBase<typename T2::elem_type, T2>& y | ||||
// ) | ||||
// { | ||||
// arma_extra_debug_sigprint(); | ||||
// | ||||
// const SpProxy<T1> pa(x.get_ref()); | ||||
// const SpProxy<T2> pb(y.get_ref()); | ||||
// | ||||
// arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n | ||||
_rows(), pb.get_n_cols(), "element-wise division"); | ||||
// | ||||
// SpMat<typename T1::elem_type> result(pa.get_n_rows(), pa.get_n_cols()) | ||||
; | ||||
// | ||||
// // terrible | ||||
// for(uword i = 0; i < result.n_elem; ++i) | ||||
// { | ||||
// result[i] = (pa[i] / pb[i]); | ||||
// } | ||||
// | ||||
// return result; | ||||
// } | ||||
//! element-wise division of one sparse and one dense object | //! element-wise division of one sparse and one dense object | |||
template<typename T1, typename T2> | template<typename T1, typename T2> | |||
inline | inline | |||
typename | typename | |||
enable_if2 | enable_if2 | |||
< | < | |||
(is_arma_sparse_type<T1>::value && is_arma_type<T2>::value && is_same_typ e<typename T1::elem_type, typename T2::elem_type>::value), | (is_arma_sparse_type<T1>::value && is_arma_type<T2>::value && is_same_typ e<typename T1::elem_type, typename T2::elem_type>::value), | |||
SpMat<typename T1::elem_type> | SpMat<typename T1::elem_type> | |||
>::result | >::result | |||
operator/ | operator/ | |||
( | ( | |||
const SpBase<typename T1::elem_type, T1>& x, | const T1& x, | |||
const Base<typename T2::elem_type, T2>& y | const T2& y | |||
) | ) | |||
{ | { | |||
arma_extra_debug_sigprint(); | arma_extra_debug_sigprint(); | |||
const SpProxy<T1> pa(x.get_ref()); | typedef typename T1::elem_type eT; | |||
const Proxy<T2> pb(y.get_ref()); | ||||
const SpProxy<T1> pa(x); | ||||
const Proxy<T2> pb(y); | ||||
const uword n_rows = pa.get_n_rows(); | ||||
const uword n_cols = pa.get_n_cols(); | ||||
arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_ro ws(), pb.get_n_cols(), "element-wise division"); | arma_debug_assert_same_size(n_rows, n_cols, pb.get_n_rows(), pb.get_n_col s(), "element-wise division"); | |||
SpMat<typename T1::elem_type> result(pa.get_n_rows(), pa.get_n_cols()); | SpMat<eT> result(n_rows, n_cols); | |||
// The compiler should be smart enough to optimize out the inner if/else | ||||
statement entirely | ||||
typename SpProxy<T1>::const_iterator_type it = pa.begin(); | ||||
uword new_n_nonzero = 0; | uword new_n_nonzero = 0; | |||
while(it != pa.end()) | ||||
for(uword col=0; col < n_cols; ++col) | ||||
for(uword row=0; row < n_rows; ++row) | ||||
{ | { | |||
if(Proxy<T2>::prefer_at_accessor == false) | const eT val = pa.at(row,col) / pb.at(row, col); | |||
{ | ||||
const typename T1::elem_type val = (*it) / pb[(it.col() * pb.get_n_ro | if(val != eT(0)) | |||
ws()) + it.row()]; | ||||
if(val != 0) | ||||
{ | ||||
++new_n_nonzero; | ||||
} | ||||
} | ||||
else | ||||
{ | { | |||
const typename T1::elem_type val = (*it) / pb.at(it.row(), it.col()); | ++new_n_nonzero; | |||
if(val != 0) | ||||
{ | ||||
++new_n_nonzero; | ||||
} | ||||
} | } | |||
++it; | ||||
} | } | |||
result.mem_resize(new_n_nonzero); | result.mem_resize(new_n_nonzero); | |||
typename SpProxy<T1>::const_iterator_type it2 = pa.begin(); | ||||
uword cur_pos = 0; | uword cur_pos = 0; | |||
while(it2 != pa.end()) | ||||
for(uword col=0; col < n_cols; ++col) | ||||
for(uword row=0; row < n_rows; ++row) | ||||
{ | { | |||
if(Proxy<T2>::prefer_at_accessor == false) | const eT val = pa.at(row,col) / pb.at(row, col); | |||
{ | ||||
const typename T1::elem_type val = (*it2) / pb[(it2.col() * pb.get_n_ | if(val != eT(0)) | |||
rows()) + it2.row()]; | ||||
if(val != 0) | ||||
{ | ||||
access::rw(result.values[cur_pos]) = val; | ||||
access::rw(result.row_indices[cur_pos]) = it2.row(); | ||||
++access::rw(result.col_ptrs[it2.col() + 1]); | ||||
++cur_pos; | ||||
} | ||||
} | ||||
else | ||||
{ | { | |||
const typename T1::elem_type val = (*it2) / pb.at(it2.row(), it2.col( | access::rw(result.values[cur_pos]) = val; | |||
)); | access::rw(result.row_indices[cur_pos]) = row; | |||
if(val != 0) | ++access::rw(result.col_ptrs[col + 1]); | |||
{ | ++cur_pos; | |||
access::rw(result.values[cur_pos]) = val; | ||||
access::rw(result.row_indices[cur_pos]) = it2.row(); | ||||
++access::rw(result.col_ptrs[it2.col() + 1]); | ||||
++cur_pos; | ||||
} | ||||
} | } | |||
++it2; | ||||
} | } | |||
// Fix column pointers | // Fix column pointers | |||
for(uword col = 1; col <= result.n_cols; ++col) | for(uword col = 1; col <= result.n_cols; ++col) | |||
{ | { | |||
access::rw(result.col_ptrs[col]) += result.col_ptrs[col - 1]; | access::rw(result.col_ptrs[col]) += result.col_ptrs[col - 1]; | |||
} | } | |||
return result; | return result; | |||
} | } | |||
skipping to change at line 296 | skipping to change at line 236 | |||
template<typename T1, typename T2> | template<typename T1, typename T2> | |||
inline | inline | |||
typename | typename | |||
enable_if2 | enable_if2 | |||
< | < | |||
(is_arma_type<T1>::value && is_arma_sparse_type<T2>::value && is_same_typ e<typename T1::elem_type, typename T2::elem_type>::value), | (is_arma_type<T1>::value && is_arma_sparse_type<T2>::value && is_same_typ e<typename T1::elem_type, typename T2::elem_type>::value), | |||
Mat<typename T1::elem_type> | Mat<typename T1::elem_type> | |||
>::result | >::result | |||
operator/ | operator/ | |||
( | ( | |||
const Base<typename T1::elem_type, T1>& x, | const T1& x, | |||
const SpBase<typename T2::elem_type, T2>& y | const T2& y | |||
) | ) | |||
{ | { | |||
arma_extra_debug_sigprint(); | arma_extra_debug_sigprint(); | |||
const Proxy<T1> pa(x.get_ref()); | typedef typename T1::elem_type eT; | |||
const SpProxy<T2> pb(y.get_ref()); | ||||
arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_ro | const Proxy<T1> pa(x); | |||
ws(), pb.get_n_cols(), "element-wise division"); | const SpProxy<T2> pb(y); | |||
Mat<typename T1::elem_type> result(pa.get_n_rows(), pa.get_n_cols()); | const uword n_rows = pa.get_n_rows(); | |||
const uword n_cols = pa.get_n_cols(); | ||||
result.fill(Datum<typename T1::elem_type>::inf); | arma_debug_assert_same_size(n_rows, n_cols, pb.get_n_rows(), pb.get_n_col s(), "element-wise division"); | |||
// Now divide each element | Mat<eT> result(n_rows, n_cols); | |||
typename SpProxy<T2>::const_iterator_type it = pb.begin(); | ||||
while(it != pb.end()) | for(uword col=0; col < n_cols; ++col) | |||
for(uword row=0; row < n_rows; ++row) | ||||
{ | { | |||
if(Proxy<T1>::prefer_at_accessor == false) | result.at(row, col) = pa.at(row, col) / pb.at(row, col); | |||
{ | ||||
const uword index = (it.col() * result.n_rows) + it.row(); | ||||
result[index] = pa[index] / (*it); | ||||
} | ||||
else | ||||
{ | ||||
result.at(it.row(), it.col()) = pa.at(it.row(), it.col()) / (*it); | ||||
} | ||||
++it; | ||||
} | } | |||
return result; | return result; | |||
} | } | |||
//! @} | //! @} | |||
End of changes. 26 change blocks. | ||||
119 lines changed or deleted | 43 lines changed or added | |||
operator_minus.hpp | operator_minus.hpp | |||
---|---|---|---|---|
skipping to change at line 192 | skipping to change at line 192 | |||
template<typename T1, typename T2> | template<typename T1, typename T2> | |||
inline | inline | |||
typename | typename | |||
enable_if2 | enable_if2 | |||
< | < | |||
(is_arma_sparse_type<T1>::value && is_arma_type<T2>::value && is_same_typ e<typename T1::elem_type, typename T2::elem_type>::value), | (is_arma_sparse_type<T1>::value && is_arma_type<T2>::value && is_same_typ e<typename T1::elem_type, typename T2::elem_type>::value), | |||
Mat<typename T1::elem_type> | Mat<typename T1::elem_type> | |||
>::result | >::result | |||
operator- | operator- | |||
( | ( | |||
const SpBase<typename T1::elem_type, T1>& x, | const T1& x, | |||
const Base<typename T2::elem_type, T2>& y | const T2& y | |||
) | ) | |||
{ | { | |||
arma_extra_debug_sigprint(); | arma_extra_debug_sigprint(); | |||
Mat<typename T1::elem_type> result(-y.get_ref()); | const SpProxy<T1> pa(x); | |||
const SpProxy<T1> pa(x.get_ref()); | Mat<typename T1::elem_type> result(-y); | |||
arma_debug_assert_same_size( pa.get_n_rows(), pa.get_n_cols(), result.n_r ows, result.n_cols, "subtraction" ); | arma_debug_assert_same_size( pa.get_n_rows(), pa.get_n_cols(), result.n_r ows, result.n_cols, "subtraction" ); | |||
typename SpProxy<T1>::const_iterator_type it = pa.begin(); | typename SpProxy<T1>::const_iterator_type it = pa.begin(); | |||
typename SpProxy<T1>::const_iterator_type it_end = pa.end(); | ||||
while(it != pa.end()) | while(it != it_end) | |||
{ | { | |||
const uword pos = it.col() * pa.get_n_cols() + it.row(); | result.at(it.row(), it.col()) += (*it); | |||
result[pos] += (*it); | ||||
++it; | ++it; | |||
} | } | |||
return result; | return result; | |||
} | } | |||
//! subtraction of one dense and one sparse object | //! subtraction of one dense and one sparse object | |||
template<typename T1, typename T2> | template<typename T1, typename T2> | |||
inline | inline | |||
typename | typename | |||
enable_if2 | enable_if2 | |||
< | < | |||
(is_arma_type<T1>::value && is_arma_sparse_type<T2>::value && is_same_typ e<typename T1::elem_type, typename T2::elem_type>::value), | (is_arma_type<T1>::value && is_arma_sparse_type<T2>::value && is_same_typ e<typename T1::elem_type, typename T2::elem_type>::value), | |||
Mat<typename T1::elem_type> | Mat<typename T1::elem_type> | |||
>::result | >::result | |||
operator- | operator- | |||
( | ( | |||
const Base<typename T1::elem_type, T1>& x, | const T1& x, | |||
const SpBase<typename T2::elem_type, T2>& y | const T2& y | |||
) | ) | |||
{ | { | |||
arma_extra_debug_sigprint(); | arma_extra_debug_sigprint(); | |||
Mat<typename T1::elem_type> result(x.get_ref()); | Mat<typename T1::elem_type> result(x); | |||
const SpProxy<T2> pb(y.get_ref()); | const SpProxy<T2> pb(y.get_ref()); | |||
arma_debug_assert_same_size( result.n_rows, result.n_cols, pb.get_n_rows( ), pb.get_n_cols(), "subtraction" ); | arma_debug_assert_same_size( result.n_rows, result.n_cols, pb.get_n_rows( ), pb.get_n_cols(), "subtraction" ); | |||
typename SpProxy<T2>::const_iterator_type it = pb.begin(); | typename SpProxy<T2>::const_iterator_type it = pb.begin(); | |||
typename SpProxy<T2>::const_iterator_type it_end = pb.end(); | ||||
while(it != pb.end()) | while(it != it_end) | |||
{ | { | |||
const uword pos = it.col() * pb.get_n_cols() + it.row(); | result.at(it.row(), it.col()) -= (*it); | |||
result[pos] -= (*it); | ||||
++it; | ++it; | |||
} | } | |||
return result; | return result; | |||
} | } | |||
//! @} | //! @} | |||
End of changes. 11 change blocks. | ||||
15 lines changed or deleted | 15 lines changed or added | |||
operator_plus.hpp | operator_plus.hpp | |||
---|---|---|---|---|
skipping to change at line 163 | skipping to change at line 163 | |||
const T2& y | const T2& y | |||
) | ) | |||
{ | { | |||
arma_extra_debug_sigprint(); | arma_extra_debug_sigprint(); | |||
return SpGlue<T1,T2,spglue_plus>(x, y); | return SpGlue<T1,T2,spglue_plus>(x, y); | |||
} | } | |||
//! addition of sparse and non-sparse object | //! addition of sparse and non-sparse object | |||
template<typename T1, typename T2> | template<typename T1, typename T2> | |||
arma_inline | inline | |||
typename | typename | |||
enable_if2 | enable_if2 | |||
< | < | |||
(is_arma_sparse_type<T1>::value && is_arma_type<T2>::value && is_same_typ e<typename T1::elem_type, typename T2::elem_type>::value), | (is_arma_type<T1>::value && is_arma_sparse_type<T2>::value && is_same_typ e<typename T1::elem_type, typename T2::elem_type>::value), | |||
Mat<typename T1::elem_type> | Mat<typename T1::elem_type> | |||
>::result | >::result | |||
operator+ | operator+ | |||
( | ( | |||
const SpBase<typename T1::elem_type, T1>& x, | const T1& x, | |||
const Base<typename T2::elem_type, T2>& y | const T2& y | |||
) | ) | |||
{ | { | |||
// Just call the other order (these operations are commutative) | arma_extra_debug_sigprint(); | |||
return (y + x); | ||||
Mat<typename T1::elem_type> result(x); | ||||
const SpProxy<T2> pb(y); | ||||
arma_debug_assert_same_size( result.n_rows, result.n_cols, pb.get_n_rows( | ||||
), pb.get_n_cols(), "addition" ); | ||||
typename SpProxy<T2>::const_iterator_type it = pb.begin(); | ||||
typename SpProxy<T2>::const_iterator_type it_end = pb.end(); | ||||
while(it != it_end) | ||||
{ | ||||
result.at(it.row(), it.col()) += (*it); | ||||
++it; | ||||
} | ||||
return result; | ||||
} | } | |||
//! addition of sparse and non-sparse object | //! addition of sparse and non-sparse object | |||
template<typename T1, typename T2> | template<typename T1, typename T2> | |||
inline | inline | |||
typename | typename | |||
enable_if2 | enable_if2 | |||
< | < | |||
(is_arma_type<T1>::value && is_arma_sparse_type<T2>::value && is_same_typ e<typename T1::elem_type, typename T2::elem_type>::value), | (is_arma_sparse_type<T1>::value && is_arma_type<T2>::value && is_same_typ e<typename T1::elem_type, typename T2::elem_type>::value), | |||
Mat<typename T1::elem_type> | Mat<typename T1::elem_type> | |||
>::result | >::result | |||
operator+ | operator+ | |||
( | ( | |||
const Base<typename T1::elem_type, T1>& x, | const T1& x, | |||
const SpBase<typename T2::elem_type, T2>& y | const T2& y | |||
) | ) | |||
{ | { | |||
arma_extra_debug_sigprint(); | arma_extra_debug_sigprint(); | |||
Mat<typename T1::elem_type> result(x.get_ref()); | // Just call the other order (these operations are commutative) | |||
return (y + x); | ||||
const SpProxy<T2> pb(y.get_ref()); | ||||
arma_debug_assert_same_size( result.n_rows, result.n_cols, pb.get_n_rows( | ||||
), pb.get_n_cols(), "addition" ); | ||||
typename SpProxy<T2>::const_iterator_type it = pb.begin(); | ||||
while(it != pb.end()) | ||||
{ | ||||
const uword pos = it.col() * pb.get_n_cols() + it.row(); | ||||
result[pos] += (*it); | ||||
++it; | ||||
} | ||||
return result; | ||||
} | } | |||
//! @} | //! @} | |||
End of changes. 7 change blocks. | ||||
26 lines changed or deleted | 28 lines changed or added | |||
operator_schur.hpp | operator_schur.hpp | |||
---|---|---|---|---|
skipping to change at line 151 | skipping to change at line 151 | |||
// Fix column pointers to be cumulative. | // Fix column pointers to be cumulative. | |||
for(uword c = 1; c <= result.n_cols; ++c) | for(uword c = 1; c <= result.n_cols; ++c) | |||
{ | { | |||
access::rw(result.col_ptrs[c]) += result.col_ptrs[c - 1]; | access::rw(result.col_ptrs[c]) += result.col_ptrs[c - 1]; | |||
} | } | |||
} | } | |||
return result; | return result; | |||
} | } | |||
//! element-wise multiplication of one sparse and one dense object | ||||
template<typename T1, typename T2> | ||||
inline | ||||
typename | ||||
enable_if2 | ||||
< | ||||
(is_arma_sparse_type<T1>::value && is_arma_type<T2>::value && is_same_typ | ||||
e<typename T1::elem_type, typename T2::elem_type>::value), | ||||
SpMat<typename T1::elem_type> | ||||
>::result | ||||
operator% | ||||
( | ||||
const SpBase<typename T1::elem_type, T1>& x, | ||||
const Base<typename T2::elem_type, T2>& y | ||||
) | ||||
{ | ||||
// This operation is commutative. | ||||
return (y % x); | ||||
} | ||||
//! element-wise multiplication of one dense and one sparse object | //! element-wise multiplication of one dense and one sparse object | |||
template<typename T1, typename T2> | template<typename T1, typename T2> | |||
inline | inline | |||
typename | typename | |||
enable_if2 | enable_if2 | |||
< | < | |||
(is_arma_type<T1>::value && is_arma_sparse_type<T2>::value && is_same_typ e<typename T1::elem_type, typename T2::elem_type>::value), | (is_arma_type<T1>::value && is_arma_sparse_type<T2>::value && is_same_typ e<typename T1::elem_type, typename T2::elem_type>::value), | |||
SpMat<typename T1::elem_type> | SpMat<typename T1::elem_type> | |||
>::result | >::result | |||
operator% | operator% | |||
( | ( | |||
const Base<typename T1::elem_type, T1>& x, | const T1& x, | |||
const SpBase<typename T2::elem_type, T2>& y | const T2& y | |||
) | ) | |||
{ | { | |||
arma_extra_debug_sigprint(); | arma_extra_debug_sigprint(); | |||
const Proxy<T1> pa(x.get_ref()); | typedef typename T1::elem_type eT; | |||
const SpProxy<T2> pb(y.get_ref()); | ||||
const Proxy<T1> pa(x); | ||||
const SpProxy<T2> pb(y); | ||||
arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_ro ws(), pb.get_n_cols(), "element-wise multiplication"); | arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_ro ws(), pb.get_n_cols(), "element-wise multiplication"); | |||
SpMat<typename T1::elem_type> result(pa.get_n_rows(), pa.get_n_cols()); | SpMat<eT> result(pa.get_n_rows(), pa.get_n_cols()); | |||
// count new size | ||||
uword new_n_nonzero = 0; | ||||
typename SpProxy<T2>::const_iterator_type it = pb.begin(); | ||||
typename SpProxy<T2>::const_iterator_type it_end = pb.end(); | ||||
if(Proxy<T1>::prefer_at_accessor == false) | while(it != it_end) | |||
{ | { | |||
// use direct operator[] access | if( ((*it) * pa.at(it.row(), it.col())) != eT(0) ) | |||
// count new size | ||||
uword new_n_nonzero = 0; | ||||
typename SpProxy<T2>::const_iterator_type it = pb.begin(); | ||||
while(it != pb.end()) | ||||
{ | { | |||
if(((*it) * pa[(it.col() * pa.get_n_rows()) + it.row()]) != 0) | ++new_n_nonzero; | |||
{ | ||||
++new_n_nonzero; | ||||
} | ||||
++it; | ||||
} | } | |||
// Resize memory accordingly. | ++it; | |||
result.mem_resize(new_n_nonzero); | } | |||
uword cur_val = 0; | // Resize memory accordingly. | |||
typename SpProxy<T2>::const_iterator_type it2 = pb.begin(); | result.mem_resize(new_n_nonzero); | |||
while(it2 != pb.end()) | ||||
{ | ||||
const typename T1::elem_type val = (*it2) * pa[(it2.col() * pa.get_n_ | ||||
rows()) + it2.row()]; | ||||
if(val != 0) | ||||
{ | ||||
access::rw(result.values[cur_val]) = val; | ||||
access::rw(result.row_indices[cur_val]) = it2.row(); | ||||
++access::rw(result.col_ptrs[it2.col() + 1]); | ||||
++cur_val; | ||||
} | ||||
++it2; | uword cur_val = 0; | |||
} | ||||
} | ||||
else | ||||
{ | ||||
// use at() access | ||||
// count new size | ||||
uword new_n_nonzero = 0; | ||||
typename SpProxy<T2>::const_iterator_type it = pb.begin(); | ||||
while(it != pb.end()) | ||||
{ | ||||
if(((*it) * pa.at(it.row(), it.col())) != 0) | ||||
{ | ||||
++new_n_nonzero; | ||||
} | ||||
++it; | typename SpProxy<T2>::const_iterator_type it2 = pb.begin(); | |||
} | ||||
// Resize memory accordingly. | while(it2 != it_end) | |||
result.mem_resize(new_n_nonzero); | { | |||
const uword it2_row = it2.row(); | ||||
const uword it2_col = it2.col(); | ||||
uword cur_val = 0; | const eT val = (*it2) * pa.at(it2_row, it2_col); | |||
typename SpProxy<T2>::const_iterator_type it2 = pb.begin(); | ||||
while(it2 != pb.end()) | ||||
{ | ||||
const typename T1::elem_type val = (*it2) * pa.at(it2.row(), it2.col( | ||||
)); | ||||
if(val != 0) | ||||
{ | ||||
access::rw(result.values[cur_val]) = val; | ||||
access::rw(result.row_indices[cur_val]) = it2.row(); | ||||
++access::rw(result.col_ptrs[it2.col() + 1]); | ||||
++cur_val; | ||||
} | ||||
++it2; | if(val != eT(0)) | |||
{ | ||||
access::rw(result.values[cur_val]) = val; | ||||
access::rw(result.row_indices[cur_val]) = it2_row; | ||||
++access::rw(result.col_ptrs[it2_col + 1]); | ||||
++cur_val; | ||||
} | } | |||
++it2; | ||||
} | } | |||
// Fix column pointers. | // Fix column pointers. | |||
for(uword c = 1; c <= result.n_cols; ++c) | for(uword c = 1; c <= result.n_cols; ++c) | |||
{ | { | |||
access::rw(result.col_ptrs[c]) += result.col_ptrs[c - 1]; | access::rw(result.col_ptrs[c]) += result.col_ptrs[c - 1]; | |||
} | } | |||
return result; | return result; | |||
} | } | |||
//! element-wise multiplication of one sparse and one dense object | ||||
template<typename T1, typename T2> | ||||
inline | ||||
typename | ||||
enable_if2 | ||||
< | ||||
(is_arma_sparse_type<T1>::value && is_arma_type<T2>::value && is_same_typ | ||||
e<typename T1::elem_type, typename T2::elem_type>::value), | ||||
SpMat<typename T1::elem_type> | ||||
>::result | ||||
operator% | ||||
( | ||||
const T1& x, | ||||
const T2& y | ||||
) | ||||
{ | ||||
arma_extra_debug_sigprint(); | ||||
// This operation is commutative. | ||||
return (y % x); | ||||
} | ||||
//! @} | //! @} | |||
End of changes. 16 change blocks. | ||||
85 lines changed or deleted | 57 lines changed or added | |||
operator_times.hpp | operator_times.hpp | |||
---|---|---|---|---|
skipping to change at line 425 | skipping to change at line 425 | |||
Mat<typename T1::elem_type> | Mat<typename T1::elem_type> | |||
>::result | >::result | |||
operator* | operator* | |||
( | ( | |||
const T1& x, | const T1& x, | |||
const T2& y | const T2& y | |||
) | ) | |||
{ | { | |||
arma_extra_debug_sigprint(); | arma_extra_debug_sigprint(); | |||
const SpProxy<T1> pa(x.get_ref()); | const SpProxy<T1> pa(x); | |||
const Proxy<T2> pb(y.get_ref()); | const Proxy<T2> pb(y); | |||
arma_debug_assert_mul_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_row s(), pb.get_n_cols(), "matrix multiplication"); | arma_debug_assert_mul_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_row s(), pb.get_n_cols(), "matrix multiplication"); | |||
Mat<typename T1::elem_type> result(pa.get_n_rows(), pb.get_n_cols()); | Mat<typename T1::elem_type> result(pa.get_n_rows(), pb.get_n_cols()); | |||
result.zeros(); | result.zeros(); | |||
if( (pa.get_n_nonzero() > 0) && (pb.get_n_elem() > 0) ) | if( (pa.get_n_nonzero() > 0) && (pb.get_n_elem() > 0) ) | |||
{ | { | |||
if(Proxy<T2>::prefer_at_accessor == false) | typename SpProxy<T1>::const_iterator_type x_it = pa.begin(); | |||
{ | typename SpProxy<T1>::const_iterator_type x_it_end = pa.end(); | |||
// use direct operator[] access | ||||
for(typename SpProxy<T1>::const_iterator_type x_it = pa.begin(); x_it | const uword result_n_cols = result.n_cols; | |||
!= pa.end(); x_it++) | ||||
{ | while(x_it != x_it_end) | |||
// We just want to use values where y.row = x_it.col. | ||||
for(uword col = 0; col < result.n_cols; col++) | ||||
{ | ||||
const uword index = x_it.col() + (pb.get_n_rows() * col); | ||||
result.at(x_it.row(), col) += (*x_it) * pb[index]; | ||||
} | ||||
} | ||||
} | ||||
else | ||||
{ | { | |||
// use at() access | for(uword col = 0; col < result_n_cols; ++col) | |||
for(typename SpProxy<T1>::const_iterator_type x_it = pa.begin(); x_it | ||||
!= pa.end(); x_it++) | ||||
{ | { | |||
for(uword col = 0; col < result.n_cols; col++) | result.at(x_it.row(), col) += (*x_it) * pb.at(x_it.col(), col); | |||
{ | ||||
result.at(x_it.row(), col) += (*x_it) * pb.at(x_it.col(), col); | ||||
} | ||||
} | } | |||
++x_it; | ||||
} | } | |||
} | } | |||
return result; | return result; | |||
} | } | |||
//! multiplication of one dense and one sparse object | //! multiplication of one dense and one sparse object | |||
template<typename T1, typename T2> | template<typename T1, typename T2> | |||
inline | inline | |||
typename | typename | |||
skipping to change at line 481 | skipping to change at line 471 | |||
Mat<typename T1::elem_type> | Mat<typename T1::elem_type> | |||
>::result | >::result | |||
operator* | operator* | |||
( | ( | |||
const T1& x, | const T1& x, | |||
const T2& y | const T2& y | |||
) | ) | |||
{ | { | |||
arma_extra_debug_sigprint(); | arma_extra_debug_sigprint(); | |||
const Proxy<T1> pa(x.get_ref()); | const Proxy<T1> pa(x); | |||
const SpProxy<T2> pb(y.get_ref()); | const SpProxy<T2> pb(y); | |||
arma_debug_assert_mul_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_row s(), pb.get_n_cols(), "matrix multiplication"); | arma_debug_assert_mul_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_row s(), pb.get_n_cols(), "matrix multiplication"); | |||
Mat<typename T1::elem_type> result(pa.get_n_rows(), pb.get_n_cols()); | Mat<typename T1::elem_type> result(pa.get_n_rows(), pb.get_n_cols()); | |||
result.zeros(); | result.zeros(); | |||
if( (pa.get_n_elem() > 0) && (pb.get_n_nonzero() > 0) ) | if( (pa.get_n_elem() > 0) && (pb.get_n_nonzero() > 0) ) | |||
{ | { | |||
if(Proxy<T1>::prefer_at_accessor == false) | typename SpProxy<T2>::const_iterator_type y_col_it = pb.begin(); | |||
{ | typename SpProxy<T2>::const_iterator_type y_col_it_end = pb.end(); | |||
// use direct operator[] access | ||||
for(typename SpProxy<T2>::const_iterator_type y_col_it = pb.begin(); | const uword result_n_rows = result.n_rows; | |||
y_col_it != pb.end(); ++y_col_it) | ||||
{ | while(y_col_it != y_col_it_end) | |||
for(uword row = 0; row < result.n_rows; ++row) | ||||
{ | ||||
const uword index = row + (y_col_it.row() * result.n_rows); | ||||
result.at(row, y_col_it.col()) += pa[index] * (*y_col_it); | ||||
} | ||||
} | ||||
} | ||||
else | ||||
{ | { | |||
// use at() access | for(uword row = 0; row < result_n_rows; ++row) | |||
for(typename SpProxy<T2>::const_iterator_type y_col_it = pb.begin(); | ||||
y_col_it != pb.end(); ++y_col_it) | ||||
{ | { | |||
for(uword row = 0; row < result.n_rows; ++row) | result.at(row, y_col_it.col()) += pa.at(row, y_col_it.row()) * (*y_ | |||
{ | col_it); | |||
result.at(row, y_col_it.col()) += pa.at(row, y_col_it.row()) * (* | ||||
y_col_it); | ||||
} | ||||
} | } | |||
++y_col_it; | ||||
} | } | |||
} | } | |||
return result; | return result; | |||
} | } | |||
//! @} | //! @} | |||
End of changes. 10 change blocks. | ||||
48 lines changed or deleted | 25 lines changed or added | |||
running_stat_meat.hpp | running_stat_meat.hpp | |||
---|---|---|---|---|
skipping to change at line 26 | skipping to change at line 26 | |||
template<typename eT> | template<typename eT> | |||
inline | inline | |||
arma_counter<eT>::~arma_counter() | arma_counter<eT>::~arma_counter() | |||
{ | { | |||
arma_extra_debug_sigprint_this(this); | arma_extra_debug_sigprint_this(this); | |||
} | } | |||
template<typename eT> | template<typename eT> | |||
inline | inline | |||
arma_counter<eT>::arma_counter() | arma_counter<eT>::arma_counter() | |||
: d_count( eT(0)) | : d_count( eT(0)) | |||
, i_count(uword(0)) | , i_count(uword(0)) | |||
{ | { | |||
arma_extra_debug_sigprint_this(this); | arma_extra_debug_sigprint_this(this); | |||
} | } | |||
template<typename eT> | template<typename eT> | |||
inline | inline | |||
const arma_counter<eT>& | const arma_counter<eT>& | |||
arma_counter<eT>::operator++() | arma_counter<eT>::operator++() | |||
{ | { | |||
if(i_count < ARMA_MAX_UWORD) | if(i_count < ARMA_MAX_UWORD) | |||
{ | { | |||
i_count++; | i_count++; | |||
} | } | |||
else | else | |||
{ | { | |||
d_count += eT(ARMA_MAX_UWORD); | d_count += eT(ARMA_MAX_UWORD); | |||
i_count = 0; | i_count = 1; | |||
} | } | |||
return *this; | return *this; | |||
} | } | |||
template<typename eT> | template<typename eT> | |||
inline | inline | |||
void | void | |||
arma_counter<eT>::operator++(int) | arma_counter<eT>::operator++(int) | |||
{ | { | |||
operator++(); | operator++(); | |||
} | } | |||
template<typename eT> | template<typename eT> | |||
inline | inline | |||
void | void | |||
arma_counter<eT>::reset() | arma_counter<eT>::reset() | |||
{ | { | |||
d_count = eT(0); | d_count = eT(0); | |||
i_count = uword(0); | i_count = uword(0); | |||
} | } | |||
template<typename eT> | template<typename eT> | |||
inline | inline | |||
eT | eT | |||
arma_counter<eT>::value() const | arma_counter<eT>::value() const | |||
{ | { | |||
return d_count + eT(i_count); | return d_count + eT(i_count); | |||
} | } | |||
End of changes. 3 change blocks. | ||||
3 lines changed or deleted | 3 lines changed or added | |||
subview_each_bones.hpp | subview_each_bones.hpp | |||
---|---|---|---|---|
skipping to change at line 94 | skipping to change at line 94 | |||
inline ~subview_each2(); | inline ~subview_each2(); | |||
// deliberately returning void | // deliberately returning void | |||
template<typename T1> inline void operator= (const Base<eT,T1>& x); | template<typename T1> inline void operator= (const Base<eT,T1>& x); | |||
template<typename T1> inline void operator+= (const Base<eT,T1>& x); | template<typename T1> inline void operator+= (const Base<eT,T1>& x); | |||
template<typename T1> inline void operator-= (const Base<eT,T1>& x); | template<typename T1> inline void operator-= (const Base<eT,T1>& x); | |||
template<typename T1> inline void operator%= (const Base<eT,T1>& x); | template<typename T1> inline void operator%= (const Base<eT,T1>& x); | |||
template<typename T1> inline void operator/= (const Base<eT,T1>& x); | template<typename T1> inline void operator/= (const Base<eT,T1>& x); | |||
// TODO: add handling of scalars | ||||
private: | private: | |||
friend class Mat<eT>; | friend class Mat<eT>; | |||
friend class subview<eT>; | friend class subview<eT>; | |||
subview_each2(); | subview_each2(); | |||
}; | }; | |||
//! @} | //! @} | |||
End of changes. 1 change blocks. | ||||
0 lines changed or deleted | 2 lines changed or added | |||