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_iterators_meat.hpp   SpMat_iterators_meat.hpp 
skipping to change at line 385 skipping to change at line 385
while(true) // This loop is terminated from the inside. while(true) // This loop is terminated from the inside.
{ {
// Is there anything in the column we are looking at? // Is there anything in the column we are looking at?
for (uword ind = 0; ((iterator_base::M->col_ptrs[cur_col] + ind < itera tor_base::M->col_ptrs[cur_col + 1]) && (iterator_base::M->row_indices[itera tor_base::M->col_ptrs[cur_col] + ind] <= cur_row)); ind++) for (uword ind = 0; ((iterator_base::M->col_ptrs[cur_col] + ind < itera tor_base::M->col_ptrs[cur_col + 1]) && (iterator_base::M->row_indices[itera tor_base::M->col_ptrs[cur_col] + ind] <= cur_row)); ind++)
{ {
// There is something in this column. Is it in the row we are lookin g at? // There is something in this column. Is it in the row we are lookin g at?
const uword row_index = iterator_base::M->row_indices[iterator_base:: M->col_ptrs[cur_col] + ind]; const uword row_index = iterator_base::M->row_indices[iterator_base:: M->col_ptrs[cur_col] + ind];
if (row_index == cur_row) if (row_index == cur_row)
{ {
// Yes, it is what we are looking for. Increment our current posit ion. // Yes, it is what we are looking for. Increment our current posit ion.
if (++cur_pos == iterator_base::internal_pos) if (++cur_pos == iterator_base::internal_pos) // TODO: HACK: if c ur_pos is std::numeric_limits<uword>::max(), ++cur_pos relies on a wraparou nd/overflow, which is not portable
{ {
actual_pos = iterator_base::M->col_ptrs[cur_col] + ind; actual_pos = iterator_base::M->col_ptrs[cur_col] + ind;
internal_row = cur_row; internal_row = cur_row;
iterator_base::internal_col = cur_col; iterator_base::internal_col = cur_col;
return; return;
} }
// We are done with this column. Break to the column incrementing code (directly below). // We are done with this column. Break to the column incrementing code (directly below).
break; break;
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 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_iterators_meat.hpp   SpSubview_iterators_meat.hpp 
skipping to change at line 535 skipping to change at line 535
} }
const uword aux_col = iterator_base::M.aux_col1; const uword aux_col = iterator_base::M.aux_col1;
const uword aux_row = iterator_base::M.aux_row1; const uword aux_row = iterator_base::M.aux_row1;
const uword ln_cols = iterator_base::M.n_cols; const uword ln_cols = iterator_base::M.n_cols;
// We don't know where the elements are in each row. What we will do is // We don't know where the elements are in each row. What we will do is
// loop across all valid columns looking for elements in row 0 (and add t o // loop across all valid columns looking for elements in row 0 (and add t o
// our sum), then in row 1, and so forth, until we get to the desired // our sum), then in row 1, and so forth, until we get to the desired
// position. // position.
uword cur_pos = -1; uword cur_pos = -1; // TODO: HACK: -1 is not a valid unsigned integer; u sing -1 is relying on wraparound/overflow, which is not portable
uword cur_row = 0; uword cur_row = 0;
uword cur_col = 0; uword cur_col = 0;
while(true) while(true)
{ {
// Is there anything in the column we are looking at? // Is there anything in the column we are looking at?
const uword colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col]; const uword colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col];
const uword next_colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col + 1]; const uword next_colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col + 1];
for(uword ind = colptr; (ind < next_colptr) && (iterator_base::M.m.row_ indices[ind] <= (cur_row + aux_row)); ++ind) for(uword ind = colptr; (ind < next_colptr) && (iterator_base::M.m.row_ indices[ind] <= (cur_row + aux_row)); ++ind)
{ {
// There is something in this column. Is it in the row we are lookin g at? // There is something in this column. Is it in the row we are lookin g at?
const uword row_index = iterator_base::M.m.row_indices[ind]; const uword row_index = iterator_base::M.m.row_indices[ind];
if(row_index == (cur_row + aux_row)) if(row_index == (cur_row + aux_row))
{ {
// Yes, it is in the right row. // Yes, it is in the right row.
if(++cur_pos == iterator_base::internal_pos) if(++cur_pos == iterator_base::internal_pos) // TODO: HACK: if cu r_pos is std::numeric_limits<uword>::max(), ++cur_pos relies on a wraparoun d/overflow, which is not portable
{ {
iterator_base::internal_col = cur_col; iterator_base::internal_col = cur_col;
internal_row = cur_row; internal_row = cur_row;
actual_pos = ind; actual_pos = ind;
return; return;
} }
// We are done with this column. Break to the column incrementing code (directly below). // We are done with this column. Break to the column incrementing code (directly below).
break; break;
 End of changes. 2 change blocks. 
2 lines changed or deleted 2 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


 arma_version.hpp   arma_version.hpp 
skipping to change at line 13 skipping to change at line 13
// //
// 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 arma_version //! \addtogroup arma_version
//! @{ //! @{
#define ARMA_VERSION_MAJOR 4 #define ARMA_VERSION_MAJOR 4
#define ARMA_VERSION_MINOR 650 #define ARMA_VERSION_MINOR 650
#define ARMA_VERSION_PATCH 0 #define ARMA_VERSION_PATCH 1
#define ARMA_VERSION_NAME "Intravenous Caffeine Injector" #define ARMA_VERSION_NAME "Intravenous Caffeine Injector"
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


 fn_accu.hpp   fn_accu.hpp 
skipping to change at line 164 skipping to change at line 164
if(Proxy<T1>::prefer_at_accessor == false) if(Proxy<T1>::prefer_at_accessor == false)
{ {
typedef typename Proxy<T1>::ea_type ea_type; typedef typename Proxy<T1>::ea_type ea_type;
ea_type A = P.get_ea(); ea_type A = P.get_ea();
const uword n_elem = P.get_n_elem(); const uword n_elem = P.get_n_elem();
for(uword i=0; i<n_elem; ++i) for(uword i=0; i<n_elem; ++i)
{ {
if(A[i] != val) { ++n_nonzero; } n_nonzero += (A[i] != val) ? uword(1) : uword(0);
} }
} }
else else
{ {
const uword P_n_cols = P.get_n_cols(); const uword P_n_cols = P.get_n_cols();
const uword P_n_rows = P.get_n_rows(); const uword P_n_rows = P.get_n_rows();
if(P_n_rows == 1) if(P_n_rows == 1)
{ {
for(uword col=0; col < P_n_cols; ++col) for(uword col=0; col < P_n_cols; ++col)
{ {
if(P.at(0,col) != val) { ++n_nonzero; } n_nonzero += (P.at(0,col) != val) ? uword(1) : uword(0);
} }
} }
else else
{ {
for(uword col=0; col < P_n_cols; ++col) for(uword col=0; col < P_n_cols; ++col)
for(uword row=0; row < P_n_rows; ++row) for(uword row=0; row < P_n_rows; ++row)
{ {
if(P.at(row,col) != val) { ++n_nonzero; } n_nonzero += (P.at(row,col) != val) ? uword(1) : uword(0);
} }
} }
} }
return n_nonzero; return n_nonzero;
} }
//! accumulate the elements of a subview (submatrix) //! accumulate the elements of a subview (submatrix)
template<typename eT> template<typename eT>
arma_hot arma_hot
 End of changes. 3 change blocks. 
3 lines changed or deleted 3 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/