diff options
Diffstat (limited to 'src/armadillo/include/armadillo_bits/MapMat_meat.hpp')
-rw-r--r-- | src/armadillo/include/armadillo_bits/MapMat_meat.hpp | 1778 |
1 files changed, 1778 insertions, 0 deletions
diff --git a/src/armadillo/include/armadillo_bits/MapMat_meat.hpp b/src/armadillo/include/armadillo_bits/MapMat_meat.hpp new file mode 100644 index 0000000..e67a307 --- /dev/null +++ b/src/armadillo/include/armadillo_bits/MapMat_meat.hpp @@ -0,0 +1,1778 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +//! \addtogroup MapMat +//! @{ + + + +template<typename eT> +inline +MapMat<eT>::~MapMat() + { + arma_extra_debug_sigprint_this(this); + + if(map_ptr) { (*map_ptr).clear(); delete map_ptr; } + + // try to expose buggy user code that accesses deleted objects + if(arma_config::debug) { map_ptr = nullptr; } + + arma_type_check(( is_supported_elem_type<eT>::value == false )); + } + + + +template<typename eT> +inline +MapMat<eT>::MapMat() + : n_rows (0) + , n_cols (0) + , n_elem (0) + , map_ptr(nullptr) + { + arma_extra_debug_sigprint_this(this); + + init_cold(); + } + + + +template<typename eT> +inline +MapMat<eT>::MapMat(const uword in_n_rows, const uword in_n_cols) + : n_rows (in_n_rows) + , n_cols (in_n_cols) + , n_elem (in_n_rows * in_n_cols) + , map_ptr(nullptr) + { + arma_extra_debug_sigprint_this(this); + + init_cold(); + } + + + +template<typename eT> +inline +MapMat<eT>::MapMat(const SizeMat& s) + : n_rows (s.n_rows) + , n_cols (s.n_cols) + , n_elem (s.n_rows * s.n_cols) + , map_ptr(nullptr) + { + arma_extra_debug_sigprint_this(this); + + init_cold(); + } + + + +template<typename eT> +inline +MapMat<eT>::MapMat(const MapMat<eT>& x) + : n_rows (0) + , n_cols (0) + , n_elem (0) + , map_ptr(nullptr) + { + arma_extra_debug_sigprint_this(this); + + init_cold(); + + (*this).operator=(x); + } + + + +template<typename eT> +inline +void +MapMat<eT>::operator=(const MapMat<eT>& x) + { + arma_extra_debug_sigprint(); + + if(this == &x) { return; } + + access::rw(n_rows) = x.n_rows; + access::rw(n_cols) = x.n_cols; + access::rw(n_elem) = x.n_elem; + + (*map_ptr) = *(x.map_ptr); + } + + + +template<typename eT> +inline +MapMat<eT>::MapMat(const SpMat<eT>& x) + : n_rows (0) + , n_cols (0) + , n_elem (0) + , map_ptr(nullptr) + { + arma_extra_debug_sigprint_this(this); + + init_cold(); + + (*this).operator=(x); + } + + + +template<typename eT> +inline +void +MapMat<eT>::operator=(const SpMat<eT>& x) + { + arma_extra_debug_sigprint(); + + const uword x_n_rows = x.n_rows; + const uword x_n_cols = x.n_cols; + + (*this).zeros(x_n_rows, x_n_cols); + + if(x.n_nonzero == 0) { return; } + + const eT* x_values = x.values; + const uword* x_row_indices = x.row_indices; + const uword* x_col_ptrs = x.col_ptrs; + + map_type& map_ref = (*map_ptr); + + for(uword col = 0; col < x_n_cols; ++col) + { + const uword start = x_col_ptrs[col ]; + const uword end = x_col_ptrs[col + 1]; + + for(uword i = start; i < end; ++i) + { + const uword row = x_row_indices[i]; + const eT val = x_values[i]; + + const uword index = (x_n_rows * col) + row; + + map_ref.emplace_hint(map_ref.cend(), index, val); + } + } + } + + + +template<typename eT> +inline +MapMat<eT>::MapMat(MapMat<eT>&& x) + : n_rows (x.n_rows ) + , n_cols (x.n_cols ) + , n_elem (x.n_elem ) + , map_ptr(x.map_ptr) + { + arma_extra_debug_sigprint_this(this); + + access::rw(x.n_rows) = 0; + access::rw(x.n_cols) = 0; + access::rw(x.n_elem) = 0; + access::rw(x.map_ptr) = nullptr; + } + + + +template<typename eT> +inline +void +MapMat<eT>::operator=(MapMat<eT>&& x) + { + arma_extra_debug_sigprint(); + + if(this == &x) { return; } + + reset(); + + if(map_ptr) { delete map_ptr; } + + access::rw(n_rows) = x.n_rows; + access::rw(n_cols) = x.n_cols; + access::rw(n_elem) = x.n_elem; + access::rw(map_ptr) = x.map_ptr; + + access::rw(x.n_rows) = 0; + access::rw(x.n_cols) = 0; + access::rw(x.n_elem) = 0; + access::rw(x.map_ptr) = nullptr; + } + + + +template<typename eT> +inline +void +MapMat<eT>::reset() + { + arma_extra_debug_sigprint(); + + access::rw(n_rows) = 0; + access::rw(n_cols) = 0; + access::rw(n_elem) = 0; + + if((*map_ptr).empty() == false) { (*map_ptr).clear(); } + } + + + +template<typename eT> +inline +void +MapMat<eT>::set_size(const uword in_n_rows) + { + arma_extra_debug_sigprint(); + + init_warm(in_n_rows, 1); + } + + + +template<typename eT> +inline +void +MapMat<eT>::set_size(const uword in_n_rows, const uword in_n_cols) + { + arma_extra_debug_sigprint(); + + init_warm(in_n_rows, in_n_cols); + } + + + +template<typename eT> +inline +void +MapMat<eT>::set_size(const SizeMat& s) + { + arma_extra_debug_sigprint(); + + init_warm(s.n_rows, s.n_cols); + } + + + +template<typename eT> +inline +void +MapMat<eT>::zeros() + { + arma_extra_debug_sigprint(); + + (*map_ptr).clear(); + } + + + +template<typename eT> +inline +void +MapMat<eT>::zeros(const uword in_n_rows) + { + arma_extra_debug_sigprint(); + + init_warm(in_n_rows, 1); + + (*map_ptr).clear(); + } + + + +template<typename eT> +inline +void +MapMat<eT>::zeros(const uword in_n_rows, const uword in_n_cols) + { + arma_extra_debug_sigprint(); + + init_warm(in_n_rows, in_n_cols); + + (*map_ptr).clear(); + } + + + +template<typename eT> +inline +void +MapMat<eT>::zeros(const SizeMat& s) + { + arma_extra_debug_sigprint(); + + init_warm(s.n_rows, s.n_cols); + + (*map_ptr).clear(); + } + + + +template<typename eT> +inline +void +MapMat<eT>::eye() + { + arma_extra_debug_sigprint(); + + (*this).eye(n_rows, n_cols); + } + + + +template<typename eT> +inline +void +MapMat<eT>::eye(const uword in_n_rows, const uword in_n_cols) + { + arma_extra_debug_sigprint(); + + zeros(in_n_rows, in_n_cols); + + const uword N = (std::min)(in_n_rows, in_n_cols); + + map_type& map_ref = (*map_ptr); + + for(uword i=0; i<N; ++i) + { + const uword index = (in_n_rows * i) + i; + + map_ref.emplace_hint(map_ref.cend(), index, eT(1)); + } + } + + + +template<typename eT> +inline +void +MapMat<eT>::eye(const SizeMat& s) + { + arma_extra_debug_sigprint(); + + (*this).eye(s.n_rows, s.n_cols); + } + + + +template<typename eT> +inline +void +MapMat<eT>::speye() + { + arma_extra_debug_sigprint(); + + (*this).eye(); + } + + + +template<typename eT> +inline +void +MapMat<eT>::speye(const uword in_n_rows, const uword in_n_cols) + { + arma_extra_debug_sigprint(); + + (*this).eye(in_n_rows, in_n_cols); + } + + + +template<typename eT> +inline +void +MapMat<eT>::speye(const SizeMat& s) + { + arma_extra_debug_sigprint(); + + (*this).eye(s); + } + + + +template<typename eT> +arma_inline +MapMat_val<eT> +MapMat<eT>::operator[](const uword index) + { + return MapMat_val<eT>(*this, index); + } + + + +template<typename eT> +inline +eT +MapMat<eT>::operator[](const uword index) const + { + map_type& map_ref = (*map_ptr); + + typename map_type::const_iterator it = map_ref.find(index); + typename map_type::const_iterator it_end = map_ref.end(); + + return (it != it_end) ? eT((*it).second) : eT(0); + } + + + +template<typename eT> +arma_inline +MapMat_val<eT> +MapMat<eT>::operator()(const uword index) + { + arma_debug_check_bounds( (index >= n_elem), "MapMat::operator(): index out of bounds" ); + + return MapMat_val<eT>(*this, index); + } + + + +template<typename eT> +inline +eT +MapMat<eT>::operator()(const uword index) const + { + arma_debug_check_bounds( (index >= n_elem), "MapMat::operator(): index out of bounds" ); + + map_type& map_ref = (*map_ptr); + + typename map_type::const_iterator it = map_ref.find(index); + typename map_type::const_iterator it_end = map_ref.end(); + + return (it != it_end) ? eT((*it).second) : eT(0); + } + + + +template<typename eT> +arma_inline +MapMat_val<eT> +MapMat<eT>::at(const uword in_row, const uword in_col) + { + const uword index = (n_rows * in_col) + in_row; + + return MapMat_val<eT>(*this, index); + } + + + +template<typename eT> +inline +eT +MapMat<eT>::at(const uword in_row, const uword in_col) const + { + const uword index = (n_rows * in_col) + in_row; + + map_type& map_ref = (*map_ptr); + + typename map_type::const_iterator it = map_ref.find(index); + typename map_type::const_iterator it_end = map_ref.end(); + + return (it != it_end) ? eT((*it).second) : eT(0); + } + + + +template<typename eT> +arma_inline +MapMat_val<eT> +MapMat<eT>::operator()(const uword in_row, const uword in_col) + { + arma_debug_check_bounds( ((in_row >= n_rows) || (in_col >= n_cols)), "MapMat::operator(): index out of bounds" ); + + const uword index = (n_rows * in_col) + in_row; + + return MapMat_val<eT>(*this, index); + } + + + +template<typename eT> +inline +eT +MapMat<eT>::operator()(const uword in_row, const uword in_col) const + { + arma_debug_check_bounds( ((in_row >= n_rows) || (in_col >= n_cols)), "MapMat::operator(): index out of bounds" ); + + const uword index = (n_rows * in_col) + in_row; + + map_type& map_ref = (*map_ptr); + + typename map_type::const_iterator it = map_ref.find(index); + typename map_type::const_iterator it_end = map_ref.end(); + + return (it != it_end) ? eT((*it).second) : eT(0); + } + + + +template<typename eT> +inline +bool +MapMat<eT>::is_empty() const + { + return (n_elem == 0); + } + + + +template<typename eT> +inline +bool +MapMat<eT>::is_vec() const + { + return ( (n_rows == 1) || (n_cols == 1) ); + } + + + +template<typename eT> +inline +bool +MapMat<eT>::is_rowvec() const + { + return (n_rows == 1); + } + + + +//! returns true if the object can be interpreted as a column vector +template<typename eT> +inline +bool +MapMat<eT>::is_colvec() const + { + return (n_cols == 1); + } + + + +template<typename eT> +inline +bool +MapMat<eT>::is_square() const + { + return (n_rows == n_cols); + } + + + +// this function is for debugging purposes only +template<typename eT> +inline +void +MapMat<eT>::sprandu(const uword in_n_rows, const uword in_n_cols, const double density) + { + arma_extra_debug_sigprint(); + + zeros(in_n_rows, in_n_cols); + + const uword N = uword(density * double(n_elem)); + + const Col<eT> vals(N, fill::randu); + const Col<uword> indx = linspace< Col<uword> >(0, ((n_elem > 0) ? uword(n_elem-1) : uword(0)) , N); + + const eT* vals_mem = vals.memptr(); + const uword* indx_mem = indx.memptr(); + + map_type& map_ref = (*map_ptr); + + for(uword i=0; i < N; ++i) + { + const uword index = indx_mem[i]; + const eT val = vals_mem[i]; + + map_ref.emplace_hint(map_ref.cend(), index, val); + } + } + + + +// this function is for debugging purposes only +template<typename eT> +inline +void +MapMat<eT>::print(const std::string& extra_text) const + { + arma_extra_debug_sigprint(); + + if(extra_text.length() != 0) + { + const std::streamsize orig_width = get_cout_stream().width(); + + get_cout_stream() << extra_text << '\n'; + + get_cout_stream().width(orig_width); + } + + map_type& map_ref = (*map_ptr); + + const uword n_nonzero = uword(map_ref.size()); + + const double density = (n_elem > 0) ? ((double(n_nonzero) / double(n_elem))*double(100)) : double(0); + + get_cout_stream() + << "[matrix size: " << n_rows << 'x' << n_cols << "; n_nonzero: " << n_nonzero + << "; density: " << density << "%]\n\n"; + + if(n_nonzero > 0) + { + typename map_type::const_iterator it = map_ref.begin(); + + for(uword i=0; i < n_nonzero; ++i) + { + const std::pair<uword, eT>& entry = (*it); + + const uword index = entry.first; + const eT val = entry.second; + + const uword row = index % n_rows; + const uword col = index / n_rows; + + get_cout_stream() << '(' << row << ", " << col << ") "; + get_cout_stream() << val << '\n'; + + ++it; + } + } + + get_cout_stream().flush(); + } + + + +template<typename eT> +inline +uword +MapMat<eT>::get_n_nonzero() const + { + arma_extra_debug_sigprint(); + + return uword((*map_ptr).size()); + } + + + +template<typename eT> +inline +void +MapMat<eT>::get_locval_format(umat& locs, Col<eT>& vals) const + { + arma_extra_debug_sigprint(); + + map_type& map_ref = (*map_ptr); + + typename map_type::const_iterator it = map_ref.begin(); + + const uword N = uword(map_ref.size()); + + locs.set_size(2,N); + vals.set_size(N); + + eT* vals_mem = vals.memptr(); + + for(uword i=0; i<N; ++i) + { + const std::pair<uword, eT>& entry = (*it); + + const uword index = entry.first; + const eT val = entry.second; + + const uword row = index % n_rows; + const uword col = index / n_rows; + + uword* locs_colptr = locs.colptr(i); + + locs_colptr[0] = row; + locs_colptr[1] = col; + + vals_mem[i] = val; + + ++it; + } + } + + + +template<typename eT> +inline +void +MapMat<eT>::init_cold() + { + arma_extra_debug_sigprint(); + + // ensure that n_elem can hold the result of (n_rows * n_cols) + + #if defined(ARMA_64BIT_WORD) + const char* error_message = "MapMat(): requested size is too large"; + #else + const char* error_message = "MapMat(): requested size is too large; suggest to enable ARMA_64BIT_WORD"; + #endif + + arma_debug_check + ( + ( + ( (n_rows > ARMA_MAX_UHWORD) || (n_cols > ARMA_MAX_UHWORD) ) + ? ( (double(n_rows) * double(n_cols)) > double(ARMA_MAX_UWORD) ) + : false + ), + error_message + ); + + map_ptr = new (std::nothrow) map_type; + + arma_check_bad_alloc( (map_ptr == nullptr), "MapMat(): out of memory" ); + } + + + +template<typename eT> +inline +void +MapMat<eT>::init_warm(const uword in_n_rows, const uword in_n_cols) + { + arma_extra_debug_sigprint(); + + if( (n_rows == in_n_rows) && (n_cols == in_n_cols)) { return; } + + // ensure that n_elem can hold the result of (n_rows * n_cols) + + #if defined(ARMA_64BIT_WORD) + const char* error_message = "MapMat(): requested size is too large"; + #else + const char* error_message = "MapMat(): requested size is too large; suggest to enable ARMA_64BIT_WORD"; + #endif + + arma_debug_check + ( + ( + ( (in_n_rows > ARMA_MAX_UHWORD) || (in_n_cols > ARMA_MAX_UHWORD) ) + ? ( (double(in_n_rows) * double(in_n_cols)) > double(ARMA_MAX_UWORD) ) + : false + ), + error_message + ); + + const uword new_n_elem = in_n_rows * in_n_cols; + + access::rw(n_rows) = in_n_rows; + access::rw(n_cols) = in_n_cols; + access::rw(n_elem) = new_n_elem; + + if(new_n_elem == 0) { (*map_ptr).clear(); } + } + + + +template<typename eT> +arma_inline +void +MapMat<eT>::set_val(const uword index, const eT& in_val) + { + arma_extra_debug_sigprint(); + + if(in_val != eT(0)) + { + map_type& map_ref = (*map_ptr); + + if( (map_ref.empty() == false) && (index > uword(map_ref.crbegin()->first)) ) + { + map_ref.emplace_hint(map_ref.cend(), index, in_val); + } + else + { + map_ref.operator[](index) = in_val; + } + } + else + { + (*this).erase_val(index); + } + } + + + +template<typename eT> +inline +void +MapMat<eT>::erase_val(const uword index) + { + arma_extra_debug_sigprint(); + + map_type& map_ref = (*map_ptr); + + typename map_type::iterator it = map_ref.find(index); + typename map_type::iterator it_end = map_ref.end(); + + if(it != it_end) { map_ref.erase(it); } + } + + + + + + +// MapMat_val + + + +template<typename eT> +arma_inline +MapMat_val<eT>::MapMat_val(MapMat<eT>& in_parent, const uword in_index) + : parent(in_parent) + , index (in_index ) + { + arma_extra_debug_sigprint(); + } + + + +template<typename eT> +arma_inline +MapMat_val<eT>::operator eT() const + { + arma_extra_debug_sigprint(); + + const MapMat<eT>& const_parent = parent; + + return const_parent.operator[](index); + } + + + +template<typename eT> +arma_inline +typename get_pod_type<eT>::result +MapMat_val<eT>::real() const + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type<eT>::result T; + + const MapMat<eT>& const_parent = parent; + + return T( access::tmp_real( const_parent.operator[](index) ) ); + } + + + +template<typename eT> +arma_inline +typename get_pod_type<eT>::result +MapMat_val<eT>::imag() const + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type<eT>::result T; + + const MapMat<eT>& const_parent = parent; + + return T( access::tmp_imag( const_parent.operator[](index) ) ); + } + + + +template<typename eT> +arma_inline +void +MapMat_val<eT>::operator=(const MapMat_val<eT>& x) + { + arma_extra_debug_sigprint(); + + const eT in_val = eT(x); + + parent.set_val(index, in_val); + } + + + +template<typename eT> +arma_inline +void +MapMat_val<eT>::operator=(const eT in_val) + { + arma_extra_debug_sigprint(); + + parent.set_val(index, in_val); + } + + + +template<typename eT> +arma_inline +void +MapMat_val<eT>::operator+=(const eT in_val) + { + arma_extra_debug_sigprint(); + + typename MapMat<eT>::map_type& map_ref = *(parent.map_ptr); + + if(in_val != eT(0)) + { + eT& val = map_ref.operator[](index); // creates the element if it doesn't exist + + val += in_val; + + if(val == eT(0)) { map_ref.erase(index); } + } + } + + + +template<typename eT> +arma_inline +void +MapMat_val<eT>::operator-=(const eT in_val) + { + arma_extra_debug_sigprint(); + + typename MapMat<eT>::map_type& map_ref = *(parent.map_ptr); + + if(in_val != eT(0)) + { + eT& val = map_ref.operator[](index); // creates the element if it doesn't exist + + val -= in_val; + + if(val == eT(0)) { map_ref.erase(index); } + } + } + + + +template<typename eT> +arma_inline +void +MapMat_val<eT>::operator*=(const eT in_val) + { + arma_extra_debug_sigprint(); + + typename MapMat<eT>::map_type& map_ref = *(parent.map_ptr); + + typename MapMat<eT>::map_type::iterator it = map_ref.find(index); + typename MapMat<eT>::map_type::iterator it_end = map_ref.end(); + + if(it != it_end) + { + if(in_val != eT(0)) + { + eT& val = (*it).second; + + val *= in_val; + + if(val == eT(0)) { map_ref.erase(it); } + } + else + { + map_ref.erase(it); + } + } + } + + + +template<typename eT> +arma_inline +void +MapMat_val<eT>::operator/=(const eT in_val) + { + arma_extra_debug_sigprint(); + + typename MapMat<eT>::map_type& map_ref = *(parent.map_ptr); + + typename MapMat<eT>::map_type::iterator it = map_ref.find(index); + typename MapMat<eT>::map_type::iterator it_end = map_ref.end(); + + if(it != it_end) + { + eT& val = (*it).second; + + val /= in_val; + + if(val == eT(0)) { map_ref.erase(it); } + } + else + { + // silly operation, but included for completness + + const eT val = eT(0) / in_val; + + if(val != eT(0)) { parent.set_val(index, val); } + } + } + + + +template<typename eT> +arma_inline +void +MapMat_val<eT>::operator++() + { + arma_extra_debug_sigprint(); + + typename MapMat<eT>::map_type& map_ref = *(parent.map_ptr); + + eT& val = map_ref.operator[](index); // creates the element if it doesn't exist + + val += eT(1); // can't use ++, as eT can be std::complex + + if(val == eT(0)) { map_ref.erase(index); } + } + + + +template<typename eT> +arma_inline +void +MapMat_val<eT>::operator++(int) + { + arma_extra_debug_sigprint(); + + (*this).operator++(); + } + + + +template<typename eT> +arma_inline +void +MapMat_val<eT>::operator--() + { + arma_extra_debug_sigprint(); + + typename MapMat<eT>::map_type& map_ref = *(parent.map_ptr); + + eT& val = map_ref.operator[](index); // creates the element if it doesn't exist + + val -= eT(1); // can't use --, as eT can be std::complex + + if(val == eT(0)) { map_ref.erase(index); } + } + + + +template<typename eT> +arma_inline +void +MapMat_val<eT>::operator--(int) + { + arma_extra_debug_sigprint(); + + (*this).operator--(); + } + + + + + +// SpMat_MapMat_val + + + +template<typename eT> +arma_inline +SpMat_MapMat_val<eT>::SpMat_MapMat_val(SpMat<eT>& in_s_parent, MapMat<eT>& in_m_parent, const uword in_row, const uword in_col) + : s_parent(in_s_parent) + , m_parent(in_m_parent) + , row (in_row ) + , col (in_col ) + { + arma_extra_debug_sigprint(); + } + + + +template<typename eT> +inline +SpMat_MapMat_val<eT>::operator eT() const + { + arma_extra_debug_sigprint(); + + const SpMat<eT>& const_s_parent = s_parent; // declare as const for clarity of intent + + return const_s_parent.get_value(row,col); + } + + + +template<typename eT> +inline +typename get_pod_type<eT>::result +SpMat_MapMat_val<eT>::real() const + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type<eT>::result T; + + const SpMat<eT>& const_s_parent = s_parent; // declare as const for clarity of intent + + return T( access::tmp_real( const_s_parent.get_value(row,col) ) ); + } + + + +template<typename eT> +inline +typename get_pod_type<eT>::result +SpMat_MapMat_val<eT>::imag() const + { + arma_extra_debug_sigprint(); + + typedef typename get_pod_type<eT>::result T; + + const SpMat<eT>& const_s_parent = s_parent; // declare as const for clarity of intent + + return T( access::tmp_imag( const_s_parent.get_value(row,col) ) ); + } + + + +template<typename eT> +inline +SpMat_MapMat_val<eT>& +SpMat_MapMat_val<eT>::operator=(const SpMat_MapMat_val<eT>& x) + { + arma_extra_debug_sigprint(); + + const eT in_val = eT(x); + + return (*this).operator=(in_val); + } + + + +template<typename eT> +inline +SpMat_MapMat_val<eT>& +SpMat_MapMat_val<eT>::operator=(const eT in_val) + { + arma_extra_debug_sigprint(); + + #if defined(ARMA_USE_OPENMP) + { + #pragma omp critical (arma_SpMat_cache) + { + (*this).set(in_val); + } + } + #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) + { + const std::lock_guard<std::mutex> lock(s_parent.cache_mutex); + + (*this).set(in_val); + } + #else + { + (*this).set(in_val); + } + #endif + + return *this; + } + + + +template<typename eT> +inline +SpMat_MapMat_val<eT>& +SpMat_MapMat_val<eT>::operator+=(const eT in_val) + { + arma_extra_debug_sigprint(); + + if(in_val == eT(0)) { return *this; } + + #if defined(ARMA_USE_OPENMP) + { + #pragma omp critical (arma_SpMat_cache) + { + (*this).add(in_val); + } + } + #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) + { + const std::lock_guard<std::mutex> lock(s_parent.cache_mutex); + + (*this).add(in_val); + } + #else + { + (*this).add(in_val); + } + #endif + + return *this; + } + + + +template<typename eT> +inline +SpMat_MapMat_val<eT>& +SpMat_MapMat_val<eT>::operator-=(const eT in_val) + { + arma_extra_debug_sigprint(); + + if(in_val == eT(0)) { return *this; } + + #if defined(ARMA_USE_OPENMP) + { + #pragma omp critical (arma_SpMat_cache) + { + (*this).sub(in_val); + } + } + #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) + { + const std::lock_guard<std::mutex> lock(s_parent.cache_mutex); + + (*this).sub(in_val); + } + #else + { + (*this).sub(in_val); + } + #endif + + return *this; + } + + + +template<typename eT> +inline +SpMat_MapMat_val<eT>& +SpMat_MapMat_val<eT>::operator*=(const eT in_val) + { + arma_extra_debug_sigprint(); + + #if defined(ARMA_USE_OPENMP) + { + #pragma omp critical (arma_SpMat_cache) + { + (*this).mul(in_val); + } + } + #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) + { + const std::lock_guard<std::mutex> lock(s_parent.cache_mutex); + + (*this).mul(in_val); + } + #else + { + (*this).mul(in_val); + } + #endif + + return *this; + } + + + +template<typename eT> +inline +SpMat_MapMat_val<eT>& +SpMat_MapMat_val<eT>::operator/=(const eT in_val) + { + arma_extra_debug_sigprint(); + + #if defined(ARMA_USE_OPENMP) + { + #pragma omp critical (arma_SpMat_cache) + { + (*this).div(in_val); + } + } + #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) + { + const std::lock_guard<std::mutex> lock(s_parent.cache_mutex); + + (*this).div(in_val); + } + #else + { + (*this).div(in_val); + } + #endif + + return *this; + } + + + +template<typename eT> +inline +SpMat_MapMat_val<eT>& +SpMat_MapMat_val<eT>::operator++() + { + arma_extra_debug_sigprint(); + + return (*this).operator+=( eT(1) ); + } + + + +template<typename eT> +inline +eT +SpMat_MapMat_val<eT>::operator++(int) + { + arma_extra_debug_sigprint(); + + const eT old_val = eT(*this); + + (*this).operator+=( eT(1) ); + + return old_val; + } + + + +template<typename eT> +inline +SpMat_MapMat_val<eT>& +SpMat_MapMat_val<eT>::operator--() + { + arma_extra_debug_sigprint(); + + return (*this).operator-=( eT(1) ); + } + + + +template<typename eT> +inline +eT +SpMat_MapMat_val<eT>::operator--(int) + { + arma_extra_debug_sigprint(); + + const eT old_val = eT(*this); + + (*this).operator-=( eT(1) ); + + return old_val; + } + + + +template<typename eT> +inline +void +SpMat_MapMat_val<eT>::set(const eT in_val) + { + arma_extra_debug_sigprint(); + + const bool done = (s_parent.sync_state == 0) ? s_parent.try_set_value_csc(row, col, in_val) : false; + + if(done == false) + { + s_parent.sync_cache_simple(); + + const uword index = (m_parent.n_rows * col) + row; + + m_parent.set_val(index, in_val); + + s_parent.sync_state = 1; + + access::rw(s_parent.n_nonzero) = m_parent.get_n_nonzero(); + } + } + + + +template<typename eT> +inline +void +SpMat_MapMat_val<eT>::add(const eT in_val) + { + arma_extra_debug_sigprint(); + + const bool done = (s_parent.sync_state == 0) ? s_parent.try_add_value_csc(row, col, in_val) : false; + + if(done == false) + { + s_parent.sync_cache_simple(); + + const uword index = (m_parent.n_rows * col) + row; + + typename MapMat<eT>::map_type& map_ref = *(m_parent.map_ptr); + + eT& val = map_ref.operator[](index); // creates the element if it doesn't exist + + val += in_val; + + if(val == eT(0)) { map_ref.erase(index); } + + s_parent.sync_state = 1; + + access::rw(s_parent.n_nonzero) = m_parent.get_n_nonzero(); + } + } + + + +template<typename eT> +inline +void +SpMat_MapMat_val<eT>::sub(const eT in_val) + { + arma_extra_debug_sigprint(); + + const bool done = (s_parent.sync_state == 0) ? s_parent.try_sub_value_csc(row, col, in_val) : false; + + if(done == false) + { + s_parent.sync_cache_simple(); + + const uword index = (m_parent.n_rows * col) + row; + + typename MapMat<eT>::map_type& map_ref = *(m_parent.map_ptr); + + eT& val = map_ref.operator[](index); // creates the element if it doesn't exist + + val -= in_val; + + if(val == eT(0)) { map_ref.erase(index); } + + s_parent.sync_state = 1; + + access::rw(s_parent.n_nonzero) = m_parent.get_n_nonzero(); + } + } + + + +template<typename eT> +inline +void +SpMat_MapMat_val<eT>::mul(const eT in_val) + { + arma_extra_debug_sigprint(); + + const bool done = (s_parent.sync_state == 0) ? s_parent.try_mul_value_csc(row, col, in_val) : false; + + if(done == false) + { + s_parent.sync_cache_simple(); + + const uword index = (m_parent.n_rows * col) + row; + + typename MapMat<eT>::map_type& map_ref = *(m_parent.map_ptr); + + typename MapMat<eT>::map_type::iterator it = map_ref.find(index); + typename MapMat<eT>::map_type::iterator it_end = map_ref.end(); + + if(it != it_end) + { + if(in_val != eT(0)) + { + eT& val = (*it).second; + + val *= in_val; + + if(val == eT(0)) { map_ref.erase(it); } + } + else + { + map_ref.erase(it); + } + + s_parent.sync_state = 1; + + access::rw(s_parent.n_nonzero) = m_parent.get_n_nonzero(); + } + else + { + // element not found, ie. it's zero; zero multiplied by anything is zero, except for nan and inf + if(arma_isfinite(in_val) == false) + { + const eT result = eT(0) * in_val; + + if(result != eT(0)) // paranoia, in case compiling with -ffast-math + { + m_parent.set_val(index, result); + + s_parent.sync_state = 1; + + access::rw(s_parent.n_nonzero) = m_parent.get_n_nonzero(); + } + } + } + } + } + + + +template<typename eT> +inline +void +SpMat_MapMat_val<eT>::div(const eT in_val) + { + arma_extra_debug_sigprint(); + + const bool done = (s_parent.sync_state == 0) ? s_parent.try_div_value_csc(row, col, in_val) : false; + + if(done == false) + { + s_parent.sync_cache_simple(); + + const uword index = (m_parent.n_rows * col) + row; + + typename MapMat<eT>::map_type& map_ref = *(m_parent.map_ptr); + + typename MapMat<eT>::map_type::iterator it = map_ref.find(index); + typename MapMat<eT>::map_type::iterator it_end = map_ref.end(); + + if(it != it_end) + { + eT& val = (*it).second; + + val /= in_val; + + if(val == eT(0)) { map_ref.erase(it); } + + s_parent.sync_state = 1; + + access::rw(s_parent.n_nonzero) = m_parent.get_n_nonzero(); + } + else + { + // element not found, ie. it's zero; zero divided by anything is zero, except for zero and nan + if( (in_val == eT(0)) || (arma_isnan(in_val)) ) + { + const eT result = eT(0) / in_val; + + if(result != eT(0)) // paranoia, in case compiling with -ffast-math + { + m_parent.set_val(index, result); + + s_parent.sync_state = 1; + + access::rw(s_parent.n_nonzero) = m_parent.get_n_nonzero(); + } + } + } + } + } + + + + +// SpSubview_MapMat_val + + + +template<typename eT> +arma_inline +SpSubview_MapMat_val<eT>::SpSubview_MapMat_val(SpSubview<eT>& in_sv_parent, MapMat<eT>& in_m_parent, const uword in_row, const uword in_col) + : SpMat_MapMat_val<eT>(access::rw(in_sv_parent.m), in_m_parent, in_row, in_col) + , sv_parent(in_sv_parent) + { + arma_extra_debug_sigprint(); + } + + + +template<typename eT> +inline +SpSubview_MapMat_val<eT>& +SpSubview_MapMat_val<eT>::operator=(const SpSubview_MapMat_val<eT>& x) + { + arma_extra_debug_sigprint(); + + const eT in_val = eT(x); + + return (*this).operator=(in_val); + } + + + +template<typename eT> +inline +SpSubview_MapMat_val<eT>& +SpSubview_MapMat_val<eT>::operator=(const eT in_val) + { + arma_extra_debug_sigprint(); + + const uword old_n_nonzero = sv_parent.m.n_nonzero; + + SpMat_MapMat_val<eT>::operator=(in_val); + + if(sv_parent.m.n_nonzero > old_n_nonzero) { access::rw(sv_parent.n_nonzero)++; } + if(sv_parent.m.n_nonzero < old_n_nonzero) { access::rw(sv_parent.n_nonzero)--; } + + return *this; + } + + + +template<typename eT> +inline +SpSubview_MapMat_val<eT>& +SpSubview_MapMat_val<eT>::operator+=(const eT in_val) + { + arma_extra_debug_sigprint(); + + const uword old_n_nonzero = sv_parent.m.n_nonzero; + + SpMat_MapMat_val<eT>::operator+=(in_val); + + if(sv_parent.m.n_nonzero > old_n_nonzero) { access::rw(sv_parent.n_nonzero)++; } + if(sv_parent.m.n_nonzero < old_n_nonzero) { access::rw(sv_parent.n_nonzero)--; } + + return *this; + } + + + +template<typename eT> +inline +SpSubview_MapMat_val<eT>& +SpSubview_MapMat_val<eT>::operator-=(const eT in_val) + { + arma_extra_debug_sigprint(); + + const uword old_n_nonzero = sv_parent.m.n_nonzero; + + SpMat_MapMat_val<eT>::operator-=(in_val); + + if(sv_parent.m.n_nonzero > old_n_nonzero) { access::rw(sv_parent.n_nonzero)++; } + if(sv_parent.m.n_nonzero < old_n_nonzero) { access::rw(sv_parent.n_nonzero)--; } + + return *this; + } + + + +template<typename eT> +inline +SpSubview_MapMat_val<eT>& +SpSubview_MapMat_val<eT>::operator*=(const eT in_val) + { + arma_extra_debug_sigprint(); + + const uword old_n_nonzero = sv_parent.m.n_nonzero; + + SpMat_MapMat_val<eT>::operator*=(in_val); + + if(sv_parent.m.n_nonzero > old_n_nonzero) { access::rw(sv_parent.n_nonzero)++; } + if(sv_parent.m.n_nonzero < old_n_nonzero) { access::rw(sv_parent.n_nonzero)--; } + + return *this; + } + + + +template<typename eT> +inline +SpSubview_MapMat_val<eT>& +SpSubview_MapMat_val<eT>::operator/=(const eT in_val) + { + arma_extra_debug_sigprint(); + + const uword old_n_nonzero = sv_parent.m.n_nonzero; + + SpMat_MapMat_val<eT>::operator/=(in_val); + + if(sv_parent.m.n_nonzero > old_n_nonzero) { access::rw(sv_parent.n_nonzero)++; } + if(sv_parent.m.n_nonzero < old_n_nonzero) { access::rw(sv_parent.n_nonzero)--; } + + return *this; + } + + + +template<typename eT> +inline +SpSubview_MapMat_val<eT>& +SpSubview_MapMat_val<eT>::operator++() + { + arma_extra_debug_sigprint(); + + const uword old_n_nonzero = sv_parent.m.n_nonzero; + + SpMat_MapMat_val<eT>::operator++(); + + if(sv_parent.m.n_nonzero > old_n_nonzero) { access::rw(sv_parent.n_nonzero)++; } + if(sv_parent.m.n_nonzero < old_n_nonzero) { access::rw(sv_parent.n_nonzero)--; } + + return *this; + } + + + +template<typename eT> +inline +eT +SpSubview_MapMat_val<eT>::operator++(int) + { + arma_extra_debug_sigprint(); + + const uword old_n_nonzero = sv_parent.m.n_nonzero; + + const eT old_val = SpMat_MapMat_val<eT>::operator++(int(0)); + + if(sv_parent.m.n_nonzero > old_n_nonzero) { access::rw(sv_parent.n_nonzero)++; } + if(sv_parent.m.n_nonzero < old_n_nonzero) { access::rw(sv_parent.n_nonzero)--; } + + return old_val; + } + + + +template<typename eT> +inline +SpSubview_MapMat_val<eT>& +SpSubview_MapMat_val<eT>::operator--() + { + arma_extra_debug_sigprint(); + + const uword old_n_nonzero = sv_parent.m.n_nonzero; + + SpMat_MapMat_val<eT>::operator--(); + + if(sv_parent.m.n_nonzero > old_n_nonzero) { access::rw(sv_parent.n_nonzero)++; } + if(sv_parent.m.n_nonzero < old_n_nonzero) { access::rw(sv_parent.n_nonzero)--; } + + return *this; + } + + + +template<typename eT> +inline +eT +SpSubview_MapMat_val<eT>::operator--(int) + { + arma_extra_debug_sigprint(); + + const uword old_n_nonzero = sv_parent.m.n_nonzero; + + const eT old_val = SpMat_MapMat_val<eT>::operator--(int(0)); + + if(sv_parent.m.n_nonzero > old_n_nonzero) { access::rw(sv_parent.n_nonzero)++; } + if(sv_parent.m.n_nonzero < old_n_nonzero) { access::rw(sv_parent.n_nonzero)--; } + + return old_val; + } + + + +//! @} |