| SpMat_bones.hpp | | SpMat_bones.hpp | |
| | | | |
| skipping to change at line 122 | | skipping to change at line 122 | |
| inline const SpMat& operator-=(const SpMat& m); | | inline const SpMat& operator-=(const SpMat& m); | |
| inline const SpMat& operator*=(const SpMat& m); | | inline const SpMat& operator*=(const SpMat& m); | |
| inline const SpMat& operator%=(const SpMat& m); | | inline const SpMat& operator%=(const SpMat& m); | |
| inline const SpMat& operator/=(const SpMat& m); | | inline const SpMat& operator/=(const SpMat& m); | |
| | | | |
| /** | | /** | |
| * Operators on other regular matrices. These work as though you would e
xpect. | | * Operators on other regular matrices. These work as though you would e
xpect. | |
| */ | | */ | |
| template<typename T1> inline explicit SpMat(const Base<eT, T1>&
m); | | template<typename T1> inline explicit SpMat(const Base<eT, T1>&
m); | |
| template<typename T1> inline const SpMat& operator=(const Base<eT, T1>&
m); | | template<typename T1> inline const SpMat& operator=(const Base<eT, T1>&
m); | |
|
| | | template<typename T1> inline const SpMat& operator+=(const Base<eT, T1>& | |
| | | m); | |
| | | template<typename T1> inline const SpMat& operator-=(const Base<eT, T1>& | |
| | | m); | |
| template<typename T1> inline const SpMat& operator*=(const Base<eT, T1>&
m); | | template<typename T1> inline const SpMat& operator*=(const Base<eT, T1>&
m); | |
| template<typename T1> inline const SpMat& operator/=(const Base<eT, T1>&
m); | | template<typename T1> inline const SpMat& operator/=(const Base<eT, T1>&
m); | |
| template<typename T1> inline const SpMat& operator%=(const Base<eT, T1>&
m); | | template<typename T1> inline const SpMat& operator%=(const Base<eT, T1>&
m); | |
| | | | |
| //! construction of complex matrix out of two non-complex matrices; | | //! construction of complex matrix out of two non-complex matrices; | |
| template<typename T1, typename T2> | | template<typename T1, typename T2> | |
| inline explicit SpMat(const SpBase<pod_type, T1>& A, const SpBase<pod_typ
e, T2>& B); | | inline explicit SpMat(const SpBase<pod_type, T1>& A, const SpBase<pod_typ
e, T2>& B); | |
| | | | |
| /** | | /** | |
| * Operations on sparse subviews. | | * Operations on sparse subviews. | |
| */ | | */ | |
| inline SpMat(const SpSubview<eT>& X); | | inline SpMat(const SpSubview<eT>& X); | |
| inline const SpMat& operator=(const SpSubview<eT>& X); | | inline const SpMat& operator=(const SpSubview<eT>& X); | |
| inline const SpMat& operator+=(const SpSubview<eT>& X); | | inline const SpMat& operator+=(const SpSubview<eT>& X); | |
| inline const SpMat& operator-=(const SpSubview<eT>& X); | | inline const SpMat& operator-=(const SpSubview<eT>& X); | |
| inline const SpMat& operator*=(const SpSubview<eT>& X); | | inline const SpMat& operator*=(const SpSubview<eT>& X); | |
| inline const SpMat& operator%=(const SpSubview<eT>& X); | | inline const SpMat& operator%=(const SpSubview<eT>& X); | |
| inline const SpMat& operator/=(const SpSubview<eT>& X); | | inline const SpMat& operator/=(const SpSubview<eT>& X); | |
| | | | |
|
| /** | | | |
| * Operations on regular subviews. | | | |
| */ | | | |
| inline SpMat(const subview<eT>& x); | | | |
| inline const SpMat& operator=(const subview<eT>& x); | | | |
| inline const SpMat& operator+=(const subview<eT>& x); | | | |
| inline const SpMat& operator-=(const subview<eT>& x); | | | |
| inline const SpMat& operator*=(const subview<eT>& x); | | | |
| inline const SpMat& operator%=(const subview<eT>& x); | | | |
| inline const SpMat& operator/=(const subview<eT>& x); | | | |
| | | | |
| // delayed unary ops | | // delayed unary ops | |
| template<typename T1, typename spop_type> inline SpMat(
const SpOp<T1, spop_type>& X); | | template<typename T1, typename spop_type> inline SpMat(
const SpOp<T1, spop_type>& X); | |
| template<typename T1, typename spop_type> inline const SpMat& operator=(
const SpOp<T1, spop_type>& X); | | template<typename T1, typename spop_type> inline const SpMat& operator=(
const SpOp<T1, spop_type>& X); | |
| template<typename T1, typename spop_type> inline const SpMat& operator+=(
const SpOp<T1, spop_type>& X); | | template<typename T1, typename spop_type> inline const SpMat& operator+=(
const SpOp<T1, spop_type>& X); | |
| template<typename T1, typename spop_type> inline const SpMat& operator-=(
const SpOp<T1, spop_type>& X); | | template<typename T1, typename spop_type> inline const SpMat& operator-=(
const SpOp<T1, spop_type>& X); | |
| template<typename T1, typename spop_type> inline const SpMat& operator*=(
const SpOp<T1, spop_type>& X); | | template<typename T1, typename spop_type> inline const SpMat& operator*=(
const SpOp<T1, spop_type>& X); | |
| template<typename T1, typename spop_type> inline const SpMat& operator%=(
const SpOp<T1, spop_type>& X); | | template<typename T1, typename spop_type> inline const SpMat& operator%=(
const SpOp<T1, spop_type>& X); | |
| template<typename T1, typename spop_type> inline const SpMat& operator/=(
const SpOp<T1, spop_type>& X); | | template<typename T1, typename spop_type> inline const SpMat& operator/=(
const SpOp<T1, spop_type>& X); | |
| | | | |
| // delayed binary ops | | // delayed binary ops | |
| | | | |
| skipping to change at line 552 | | skipping to change at line 543 | |
| | | | |
| /** | | /** | |
| * Resize memory. You are responsible for updating the column pointers a
nd | | * Resize memory. You are responsible for updating the column pointers a
nd | |
| * filling the new memory (if the new size is larger). If the new size i
s | | * filling the new memory (if the new size is larger). If the new size i
s | |
| * smaller, the first new_n_nonzero elements will be copied. n_nonzero i
s | | * smaller, the first new_n_nonzero elements will be copied. n_nonzero i
s | |
| * updated. | | * updated. | |
| */ | | */ | |
| inline void mem_resize(const uword new_n_nonzero); | | inline void mem_resize(const uword new_n_nonzero); | |
| | | | |
| //! don't use this unless you're writing internal Armadillo code | | //! don't use this unless you're writing internal Armadillo code | |
|
| | | inline void remove_zeros(); | |
| | | | |
| | | //! don't use this unless you're writing internal Armadillo code | |
| inline void steal_mem(SpMat& X); | | inline void steal_mem(SpMat& X); | |
| | | | |
| //! don't use this unless you're writing internal Armadillo code | | //! don't use this unless you're writing internal Armadillo code | |
| template< typename T1, typename Functor> arma_hot inline voi
d init_xform (const SpBase<eT, T1>& x, const Functor& func); | | template< typename T1, typename Functor> arma_hot inline voi
d init_xform (const SpBase<eT, T1>& x, const Functor& func); | |
| template<typename eT2, typename T1, typename Functor> arma_hot inline voi
d init_xform_mt(const SpBase<eT2,T1>& x, const Functor& func); | | template<typename eT2, typename T1, typename Functor> arma_hot inline voi
d init_xform_mt(const SpBase<eT2,T1>& x, const Functor& func); | |
| | | | |
| protected: | | protected: | |
| | | | |
| /** | | /** | |
| * Initialize the matrix to the specified size. Data is not preserved, s
o the matrix is assumed to be entirely sparse (empty). | | * Initialize the matrix to the specified size. Data is not preserved, s
o the matrix is assumed to be entirely sparse (empty). | |
| | | | |
End of changes. 3 change blocks. |
| 11 lines changed or deleted | | 7 lines changed or added | |
|
| SpMat_meat.hpp | | SpMat_meat.hpp | |
|
| // Copyright (C) 2011-2014 Ryan Curtin | | // Copyright (C) 2011-2015 Ryan Curtin | |
| // Copyright (C) 2012-2015 Conrad Sanderson | | // Copyright (C) 2012-2015 Conrad Sanderson | |
| // Copyright (C) 2011 Matthew Amidon | | // Copyright (C) 2011 Matthew Amidon | |
| // | | // | |
| // This Source Code Form is subject to the terms of the Mozilla Public | | // This Source Code Form is subject to the terms of the Mozilla Public | |
| // License, v. 2.0. If a copy of the MPL was not distributed with this | | // License, v. 2.0. If a copy of the MPL was not distributed with this | |
| // file, You can obtain one at http://mozilla.org/MPL/2.0/. | | // file, You can obtain one at http://mozilla.org/MPL/2.0/. | |
| | | | |
| //! \addtogroup SpMat | | //! \addtogroup SpMat | |
| //! @{ | | //! @{ | |
| | | | |
| | | | |
| skipping to change at line 98 | | skipping to change at line 98 | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| const SpMat<eT>& | | const SpMat<eT>& | |
| SpMat<eT>::operator=(const char* text) | | SpMat<eT>::operator=(const char* text) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| init(std::string(text)); | | init(std::string(text)); | |
|
| | | | |
| | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| SpMat<eT>::SpMat(const std::string& text) | | SpMat<eT>::SpMat(const std::string& text) | |
| : n_rows(0) | | : n_rows(0) | |
| , n_cols(0) | | , n_cols(0) | |
| , n_elem(0) | | , n_elem(0) | |
| , n_nonzero(0) | | , n_nonzero(0) | |
| , vec_state(0) | | , vec_state(0) | |
| | | | |
| skipping to change at line 125 | | skipping to change at line 127 | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| const SpMat<eT>& | | const SpMat<eT>& | |
| SpMat<eT>::operator=(const std::string& text) | | SpMat<eT>::operator=(const std::string& text) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| init(text); | | init(text); | |
|
| | | | |
| | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| SpMat<eT>::SpMat(const SpMat<eT>& x) | | SpMat<eT>::SpMat(const SpMat<eT>& x) | |
| : n_rows(0) | | : n_rows(0) | |
| , n_cols(0) | | , n_cols(0) | |
| , n_elem(0) | | , n_elem(0) | |
| , n_nonzero(0) | | , n_nonzero(0) | |
| , vec_state(0) | | , vec_state(0) | |
| | | | |
| skipping to change at line 491 | | skipping to change at line 495 | |
| 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)) | |
| { | | { | |
| arrayops::inplace_mul( access::rwp(values), val, n_nonzero ); | | arrayops::inplace_mul( access::rwp(values), val, n_nonzero ); | |
|
| | | | |
| | | remove_zeros(); | |
| } | | } | |
| else | | else | |
| { | | { | |
| // Everything will be zero. | | // Everything will be zero. | |
| init(n_rows, n_cols); | | init(n_rows, n_cols); | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 512 | | skipping to change at line 518 | |
| 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" ); | |
| | | | |
| arrayops::inplace_div( access::rwp(values), val, n_nonzero ); | | arrayops::inplace_div( access::rwp(values), val, n_nonzero ); | |
| | | | |
|
| | | remove_zeros(); | |
| | | | |
| 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 723 | | skipping to change at line 731 | |
| { | | { | |
| arma_extra_debug_sigprint_this(this); | | arma_extra_debug_sigprint_this(this); | |
| | | | |
| (*this).operator=(x); | | (*this).operator=(x); | |
| } | | } | |
| | | | |
| 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>& expr) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
|
| const Proxy<T1> p(x.get_ref()); | | const quasi_unwrap<T1> tmp(expr.get_ref()); | |
| | | const Mat<eT>& x = tmp.M; | |
| | | | |
|
| const uword x_n_rows = p.get_n_rows(); | | const uword x_n_rows = x.n_rows; | |
| const uword x_n_cols = p.get_n_cols(); | | const uword x_n_cols = x.n_cols; | |
| const uword x_n_elem = p.get_n_elem(); | | const uword x_n_elem = x.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) | | | |
| { | | const eT* x_mem = x.memptr(); | |
| 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_elem; ++i) | |
| { | | | |
| if(p.at(i, j) != eT(0)) { ++n; } | | | |
| } | | | |
| } | | | |
| else | | | |
| { | | { | |
|
| for(uword i = 0; i < x_n_elem; ++i) | | n += (x_mem[i] != eT(0)) ? uword(1) : uword(0); | |
| { | | | |
| if(p[i] != eT(0)) { ++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); | | const eT val = (*x_mem); x_mem++; | |
| | | | |
| if(val != eT(0)) | | if(val != eT(0)) | |
| { | | { | |
| access::rw(values[n]) = val; | | access::rw(values[n]) = val; | |
| access::rw(row_indices[n]) = i; | | access::rw(row_indices[n]) = i; | |
| access::rw(col_ptrs[j + 1])++; | | access::rw(col_ptrs[j + 1])++; | |
| ++n; | | ++n; | |
| } | | } | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 784 | | skipping to change at line 785 | |
| access::rw(col_ptrs[c]) += col_ptrs[c - 1]; | | access::rw(col_ptrs[c]) += col_ptrs[c - 1]; | |
| } | | } | |
| | | | |
| 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) | |
| | | { | |
| | | arma_extra_debug_sigprint(); | |
| | | | |
| | | return (*this).operator=( (*this) + x.get_ref() ); | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | template<typename T1> | |
| | | inline | |
| | | const SpMat<eT>& | |
| | | SpMat<eT>::operator-=(const Base<eT, T1>& x) | |
| | | { | |
| | | arma_extra_debug_sigprint(); | |
| | | | |
| | | return (*this).operator=( (*this) - x.get_ref() ); | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | template<typename T1> | |
| | | inline | |
| | | const SpMat<eT>& | |
| SpMat<eT>::operator*=(const Base<eT, T1>& y) | | SpMat<eT>::operator*=(const Base<eT, T1>& y) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| const Proxy<T1> p(y.get_ref()); | | const Proxy<T1> p(y.get_ref()); | |
| | | | |
| arma_debug_assert_mul_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols()
, "matrix multiplication"); | | arma_debug_assert_mul_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols()
, "matrix multiplication"); | |
| | | | |
| // We assume the matrix structure is such that we will end up with a spar
se | | // We assume the matrix structure is such that we will end up with a spar
se | |
| // matrix. Assuming that every entry in the dense matrix is nonzero (whi
ch is | | // matrix. Assuming that every entry in the dense matrix is nonzero (whi
ch is | |
| | | | |
| skipping to change at line 1090 | | skipping to change at line 1113 | |
| | | | |
| // There is no pretty way to do this. | | // There is no pretty way to do this. | |
| for(uword elem = 0; elem < n_elem; elem++) | | for(uword elem = 0; elem < n_elem; elem++) | |
| { | | { | |
| at(elem) /= x(elem); | | at(elem) /= x(elem); | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
|
| /** | | | |
| * Operators on regular subviews. | | | |
| */ | | | |
| template<typename eT> | | | |
| inline | | | |
| SpMat<eT>::SpMat(const subview<eT>& x) | | | |
| : n_rows(0) | | | |
| , n_cols(0) | | | |
| , n_elem(0) | | | |
| , n_nonzero(0) | | | |
| , vec_state(0) | | | |
| , values(NULL) // extra value set in operator=() | | | |
| , row_indices(NULL) | | | |
| , col_ptrs(NULL) | | | |
| { | | | |
| arma_extra_debug_sigprint_this(this); | | | |
| | | | |
| (*this).operator=(x); | | | |
| } | | | |
| | | | |
| template<typename eT> | | | |
| inline | | | |
| const SpMat<eT>& | | | |
| SpMat<eT>::operator=(const subview<eT>& x) | | | |
| { | | | |
| arma_extra_debug_sigprint(); | | | |
| | | | |
| const uword x_n_rows = x.n_rows; | | | |
| const uword x_n_cols = x.n_cols; | | | |
| | | | |
| // Set the size correctly. | | | |
| init(x_n_rows, x_n_cols); | | | |
| | | | |
| // Count number of nonzero elements. | | | |
| uword n = 0; | | | |
| for(uword c = 0; c < x_n_cols; ++c) | | | |
| { | | | |
| for(uword r = 0; r < x_n_rows; ++r) | | | |
| { | | | |
| if(x.at(r, c) != eT(0)) | | | |
| { | | | |
| ++n; | | | |
| } | | | |
| } | | | |
| } | | | |
| | | | |
| // Resize memory appropriately. | | | |
| mem_resize(n); | | | |
| | | | |
| n = 0; | | | |
| for(uword c = 0; c < x_n_cols; ++c) | | | |
| { | | | |
| for(uword r = 0; r < x_n_rows; ++r) | | | |
| { | | | |
| const eT val = x.at(r, c); | | | |
| | | | |
| if(val != eT(0)) | | | |
| { | | | |
| access::rw(values[n]) = val; | | | |
| access::rw(row_indices[n]) = r; | | | |
| ++access::rw(col_ptrs[c + 1]); | | | |
| ++n; | | | |
| } | | | |
| } | | | |
| } | | | |
| | | | |
| // Fix column counts into column pointers. | | | |
| for(uword c = 1; c <= n_cols; ++c) | | | |
| { | | | |
| access::rw(col_ptrs[c]) += col_ptrs[c - 1]; | | | |
| } | | | |
| | | | |
| return *this; | | | |
| } | | | |
| | | | |
| template<typename eT> | | | |
| inline | | | |
| const SpMat<eT>& | | | |
| SpMat<eT>::operator+=(const subview<eT>& x) | | | |
| { | | | |
| arma_extra_debug_sigprint(); | | | |
| | | | |
| arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "addition | | | |
| "); | | | |
| | | | |
| // Loop over every element. This could probably be written in a more | | | |
| // efficient way, by calculating the number of nonzero elements the outpu | | | |
| t | | | |
| // matrix will have, allocating the memory correctly, and then filling th | | | |
| e | | | |
| // matrix correctly. However... for now, this works okay. | | | |
| for(uword lcol = 0; lcol < n_cols; ++lcol) | | | |
| for(uword lrow = 0; lrow < n_rows; ++lrow) | | | |
| { | | | |
| at(lrow, lcol) += x.at(lrow, lcol); | | | |
| } | | | |
| | | | |
| return *this; | | | |
| } | | | |
| | | | |
| template<typename eT> | | | |
| inline | | | |
| const SpMat<eT>& | | | |
| SpMat<eT>::operator-=(const subview<eT>& x) | | | |
| { | | | |
| arma_extra_debug_sigprint(); | | | |
| | | | |
| arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "subtract | | | |
| ion"); | | | |
| | | | |
| // Loop over every element. | | | |
| for(uword lcol = 0; lcol < n_cols; ++lcol) | | | |
| for(uword lrow = 0; lrow < n_rows; ++lrow) | | | |
| { | | | |
| at(lrow, lcol) -= x.at(lrow, lcol); | | | |
| } | | | |
| | | | |
| return *this; | | | |
| } | | | |
| | | | |
| template<typename eT> | | | |
| inline | | | |
| const SpMat<eT>& | | | |
| SpMat<eT>::operator*=(const subview<eT>& y) | | | |
| { | | | |
| arma_extra_debug_sigprint(); | | | |
| | | | |
| arma_debug_assert_mul_size(n_rows, n_cols, y.n_rows, y.n_cols, "matrix mu | | | |
| ltiplication"); | | | |
| | | | |
| SpMat<eT> z(n_rows, y.n_cols); | | | |
| | | | |
| // Performed in the same fashion as operator*=(SpMat). | | | |
| for (const_row_iterator x_row_it = begin_row(); x_row_it.pos() < n_nonzer | | | |
| o; ++x_row_it) | | | |
| { | | | |
| for (uword lcol = 0; lcol < y.n_cols; ++lcol) | | | |
| { | | | |
| // At this moment in the loop, we are calculating anything that is co | | | |
| ntributed to by *x_row_it and *y_col_it. | | | |
| // Given that our position is x_ab and y_bc, there will only be a con | | | |
| tribution if x.col == y.row, and that | | | |
| // contribution will be in location z_ac. | | | |
| z.at(x_row_it.row, lcol) += (*x_row_it) * y.at(x_row_it.col, lcol); | | | |
| } | | | |
| } | | | |
| | | | |
| steal_mem(z); | | | |
| | | | |
| return *this; | | | |
| } | | | |
| | | | |
| template<typename eT> | | | |
| inline | | | |
| const SpMat<eT>& | | | |
| SpMat<eT>::operator%=(const subview<eT>& x) | | | |
| { | | | |
| arma_extra_debug_sigprint(); | | | |
| | | | |
| arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "element- | | | |
| wise multiplication"); | | | |
| | | | |
| // Loop over every element. | | | |
| for(uword lcol = 0; lcol < n_cols; ++lcol) | | | |
| for(uword lrow = 0; lrow < n_rows; ++lrow) | | | |
| { | | | |
| at(lrow, lcol) *= x.at(lrow, lcol); | | | |
| } | | | |
| | | | |
| return *this; | | | |
| } | | | |
| | | | |
| template<typename eT> | | | |
| inline | | | |
| const SpMat<eT>& | | | |
| SpMat<eT>::operator/=(const subview<eT>& x) | | | |
| { | | | |
| arma_extra_debug_sigprint(); | | | |
| | | | |
| arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "element- | | | |
| wise division"); | | | |
| | | | |
| // Loop over every element. | | | |
| for(uword lcol = 0; lcol < n_cols; ++lcol) | | | |
| for(uword lrow = 0; lrow < n_rows; ++lrow) | | | |
| { | | | |
| at(lrow, lcol) /= x.at(lrow, lcol); | | | |
| } | | | |
| | | | |
| return *this; | | | |
| } | | | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| template<typename T1, typename spop_type> | | template<typename T1, typename spop_type> | |
| inline | | inline | |
| SpMat<eT>::SpMat(const SpOp<T1, spop_type>& X) | | SpMat<eT>::SpMat(const SpOp<T1, spop_type>& X) | |
| : n_rows(0) | | : n_rows(0) | |
| , n_cols(0) | | , n_cols(0) | |
| , n_elem(0) | | , n_elem(0) | |
| , n_nonzero(0) | | , n_nonzero(0) | |
| , vec_state(0) | | , vec_state(0) | |
| , values(NULL) // set in application of sparse operation | | , values(NULL) // set in application of sparse operation | |
| | | | |
| skipping to change at line 3539 | | skipping to change at line 3380 | |
| // Clean out the existing memory. | | // Clean out the existing memory. | |
| if (values) | | if (values) | |
| { | | { | |
| memory::release(values); | | memory::release(values); | |
| memory::release(row_indices); | | memory::release(row_indices); | |
| } | | } | |
| | | | |
| access::rw(values) = memory::acquire_chunked<eT> (1); | | access::rw(values) = memory::acquire_chunked<eT> (1); | |
| access::rw(row_indices) = memory::acquire_chunked<uword>(1); | | access::rw(row_indices) = memory::acquire_chunked<uword>(1); | |
| | | | |
|
| access::rw(values[0]) = 0; | | access::rw(values[0]) = 0; | |
| access::rw(row_indices[0]) = 0; | | access::rw(row_indices[0]) = 0; | |
| | | | |
| memory::release(col_ptrs); | | memory::release(col_ptrs); | |
| | | | |
| // Set the new size accordingly. | | // Set the new size accordingly. | |
| access::rw(n_rows) = in_rows; | | access::rw(n_rows) = in_rows; | |
| access::rw(n_cols) = in_cols; | | access::rw(n_cols) = in_cols; | |
| access::rw(n_elem) = (in_rows * in_cols); | | access::rw(n_elem) = (in_rows * in_cols); | |
| access::rw(n_nonzero) = 0; | | access::rw(n_nonzero) = 0; | |
| | | | |
| | | | |
| skipping to change at line 4023 | | skipping to change at line 3864 | |
| // Set the "fake end" of the matrix by setting the last value and row | | // Set the "fake end" of the matrix by setting the last value and row | |
| // index to 0. This helps the iterators work correctly. | | // index to 0. This helps the iterators work correctly. | |
| access::rw( values[new_n_nonzero]) = 0; | | access::rw( values[new_n_nonzero]) = 0; | |
| access::rw(row_indices[new_n_nonzero]) = 0; | | access::rw(row_indices[new_n_nonzero]) = 0; | |
| } | | } | |
| | | | |
| access::rw(n_nonzero) = new_n_nonzero; | | access::rw(n_nonzero) = new_n_nonzero; | |
| } | | } | |
| } | | } | |
| | | | |
|
| | | template<typename eT> | |
| | | inline | |
| | | void | |
| | | SpMat<eT>::remove_zeros() | |
| | | { | |
| | | arma_extra_debug_sigprint(); | |
| | | | |
| | | const uword old_n_nonzero = n_nonzero; | |
| | | uword new_n_nonzero = 0; | |
| | | | |
| | | const eT* old_values = values; | |
| | | | |
| | | for(uword i=0; i < old_n_nonzero; ++i) | |
| | | { | |
| | | new_n_nonzero += (old_values[i] != eT(0)) ? uword(1) : uword(0); | |
| | | } | |
| | | | |
| | | if(new_n_nonzero != old_n_nonzero) | |
| | | { | |
| | | if(new_n_nonzero == 0) { init(n_rows, n_cols); return; } | |
| | | | |
| | | SpMat<eT> tmp(n_rows, n_cols); | |
| | | | |
| | | tmp.mem_resize(new_n_nonzero); | |
| | | | |
| | | uword new_index = 0; | |
| | | | |
| | | const_iterator it = begin(); | |
| | | const_iterator it_end = end(); | |
| | | | |
| | | for(; it != it_end; ++it) | |
| | | { | |
| | | const eT val = eT(*it); | |
| | | | |
| | | if(val != eT(0)) | |
| | | { | |
| | | access::rw(tmp.values[new_index]) = val; | |
| | | access::rw(tmp.row_indices[new_index]) = it.row(); | |
| | | access::rw(tmp.col_ptrs[it.col() + 1])++; | |
| | | ++new_index; | |
| | | } | |
| | | } | |
| | | | |
| | | for(uword i=0; i < n_cols; ++i) | |
| | | { | |
| | | access::rw(tmp.col_ptrs[i + 1]) += tmp.col_ptrs[i]; | |
| | | } | |
| | | | |
| | | steal_mem(tmp); | |
| | | } | |
| | | } | |
| | | | |
| // Steal memory from another matrix. | | // Steal memory from another matrix. | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| void | | void | |
| SpMat<eT>::steal_mem(SpMat<eT>& x) | | SpMat<eT>::steal_mem(SpMat<eT>& x) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| if(this != &x) | | if(this != &x) | |
| { | | { | |
| | | | |
| skipping to change at line 4080 | | skipping to change at line 3973 | |
| (*this) = A.get_ref(); | | (*this) = A.get_ref(); | |
| | | | |
| const uword nnz = n_nonzero; | | const uword nnz = n_nonzero; | |
| | | | |
| eT* t_values = access::rwp(values); | | eT* t_values = access::rwp(values); | |
| | | | |
| for(uword i=0; i < nnz; ++i) | | for(uword i=0; i < nnz; ++i) | |
| { | | { | |
| t_values[i] = func(t_values[i]); | | t_values[i] = func(t_values[i]); | |
| } | | } | |
|
| | | | |
| | | remove_zeros(); | |
| } | | } | |
| else | | else | |
| { | | { | |
| init_xform_mt(A.get_ref(), func); | | init_xform_mt(A.get_ref(), func); | |
| } | | } | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| template<typename eT2, typename T1, typename Functor> | | template<typename eT2, typename T1, typename Functor> | |
| arma_hot | | arma_hot | |
| | | | |
| skipping to change at line 4144 | | skipping to change at line 4039 | |
| { | | { | |
| t_values[i] = func(x_values[i]); // NOTE: func() must produce a val
ue of type eT (ie. act as a convertor between eT2 and eT) | | t_values[i] = func(x_values[i]); // NOTE: func() must produce a val
ue of type eT (ie. act as a convertor between eT2 and eT) | |
| } | | } | |
| } | | } | |
| else | | else | |
| { | | { | |
| init(P.get_n_rows(), P.get_n_cols()); | | init(P.get_n_rows(), P.get_n_cols()); | |
| | | | |
| mem_resize(P.get_n_nonzero()); | | mem_resize(P.get_n_nonzero()); | |
| | | | |
|
| 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) | |
| { | | { | |
| access::rw(row_indices[it.pos()]) = it.row(); | | access::rw(row_indices[it.pos()]) = it.row(); | |
| access::rw(values[it.pos()]) = func(*it); // NOTE: func() must prod
uce a value of type eT (ie. act as a convertor between eT2 and eT) | | access::rw(values[it.pos()]) = func(*it); // NOTE: func() must prod
uce a value of type eT (ie. act as a convertor between eT2 and eT) | |
| ++access::rw(col_ptrs[it.col() + 1]); | | ++access::rw(col_ptrs[it.col() + 1]); | |
| ++it; | | ++it; | |
| } | | } | |
| | | | |
| // Now sum column pointers. | | // Now sum 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]; | |
| } | | } | |
| } | | } | |
|
| | | | |
| | | remove_zeros(); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| typename SpMat<eT>::iterator | | typename SpMat<eT>::iterator | |
| SpMat<eT>::begin() | | SpMat<eT>::begin() | |
| { | | { | |
| return iterator(*this); | | return iterator(*this); | |
| } | | } | |
| | | | |
| | | | |
End of changes. 19 change blocks. |
| 215 lines changed or deleted | | 103 lines changed or added | |
|
| SpSubview_meat.hpp | | SpSubview_meat.hpp | |
|
| // Copyright (C) 2011-2012 Ryan Curtin | | // Copyright (C) 2011-2015 Ryan Curtin | |
| // Copyright (C) 2012-2014 Conrad Sanderson | | // Copyright (C) 2012-2015 Conrad Sanderson | |
| // Copyright (C) 2011 Matthew Amidon | | // Copyright (C) 2011 Matthew Amidon | |
| // | | // | |
| // This Source Code Form is subject to the terms of the Mozilla Public | | // This Source Code Form is subject to the terms of the Mozilla Public | |
| // License, v. 2.0. If a copy of the MPL was not distributed with this | | // License, v. 2.0. If a copy of the MPL was not distributed with this | |
| // file, You can obtain one at http://mozilla.org/MPL/2.0/. | | // file, You can obtain one at http://mozilla.org/MPL/2.0/. | |
| | | | |
| //! \addtogroup SpSubview | | //! \addtogroup SpSubview | |
| //! @{ | | //! @{ | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| | | | |
| skipping to change at line 32 | | skipping to change at line 32 | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| // There must be a O(1) way to do this | | // There must be a O(1) way to do this | |
| uword lend = m.col_ptrs[in_col1 + in_n_cols]; | | uword lend = m.col_ptrs[in_col1 + in_n_cols]; | |
| uword lend_row = in_row1 + in_n_rows; | | uword lend_row = in_row1 + in_n_rows; | |
| uword count = 0; | | uword count = 0; | |
| | | | |
| for(uword i = m.col_ptrs[in_col1]; i < lend; ++i) | | for(uword i = m.col_ptrs[in_col1]; i < lend; ++i) | |
| { | | { | |
|
| if(m.row_indices[i] >= in_row1 && m.row_indices[i] < lend_row) | | const uword m_row_indices_i = m.row_indices[i]; | |
| { | | | |
| ++count; | | const bool condition = (m_row_indices_i >= in_row1) && (m_row_indices_i | |
| } | | < lend_row); | |
| | | | |
| | | count += condition ? uword(1) : uword(0); | |
| } | | } | |
| | | | |
| access::rw(n_nonzero) = count; | | access::rw(n_nonzero) = count; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| arma_inline | | arma_inline | |
| SpSubview<eT>::SpSubview(SpMat<eT>& in_m, const uword in_row1, const uword
in_col1, const uword in_n_rows, const uword in_n_cols) | | SpSubview<eT>::SpSubview(SpMat<eT>& in_m, const uword in_row1, const uword
in_col1, const uword in_n_rows, const uword in_n_cols) | |
| : m(in_m) | | : m(in_m) | |
| , aux_row1(in_row1) | | , aux_row1(in_row1) | |
| | | | |
| skipping to change at line 61 | | skipping to change at line 62 | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| // There must be a O(1) way to do this | | // There must be a O(1) way to do this | |
| uword lend = m.col_ptrs[in_col1 + in_n_cols]; | | uword lend = m.col_ptrs[in_col1 + in_n_cols]; | |
| uword lend_row = in_row1 + in_n_rows; | | uword lend_row = in_row1 + in_n_rows; | |
| uword count = 0; | | uword count = 0; | |
| | | | |
| for(uword i = m.col_ptrs[in_col1]; i < lend; ++i) | | for(uword i = m.col_ptrs[in_col1]; i < lend; ++i) | |
| { | | { | |
|
| if(m.row_indices[i] >= in_row1 && m.row_indices[i] < lend_row) | | const uword m_row_indices_i = m.row_indices[i]; | |
| { | | | |
| ++count; | | const bool condition = (m_row_indices_i >= in_row1) && (m_row_indices_i | |
| } | | < lend_row); | |
| | | | |
| | | count += condition ? uword(1) : uword(0); | |
| } | | } | |
| | | | |
| access::rw(n_nonzero) = count; | | access::rw(n_nonzero) = count; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| SpSubview<eT>::~SpSubview() | | SpSubview<eT>::~SpSubview() | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| skipping to change at line 122 | | skipping to change at line 124 | |
| return (*this).operator=( (*this) - tmp ); | | return (*this).operator=( (*this) - tmp ); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| const SpSubview<eT>& | | const SpSubview<eT>& | |
| SpSubview<eT>::operator*=(const eT val) | | SpSubview<eT>::operator*=(const eT val) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
|
| if(val != eT(0)) | | const uword lstart_row = aux_row1; | |
| { | | const uword lend_row = aux_row1 + n_rows; | |
| const uword lstart_row = aux_row1; | | | |
| const uword lend_row = aux_row1 + n_rows; | | | |
| | | | |
|
| const uword lstart_col = aux_col1; | | const uword lstart_col = aux_col1; | |
| const uword lend_col = aux_col1 + n_cols; | | const uword lend_col = aux_col1 + n_cols; | |
| | | | |
| | | const uword* m_row_indices = m.row_indices; | |
| | | eT* m_values = access::rwp(m.values); | |
| | | | |
| | | for(uword c = lstart_col; c < lend_col; ++c) | |
| | | { | |
| | | const uword r_start = m.col_ptrs[c ]; | |
| | | const uword r_end = m.col_ptrs[c + 1]; | |
| | | | |
|
| for(uword c = lstart_col; c < lend_col; ++c) | | for(uword r = r_start; r < r_end; ++r) | |
| { | | { | |
|
| for(uword r = m.col_ptrs[c]; r < m.col_ptrs[c + 1]; ++r) | | const uword m_row_indices_r = m_row_indices[r]; | |
| | | | |
| | | if( (m_row_indices_r >= lstart_row) && (m_row_indices_r < lend_row) ) | |
| { | | { | |
|
| if(m.row_indices[r] >= lstart_row && m.row_indices[r] < lend_row) | | m_values[r] *= val; | |
| { | | | |
| access::rw(m.values[r]) *= val; | | | |
| } | | | |
| } | | } | |
| } | | } | |
| } | | } | |
|
| else | | | |
| | | const uword old_m_n_nonzero = m.n_nonzero; | |
| | | | |
| | | access::rw(m).remove_zeros(); | |
| | | | |
| | | if(m.n_nonzero != old_m_n_nonzero) | |
| { | | { | |
|
| (*this).zeros(); | | access::rw(n_nonzero) = n_nonzero - (old_m_n_nonzero - m.n_nonzero); | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| const SpSubview<eT>& | | const SpSubview<eT>& | |
| SpSubview<eT>::operator/=(const eT val) | | SpSubview<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" ); | |
| | | | |
| const uword lstart_row = aux_row1; | | const uword lstart_row = aux_row1; | |
| const uword lend_row = aux_row1 + n_rows; | | const uword lend_row = aux_row1 + n_rows; | |
| | | | |
| const uword lstart_col = aux_col1; | | const uword lstart_col = aux_col1; | |
| const uword lend_col = aux_col1 + n_cols; | | const uword lend_col = aux_col1 + n_cols; | |
| | | | |
|
| | | const uword* m_row_indices = m.row_indices; | |
| | | eT* m_values = access::rwp(m.values); | |
| | | | |
| for(uword c = lstart_col; c < lend_col; ++c) | | for(uword c = lstart_col; c < lend_col; ++c) | |
| { | | { | |
|
| for(uword r = m.col_ptrs[c]; r < m.col_ptrs[c + 1]; ++r) | | const uword r_start = m.col_ptrs[c ]; | |
| | | const uword r_end = m.col_ptrs[c + 1]; | |
| | | | |
| | | for(uword r = r_start; r < r_end; ++r) | |
| { | | { | |
|
| if(m.row_indices[r] >= lstart_row && m.row_indices[r] < lend_row) | | const uword m_row_indices_r = m_row_indices[r]; | |
| | | | |
| | | if( (m_row_indices_r >= lstart_row) && (m_row_indices_r < lend_row) ) | |
| { | | { | |
|
| access::rw(m.values[r]) /= val; | | m_values[r] /= val; | |
| } | | } | |
| } | | } | |
| } | | } | |
| | | | |
|
| | | const uword old_m_n_nonzero = m.n_nonzero; | |
| | | | |
| | | access::rw(m).remove_zeros(); | |
| | | | |
| | | if(m.n_nonzero != old_m_n_nonzero) | |
| | | { | |
| | | access::rw(n_nonzero) = n_nonzero - (old_m_n_nonzero - m.n_nonzero); | |
| | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
| const SpSubview<eT>& | | const SpSubview<eT>& | |
| SpSubview<eT>::operator=(const Base<eT, T1>& in) | | SpSubview<eT>::operator=(const Base<eT, T1>& in) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| skipping to change at line 210 | | skipping to change at line 239 | |
| | | | |
| const uword pa_n_rows = pa.get_n_rows(); | | const uword pa_n_rows = pa.get_n_rows(); | |
| | | | |
| const uword b_n_elem = b.n_elem; | | const uword b_n_elem = b.n_elem; | |
| const eT* b_mem = b.memptr(); | | const eT* b_mem = b.memptr(); | |
| | | | |
| uword box_count = 0; | | uword box_count = 0; | |
| | | | |
| for(uword i=0; i<b_n_elem; ++i) | | for(uword i=0; i<b_n_elem; ++i) | |
| { | | { | |
|
| if(b_mem[i] != eT(0)) { ++box_count; } | | box_count += (b_mem[i] != eT(0)) ? uword(1) : uword(0); | |
| } | | } | |
| | | | |
| SpMat<eT> out(pa.get_n_rows(), pa.get_n_cols()); | | SpMat<eT> out(pa.get_n_rows(), pa.get_n_cols()); | |
| | | | |
| const uword alt_count = pa.get_n_nonzero() - (*this).n_nonzero + box_coun
t; | | const uword alt_count = pa.get_n_nonzero() - (*this).n_nonzero + box_coun
t; | |
| | | | |
| // Resize memory to correct size. | | // Resize memory to correct size. | |
| out.mem_resize(alt_count); | | out.mem_resize(alt_count); | |
| | | | |
| typename SpProxy< SpMat<eT> >::const_iterator_type x_it = pa.begin(); | | typename SpProxy< SpMat<eT> >::const_iterator_type x_it = pa.begin(); | |
| | | | |
| skipping to change at line 756 | | skipping to change at line 785 | |
| } | | } | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| void | | void | |
| SpSubview<eT>::zeros() | | SpSubview<eT>::zeros() | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
|
| const SpMat<eT> tmp( (*this).n_rows, (*this).n_cols ); | | (*this).operator*=(eT(0)); | |
| | | | |
| (*this).operator=(tmp); | | | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| void | | void | |
| SpSubview<eT>::ones() | | SpSubview<eT>::ones() | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| (*this).fill(eT(1)); | | (*this).fill(eT(1)); | |
| | | | |
End of changes. 17 change blocks. |
| 31 lines changed or deleted | | 60 lines changed or added | |
|