Base_bones.hpp   Base_bones.hpp 
skipping to change at line 96 skipping to change at line 96
, public Base_eval<elem_type, derived, is_Mat<derived>::value>::result , public Base_eval<elem_type, derived, is_Mat<derived>::value>::result
, public Base_trans<derived, is_cx<elem_type>::value>::result , public Base_trans<derived, is_cx<elem_type>::value>::result
{ {
arma_inline const derived& get_ref() const; arma_inline const derived& get_ref() const;
inline void print(const std::string extra_text = "") const; inline void print(const std::string extra_text = "") const;
inline void print(std::ostream& user_stream, const std::string extra_text = "") const; inline void print(std::ostream& user_stream, const std::string extra_text = "") const;
inline void raw_print(const std::string extra_text = "") const; inline void raw_print(const std::string extra_text = "") const;
inline void raw_print(std::ostream& user_stream, const std::string extra_ text = "") const; inline void raw_print(std::ostream& user_stream, const std::string extra_ text = "") const;
inline arma_warn_unused elem_type min() const;
inline arma_warn_unused elem_type max() const;
inline elem_type min(uword& index_of_min_val) const;
inline elem_type max(uword& index_of_max_val) const;
inline elem_type min(uword& row_of_min_val, uword& col_of_min_val) const;
inline elem_type max(uword& row_of_max_val, uword& col_of_max_val) const;
}; };
//! @} //! @}
 End of changes. 1 change blocks. 
0 lines changed or deleted 9 lines changed or added


 Base_meat.hpp   Base_meat.hpp 
skipping to change at line 67 skipping to change at line 67
void void
Base<elem_type,derived>::raw_print(std::ostream& user_stream, const std::st ring extra_text) const Base<elem_type,derived>::raw_print(std::ostream& user_stream, const std::st ring extra_text) const
{ {
const Proxy<derived> P( (*this).get_ref() ); const Proxy<derived> P( (*this).get_ref() );
const quasi_unwrap< typename Proxy<derived>::stored_type > tmp(P.Q); const quasi_unwrap< typename Proxy<derived>::stored_type > tmp(P.Q);
tmp.M.impl_raw_print(user_stream, extra_text); tmp.M.impl_raw_print(user_stream, extra_text);
} }
template<typename elem_type, typename derived>
inline
arma_warn_unused
elem_type
Base<elem_type,derived>::min() const
{
return op_min::min( (*this).get_ref() );
}
template<typename elem_type, typename derived>
inline
arma_warn_unused
elem_type
Base<elem_type,derived>::max() const
{
return op_max::max( (*this).get_ref() );
}
template<typename elem_type, typename derived>
inline
elem_type
Base<elem_type,derived>::min(uword& index_of_min_val) const
{
const Proxy<derived> P( (*this).get_ref() );
return op_min::min_with_index(P, index_of_min_val);
}
template<typename elem_type, typename derived>
inline
elem_type
Base<elem_type,derived>::max(uword& index_of_max_val) const
{
const Proxy<derived> P( (*this).get_ref() );
return op_max::max_with_index(P, index_of_max_val);
}
template<typename elem_type, typename derived>
inline
elem_type
Base<elem_type,derived>::min(uword& row_of_min_val, uword& col_of_min_val)
const
{
const Proxy<derived> P( (*this).get_ref() );
uword index;
const elem_type val = op_min::min_with_index(P, index);
const uword local_n_rows = P.get_n_rows();
row_of_min_val = index % local_n_rows;
col_of_min_val = index / local_n_rows;
return val;
}
template<typename elem_type, typename derived>
inline
elem_type
Base<elem_type,derived>::max(uword& row_of_max_val, uword& col_of_max_val)
const
{
const Proxy<derived> P( (*this).get_ref() );
uword index;
const elem_type val = op_max::max_with_index(P, index);
const uword local_n_rows = P.get_n_rows();
row_of_max_val = index % local_n_rows;
col_of_max_val = index / local_n_rows;
return val;
}
// //
// extra functions defined in Base_inv_yes // extra functions defined in Base_inv_yes
template<typename derived> template<typename derived>
arma_inline arma_inline
const Op<derived,op_inv> const Op<derived,op_inv>
Base_inv_yes<derived>::i(const bool slow) const Base_inv_yes<derived>::i(const bool slow) const
{ {
return Op<derived,op_inv>( static_cast<const derived&>(*this), ((slow == false) ? 0 : 1), 0 ); return Op<derived,op_inv>( static_cast<const derived&>(*this), ((slow == false) ? 0 : 1), 0 );
} }
 End of changes. 1 change blocks. 
0 lines changed or deleted 78 lines changed or added


 Cube_bones.hpp   Cube_bones.hpp 
skipping to change at line 51 skipping to change at line 51
protected: protected:
arma_align_mem Mat<eT>* mat_ptrs_local[ Cube_prealloc::mat_ptrs_size ]; arma_align_mem Mat<eT>* mat_ptrs_local[ Cube_prealloc::mat_ptrs_size ];
arma_align_mem eT mem_local[ Cube_prealloc::mem_n_elem ]; arma_align_mem eT mem_local[ Cube_prealloc::mem_n_elem ];
public: public:
inline ~Cube(); inline ~Cube();
inline Cube(); inline Cube();
inline Cube(const uword in_rows, const uword in_cols, const uwor d in_slices); inline Cube(const uword in_rows, const uword in_cols, const uword in_slic es);
template<typename fill_type> template<typename fill_type>
inline Cube(const uword in_rows, const uword in_cols, const uword in_slic es, const fill::fill_class<fill_type>& f); inline Cube(const uword in_rows, const uword in_cols, const uword in_slic es, const fill::fill_class<fill_type>& f);
#if defined(ARMA_USE_CXX11) #if defined(ARMA_USE_CXX11)
inline Cube(Cube&& m); inline Cube(Cube&& m);
inline const Cube& operator=(Cube&& m); inline const Cube& operator=(Cube&& m);
#endif #endif
inline Cube( eT* aux_mem, const uword aux_n_rows, const uword aux_n_ cols, const uword aux_n_slices, const bool copy_aux_mem = true, const bool strict = true); inline Cube( eT* aux_mem, const uword aux_n_rows, const uword aux_n_ cols, const uword aux_n_slices, const bool copy_aux_mem = true, const bool strict = true);
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 Mat_bones.hpp   Mat_bones.hpp 
// Copyright (C) 2008-2014 Conrad Sanderson // Copyright (C) 2008-2014 Conrad Sanderson
// Copyright (C) 2008-2014 NICTA (www.nicta.com.au) // Copyright (C) 2008-2014 NICTA (www.nicta.com.au)
// Copyright (C) 2012 Ryan Curtin // Copyright (C) 2012-2014 Ryan Curtin
// //
// 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 Mat //! \addtogroup Mat
//! @{ //! @{
//! Dense matrix class //! Dense matrix class
skipping to change at line 472 skipping to change at line 472
inline void operator--(int); inline void operator--(int);
inline bool operator!=(const const_row_iterator& X) const; inline bool operator!=(const const_row_iterator& X) const;
inline bool operator==(const const_row_iterator& X) const; inline bool operator==(const const_row_iterator& X) const;
arma_aligned const Mat<eT>& M; arma_aligned const Mat<eT>& M;
arma_aligned uword row; arma_aligned uword row;
arma_aligned uword col; arma_aligned uword col;
}; };
class const_row_col_iterator;
class row_col_iterator
{
public:
inline row_col_iterator();
inline row_col_iterator(const row_col_iterator& in_it);
inline row_col_iterator(Mat<eT>& in_M, const uword row = 0, const uword
col = 0);
inline arma_hot eT& operator*();
inline arma_hot row_col_iterator& operator++();
inline arma_hot row_col_iterator operator++(int);
inline arma_hot row_col_iterator& operator--();
inline arma_hot row_col_iterator operator--(int);
inline uword row() const;
inline uword col() const;
inline arma_hot bool operator==(const row_col_iterator& rhs) cons
t;
inline arma_hot bool operator!=(const row_col_iterator& rhs) cons
t;
inline arma_hot bool operator==(const const_row_col_iterator& rhs) cons
t;
inline arma_hot bool operator!=(const const_row_col_iterator& rhs) cons
t;
// So that we satisfy the STL iterator types.
typedef std::bidirectional_iterator_tag iterator_category;
typedef eT value_type;
typedef uword difference_type; // not certain
on this one
typedef const eT* pointer;
typedef const eT& reference;
arma_aligned Mat<eT>* M;
arma_aligned eT* current_pos;
arma_aligned uword internal_col;
arma_aligned uword internal_row;
};
class const_row_col_iterator
{
public:
inline const_row_col_iterator();
inline const_row_col_iterator(const row_col_iterator& in_it);
inline const_row_col_iterator(const const_row_col_iterator& in_it);
inline const_row_col_iterator(const Mat<eT>& in_M, const uword row = 0,
const uword col = 0);
inline arma_hot const eT& operator*() const;
inline arma_hot const_row_col_iterator& operator++();
inline arma_hot const_row_col_iterator operator++(int);
inline arma_hot const_row_col_iterator& operator--();
inline arma_hot const_row_col_iterator operator--(int);
inline uword row() const;
inline uword col() const;
inline arma_hot bool operator==(const const_row_col_iterator& rhs) cons
t;
inline arma_hot bool operator!=(const const_row_col_iterator& rhs) cons
t;
inline arma_hot bool operator==(const row_col_iterator& rhs) cons
t;
inline arma_hot bool operator!=(const row_col_iterator& rhs) cons
t;
// So that we satisfy the STL iterator types.
typedef std::bidirectional_iterator_tag iterator_category;
typedef eT value_type;
typedef uword difference_type; // not certain
on this one
typedef const eT* pointer;
typedef const eT& reference;
arma_aligned const Mat<eT>* M;
arma_aligned const eT* current_pos;
arma_aligned uword internal_col;
arma_aligned uword internal_row;
};
inline iterator begin(); inline iterator begin();
inline const_iterator begin() const; inline const_iterator begin() const;
inline const_iterator cbegin() const; inline const_iterator cbegin() const;
inline iterator end(); inline iterator end();
inline const_iterator end() const; inline const_iterator end() const;
inline const_iterator cend() const; inline const_iterator cend() const;
inline col_iterator begin_col(const uword col_num); inline col_iterator begin_col(const uword col_num);
inline const_col_iterator begin_col(const uword col_num) const; inline const_col_iterator begin_col(const uword col_num) const;
inline col_iterator end_col (const uword col_num); inline col_iterator end_col (const uword col_num);
inline const_col_iterator end_col (const uword col_num) const; inline const_col_iterator end_col (const uword col_num) const;
inline row_iterator begin_row(const uword row_num); inline row_iterator begin_row(const uword row_num);
inline const_row_iterator begin_row(const uword row_num) const; inline const_row_iterator begin_row(const uword row_num) const;
inline row_iterator end_row (const uword row_num); inline row_iterator end_row (const uword row_num);
inline const_row_iterator end_row (const uword row_num) const; inline const_row_iterator end_row (const uword row_num) const;
inline row_col_iterator begin_row_col();
inline const_row_col_iterator begin_row_col() const;
inline row_col_iterator end_row_col();
inline const_row_col_iterator end_row_col() const;
inline void clear(); inline void clear();
inline bool empty() const; inline bool empty() const;
inline uword size() const; inline uword size() const;
inline void swap(Mat& B); inline void swap(Mat& B);
inline void steal_mem(Mat& X); //!< don't use this unless you're writing code internal to Armadillo inline void steal_mem(Mat& X); //!< don't use this unless you're writing code internal to Armadillo
inline void steal_mem_col(Mat& X, const uword max_n_rows); inline void steal_mem_col(Mat& X, const uword max_n_rows);
 End of changes. 3 change blocks. 
1 lines changed or deleted 96 lines changed or added


 Mat_meat.hpp   Mat_meat.hpp 
// Copyright (C) 2008-2014 Conrad Sanderson // Copyright (C) 2008-2014 Conrad Sanderson
// Copyright (C) 2008-2014 NICTA (www.nicta.com.au) // Copyright (C) 2008-2014 NICTA (www.nicta.com.au)
// Copyright (C) 2012 Ryan Curtin // Copyright (C) 2012-2014 Ryan Curtin
// //
// 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 Mat //! \addtogroup Mat
//! @{ //! @{
template<typename eT> template<typename eT>
inline inline
skipping to change at line 906 skipping to change at line 906
//! if memory can't be stolen, copy the given matrix //! if memory can't be stolen, copy the given matrix
template<typename eT> template<typename eT>
inline inline
void void
Mat<eT>::steal_mem(Mat<eT>& x) Mat<eT>::steal_mem(Mat<eT>& x)
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
if(this != &x) if(this != &x)
{ {
const uword x_n_rows = x.n_rows; const uword x_n_rows = x.n_rows;
const uword x_n_cols = x.n_cols; const uword x_n_cols = x.n_cols;
const uword x_n_elem = x.n_elem; const uword x_n_elem = x.n_elem;
const uword x_vec_state = x.vec_state; const uhword x_vec_state = x.vec_state;
const uword x_mem_state = x.mem_state; const uhword x_mem_state = x.mem_state;
const uword t_vec_state = vec_state; const uhword t_vec_state = vec_state;
const uword t_mem_state = mem_state; const uhword t_mem_state = mem_state;
bool layout_ok = false; bool layout_ok = false;
if(t_vec_state == x_vec_state) if(t_vec_state == x_vec_state)
{ {
layout_ok = true; layout_ok = true;
} }
else else
{ {
if( (t_vec_state == 1) && (x_n_cols == 1) ) { layout_ok = true; } if( (t_vec_state == 1) && (x_n_cols == 1) ) { layout_ok = true; }
skipping to change at line 957 skipping to change at line 957
} }
} }
template<typename eT> template<typename eT>
inline inline
void void
Mat<eT>::steal_mem_col(Mat<eT>& x, const uword max_n_rows) Mat<eT>::steal_mem_col(Mat<eT>& x, const uword max_n_rows)
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
const uword x_n_elem = x.n_elem; const uword x_n_elem = x.n_elem;
const uword x_mem_state = x.mem_state; const uhword x_mem_state = x.mem_state;
const uword t_vec_state = vec_state; const uhword t_vec_state = vec_state;
const uword t_mem_state = mem_state; const uhword t_mem_state = mem_state;
const uword alt_n_rows = (std::min)(x.n_rows, max_n_rows); const uword alt_n_rows = (std::min)(x.n_rows, max_n_rows);
if((x_n_elem == 0) || (alt_n_rows == 0)) if((x_n_elem == 0) || (alt_n_rows == 0))
{ {
(*this).set_size(0,1); (*this).set_size(0,1);
return; return;
} }
skipping to change at line 5279 skipping to change at line 5279
} }
template<typename eT> template<typename eT>
inline inline
arma_warn_unused arma_warn_unused
eT eT
Mat<eT>::min() const Mat<eT>::min() const
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
arma_debug_check( (n_elem == 0), "min(): object has no elements" ); arma_debug_check( (n_elem == 0), "Mat::min(): object has no elements" );
return op_min::direct_min(memptr(), n_elem); return op_min::direct_min(memptr(), n_elem);
} }
template<typename eT> template<typename eT>
inline inline
arma_warn_unused arma_warn_unused
eT eT
Mat<eT>::max() const Mat<eT>::max() const
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
arma_debug_check( (n_elem == 0), "max(): object has no elements" ); arma_debug_check( (n_elem == 0), "Mat::max(): object has no elements" );
return op_max::direct_max(memptr(), n_elem); return op_max::direct_max(memptr(), n_elem);
} }
template<typename eT> template<typename eT>
inline inline
eT eT
Mat<eT>::min(uword& index_of_min_val) const Mat<eT>::min(uword& index_of_min_val) const
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
arma_debug_check( (n_elem == 0), "min(): object has no elements" ); arma_debug_check( (n_elem == 0), "Mat::min(): object has no elements" );
return op_min::direct_min(memptr(), n_elem, index_of_min_val); return op_min::direct_min(memptr(), n_elem, index_of_min_val);
} }
template<typename eT> template<typename eT>
inline inline
eT eT
Mat<eT>::max(uword& index_of_max_val) const Mat<eT>::max(uword& index_of_max_val) const
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
arma_debug_check( (n_elem == 0), "max(): object has no elements" ); arma_debug_check( (n_elem == 0), "Mat::max(): object has no elements" );
return op_max::direct_max(memptr(), n_elem, index_of_max_val); return op_max::direct_max(memptr(), n_elem, index_of_max_val);
} }
template<typename eT> template<typename eT>
inline inline
eT eT
Mat<eT>::min(uword& row_of_min_val, uword& col_of_min_val) const Mat<eT>::min(uword& row_of_min_val, uword& col_of_min_val) const
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
arma_debug_check( (n_elem == 0), "min(): object has no elements" ); arma_debug_check( (n_elem == 0), "Mat::min(): object has no elements" );
uword iq; uword iq;
eT val = op_min::direct_min(memptr(), n_elem, iq); eT val = op_min::direct_min(memptr(), n_elem, iq);
row_of_min_val = iq % n_rows; row_of_min_val = iq % n_rows;
col_of_min_val = iq / n_rows; col_of_min_val = iq / n_rows;
return val; return val;
} }
template<typename eT> template<typename eT>
inline inline
eT eT
Mat<eT>::max(uword& row_of_max_val, uword& col_of_max_val) const Mat<eT>::max(uword& row_of_max_val, uword& col_of_max_val) const
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
arma_debug_check( (n_elem == 0), "max(): object has no elements" ); arma_debug_check( (n_elem == 0), "Mat::max(): object has no elements" );
uword iq; uword iq;
eT val = op_max::direct_max(memptr(), n_elem, iq); eT val = op_max::direct_max(memptr(), n_elem, iq);
row_of_max_val = iq % n_rows; row_of_max_val = iq % n_rows;
col_of_max_val = iq / n_rows; col_of_max_val = iq / n_rows;
return val; return val;
} }
skipping to change at line 5821 skipping to change at line 5821
template<typename eT> template<typename eT>
inline inline
bool bool
Mat<eT>::const_row_iterator::operator==(const typename Mat<eT>::const_row_i terator& X) const Mat<eT>::const_row_iterator::operator==(const typename Mat<eT>::const_row_i terator& X) const
{ {
return ( (row == X.row) && (col == X.col) ) ? true : false; return ( (row == X.row) && (col == X.col) ) ? true : false;
} }
template<typename eT> template<typename eT>
inline inline
Mat<eT>::row_col_iterator::row_col_iterator()
: M (NULL)
, current_pos (NULL)
, internal_col(0 )
, internal_row(0 )
{
arma_extra_debug_sigprint();
// Technically this iterator is invalid (it does not point to a real elem
ent)
}
template<typename eT>
inline
Mat<eT>::row_col_iterator::row_col_iterator(const row_col_iterator& in_it)
: M (in_it.M )
, current_pos (in_it.current_pos )
, internal_col(in_it.internal_col)
, internal_row(in_it.internal_row)
{
arma_extra_debug_sigprint();
}
template<typename eT>
inline
Mat<eT>::row_col_iterator::row_col_iterator(Mat<eT>& in_M, const uword row,
const uword col)
: M (&in_M )
, current_pos (&in_M.at(row,col))
, internal_col(col )
, internal_row(row )
{
arma_extra_debug_sigprint();
}
template<typename eT>
inline
eT&
Mat<eT>::row_col_iterator::operator*()
{
return *current_pos;
}
template<typename eT>
inline
typename Mat<eT>::row_col_iterator&
Mat<eT>::row_col_iterator::operator++()
{
current_pos++;
internal_row++;
// Check to see if we moved a column.
if(internal_row == M->n_rows)
{
internal_col++;
internal_row = 0;
}
return *this;
}
template<typename eT>
inline
typename Mat<eT>::row_col_iterator
Mat<eT>::row_col_iterator::operator++(int)
{
typename Mat<eT>::row_col_iterator temp(*this);
++(*this);
return temp;
}
template<typename eT>
inline typename Mat<eT>::row_col_iterator&
Mat<eT>::row_col_iterator::operator--()
{
if(internal_row > 0)
{
current_pos--;
internal_row--;
}
else
if(internal_col > 0)
{
current_pos--;
internal_col--;
internal_row = M->n_rows - 1;
}
return *this;
}
template<typename eT>
inline
typename Mat<eT>::row_col_iterator
Mat<eT>::row_col_iterator::operator--(int)
{
typename Mat<eT>::row_col_iterator temp(*this);
--(*this);
return temp;
}
template<typename eT>
inline
uword
Mat<eT>::row_col_iterator::row() const
{
return internal_row;
}
template<typename eT>
inline
uword
Mat<eT>::row_col_iterator::col() const
{
return internal_col;
}
template<typename eT>
inline
bool
Mat<eT>::row_col_iterator::operator==(const row_col_iterator& rhs) const
{
return (current_pos == rhs.current_pos);
}
template<typename eT>
inline
bool
Mat<eT>::row_col_iterator::operator!=(const row_col_iterator& rhs) const
{
return (current_pos != rhs.current_pos);
}
template<typename eT>
inline
bool
Mat<eT>::row_col_iterator::operator==(const const_row_col_iterator& rhs) co
nst
{
return (current_pos == rhs.current_pos);
}
template<typename eT>
inline
bool
Mat<eT>::row_col_iterator::operator!=(const const_row_col_iterator& rhs) co
nst
{
return (current_pos != rhs.current_pos);
}
template<typename eT>
inline
Mat<eT>::const_row_col_iterator::const_row_col_iterator()
: M (NULL)
, current_pos (NULL)
, internal_col(0 )
, internal_row(0 )
{
arma_extra_debug_sigprint();
// Technically this iterator is invalid (it does not point to a real elem
ent)
}
template<typename eT>
inline
Mat<eT>::const_row_col_iterator::const_row_col_iterator(const row_col_itera
tor& in_it)
: M (in_it.M )
, current_pos (in_it.current_pos)
, internal_col(in_it.col() )
, internal_row(in_it.row() )
{
arma_extra_debug_sigprint();
}
template<typename eT>
inline
Mat<eT>::const_row_col_iterator::const_row_col_iterator(const const_row_col
_iterator& in_it)
: M (in_it.M )
, current_pos (in_it.current_pos)
, internal_col(in_it.col() )
, internal_row(in_it.row() )
{
arma_extra_debug_sigprint();
}
template<typename eT>
inline
Mat<eT>::const_row_col_iterator::const_row_col_iterator(const Mat<eT>& in_M
, const uword row, const uword col)
: M (&in_M )
, current_pos (&in_M.at(row,col))
, internal_col(col )
, internal_row(row )
{
arma_extra_debug_sigprint();
}
template<typename eT>
inline
const eT&
Mat<eT>::const_row_col_iterator::operator*() const
{
return *current_pos;
}
template<typename eT>
inline
typename Mat<eT>::const_row_col_iterator&
Mat<eT>::const_row_col_iterator::operator++()
{
current_pos++;
internal_row++;
// Check to see if we moved a column.
if(internal_row == M->n_rows)
{
internal_col++;
internal_row = 0;
}
return *this;
}
template<typename eT>
inline
typename Mat<eT>::const_row_col_iterator
Mat<eT>::const_row_col_iterator::operator++(int)
{
typename Mat<eT>::const_row_col_iterator temp(*this);
++(*this);
return temp;
}
template<typename eT>
inline
typename Mat<eT>::const_row_col_iterator&
Mat<eT>::const_row_col_iterator::operator--()
{
if(internal_row > 0)
{
current_pos--;
internal_row--;
}
else
if(internal_col > 0)
{
current_pos--;
internal_col--;
internal_row = M->n_rows - 1;
}
return *this;
}
template<typename eT>
inline
typename Mat<eT>::const_row_col_iterator
Mat<eT>::const_row_col_iterator::operator--(int)
{
typename Mat<eT>::const_row_col_iterator temp(*this);
--(*this);
return temp;
}
template<typename eT>
inline
uword
Mat<eT>::const_row_col_iterator::row() const
{
return internal_row;
}
template<typename eT>
inline
uword
Mat<eT>::const_row_col_iterator::col() const
{
return internal_col;
}
template<typename eT>
inline
bool
Mat<eT>::const_row_col_iterator::operator==(const const_row_col_iterator& r
hs) const
{
return (current_pos == rhs.current_pos);
}
template<typename eT>
inline
bool
Mat<eT>::const_row_col_iterator::operator!=(const const_row_col_iterator& r
hs) const
{
return (current_pos != rhs.current_pos);
}
template<typename eT>
inline
bool
Mat<eT>::const_row_col_iterator::operator==(const row_col_iterator& rhs) co
nst
{
return (current_pos == rhs.current_pos);
}
template<typename eT>
inline
bool
Mat<eT>::const_row_col_iterator::operator!=(const row_col_iterator& rhs) co
nst
{
return (current_pos != rhs.current_pos);
}
template<typename eT>
inline
typename Mat<eT>::iterator typename Mat<eT>::iterator
Mat<eT>::begin() Mat<eT>::begin()
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
return memptr(); return memptr();
} }
template<typename eT> template<typename eT>
inline inline
skipping to change at line 5975 skipping to change at line 6291
typename Mat<eT>::const_row_iterator typename Mat<eT>::const_row_iterator
Mat<eT>::end_row(const uword row_num) const Mat<eT>::end_row(const uword row_num) const
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
arma_debug_check( (row_num >= n_rows), "Mat::end_row(): index out of boun ds" ); arma_debug_check( (row_num >= n_rows), "Mat::end_row(): index out of boun ds" );
return typename Mat<eT>::const_row_iterator(*this, row_num + 1); return typename Mat<eT>::const_row_iterator(*this, row_num + 1);
} }
template<typename eT>
inline
typename Mat<eT>::row_col_iterator
Mat<eT>::begin_row_col()
{
return row_col_iterator(*this);
}
template<typename eT>
inline
typename Mat<eT>::const_row_col_iterator
Mat<eT>::begin_row_col() const
{
return const_row_col_iterator(*this);
}
template<typename eT>
inline typename Mat<eT>::row_col_iterator
Mat<eT>::end_row_col()
{
return row_col_iterator(*this, 0, n_cols);
}
template<typename eT>
inline typename Mat<eT>::const_row_col_iterator
Mat<eT>::end_row_col() const
{
return const_row_col_iterator(*this, 0, n_cols);
}
//! resets this matrix to an empty matrix //! resets this matrix to an empty matrix
template<typename eT> template<typename eT>
inline inline
void void
Mat<eT>::clear() Mat<eT>::clear()
{ {
reset(); reset();
} }
//! returns true if the matrix has no elements //! returns true if the matrix has no elements
 End of changes. 13 change blocks. 
18 lines changed or deleted 376 lines changed or added


 SpBase_bones.hpp   SpBase_bones.hpp 
skipping to change at line 53 skipping to change at line 53
inline void print(std::ostream& user_stream, const std::string extra_text = "") const; inline void print(std::ostream& user_stream, const std::string extra_text = "") const;
inline void raw_print(const std::string extra_text = "") const; inline void raw_print(const std::string extra_text = "") const;
inline void raw_print(std::ostream& user_stream, const std::string extra_ text = "") const; inline void raw_print(std::ostream& user_stream, const std::string extra_ text = "") const;
inline void print_dense(const std::string extra_text = "") const; inline void print_dense(const std::string extra_text = "") const;
inline void print_dense(std::ostream& user_stream, const std::string extr a_text = "") const; inline void print_dense(std::ostream& user_stream, const std::string extr a_text = "") const;
inline void raw_print_dense(const std::string extra_text = "") const; inline void raw_print_dense(const std::string extra_text = "") const;
inline void raw_print_dense(std::ostream& user_stream, const std::string extra_text = "") const; inline void raw_print_dense(std::ostream& user_stream, const std::string extra_text = "") const;
inline arma_warn_unused elem_type min() const;
inline arma_warn_unused elem_type max() const;
inline elem_type min(uword& index_of_min_val) const;
inline elem_type max(uword& index_of_max_val) const;
inline elem_type min(uword& row_of_min_val, uword& col_of_min_val) const;
inline elem_type max(uword& row_of_max_val, uword& col_of_max_val) const;
}; };
//! @} //! @}
 End of changes. 1 change blocks. 
0 lines changed or deleted 9 lines changed or added


 SpBase_meat.hpp   SpBase_meat.hpp 
skipping to change at line 149 skipping to change at line 149
template<typename elem_type, typename derived> template<typename elem_type, typename derived>
inline inline
SpMat<elem_type> SpMat<elem_type>
SpBase_eval_expr<elem_type, derived>::eval() const SpBase_eval_expr<elem_type, derived>::eval() const
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
return SpMat<elem_type>( static_cast<const derived&>(*this) ); return SpMat<elem_type>( static_cast<const derived&>(*this) );
} }
template<typename elem_type, typename derived>
inline
arma_warn_unused
elem_type
SpBase<elem_type, derived>::min() const
{
return spop_min::min( (*this).get_ref() );
}
template<typename elem_type, typename derived>
inline
arma_warn_unused
elem_type
SpBase<elem_type, derived>::max() const
{
return spop_max::max( (*this).get_ref() );
}
template<typename elem_type, typename derived>
inline
elem_type
SpBase<elem_type, derived>::min(uword& index_of_min_val) const
{
const SpProxy<derived> P( (*this).get_ref() );
return spop_min::min_with_index(P, index_of_min_val);
}
template<typename elem_type, typename derived>
inline
elem_type
SpBase<elem_type, derived>::max(uword& index_of_max_val) const
{
const SpProxy<derived> P( (*this).get_ref() );
return spop_max::max_with_index(P, index_of_max_val);
}
template<typename elem_type, typename derived>
inline
elem_type
SpBase<elem_type, derived>::min(uword& row_of_min_val, uword& col_of_min_va
l) const
{
const SpProxy<derived> P( (*this).get_ref() );
uword index;
const elem_type val = spop_min::min_with_index(P, index);
const uword local_n_rows = P.get_n_rows();
row_of_min_val = index % local_n_rows;
col_of_min_val = index / local_n_rows;
return val;
}
template<typename elem_type, typename derived>
inline
elem_type
SpBase<elem_type, derived>::max(uword& row_of_max_val, uword& col_of_max_va
l) const
{
const SpProxy<derived> P( (*this).get_ref() );
uword index;
const elem_type val = spop_max::max_with_index(P, index);
const uword local_n_rows = P.get_n_rows();
row_of_max_val = index % local_n_rows;
col_of_max_val = index / local_n_rows;
return val;
}
//! @} //! @}
 End of changes. 1 change blocks. 
0 lines changed or deleted 78 lines changed or added


 SpMat_bones.hpp   SpMat_bones.hpp 
// Copyright (C) 2011-2013 Ryan Curtin // Copyright (C) 2011-2014 Ryan Curtin
// Copyright (C) 2012-2014 Conrad Sanderson // Copyright (C) 2012-2014 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 39 skipping to change at line 39
const uword vec_state; //!< 0: matrix; 1: column vector; 2: row vector const uword vec_state; //!< 0: matrix; 1: column vector; 2: row vector
// So that SpValProxy can call add_element() and delete_element(). // So that SpValProxy can call add_element() and delete_element().
friend class SpValProxy<SpMat<eT> >; friend class SpValProxy<SpMat<eT> >;
friend class SpSubview<eT>; friend class SpSubview<eT>;
/** /**
* The memory used to store the values of the matrix. * The memory used to store the values of the matrix.
* In accordance with the CSC format, this stores only the actual values. * In accordance with the CSC format, this stores only the actual values.
* The correct locations of the values are assembled from the row indices * The correct locations of the values are assembled from the row indices
* and the column pointers. The length of this array is n_nonzero + 1; t * and the column pointers.
he *
* final value ensures the integrity of iterators. If you are planning o * The length of this array is (n_nonzero + 1); the final value ensures
n * the integrity of iterators. If you are planning on resizing this vect
* resizing this vector, it's probably best to use mem_resize() instead. or,
* it's probably best to use mem_resize() instead, which automatically se
ts
* the length to (n_nonzero + 1). If you need to allocate the memory you
rself
* for some reason, be sure to set values[n_nonzero] to 0.
*/ */
const eT* const values; const eT* const values;
/** /**
* The row indices of each value. row_indices[i] is the row of values[i] . * The row indices of each value. row_indices[i] is the row of values[i] .
* The length of this array is n_nonzero + 1; the final value ensures the *
* integrity of iterators. If you are planning on resizing this vector, * The length of this array is (n_nonzero + 1); the final value ensures
it's * the integrity of iterators. If you are planning on resizing this vect
* probably best to use mem_resize() instead. or,
* it's probably best to use mem_resize() instead. If you need to alloca
te
* the memory yourself for some reason, be sure to set row_indices[n_nonz
ero] to 0.
*/ */
const uword* const row_indices; const uword* const row_indices;
/** /**
* The column pointers. This stores the index of the first item in colum n i. * The column pointers. This stores the index of the first item in colum n i.
* That is, values[col_ptrs[i]] is the first value in column i, and it is in * That is, values[col_ptrs[i]] is the first value in column i, and it is in
* row row_indices[col_ptrs[i]]. This array is of length (n_cols + 2); t * the row indicated by row_indices[col_ptrs[i]].
he *
* element col_ptrs[n_cols] should be equal to n_nonzero, and the element * This array is of length (n_cols + 2); the element col_ptrs[n_cols] sho
* col_ptrs[n_cols + 1] is an invalid very large value that ensures the uld
* integrity of iterators. * be equal to n_nonzero, and the element col_ptrs[n_cols + 1] is an inva
lid
* very large value that ensures the integrity of iterators.
*
* The col_ptrs array is set by the init() function (which is called by t
he
* constructors and set_size() and other functions that set the size of t
he
* matrix), so allocating col_ptrs by hand should not be necessary.
*/ */
const uword* const col_ptrs; const uword* const col_ptrs;
inline SpMat(); //! Size will be 0x0 (empty). inline SpMat(); //! Size will be 0x0 (empty).
inline ~SpMat(); inline ~SpMat();
inline SpMat(const uword in_rows, const uword in_cols); inline SpMat(const uword in_rows, const uword in_cols);
inline SpMat(const char* text); inline SpMat(const char* text);
inline const SpMat& operator=(const char* text); inline const SpMat& operator=(const char* text);
inline SpMat(const std::string& text); inline SpMat(const std::string& text);
inline const SpMat& operator=(const std::string& text); inline const SpMat& operator=(const std::string& text);
inline SpMat(const SpMat<eT>& x); inline SpMat(const SpMat<eT>& x);
#if defined(ARMA_USE_CXX11) #if defined(ARMA_USE_CXX11)
inline SpMat(SpMat&& m); inline SpMat(SpMat&& m);
inline const SpMat& operator=(SpMat&& m); inline const SpMat& operator=(SpMat&& m);
#endif #endif
template<typename T1, typename T2> inline SpMat(const Base<uword,T1>& loc template<typename T1, typename T2, typename T3>
ations, const Base<eT,T2>& values, const bool sort_locations = true); inline SpMat(const Base<uword,T1>& rowind, const Base<uword,T2>& colptr,
template<typename T1, typename T2> inline SpMat(const Base<uword,T1>& loc const Base<eT,T3>& values, const uword n_rows, const uword n_cols);
ations, const Base<eT,T2>& values, const uword n_rows, const uword n_cols,
const bool sort_locations = true, const bool check_for_zeros = true);
template<typename T1, typename T2, typename T3> inline SpMat(const Base<u template<typename T1, typename T2>
word,T1>& rowind, const Base<uword,T2>& colptr, const Base<eT,T3>& values, inline SpMat(const Base<uword,T1>& locations, const Base<eT,T2>& values,
const uword n_rows, const uword n_cols); const bool sort_locations = true);
template<typename T1, typename T2>
inline SpMat(const Base<uword,T1>& locations, const Base<eT,T2>& values,
const uword n_rows, const uword n_cols, const bool sort_locations = true, c
onst bool check_for_zeros = true);
template<typename T1, typename T2>
inline SpMat(const bool add_values, const Base<uword,T1>& locations, cons
t Base<eT,T2>& values, const uword n_rows, const uword n_cols, const bool s
ort_locations = true, const bool check_for_zeros = true);
inline const SpMat& operator=(const eT val); //! Sets size to 1x1. inline const SpMat& operator=(const eT val); //! Sets size to 1x1.
inline const SpMat& operator*=(const eT val); inline const SpMat& operator*=(const eT val);
inline const SpMat& operator/=(const eT val); inline const SpMat& operator/=(const eT val);
// operator+=(val) and operator-=(val) are not defined as they don't make sense for sparse matrices // operator+=(val) and operator-=(val) are not defined as they don't make sense for sparse matrices
/** /**
* Operators on other sparse matrices. These work as though you would ex pect. * Operators on other sparse matrices. These work as though you would ex pect.
*/ */
inline const SpMat& operator=(const SpMat& m); inline const SpMat& operator=(const SpMat& m);
skipping to change at line 305 skipping to change at line 323
inline const SpMat& speye(); inline const SpMat& speye();
inline const SpMat& speye(const uword in_rows, const uword in_cols); inline const SpMat& speye(const uword in_rows, const uword in_cols);
inline const SpMat& sprandu(const uword in_rows, const uword in_cols, con st double density); inline const SpMat& sprandu(const uword in_rows, const uword in_cols, con st double density);
inline const SpMat& sprandn(const uword in_rows, const uword in_cols, con st double density); inline const SpMat& sprandn(const uword in_rows, const uword in_cols, con st double density);
inline void reset(); inline void reset();
/**
* Get the minimum or maximum of the matrix.
*/
inline arma_warn_unused eT min() const;
inline eT min(uword& index_of_min_val) const;
inline eT min(uword& row_of_min_val, uword& col_of_min_v
al) const;
inline arma_warn_unused eT max() const;
inline eT max(uword& index_of_max_val) const;
inline eT max(uword& row_of_min_val, uword& col_of_min_v
al) const;
// saving and loading // saving and loading
inline bool save(const std::string name, const file_type type = arma_bi nary, const bool print_status = true) const; inline bool save(const std::string name, const file_type type = arma_bi nary, const bool print_status = true) const;
inline bool save( std::ostream& os, const file_type type = arma_bi nary, const bool print_status = true) const; inline bool save( std::ostream& os, const file_type type = arma_bi nary, const bool print_status = true) const;
inline bool load(const std::string name, const file_type type = arma_bi nary, const bool print_status = true); inline bool load(const std::string name, const file_type type = arma_bi nary, const bool print_status = true);
inline bool load( std::istream& is, const file_type type = arma_bi nary, const bool print_status = true); inline bool load( std::istream& is, const file_type type = arma_bi nary, const bool print_status = true);
inline bool quiet_save(const std::string name, const file_type type = a rma_binary) const; inline bool quiet_save(const std::string name, const file_type type = a rma_binary) const;
inline bool quiet_save( std::ostream& os, const file_type type = a rma_binary) const; inline bool quiet_save( std::ostream& os, const file_type type = a rma_binary) const;
skipping to change at line 347 skipping to change at line 354
class const_iterator; class const_iterator;
class row_iterator; class row_iterator;
class const_row_iterator; class const_row_iterator;
// Iterator base provides basic operators but not how to compare or how t o // Iterator base provides basic operators but not how to compare or how t o
// iterate. // iterate.
class iterator_base class iterator_base
{ {
public: public:
inline iterator_base();
inline iterator_base(const SpMat& in_M); inline iterator_base(const SpMat& in_M);
inline iterator_base(const SpMat& in_M, const uword col, const uword po s); inline iterator_base(const SpMat& in_M, const uword col, const uword po s);
inline arma_hot eT operator*() const; inline arma_hot eT operator*() const;
// Don't hold location internally; call "dummy" methods to get that inf ormation. // Don't hold location internally; call "dummy" methods to get that inf ormation.
arma_inline uword row() const { return M.row_indices[internal_pos]; } arma_inline uword row() const { return M->row_indices[internal_pos]; }
arma_inline uword col() const { return internal_col; } arma_inline uword col() const { return internal_col; }
arma_inline uword pos() const { return internal_pos; } arma_inline uword pos() const { return internal_pos; }
arma_aligned const SpMat& M; arma_aligned const SpMat* M;
arma_aligned uword internal_col; arma_aligned uword internal_col;
arma_aligned uword internal_pos; arma_aligned uword internal_pos;
// So that we satisfy the STL iterator types. // So that we satisfy the STL iterator types.
typedef std::bidirectional_iterator_tag iterator_category; typedef std::bidirectional_iterator_tag iterator_category;
typedef eT value_type; typedef eT value_type;
typedef uword difference_type; // not certain on this one typedef uword difference_type; // not certain on this one
typedef const eT* pointer; typedef const eT* pointer;
typedef const eT& reference; typedef const eT& reference;
}; };
class const_iterator : public iterator_base class const_iterator : public iterator_base
{ {
public: public:
inline const_iterator();
inline const_iterator(const SpMat& in_M, uword initial_pos = 0); // Ass umes initial_pos is valid. inline const_iterator(const SpMat& in_M, uword initial_pos = 0); // Ass umes initial_pos is valid.
//! Once initialized, will be at the first nonzero value after the give n position (using forward columnwise traversal). //! Once initialized, will be at the first nonzero value after the give n position (using forward columnwise traversal).
inline const_iterator(const SpMat& in_M, uword in_row, uword in_col); inline const_iterator(const SpMat& in_M, uword in_row, uword in_col);
//! If you know the exact position of the iterator. in_row is a dummy argument. //! If you know the exact position of the iterator. in_row is a dummy argument.
inline const_iterator(const SpMat& in_M, uword in_row, uword in_col, uw ord in_pos); inline const_iterator(const SpMat& in_M, uword in_row, uword in_col, uw ord in_pos);
inline const_iterator(const const_iterator& other); inline const_iterator(const const_iterator& other);
inline arma_hot const_iterator& operator++(); inline arma_hot const_iterator& operator++();
inline arma_hot const_iterator operator++(int); inline arma_hot const_iterator operator++(int);
skipping to change at line 409 skipping to change at line 418
/** /**
* So that we can iterate over nonzero values, we need an iterator * So that we can iterate over nonzero values, we need an iterator
* implementation. This can't be as simple as Mat's, which is just a poi nter * implementation. This can't be as simple as Mat's, which is just a poi nter
* to an eT. If a value is set to 0 using this iterator, the iterator is no * to an eT. If a value is set to 0 using this iterator, the iterator is no
* longer valid! * longer valid!
*/ */
class iterator : public const_iterator class iterator : public const_iterator
{ {
public: public:
inline iterator() : const_iterator() { }
inline iterator(SpMat& in_M, uword initial_pos = 0) : const_iterator(in _M, initial_pos) { } inline iterator(SpMat& in_M, uword initial_pos = 0) : const_iterator(in _M, initial_pos) { }
inline iterator(SpMat& in_M, uword in_row, uword in_col) : const_iterat or(in_M, in_row, in_col) { } inline iterator(SpMat& in_M, uword in_row, uword in_col) : const_iterat or(in_M, in_row, in_col) { }
inline iterator(SpMat& in_M, uword in_row, uword in_col, uword in_pos) : const_iterator(in_M, in_row, in_col, in_pos) { } inline iterator(SpMat& in_M, uword in_row, uword in_col, uword in_pos) : const_iterator(in_M, in_row, in_col, in_pos) { }
inline iterator(const const_iterator& other) : const_iterator(other) { } inline iterator(const const_iterator& other) : const_iterator(other) { }
inline arma_hot SpValProxy<SpMat<eT> > operator*(); inline arma_hot SpValProxy<SpMat<eT> > operator*();
// overloads needed for return type correctness // overloads needed for return type correctness
inline arma_hot iterator& operator++(); inline arma_hot iterator& operator++();
inline arma_hot iterator operator++(int); inline arma_hot iterator operator++(int);
skipping to change at line 433 skipping to change at line 443
// This has a different value_type than iterator_base. // This has a different value_type than iterator_base.
typedef SpValProxy<SpMat<eT> > value_type; typedef SpValProxy<SpMat<eT> > value_type;
typedef const SpValProxy<SpMat<eT> >* pointer; typedef const SpValProxy<SpMat<eT> >* pointer;
typedef const SpValProxy<SpMat<eT> >& reference; typedef const SpValProxy<SpMat<eT> >& reference;
}; };
class const_row_iterator : public iterator_base class const_row_iterator : public iterator_base
{ {
public: public:
inline const_row_iterator();
inline const_row_iterator(const SpMat& in_M, uword initial_pos = 0); inline const_row_iterator(const SpMat& in_M, uword initial_pos = 0);
//! Once initialized, will be at the first nonzero value after the give n position (using forward row-wise traversal). //! Once initialized, will be at the first nonzero value after the give n position (using forward row-wise traversal).
inline const_row_iterator(const SpMat& in_M, uword in_row, uword in_col ); inline const_row_iterator(const SpMat& in_M, uword in_row, uword in_col );
inline const_row_iterator(const const_row_iterator& other); inline const_row_iterator(const const_row_iterator& other);
inline arma_hot const_row_iterator& operator++(); inline arma_hot const_row_iterator& operator++();
inline arma_hot const_row_iterator operator++(int); inline arma_hot const_row_iterator operator++(int);
inline arma_hot const_row_iterator& operator--(); inline arma_hot const_row_iterator& operator--();
inline arma_hot const_row_iterator operator--(int); inline arma_hot const_row_iterator operator--(int);
uword internal_row; // Hold row internally because we use internal_pos differently. uword internal_row; // Hold row internally because we use internal_pos differently.
uword actual_pos; // Actual position in matrix. uword actual_pos; // Actual position in matrix.
arma_inline eT operator*() const { return iterator_base::M.values[actua l_pos]; } arma_inline eT operator*() const { return iterator_base::M->values[actu al_pos]; }
arma_inline uword row() const { return internal_row; } arma_inline uword row() const { return internal_row; }
inline arma_hot bool operator==(const const_iterator& rhs) const; inline arma_hot bool operator==(const const_iterator& rhs) const;
inline arma_hot bool operator!=(const const_iterator& rhs) const; inline arma_hot bool operator!=(const const_iterator& rhs) const;
inline arma_hot bool operator==(const typename SpSubview<eT>::const_ite rator& rhs) const; inline arma_hot bool operator==(const typename SpSubview<eT>::const_ite rator& rhs) const;
inline arma_hot bool operator!=(const typename SpSubview<eT>::const_ite rator& rhs) const; inline arma_hot bool operator!=(const typename SpSubview<eT>::const_ite rator& rhs) const;
inline arma_hot bool operator==(const const_row_iterator& rhs) const; inline arma_hot bool operator==(const const_row_iterator& rhs) const;
inline arma_hot bool operator!=(const const_row_iterator& rhs) const; inline arma_hot bool operator!=(const const_row_iterator& rhs) const;
inline arma_hot bool operator==(const typename SpSubview<eT>::const_row _iterator& rhs) const; inline arma_hot bool operator==(const typename SpSubview<eT>::const_row _iterator& rhs) const;
inline arma_hot bool operator!=(const typename SpSubview<eT>::const_row _iterator& rhs) const; inline arma_hot bool operator!=(const typename SpSubview<eT>::const_row _iterator& rhs) const;
}; };
class row_iterator : public const_row_iterator class row_iterator : public const_row_iterator
{ {
public: public:
inline row_iterator() : const_row_iterator() {}
inline row_iterator(SpMat& in_M, uword initial_pos = 0) : const_row_ite rator(in_M, initial_pos) { } inline row_iterator(SpMat& in_M, uword initial_pos = 0) : const_row_ite rator(in_M, initial_pos) { }
//! Once initialized, will be at the first nonzero value after the give n position (using forward row-wise traversal). //! Once initialized, will be at the first nonzero value after the give n position (using forward row-wise traversal).
inline row_iterator(SpMat& in_M, uword in_row, uword in_col) : const_ro w_iterator(in_M, in_row, in_col) { } inline row_iterator(SpMat& in_M, uword in_row, uword in_col) : const_ro w_iterator(in_M, in_row, in_col) { }
inline row_iterator(const row_iterator& other) : const_row_iterator(oth er) { } inline row_iterator(const row_iterator& other) : const_row_iterator(oth er) { }
inline arma_hot SpValProxy<SpMat<eT> > operator*(); inline arma_hot SpValProxy<SpMat<eT> > operator*();
// overloads required for return type correctness // overloads required for return type correctness
inline arma_hot row_iterator& operator++(); inline arma_hot row_iterator& operator++();
inline arma_hot row_iterator operator++(int); inline arma_hot row_iterator operator++(int);
inline arma_hot row_iterator& operator--(); inline arma_hot row_iterator& operator--();
inline arma_hot row_iterator operator--(int); inline arma_hot row_iterator operator--(int);
// This has a different value_type than iterator_base. // This has a different value_type than iterator_base.
typedef SpValProxy<SpMat<eT> > value_type; typedef SpValProxy<SpMat<eT> > value_type;
typedef const SpValProxy<SpMat<eT> >* pointer; typedef const SpValProxy<SpMat<eT> >* pointer;
typedef const SpValProxy<SpMat<eT> >& reference; typedef const SpValProxy<SpMat<eT> >& reference;
}; };
typedef iterator row_col_iterator;
typedef const_iterator const_row_col_iterator;
inline iterator begin(); inline iterator begin();
inline const_iterator begin() const; inline const_iterator begin() const;
inline iterator end(); inline iterator end();
inline const_iterator end() const; inline const_iterator end() const;
inline iterator begin_col(const uword col_num); inline iterator begin_col(const uword col_num);
inline const_iterator begin_col(const uword col_num) const; inline const_iterator begin_col(const uword col_num) const;
inline iterator end_col(const uword col_num); inline iterator end_col(const uword col_num);
inline const_iterator end_col(const uword col_num) const; inline const_iterator end_col(const uword col_num) const;
inline row_iterator begin_row(const uword row_num = 0); inline row_iterator begin_row(const uword row_num = 0);
inline const_row_iterator begin_row(const uword row_num = 0) const; inline const_row_iterator begin_row(const uword row_num = 0) const;
inline row_iterator end_row(); inline row_iterator end_row();
inline const_row_iterator end_row() const; inline const_row_iterator end_row() const;
inline row_iterator end_row(const uword row_num); inline row_iterator end_row(const uword row_num);
inline const_row_iterator end_row(const uword row_num) const; inline const_row_iterator end_row(const uword row_num) const;
inline row_col_iterator begin_row_col();
inline const_row_col_iterator begin_row_col() const;
inline row_col_iterator end_row_col();
inline const_row_col_iterator end_row_col() const;
inline void clear(); inline void clear();
inline bool empty() const; inline bool empty() const;
inline uword size() const; inline uword size() const;
/** /**
* 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.
*/ */
skipping to change at line 546 skipping to change at line 567
* Initialize the matrix from text. Data is (of course) not preserved, a nd * Initialize the matrix from text. Data is (of course) not preserved, a nd
* the size will be reset. * the size will be reset.
*/ */
inline void init(const std::string& text); inline void init(const std::string& text);
/** /**
* Initialize from another matrix (copy). * Initialize from another matrix (copy).
*/ */
inline void init(const SpMat& x); inline void init(const SpMat& x);
inline void init_batch(const Mat<uword>& locations, const Mat<eT>& values inline void init_batch_std(const Mat<uword>& locations, const Mat<eT>& va
, const bool sort_locations); lues, const bool sort_locations);
inline void init_batch_add(const Mat<uword>& locations, const Mat<eT>& va
lues, const bool sort_locations);
private: private:
/** /**
* Return the given element. * Return the given element.
*/ */
inline arma_hot arma_warn_unused SpValProxy<SpMat<eT> > get_value(const u word i); inline arma_hot arma_warn_unused SpValProxy<SpMat<eT> > get_value(const u word i);
inline arma_hot arma_warn_unused eT get_value(const u word i) const; inline arma_hot arma_warn_unused eT get_value(const u word i) const;
inline arma_hot arma_warn_unused SpValProxy<SpMat<eT> > get_value(const u word in_row, const uword in_col); inline arma_hot arma_warn_unused SpValProxy<SpMat<eT> > get_value(const u word in_row, const uword in_col);
 End of changes. 19 change blocks. 
45 lines changed or deleted 73 lines changed or added


 SpMat_iterators_meat.hpp   SpMat_iterators_meat.hpp 
// Copyright (C) 2011-2012 Ryan Curtin // Copyright (C) 2011-2014 Ryan Curtin
// Copyright (C) 2012-2014 Conrad Sanderson
// Copyright (C) 2011 Matthew Amidon // Copyright (C) 2011 Matthew Amidon
// Copyright (C) 2012 Conrad Sanderson
// //
// 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
//! @{ //! @{
/////////////////////////////////////////////////////////////////////////// //// /////////////////////////////////////////////////////////////////////////// ////
// SpMat::iterator_base implementation // // SpMat::iterator_base implementation //
/////////////////////////////////////////////////////////////////////////// //// /////////////////////////////////////////////////////////////////////////// ////
template<typename eT> template<typename eT>
inline inline
SpMat<eT>::iterator_base::iterator_base()
: M(NULL)
, internal_col(0)
, internal_pos(0)
{
// Technically this iterator is invalid (it may not point to a real eleme
nt)
}
template<typename eT>
inline
SpMat<eT>::iterator_base::iterator_base(const SpMat<eT>& in_M) SpMat<eT>::iterator_base::iterator_base(const SpMat<eT>& in_M)
: M(in_M) : M(&in_M)
, internal_col(0) , internal_col(0)
, internal_pos(0) , internal_pos(0)
{ {
// Technically this iterator is invalid (it may not point to a real eleme nt) // Technically this iterator is invalid (it may not point to a real eleme nt)
} }
template<typename eT> template<typename eT>
inline inline
SpMat<eT>::iterator_base::iterator_base(const SpMat<eT>& in_M, const uword in_col, const uword in_pos) SpMat<eT>::iterator_base::iterator_base(const SpMat<eT>& in_M, const uword in_col, const uword in_pos)
: M(in_M) : M(&in_M)
, internal_col(in_col) , internal_col(in_col)
, internal_pos(in_pos) , internal_pos(in_pos)
{ {
// Nothing to do. // Nothing to do.
} }
template<typename eT> template<typename eT>
inline inline
arma_hot arma_hot
eT eT
SpMat<eT>::iterator_base::operator*() const SpMat<eT>::iterator_base::operator*() const
{ {
return M.values[internal_pos]; return M->values[internal_pos];
} }
/////////////////////////////////////////////////////////////////////////// //// /////////////////////////////////////////////////////////////////////////// ////
// SpMat::const_iterator implementation // // SpMat::const_iterator implementation //
/////////////////////////////////////////////////////////////////////////// //// /////////////////////////////////////////////////////////////////////////// ////
template<typename eT> template<typename eT>
inline inline
SpMat<eT>::const_iterator::const_iterator()
: iterator_base()
{
}
template<typename eT>
inline
SpMat<eT>::const_iterator::const_iterator(const SpMat<eT>& in_M, uword init ial_pos) SpMat<eT>::const_iterator::const_iterator(const SpMat<eT>& in_M, uword init ial_pos)
: iterator_base(in_M, 0, initial_pos) : iterator_base(in_M, 0, initial_pos)
{ {
// Corner case for empty matrices. // Corner case for empty matrices.
if(in_M.n_nonzero == 0) if(in_M.n_nonzero == 0)
{ {
iterator_base::internal_col = in_M.n_cols; iterator_base::internal_col = in_M.n_cols;
return; return;
} }
// Determine which column we should be in. // Determine which column we should be in.
while(iterator_base::M.col_ptrs[iterator_base::internal_col + 1] <= itera tor_base::internal_pos) while(iterator_base::M->col_ptrs[iterator_base::internal_col + 1] <= iter ator_base::internal_pos)
{ {
iterator_base::internal_col++; iterator_base::internal_col++;
} }
} }
template<typename eT> template<typename eT>
inline inline
SpMat<eT>::const_iterator::const_iterator(const SpMat<eT>& in_M, uword in_r ow, uword in_col) SpMat<eT>::const_iterator::const_iterator(const SpMat<eT>& in_M, uword in_r ow, uword in_col)
: iterator_base(in_M, in_col, 0) : iterator_base(in_M, in_col, 0)
{ {
// So we have a position we want to be right after. Skip to the column. // So we have a position we want to be right after. Skip to the column.
iterator_base::internal_pos = iterator_base::M.col_ptrs[iterator_base::in ternal_col]; iterator_base::internal_pos = iterator_base::M->col_ptrs[iterator_base::i nternal_col];
// Now we have to make sure that is the right column. // Now we have to make sure that is the right column.
while(iterator_base::M.col_ptrs[iterator_base::internal_col + 1] <= itera tor_base::internal_pos) while(iterator_base::M->col_ptrs[iterator_base::internal_col + 1] <= iter ator_base::internal_pos)
{ {
iterator_base::internal_col++; iterator_base::internal_col++;
} }
// Now we have to get to the right row. // Now we have to get to the right row.
while((iterator_base::M.row_indices[iterator_base::internal_pos] < in_row ) && (iterator_base::internal_col == in_col)) while((iterator_base::M->row_indices[iterator_base::internal_pos] < in_ro w) && (iterator_base::internal_col == in_col))
{ {
++(*this); // Increment iterator. ++(*this); // Increment iterator.
} }
} }
template<typename eT> template<typename eT>
inline inline
SpMat<eT>::const_iterator::const_iterator(const SpMat<eT>& in_M, const uwor d /* in_row */, const uword in_col, const uword in_pos) SpMat<eT>::const_iterator::const_iterator(const SpMat<eT>& in_M, const uwor d /* in_row */, const uword in_col, const uword in_pos)
: iterator_base(in_M, in_col, in_pos) : iterator_base(in_M, in_col, in_pos)
{ {
// Nothing to do. // Nothing to do.
} }
template<typename eT> template<typename eT>
inline inline
SpMat<eT>::const_iterator::const_iterator(const typename SpMat<eT>::const_i terator& other) SpMat<eT>::const_iterator::const_iterator(const typename SpMat<eT>::const_i terator& other)
: iterator_base(other.M, other.internal_col, other.internal_pos) : iterator_base(*other.M, other.internal_col, other.internal_pos)
{ {
// Nothing to do. // Nothing to do.
} }
template<typename eT> template<typename eT>
inline inline
arma_hot arma_hot
typename SpMat<eT>::const_iterator& typename SpMat<eT>::const_iterator&
SpMat<eT>::const_iterator::operator++() SpMat<eT>::const_iterator::operator++()
{ {
++iterator_base::internal_pos; ++iterator_base::internal_pos;
if (iterator_base::internal_pos == iterator_base::M.n_nonzero) if (iterator_base::internal_pos == iterator_base::M->n_nonzero)
{ {
iterator_base::internal_col = iterator_base::M.n_cols; iterator_base::internal_col = iterator_base::M->n_cols;
return *this; return *this;
} }
// Check to see if we moved a column. // Check to see if we moved a column.
while (iterator_base::M.col_ptrs[iterator_base::internal_col + 1] <= iter ator_base::internal_pos) while (iterator_base::M->col_ptrs[iterator_base::internal_col + 1] <= ite rator_base::internal_pos)
{ {
++iterator_base::internal_col; ++iterator_base::internal_col;
} }
return *this; return *this;
} }
template<typename eT> template<typename eT>
inline inline
arma_hot arma_hot
skipping to change at line 156 skipping to change at line 173
{ {
//iterator_base::M.print("M"); //iterator_base::M.print("M");
// printf("decrement from %d, %d, %d\n", iterator_base::internal_pos, ite rator_base::internal_col, iterator_base::row()); // printf("decrement from %d, %d, %d\n", iterator_base::internal_pos, ite rator_base::internal_col, iterator_base::row());
--iterator_base::internal_pos; --iterator_base::internal_pos;
// printf("now pos %d\n", iterator_base::internal_pos); // printf("now pos %d\n", iterator_base::internal_pos);
// First, see if we moved back a column. // First, see if we moved back a column.
while (iterator_base::internal_pos < iterator_base::M.col_ptrs[iterator_b ase::internal_col]) while (iterator_base::internal_pos < iterator_base::M->col_ptrs[iterator_ base::internal_col])
{ {
// printf("colptr %d (col %d)\n", iterator_base::M.col_ptrs[iterator_ba se::internal_col], iterator_base::internal_col); // printf("colptr %d (col %d)\n", iterator_base::M.col_ptrs[iterator_ba se::internal_col], iterator_base::internal_col);
--iterator_base::internal_col; --iterator_base::internal_col;
} }
return *this; return *this;
} }
template<typename eT> template<typename eT>
skipping to change at line 262 skipping to change at line 279
// SpMat::iterator implementation // // SpMat::iterator implementation //
/////////////////////////////////////////////////////////////////////////// //// /////////////////////////////////////////////////////////////////////////// ////
template<typename eT> template<typename eT>
inline inline
arma_hot arma_hot
SpValProxy<SpMat<eT> > SpValProxy<SpMat<eT> >
SpMat<eT>::iterator::operator*() SpMat<eT>::iterator::operator*()
{ {
return SpValProxy<SpMat<eT> >( return SpValProxy<SpMat<eT> >(
iterator_base::M.row_indices[iterator_base::internal_pos], iterator_base::M->row_indices[iterator_base::internal_pos],
iterator_base::internal_col, iterator_base::internal_col,
access::rw(iterator_base::M), access::rw(*iterator_base::M),
&access::rw(iterator_base::M.values[iterator_base::internal_pos])); &access::rw(iterator_base::M->values[iterator_base::internal_pos]));
} }
template<typename eT> template<typename eT>
inline inline
arma_hot arma_hot
typename SpMat<eT>::iterator& typename SpMat<eT>::iterator&
SpMat<eT>::iterator::operator++() SpMat<eT>::iterator::operator++()
{ {
const_iterator::operator++(); const_iterator::operator++();
return *this; return *this;
skipping to change at line 321 skipping to change at line 338
return tmp; return tmp;
} }
/////////////////////////////////////////////////////////////////////////// //// /////////////////////////////////////////////////////////////////////////// ////
// SpMat::const_row_iterator implementation // // SpMat::const_row_iterator implementation //
/////////////////////////////////////////////////////////////////////////// //// /////////////////////////////////////////////////////////////////////////// ////
/** /**
* Initialize the const_row_iterator. * Initialize the const_row_iterator.
*/ */
template<typename eT>
inline
SpMat<eT>::const_row_iterator::const_row_iterator()
: iterator_base()
, internal_row(0)
, actual_pos(0)
{
}
template<typename eT> template<typename eT>
inline inline
SpMat<eT>::const_row_iterator::const_row_iterator(const SpMat<eT>& in_M, uw ord initial_pos) SpMat<eT>::const_row_iterator::const_row_iterator(const SpMat<eT>& in_M, uw ord initial_pos)
: iterator_base(in_M, 0, initial_pos) : iterator_base(in_M, 0, initial_pos)
, internal_row(0) , internal_row(0)
, actual_pos(0) , actual_pos(0)
{ {
// Corner case for empty matrix. // Corner case for empty matrix.
if(in_M.n_nonzero == 0) if(in_M.n_nonzero == 0)
{ {
skipping to change at line 344 skipping to change at line 371
} }
// We don't count zeros in our position count, so we have to find the non zero // We don't count zeros in our position count, so we have to find the non zero
// value corresponding to the given initial position. We assume initial_ pos // value corresponding to the given initial position. We assume initial_ pos
// is valid. // is valid.
// This is irritating because we don't know where the elements are in eac h // This is irritating because we don't know where the elements are in eac h
// row. What we will do is loop across all columns looking for elements in // row. What we will do is loop across all columns looking for elements in
// row 0 (and add to our sum), then in row 1, and so forth, until we get to // row 0 (and add to our sum), then in row 1, and so forth, until we get to
// the desired position. // the desired position.
uword cur_pos = -1; uword cur_pos = std::numeric_limits<uword>::max(); // Invalid value.
uword cur_row = 0; uword cur_row = 0;
uword cur_col = 0; uword cur_col = 0;
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 < iterat or_base::M.col_ptrs[cur_col + 1]) && (iterator_base::M.row_indices[iterator _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)
{ {
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;
} }
else if(row_index > cur_row) else if(row_index > cur_row)
{ {
break; // Can't be in this column. break; // Can't be in this column.
} }
} }
cur_col++; // Done with the column. Move on. cur_col++; // Done with the column. Move on.
if (cur_col == iterator_base::M.n_cols) if (cur_col == iterator_base::M->n_cols)
{ {
// We are out of columns. Loop back to the beginning and look on the // We are out of columns. Loop back to the beginning and look on the
// next row. // next row.
cur_col = 0; cur_col = 0;
cur_row++; cur_row++;
} }
} }
} }
template<typename eT> template<typename eT>
skipping to change at line 415 skipping to change at line 442
internal_row = it.internal_row; internal_row = it.internal_row;
actual_pos = it.actual_pos; actual_pos = it.actual_pos;
} }
/** /**
* Initialize the const_row_iterator from another const_row_iterator. * Initialize the const_row_iterator from another const_row_iterator.
*/ */
template<typename eT> template<typename eT>
inline inline
SpMat<eT>::const_row_iterator::const_row_iterator(const typename SpMat<eT>: :const_row_iterator& other) SpMat<eT>::const_row_iterator::const_row_iterator(const typename SpMat<eT>: :const_row_iterator& other)
: iterator_base(other.M, other.internal_col, other.internal_pos) : iterator_base(*other.M, other.internal_col, other.internal_pos)
, internal_row(other.internal_row) , internal_row(other.internal_row)
, actual_pos(other.actual_pos) , actual_pos(other.actual_pos)
{ {
// Nothing to do. // Nothing to do.
} }
/** /**
* Increment the row_iterator. * Increment the row_iterator.
*/ */
template<typename eT> template<typename eT>
inline inline
arma_hot arma_hot
typename SpMat<eT>::const_row_iterator& typename SpMat<eT>::const_row_iterator&
SpMat<eT>::const_row_iterator::operator++() SpMat<eT>::const_row_iterator::operator++()
{ {
// We just need to find the next nonzero element. // We just need to find the next nonzero element.
iterator_base::internal_pos++; iterator_base::internal_pos++;
if(iterator_base::internal_pos == iterator_base::M.n_nonzero) if(iterator_base::internal_pos == iterator_base::M->n_nonzero)
{ {
internal_row = iterator_base::M.n_rows; internal_row = iterator_base::M->n_rows;
iterator_base::internal_col = 0; iterator_base::internal_col = 0;
actual_pos = iterator_base::M.n_nonzero; actual_pos = iterator_base::M->n_nonzero;
return *this; return *this;
} }
// Otherwise, we need to search. // Otherwise, we need to search.
uword cur_col = iterator_base::internal_col; uword cur_col = iterator_base::internal_col;
uword cur_row = internal_row; uword cur_row = internal_row;
while (true) // This loop is terminated from the inside. while (true) // This loop is terminated from the inside.
{ {
// Increment the current column and see if we are now on a new row. // Increment the current column and see if we are now on a new row.
if (++cur_col == iterator_base::M.n_cols) if (++cur_col == iterator_base::M->n_cols)
{ {
cur_col = 0; cur_col = 0;
cur_row++; cur_row++;
} }
// Is there anything in this new column? // Is there anything in this new column?
for (uword ind = 0; ((iterator_base::M.col_ptrs[cur_col] + ind < iterat or_base::M.col_ptrs[cur_col + 1]) && (iterator_base::M.row_indices[iterator _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++)
{ {
if (iterator_base::M.row_indices[iterator_base::M.col_ptrs[cur_col] + ind] == cur_row) if (iterator_base::M->row_indices[iterator_base::M->col_ptrs[cur_col] + ind] == cur_row)
{ {
// We have successfully incremented. // We have successfully incremented.
internal_row = cur_row; internal_row = cur_row;
iterator_base::internal_col = cur_col; iterator_base::internal_col = cur_col;
actual_pos = iterator_base::M.col_ptrs[cur_col] + ind; actual_pos = iterator_base::M->col_ptrs[cur_col] + ind;
return *this; // Now we are done. return *this; // Now we are done.
} }
} }
} }
} }
/** /**
* Increment the row_iterator (but do not return anything. * Increment the row_iterator (but do not return anything.
*/ */
skipping to change at line 506 skipping to change at line 533
{ {
iterator_base::internal_pos--; iterator_base::internal_pos--;
// We have to search backwards. // We have to search backwards.
uword cur_col = iterator_base::internal_col; uword cur_col = iterator_base::internal_col;
uword cur_row = internal_row; uword cur_row = internal_row;
while (true) // This loop is terminated from the inside. while (true) // This loop is terminated from the inside.
{ {
// Decrement the current column and see if we are now on a new row. Th is is a uword so a negativity check won't work. // Decrement the current column and see if we are now on a new row. Th is is a uword so a negativity check won't work.
if (--cur_col > iterator_base::M.n_cols /* this means it underflew */) if (--cur_col > iterator_base::M->n_cols /* this means it underflew */)
{ {
cur_col = iterator_base::M.n_cols - 1; cur_col = iterator_base::M->n_cols - 1;
cur_row--; cur_row--;
} }
// Is there anything in this new column? // Is there anything in this new column?
for (uword ind = 0; ((iterator_base::M.col_ptrs[cur_col] + ind < iterat or_base::M.col_ptrs[cur_col + 1]) && (iterator_base::M.row_indices[iterator _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++)
{ {
if (iterator_base::M.row_indices[iterator_base::M.col_ptrs[cur_col] + ind] == cur_row) if (iterator_base::M->row_indices[iterator_base::M->col_ptrs[cur_col] + ind] == cur_row)
{ {
// We have successfully decremented. // We have successfully decremented.
iterator_base::internal_col = cur_col; iterator_base::internal_col = cur_col;
internal_row = cur_row; internal_row = cur_row;
actual_pos = iterator_base::M.col_ptrs[cur_col] + ind; actual_pos = iterator_base::M->col_ptrs[cur_col] + ind;
return *this; // Now we are done. return *this; // Now we are done.
} }
} }
} }
} }
/** /**
* Decrement the row_iterator. * Decrement the row_iterator.
*/ */
skipping to change at line 629 skipping to change at line 656
template<typename eT> template<typename eT>
inline inline
arma_hot arma_hot
SpValProxy<SpMat<eT> > SpValProxy<SpMat<eT> >
SpMat<eT>::row_iterator::operator*() SpMat<eT>::row_iterator::operator*()
{ {
return SpValProxy<SpMat<eT> >( return SpValProxy<SpMat<eT> >(
const_row_iterator::internal_row, const_row_iterator::internal_row,
iterator_base::internal_col, iterator_base::internal_col,
access::rw(iterator_base::M), access::rw(*iterator_base::M),
&access::rw(iterator_base::M.values[const_row_iterator::actual_pos])); &access::rw(iterator_base::M->values[const_row_iterator::actual_pos]));
} }
template<typename eT> template<typename eT>
inline inline
arma_hot arma_hot
typename SpMat<eT>::row_iterator& typename SpMat<eT>::row_iterator&
SpMat<eT>::row_iterator::operator++() SpMat<eT>::row_iterator::operator++()
{ {
const_row_iterator::operator++(); const_row_iterator::operator++();
return *this; return *this;
 End of changes. 38 change blocks. 
37 lines changed or deleted 65 lines changed or added


 SpMat_meat.hpp   SpMat_meat.hpp 
// Copyright (C) 2011-2013 Ryan Curtin // Copyright (C) 2011-2014 Ryan Curtin
// Copyright (C) 2012-2014 Conrad Sanderson // Copyright (C) 2012-2014 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 243 skipping to change at line 243
{ {
filtered_vals[index] = vals[i]; filtered_vals[index] = vals[i];
filtered_locs.at(0, index) = locs.at(0, i); filtered_locs.at(0, index) = locs.at(0, i);
filtered_locs.at(1, index) = locs.at(1, i); filtered_locs.at(1, index) = locs.at(1, i);
++index; ++index;
} }
} }
init_batch(filtered_locs, filtered_vals, sort_locations); init_batch_std(filtered_locs, filtered_vals, sort_locations);
} }
else else
{ {
init_batch(locs, vals, sort_locations); init_batch_std(locs, vals, sort_locations);
} }
} }
//! Insert a large number of values at once. //! Insert a large number of values at once.
//! locations.row[0] should be row indices, locations.row[1] should be colu mn indices, //! locations.row[0] should be row indices, locations.row[1] should be colu mn indices,
//! and values should be the corresponding values. //! and values should be the corresponding values.
//! If sort_locations is false, then it is assumed that the locations and v alues //! If sort_locations is false, then it is assumed that the locations and v alues
//! are already sorted in column-major ordering. //! are already sorted in column-major ordering.
//! In this constructor the size is explicitly given. //! In this constructor the size is explicitly given.
template<typename eT> template<typename eT>
skipping to change at line 314 skipping to change at line 314
{ {
filtered_vals[index] = vals[i]; filtered_vals[index] = vals[i];
filtered_locs.at(0, index) = locs.at(0, i); filtered_locs.at(0, index) = locs.at(0, i);
filtered_locs.at(1, index) = locs.at(1, i); filtered_locs.at(1, index) = locs.at(1, i);
++index; ++index;
} }
} }
init_batch(filtered_locs, filtered_vals, sort_locations); init_batch_std(filtered_locs, filtered_vals, sort_locations);
} }
else else
{ {
init_batch(locs, vals, sort_locations); init_batch_std(locs, vals, sort_locations);
} }
} }
else else
{ {
init_batch(locs, vals, sort_locations); init_batch_std(locs, vals, sort_locations);
}
}
template<typename eT>
template<typename T1, typename T2>
inline
SpMat<eT>::SpMat(const bool add_values, const Base<uword,T1>& locations_exp
r, const Base<eT,T2>& vals_expr, const uword in_n_rows, const uword in_n_co
ls, const bool sort_locations, const bool check_for_zeros)
: n_rows(0)
, n_cols(0)
, n_elem(0)
, n_nonzero(0)
, vec_state(0)
, values(NULL)
, row_indices(NULL)
, col_ptrs(NULL)
{
arma_extra_debug_sigprint_this(this);
const unwrap<T1> locs_tmp( locations_expr.get_ref() );
const unwrap<T2> vals_tmp( vals_expr.get_ref() );
const Mat<uword>& locs = locs_tmp.M;
const Mat<eT>& vals = vals_tmp.M;
arma_debug_check( (vals.is_vec() == false), "SpMat::SpMat(): given 'v
alues' object is not a vector" );
arma_debug_check( (locs.n_rows != 2), "SpMat::SpMat(): location
s matrix must have two rows" );
arma_debug_check( (locs.n_cols != vals.n_elem), "SpMat::SpMat(): number o
f locations is different than number of values" );
init(in_n_rows, in_n_cols);
// Ensure that there are no zeros, unless the user asked not to.
if(check_for_zeros)
{
const uword N_old = vals.n_elem;
uword N_new = 0;
for(uword i = 0; i < N_old; ++i)
{
if(vals[i] != eT(0)) { ++N_new; }
}
if(N_new != N_old)
{
Col<eT> filtered_vals(N_new);
Mat<uword> filtered_locs(2, N_new);
uword index = 0;
for(uword i = 0; i < N_old; ++i)
{
if(vals[i] != eT(0))
{
filtered_vals[index] = vals[i];
filtered_locs.at(0, index) = locs.at(0, i);
filtered_locs.at(1, index) = locs.at(1, i);
++index;
}
}
add_values ? init_batch_add(filtered_locs, filtered_vals, sort_locati
ons) : init_batch_std(filtered_locs, filtered_vals, sort_locations);
}
else
{
add_values ? init_batch_add(locs, vals, sort_locations) : init_batch_
std(locs, vals, sort_locations);
}
}
else
{
add_values ? init_batch_add(locs, vals, sort_locations) : init_batch_st
d(locs, vals, sort_locations);
} }
} }
//! Insert a large number of values at once. //! Insert a large number of values at once.
//! Per CSC format, rowind_expr should be row indices, //! Per CSC format, rowind_expr should be row indices,
//! colptr_expr should column ptr indices locations, //! colptr_expr should column ptr indices locations,
//! and values should be the corresponding values. //! and values should be the corresponding values.
//! In this constructor the size is explicitly given. //! In this constructor the size is explicitly given.
//! Values are assumed to be sorted, and the size //! Values are assumed to be sorted, and the size
//! information is trusted //! information is trusted
skipping to change at line 3099 skipping to change at line 3169
case 1: case 1:
init(0, 1); init(0, 1);
break; break;
case 2: case 2:
init(1, 0); init(1, 0);
break; break;
} }
} }
/**
* Get the minimum or the maximum of the matrix.
*/
template<typename eT>
inline
arma_warn_unused
eT
SpMat<eT>::min() const
{
arma_extra_debug_sigprint();
arma_debug_check((n_elem == 0), "min(): object has no elements");
if (n_nonzero == 0)
{
return 0;
}
eT val = op_min::direct_min(values, n_nonzero);
if ((val > 0) && (n_nonzero < n_elem)) // A sparse 0 is less.
{
val = 0;
}
return val;
}
template<typename eT>
inline
eT
SpMat<eT>::min(uword& index_of_min_val) const
{
arma_extra_debug_sigprint();
arma_debug_check((n_elem == 0), "min(): object has no elements");
eT val = 0;
if (n_nonzero == 0) // There are no other elements. It must be 0.
{
index_of_min_val = 0;
}
else
{
uword location;
val = op_min::direct_min(values, n_nonzero, location);
if ((val > 0) && (n_nonzero < n_elem)) // A sparse 0 is less.
{
val = 0;
// Give back the index to the first zero position.
index_of_min_val = 0;
while (get_position(index_of_min_val) == index_of_min_val) // An elem
ent exists at that position.
{
index_of_min_val++;
}
}
else
{
index_of_min_val = get_position(location);
}
}
return val;
}
template<typename eT>
inline
eT
SpMat<eT>::min(uword& row_of_min_val, uword& col_of_min_val) const
{
arma_extra_debug_sigprint();
arma_debug_check((n_elem == 0), "min(): object has no elements");
eT val = 0;
if (n_nonzero == 0) // There are no other elements. It must be 0.
{
row_of_min_val = 0;
col_of_min_val = 0;
}
else
{
uword location;
val = op_min::direct_min(values, n_nonzero, location);
if ((val > 0) && (n_nonzero < n_elem)) // A sparse 0 is less.
{
val = 0;
location = 0;
while (get_position(location) == location) // An element exists at th
at position.
{
location++;
}
row_of_min_val = location % n_rows;
col_of_min_val = location / n_rows;
}
else
{
get_position(location, row_of_min_val, col_of_min_val);
}
}
return val;
}
template<typename eT>
inline
arma_warn_unused
eT
SpMat<eT>::max() const
{
arma_extra_debug_sigprint();
arma_debug_check((n_elem == 0), "max(): object has no elements");
if (n_nonzero == 0)
{
return 0;
}
eT val = op_max::direct_max(values, n_nonzero);
if ((val < 0) && (n_nonzero < n_elem)) // A sparse 0 is more.
{
return 0;
}
return val;
}
template<typename eT>
inline
eT
SpMat<eT>::max(uword& index_of_max_val) const
{
arma_extra_debug_sigprint();
arma_debug_check((n_elem == 0), "max(): object has no elements");
eT val = 0;
if (n_nonzero == 0)
{
index_of_max_val = 0;
}
else
{
uword location;
val = op_max::direct_max(values, n_nonzero, location);
if ((val < 0) && (n_nonzero < n_elem)) // A sparse 0 is more.
{
val = 0;
location = 0;
while (get_position(location) == location) // An element exists at th
at position.
{
location++;
}
}
else
{
index_of_max_val = get_position(location);
}
}
return val;
}
template<typename eT>
inline
eT
SpMat<eT>::max(uword& row_of_max_val, uword& col_of_max_val) const
{
arma_extra_debug_sigprint();
arma_debug_check((n_elem == 0), "max(): object has no elements");
eT val = 0;
if (n_nonzero == 0)
{
row_of_max_val = 0;
col_of_max_val = 0;
}
else
{
uword location;
val = op_max::direct_max(values, n_nonzero, location);
if ((val < 0) && (n_nonzero < n_elem)) // A sparse 0 is more.
{
val = 0;
location = 0;
while (get_position(location) == location) // An element exists at th
at position.
{
location++;
}
row_of_max_val = location % n_rows;
col_of_max_val = location / n_rows;
}
else
{
get_position(location, row_of_max_val, col_of_max_val);
}
}
return val;
}
//! save the matrix to a file //! save the matrix to a file
template<typename eT> template<typename eT>
inline inline
bool bool
SpMat<eT>::save(const std::string name, const file_type type, const bool pr int_status) const SpMat<eT>::save(const std::string name, const file_type type, const bool pr int_status) const
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
bool save_okay; bool save_okay;
skipping to change at line 3774 skipping to change at line 3616
arrayops::copy(access::rwp(row_indices), x.row_indices, x.n_nonzero + 1 ); arrayops::copy(access::rwp(row_indices), x.row_indices, x.n_nonzero + 1 );
arrayops::copy(access::rwp(col_ptrs), x.col_ptrs, x.n_cols + 1); arrayops::copy(access::rwp(col_ptrs), x.col_ptrs, x.n_cols + 1);
access::rw(n_nonzero) = x.n_nonzero; access::rw(n_nonzero) = x.n_nonzero;
} }
} }
template<typename eT> template<typename eT>
inline inline
void void
SpMat<eT>::init_batch(const Mat<uword>& locs, const Mat<eT>& vals, const bo ol sort_locations) SpMat<eT>::init_batch_std(const Mat<uword>& locs, const Mat<eT>& vals, cons t bool sort_locations)
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
// Resize to correct number of elements. // Resize to correct number of elements.
mem_resize(vals.n_elem); mem_resize(vals.n_elem);
// Reset column pointers to zero. // Reset column pointers to zero.
arrayops::inplace_set(access::rwp(col_ptrs), uword(0), n_cols + 1); arrayops::inplace_set(access::rwp(col_ptrs), uword(0), n_cols + 1);
bool actually_sorted = true; bool actually_sorted = true;
skipping to change at line 3821 skipping to change at line 3663
abslocs[i] = locs_i[1] * n_rows + locs_i[0]; abslocs[i] = locs_i[1] * n_rows + locs_i[0];
} }
uvec sorted_indices = sort_index(abslocs); // Ascending sort. uvec sorted_indices = sort_index(abslocs); // Ascending sort.
// Now we add the elements in this sorted order. // Now we add the elements in this sorted order.
for (uword i = 0; i < sorted_indices.n_elem; ++i) for (uword i = 0; i < sorted_indices.n_elem; ++i)
{ {
const uword* locs_i = locs.colptr( sorted_indices[i] ); const uword* locs_i = locs.colptr( sorted_indices[i] );
arma_debug_check arma_debug_check( ( (locs_i[0] >= n_rows) || (locs_i[1] >= n_cols)
( ), "SpMat::SpMat(): invalid row or column index" );
( (locs_i[0] >= n_rows) || (locs_i[1] >= n_cols) ),
"SpMat::SpMat(): invalid row or column index"
);
if(i > 0) if(i > 0)
{ {
const uword* locs_im1 = locs.colptr( sorted_indices[i-1] ); const uword* locs_im1 = locs.colptr( sorted_indices[i-1] );
arma_debug_check arma_debug_check( ( (locs_i[1] == locs_im1[1]) && (locs_i[0] == l
( ocs_im1[0]) ), "SpMat::SpMat(): detected identical locations" );
( (locs_i[1] == locs_im1[1]) && (locs_i[0] == locs_im1[0]) ),
"SpMat::SpMat(): two identical point locations in list"
);
} }
access::rw(values[i]) = vals[ sorted_indices[i] ]; access::rw(values[i]) = vals[ sorted_indices[i] ];
access::rw(row_indices[i]) = locs_i[0]; access::rw(row_indices[i]) = locs_i[0];
access::rw(col_ptrs[ locs_i[1] + 1 ])++; access::rw(col_ptrs[ locs_i[1] + 1 ])++;
} }
} }
} }
if( (sort_locations == false) || (actually_sorted == true) ) if( (sort_locations == false) || (actually_sorted == true) )
{ {
// Now set the values and row indices correctly. // Now set the values and row indices correctly.
// Increment the column pointers in each column (so they are column "co unts"). // Increment the column pointers in each column (so they are column "co unts").
for (uword i = 0; i < vals.n_elem; ++i) for(uword i = 0; i < vals.n_elem; ++i)
{ {
const uword* locs_i = locs.colptr(i); const uword* locs_i = locs.colptr(i);
arma_debug_check arma_debug_check( ( (locs_i[0] >= n_rows) || (locs_i[1] >= n_cols) ),
( "SpMat::SpMat(): invalid row or column index" );
( (locs_i[0] >= n_rows) || (locs_i[1] >= n_cols) ),
"SpMat::SpMat(): invalid row or column index"
);
if(i > 0) if(i > 0)
{ {
const uword* locs_im1 = locs.colptr(i-1); const uword* locs_im1 = locs.colptr(i-1);
arma_debug_check arma_debug_check
( (
( (locs_i[1] < locs_im1[1]) || (locs_i[1] == locs_im1[1] && loc s_i[0] < locs_im1[0]) ), ( (locs_i[1] < locs_im1[1]) || (locs_i[1] == locs_im1[1] && loc s_i[0] < locs_im1[0]) ),
"SpMat::SpMat(): out of order points; either pass sort_locations = true, or sort points in column-major ordering" "SpMat::SpMat(): out of order points; either pass sort_locations = true, or sort points in column-major ordering"
); );
arma_debug_check arma_debug_check( ( (locs_i[1] == locs_im1[1]) && (locs_i[0] == loc
( s_im1[0]) ), "SpMat::SpMat(): detected identical locations" );
( (locs_i[1] == locs_im1[1]) && (locs_i[0] == locs_im1[0]) ),
"SpMat::SpMat(): two identical point locations in list"
);
} }
access::rw(values[i]) = vals[i]; access::rw(values[i]) = vals[i];
access::rw(row_indices[i]) = locs_i[0]; access::rw(row_indices[i]) = locs_i[0];
access::rw(col_ptrs[ locs_i[1] + 1 ])++; access::rw(col_ptrs[ locs_i[1] + 1 ])++;
} }
} }
// Now fix the column pointers. // Now fix the column pointers.
for (uword i = 0; i <= n_cols; ++i) for (uword i = 0; i <= n_cols; ++i)
{ {
access::rw(col_ptrs[i + 1]) += col_ptrs[i]; access::rw(col_ptrs[i + 1]) += col_ptrs[i];
} }
} }
template<typename eT> template<typename eT>
inline inline
void void
SpMat<eT>::init_batch_add(const Mat<uword>& locs, const Mat<eT>& vals, cons
t bool sort_locations)
{
arma_extra_debug_sigprint();
if(locs.n_cols < 2)
{
init_batch_std(locs, vals, false);
return;
}
// Reset column pointers to zero.
arrayops::inplace_set(access::rwp(col_ptrs), uword(0), n_cols + 1);
bool actually_sorted = true;
if(sort_locations == true)
{
// sort_index() uses std::sort() which may use quicksort... so we bette
r
// make sure it's not already sorted before taking an O(N^2) sort penal
ty.
for (uword i = 1; i < locs.n_cols; ++i)
{
const uword* locs_i = locs.colptr(i );
const uword* locs_im1 = locs.colptr(i-1);
if( (locs_i[1] < locs_im1[1]) || (locs_i[1] == locs_im1[1] && locs_
i[0] <= locs_im1[0]) )
{
actually_sorted = false;
break;
}
}
if(actually_sorted == false)
{
// This may not be the fastest possible implementation but it maximiz
es code reuse.
Col<uword> abslocs(locs.n_cols);
for (uword i = 0; i < locs.n_cols; ++i)
{
const uword* locs_i = locs.colptr(i);
abslocs[i] = locs_i[1] * n_rows + locs_i[0];
}
uvec sorted_indices = sort_index(abslocs); // Ascending sort.
// work out the number of unique elments
uword n_unique = 1; // first element is unique
for(uword i=1; i < sorted_indices.n_elem; ++i)
{
const uword* locs_i = locs.colptr( sorted_indices[i ] );
const uword* locs_im1 = locs.colptr( sorted_indices[i-1] );
if( (locs_i[1] != locs_im1[1]) || (locs_i[0] != locs_im1[0]) ) { +
+n_unique; }
}
// resize to correct number of elements
mem_resize(n_unique);
// Now we add the elements in this sorted order.
uword count = 0;
// first element
{
const uword i = 0;
const uword* locs_i = locs.colptr( sorted_indices[i] );
arma_debug_check( ( (locs_i[0] >= n_rows) || (locs_i[1] >= n_cols)
), "SpMat::SpMat(): invalid row or column index" );
access::rw(values[count]) = vals[ sorted_indices[i] ];
access::rw(row_indices[count]) = locs_i[0];
access::rw(col_ptrs[ locs_i[1] + 1 ])++;
}
for(uword i=1; i < sorted_indices.n_elem; ++i)
{
const uword* locs_i = locs.colptr( sorted_indices[i ] );
const uword* locs_im1 = locs.colptr( sorted_indices[i-1] );
arma_debug_check( ( (locs_i[0] >= n_rows) || (locs_i[1] >= n_cols)
), "SpMat::SpMat(): invalid row or column index" );
if( (locs_i[1] == locs_im1[1]) && (locs_i[0] == locs_im1[0]) )
{
access::rw(values[count]) += vals[ sorted_indices[i] ];
}
else
{
count++;
access::rw(values[count]) = vals[ sorted_indices[i] ];
access::rw(row_indices[count]) = locs_i[0];
access::rw(col_ptrs[ locs_i[1] + 1 ])++;
}
}
}
}
if( (sort_locations == false) || (actually_sorted == true) )
{
// work out the number of unique elments
uword n_unique = 1; // first element is unique
for(uword i=1; i < locs.n_cols; ++i)
{
const uword* locs_i = locs.colptr(i );
const uword* locs_im1 = locs.colptr(i-1);
if( (locs_i[1] != locs_im1[1]) || (locs_i[0] != locs_im1[0]) ) { ++n
_unique; }
}
// resize to correct number of elements
mem_resize(n_unique);
// Now set the values and row indices correctly.
// Increment the column pointers in each column (so they are column "co
unts").
uword count = 0;
// first element
{
const uword i = 0;
const uword* locs_i = locs.colptr(i);
arma_debug_check( ( (locs_i[0] >= n_rows) || (locs_i[1] >= n_cols) ),
"SpMat::SpMat(): invalid row or column index" );
access::rw(values[count]) = vals[i];
access::rw(row_indices[count]) = locs_i[0];
access::rw(col_ptrs[ locs_i[1] + 1 ])++;
}
for(uword i=1; i < locs.n_cols; ++i)
{
const uword* locs_i = locs.colptr(i );
const uword* locs_im1 = locs.colptr(i-1);
arma_debug_check( ( (locs_i[0] >= n_rows) || (locs_i[1] >= n_cols) ),
"SpMat::SpMat(): invalid row or column index" );
arma_debug_check
(
( (locs_i[1] < locs_im1[1]) || (locs_i[1] == locs_im1[1] && locs_
i[0] < locs_im1[0]) ),
"SpMat::SpMat(): out of order points; either pass sort_locations =
true, or sort points in column-major ordering"
);
if( (locs_i[1] == locs_im1[1]) && (locs_i[0] == locs_im1[0]) )
{
access::rw(values[count]) += vals[i];
}
else
{
count++;
access::rw(values[count]) = vals[i];
access::rw(row_indices[count]) = locs_i[0];
access::rw(col_ptrs[ locs_i[1] + 1 ])++;
}
}
}
// Now fix the column pointers.
for (uword i = 0; i <= n_cols; ++i)
{
access::rw(col_ptrs[i + 1]) += col_ptrs[i];
}
}
template<typename eT>
inline
void
SpMat<eT>::mem_resize(const uword new_n_nonzero) SpMat<eT>::mem_resize(const uword new_n_nonzero)
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
if(n_nonzero != new_n_nonzero) if(n_nonzero != new_n_nonzero)
{ {
if(new_n_nonzero == 0) if(new_n_nonzero == 0)
{ {
memory::release(values); memory::release(values);
memory::release(row_indices); memory::release(row_indices);
skipping to change at line 4201 skipping to change at line 4198
template<typename eT> template<typename eT>
inline inline
typename SpMat<eT>::const_row_iterator typename SpMat<eT>::const_row_iterator
SpMat<eT>::end_row(const uword row_num) const SpMat<eT>::end_row(const uword row_num) const
{ {
return const_row_iterator(*this, row_num + 1, 0); return const_row_iterator(*this, row_num + 1, 0);
} }
template<typename eT> template<typename eT>
inline inline
typename SpMat<eT>::row_col_iterator
SpMat<eT>::begin_row_col()
{
return begin();
}
template<typename eT>
inline
typename SpMat<eT>::const_row_col_iterator
SpMat<eT>::begin_row_col() const
{
return begin();
}
template<typename eT>
inline typename SpMat<eT>::row_col_iterator
SpMat<eT>::end_row_col()
{
return end();
}
template<typename eT>
inline
typename SpMat<eT>::const_row_col_iterator
SpMat<eT>::end_row_col() const
{
return end();
}
template<typename eT>
inline
void void
SpMat<eT>::clear() SpMat<eT>::clear()
{ {
(*this).reset(); (*this).reset();
} }
template<typename eT> template<typename eT>
inline inline
bool bool
SpMat<eT>::empty() const SpMat<eT>::empty() const
 End of changes. 15 change blocks. 
260 lines changed or deleted 310 lines changed or added


 arma_ostream_meat.hpp   arma_ostream_meat.hpp 
skipping to change at line 270 skipping to change at line 270
o << eT(0); o << eT(0);
} }
} }
//! Print an element to the specified stream //! Print an element to the specified stream
template<typename eT> template<typename eT>
arma_inline arma_inline
void void
arma_ostream::print_elem(std::ostream& o, const eT& x, const bool modify) arma_ostream::print_elem(std::ostream& o, const eT& x, const bool modify)
{ {
if(x != eT(0)) if(is_signed<eT>::value)
{ {
o << x; typedef typename promote_type<eT, s16>::result promoted_eT;
if(x != eT(0))
{
o << promoted_eT(x);
}
else
{
arma_ostream::print_elem_zero<promoted_eT>(o, modify);
}
} }
else else
{ {
arma_ostream::print_elem_zero<eT>(o, modify); typedef typename promote_type<eT, u16>::result promoted_eT;
if(x != eT(0))
{
o << promoted_eT(x);
}
else
{
arma_ostream::print_elem_zero<promoted_eT>(o, modify);
}
} }
} }
//! Print a complex element to the specified stream //! Print a complex element to the specified stream
template<typename T> template<typename T>
inline inline
void void
arma_ostream::print_elem(std::ostream& o, const std::complex<T>& x, const b ool modify) arma_ostream::print_elem(std::ostream& o, const std::complex<T>& x, const b ool modify)
{ {
if( (x.real() != T(0)) || (x.imag() != T(0)) || (modify == false) ) if( (x.real() != T(0)) || (x.imag() != T(0)) || (modify == false) )
 End of changes. 3 change blocks. 
3 lines changed or deleted 21 lines changed or added


 arma_version.hpp   arma_version.hpp 
skipping to change at line 12 skipping to change at line 12
// Copyright (C) 2009-2014 NICTA (www.nicta.com.au) // Copyright (C) 2009-2014 NICTA (www.nicta.com.au)
// //
// 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 320 #define ARMA_VERSION_MINOR 400
#define ARMA_VERSION_PATCH 2 #define ARMA_VERSION_PATCH 0
#define ARMA_VERSION_NAME "Daintree Tea Raider" #define ARMA_VERSION_NAME "Winter Shark Alley"
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
std::string std::string
 End of changes. 1 change blocks. 
3 lines changed or deleted 3 lines changed or added


 armadillo   armadillo 
skipping to change at line 73 skipping to change at line 73
#include "armadillo_bits/include_atlas.hpp" #include "armadillo_bits/include_atlas.hpp"
#if defined(ARMA_USE_HDF5) #if defined(ARMA_USE_HDF5)
#include <hdf5.h> #include <hdf5.h>
#if defined(H5_USE_16_API_DEFAULT) || defined(H5_USE_16_API) #if defined(H5_USE_16_API_DEFAULT) || defined(H5_USE_16_API)
#pragma message ("WARNING: disabling use of HDF5 due to its incompatibl e configuration") #pragma message ("WARNING: disabling use of HDF5 due to its incompatibl e configuration")
#undef ARMA_USE_HDF5 #undef ARMA_USE_HDF5
#endif #endif
#endif #endif
#if defined(_OPENMP)
#include <omp.h>
#endif
//! \namespace arma namespace for Armadillo classes and functions //! \namespace arma namespace for Armadillo classes and functions
namespace arma namespace arma
{ {
// preliminaries // preliminaries
#include "armadillo_bits/forward_bones.hpp" #include "armadillo_bits/forward_bones.hpp"
#include "armadillo_bits/arma_static_check.hpp" #include "armadillo_bits/arma_static_check.hpp"
#include "armadillo_bits/typedef_elem.hpp" #include "armadillo_bits/typedef_elem.hpp"
#include "armadillo_bits/typedef_elem_check.hpp" #include "armadillo_bits/typedef_elem_check.hpp"
skipping to change at line 228 skipping to change at line 232
#include "armadillo_bits/op_trimat_bones.hpp" #include "armadillo_bits/op_trimat_bones.hpp"
#include "armadillo_bits/op_cumsum_bones.hpp" #include "armadillo_bits/op_cumsum_bones.hpp"
#include "armadillo_bits/op_symmat_bones.hpp" #include "armadillo_bits/op_symmat_bones.hpp"
#include "armadillo_bits/op_hist_bones.hpp" #include "armadillo_bits/op_hist_bones.hpp"
#include "armadillo_bits/op_unique_bones.hpp" #include "armadillo_bits/op_unique_bones.hpp"
#include "armadillo_bits/op_toeplitz_bones.hpp" #include "armadillo_bits/op_toeplitz_bones.hpp"
#include "armadillo_bits/op_fft_bones.hpp" #include "armadillo_bits/op_fft_bones.hpp"
#include "armadillo_bits/op_any_bones.hpp" #include "armadillo_bits/op_any_bones.hpp"
#include "armadillo_bits/op_all_bones.hpp" #include "armadillo_bits/op_all_bones.hpp"
#include "armadillo_bits/op_normalise_bones.hpp" #include "armadillo_bits/op_normalise_bones.hpp"
#include "armadillo_bits/op_clamp_bones.hpp"
#include "armadillo_bits/glue_times_bones.hpp" #include "armadillo_bits/glue_times_bones.hpp"
#include "armadillo_bits/glue_mixed_bones.hpp" #include "armadillo_bits/glue_mixed_bones.hpp"
#include "armadillo_bits/glue_cov_bones.hpp" #include "armadillo_bits/glue_cov_bones.hpp"
#include "armadillo_bits/glue_cor_bones.hpp" #include "armadillo_bits/glue_cor_bones.hpp"
#include "armadillo_bits/glue_kron_bones.hpp" #include "armadillo_bits/glue_kron_bones.hpp"
#include "armadillo_bits/glue_cross_bones.hpp" #include "armadillo_bits/glue_cross_bones.hpp"
#include "armadillo_bits/glue_join_bones.hpp" #include "armadillo_bits/glue_join_bones.hpp"
#include "armadillo_bits/glue_relational_bones.hpp" #include "armadillo_bits/glue_relational_bones.hpp"
#include "armadillo_bits/glue_solve_bones.hpp" #include "armadillo_bits/glue_solve_bones.hpp"
skipping to change at line 427 skipping to change at line 432
#include "armadillo_bits/fn_fft2.hpp" #include "armadillo_bits/fn_fft2.hpp"
#include "armadillo_bits/fn_any.hpp" #include "armadillo_bits/fn_any.hpp"
#include "armadillo_bits/fn_all.hpp" #include "armadillo_bits/fn_all.hpp"
#include "armadillo_bits/fn_size.hpp" #include "armadillo_bits/fn_size.hpp"
#include "armadillo_bits/fn_numel.hpp" #include "armadillo_bits/fn_numel.hpp"
#include "armadillo_bits/fn_inplace_strans.hpp" #include "armadillo_bits/fn_inplace_strans.hpp"
#include "armadillo_bits/fn_inplace_trans.hpp" #include "armadillo_bits/fn_inplace_trans.hpp"
#include "armadillo_bits/fn_randi.hpp" #include "armadillo_bits/fn_randi.hpp"
#include "armadillo_bits/fn_cond.hpp" #include "armadillo_bits/fn_cond.hpp"
#include "armadillo_bits/fn_normalise.hpp" #include "armadillo_bits/fn_normalise.hpp"
#include "armadillo_bits/fn_clamp.hpp"
#include "armadillo_bits/fn_speye.hpp" #include "armadillo_bits/fn_speye.hpp"
#include "armadillo_bits/fn_spones.hpp" #include "armadillo_bits/fn_spones.hpp"
#include "armadillo_bits/fn_sprandn.hpp" #include "armadillo_bits/fn_sprandn.hpp"
#include "armadillo_bits/fn_sprandu.hpp" #include "armadillo_bits/fn_sprandu.hpp"
#include "armadillo_bits/fn_eigs_sym.hpp" #include "armadillo_bits/fn_eigs_sym.hpp"
#include "armadillo_bits/fn_eigs_gen.hpp" #include "armadillo_bits/fn_eigs_gen.hpp"
#include "armadillo_bits/fn_norm_sparse.hpp" #include "armadillo_bits/fn_norm_sparse.hpp"
// //
// misc stuff // misc stuff
#include "armadillo_bits/hdf5_misc.hpp" #include "armadillo_bits/hdf5_misc.hpp"
#include "armadillo_bits/fft_engine.hpp" #include "armadillo_bits/fft_engine.hpp"
#include "armadillo_bits/gmm_misc_bones.hpp"
#include "armadillo_bits/gmm_misc_meat.hpp"
#include "armadillo_bits/gmm_diag_bones.hpp"
#include "armadillo_bits/gmm_diag_meat.hpp"
// //
// classes implementing various forms of dense matrix multiplication // classes implementing various forms of dense matrix multiplication
#include "armadillo_bits/mul_gemv.hpp" #include "armadillo_bits/mul_gemv.hpp"
#include "armadillo_bits/mul_gemm.hpp" #include "armadillo_bits/mul_gemm.hpp"
#include "armadillo_bits/mul_gemm_mixed.hpp" #include "armadillo_bits/mul_gemm_mixed.hpp"
#include "armadillo_bits/mul_syrk.hpp" #include "armadillo_bits/mul_syrk.hpp"
#include "armadillo_bits/mul_herk.hpp" #include "armadillo_bits/mul_herk.hpp"
skipping to change at line 536 skipping to change at line 546
#include "armadillo_bits/op_trimat_meat.hpp" #include "armadillo_bits/op_trimat_meat.hpp"
#include "armadillo_bits/op_cumsum_meat.hpp" #include "armadillo_bits/op_cumsum_meat.hpp"
#include "armadillo_bits/op_symmat_meat.hpp" #include "armadillo_bits/op_symmat_meat.hpp"
#include "armadillo_bits/op_hist_meat.hpp" #include "armadillo_bits/op_hist_meat.hpp"
#include "armadillo_bits/op_unique_meat.hpp" #include "armadillo_bits/op_unique_meat.hpp"
#include "armadillo_bits/op_toeplitz_meat.hpp" #include "armadillo_bits/op_toeplitz_meat.hpp"
#include "armadillo_bits/op_fft_meat.hpp" #include "armadillo_bits/op_fft_meat.hpp"
#include "armadillo_bits/op_any_meat.hpp" #include "armadillo_bits/op_any_meat.hpp"
#include "armadillo_bits/op_all_meat.hpp" #include "armadillo_bits/op_all_meat.hpp"
#include "armadillo_bits/op_normalise_meat.hpp" #include "armadillo_bits/op_normalise_meat.hpp"
#include "armadillo_bits/op_clamp_meat.hpp"
#include "armadillo_bits/glue_times_meat.hpp" #include "armadillo_bits/glue_times_meat.hpp"
#include "armadillo_bits/glue_mixed_meat.hpp" #include "armadillo_bits/glue_mixed_meat.hpp"
#include "armadillo_bits/glue_cov_meat.hpp" #include "armadillo_bits/glue_cov_meat.hpp"
#include "armadillo_bits/glue_cor_meat.hpp" #include "armadillo_bits/glue_cor_meat.hpp"
#include "armadillo_bits/glue_kron_meat.hpp" #include "armadillo_bits/glue_kron_meat.hpp"
#include "armadillo_bits/glue_cross_meat.hpp" #include "armadillo_bits/glue_cross_meat.hpp"
#include "armadillo_bits/glue_join_meat.hpp" #include "armadillo_bits/glue_join_meat.hpp"
#include "armadillo_bits/glue_relational_meat.hpp" #include "armadillo_bits/glue_relational_meat.hpp"
#include "armadillo_bits/glue_solve_meat.hpp" #include "armadillo_bits/glue_solve_meat.hpp"
 End of changes. 5 change blocks. 
0 lines changed or deleted 11 lines changed or added


 diskio_meat.hpp   diskio_meat.hpp 
skipping to change at line 690 skipping to change at line 690
{ {
conv_to_hex(&tmp[char_count], ptr_ptr_x[i]); conv_to_hex(&tmp[char_count], ptr_ptr_x[i]);
char_count += 2; char_count += 2;
} }
const uword x_size = static_cast<uword>(x.size()); const uword x_size = static_cast<uword>(x.size());
u8 sum = 0; u8 sum = 0;
for(uword i=0; i<x_size; ++i) for(uword i=0; i<x_size; ++i)
{ {
sum += u8(x[i]); sum = (sum + u8(x[i])) & 0xff;
} }
conv_to_hex(&tmp[char_count], sum); conv_to_hex(&tmp[char_count], sum);
char_count += 2; char_count += 2;
conv_to_hex(&tmp[char_count], u8(x_size)); conv_to_hex(&tmp[char_count], u8(x_size));
std::string out; std::string out;
out.resize(x_size + extra_size + tmp_size); out.resize(x_size + extra_size + tmp_size);
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 fn_as_scalar.hpp   fn_as_scalar.hpp 
skipping to change at line 372 skipping to change at line 372
template<typename T> template<typename T>
arma_inline arma_inline
arma_warn_unused arma_warn_unused
const typename arma_scalar_only<T>::result & const typename arma_scalar_only<T>::result &
as_scalar(const T& x) as_scalar(const T& x)
{ {
return x; return x;
} }
template<typename T1> template<typename T1>
arma_inline inline
arma_warn_unused arma_warn_unused
typename T1::elem_type typename T1::elem_type
as_scalar(const SpBase<typename T1::elem_type, T1>& X) as_scalar(const SpBase<typename T1::elem_type, T1>& X)
{ {
typedef typename T1::elem_type eT; typedef typename T1::elem_type eT;
const unwrap_spmat<T1> tmp(X.get_ref()); const unwrap_spmat<T1> tmp(X.get_ref());
const SpMat<eT>& A = tmp.M; const SpMat<eT>& A = tmp.M;
arma_debug_check( (A.n_elem != 1), "as_scalar(): expression doesn't evalu ate to exactly one element" ); arma_debug_check( (A.n_elem != 1), "as_scalar(): expression doesn't evalu ate to exactly one element" );
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 forward_bones.hpp   forward_bones.hpp 
skipping to change at line 68 skipping to change at line 68
class op_htrans2; class op_htrans2;
class op_inv; class op_inv;
class op_sum; class op_sum;
class op_abs; class op_abs;
class op_diagmat; class op_diagmat;
class op_trimat; class op_trimat;
class op_diagvec; class op_diagvec;
class op_vectorise_col; class op_vectorise_col;
class op_normalise_colvec; class op_normalise_colvec;
class op_normalise_rowvec; class op_normalise_rowvec;
class op_clamp;
class eop_conj; class eop_conj;
class glue_times; class glue_times;
class glue_times_diag; class glue_times_diag;
class glue_rel_lt; class glue_rel_lt;
class glue_rel_gt; class glue_rel_gt;
class glue_rel_lteq; class glue_rel_lteq;
class glue_rel_gteq; class glue_rel_gteq;
 End of changes. 1 change blocks. 
0 lines changed or deleted 1 lines changed or added


 mtOp_bones.hpp   mtOp_bones.hpp 
// Copyright (C) 2008-2011 Conrad Sanderson // Copyright (C) 2008-2014 Conrad Sanderson
// Copyright (C) 2008-2011 NICTA (www.nicta.com.au) // Copyright (C) 2008-2014 NICTA (www.nicta.com.au)
// //
// 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 mtOp //! \addtogroup mtOp
//! @{ //! @{
struct mtOp_dual_aux_indicator {};
template<typename out_eT, typename T1, typename op_type> template<typename out_eT, typename T1, typename op_type>
class mtOp : public Base<out_eT, mtOp<out_eT, T1, op_type> > class mtOp : public Base<out_eT, mtOp<out_eT, T1, op_type> >
{ {
public: public:
typedef out_eT elem_type; typedef out_eT elem_type;
typedef typename get_pod_type<out_eT>::result pod_type; typedef typename get_pod_type<out_eT>::result pod_type;
typedef typename T1::elem_type in_eT; typedef typename T1::elem_type in_eT;
static const bool is_row = T1::is_row && is_op_mixed_elem<op_type>::value static const bool is_row = T1::is_row && (is_op_mixed_elem<op_type>::valu
; e || is_same_type<op_type, op_clamp>::value);
static const bool is_col = T1::is_col && is_op_mixed_elem<op_type>::value static const bool is_col = T1::is_col && (is_op_mixed_elem<op_type>::valu
; e || is_same_type<op_type, op_clamp>::value);
inline explicit mtOp(const T1& in_m); inline explicit mtOp(const T1& in_m);
inline mtOp(const T1& in_m, const in_eT in_aux); inline mtOp(const T1& in_m, const in_eT in_aux);
inline mtOp(const T1& in_m, const uword in_aux_uword_a, const uw ord in_aux_uword_b); inline mtOp(const T1& in_m, const uword in_aux_uword_a, const uw ord in_aux_uword_b);
inline mtOp(const T1& in_m, const in_eT in_aux, const uw ord in_aux_uword_a, const uword in_aux_uword_b); inline mtOp(const T1& in_m, const in_eT in_aux, const uw ord in_aux_uword_a, const uword in_aux_uword_b);
inline mtOp(const char junk, const T1& in_m, const out_eT in_aux ); inline mtOp(const char junk, const T1& in_m, const out_eT in_aux );
inline mtOp(const mtOp_dual_aux_indicator&, const T1& in_m, cons
t in_eT in_aux_a, const out_eT in_aux_b);
inline ~mtOp(); inline ~mtOp();
arma_aligned const T1& m; //!< storage of reference to the operand (eg. a matrix) arma_aligned const T1& m; //!< storage of reference to the operand (eg. a matrix)
arma_aligned in_eT aux; //!< storage of auxiliary data, u sing the element type as used by T1 arma_aligned in_eT aux; //!< storage of auxiliary data, u sing the element type as used by T1
arma_aligned out_eT aux_out_eT; //!< storage of auxiliary data, u sing the element type as specified by the out_eT template parameter arma_aligned out_eT aux_out_eT; //!< storage of auxiliary data, u sing the element type as specified by the out_eT template parameter
arma_aligned uword aux_uword_a; //!< storage of auxiliary data, u word format arma_aligned uword aux_uword_a; //!< storage of auxiliary data, u word format
arma_aligned uword aux_uword_b; //!< storage of auxiliary data, u word format arma_aligned uword aux_uword_b; //!< storage of auxiliary data, u word format
}; };
 End of changes. 4 change blocks. 
6 lines changed or deleted 11 lines changed or added


 mtOp_meat.hpp   mtOp_meat.hpp 
skipping to change at line 62 skipping to change at line 62
: m(in_m) : m(in_m)
, aux_out_eT(in_aux) , aux_out_eT(in_aux)
{ {
arma_ignore(junk); arma_ignore(junk);
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
} }
template<typename out_eT, typename T1, typename op_type> template<typename out_eT, typename T1, typename op_type>
inline inline
mtOp<out_eT, T1, op_type>::mtOp(const mtOp_dual_aux_indicator&, const T1& i
n_m, const typename T1::elem_type in_aux_a, const out_eT in_aux_b)
: m (in_m )
, aux (in_aux_a)
, aux_out_eT(in_aux_b)
{
arma_extra_debug_sigprint();
}
template<typename out_eT, typename T1, typename op_type>
inline
mtOp<out_eT, T1, op_type>::~mtOp() mtOp<out_eT, T1, op_type>::~mtOp()
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
} }
//! @} //! @}
 End of changes. 1 change blocks. 
0 lines changed or deleted 11 lines changed or added


 op_dot_meat.hpp   op_dot_meat.hpp 
skipping to change at line 199 skipping to change at line 199
template<typename T1, typename T2> template<typename T1, typename T2>
arma_hot arma_hot
inline inline
typename T1::elem_type typename T1::elem_type
op_dot::apply(const T1& X, const T2& Y) op_dot::apply(const T1& X, const T2& Y)
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
const bool prefer_at_accessor = (Proxy<T1>::prefer_at_accessor) || (Proxy <T2>::prefer_at_accessor); const bool prefer_at_accessor = (Proxy<T1>::prefer_at_accessor) || (Proxy <T2>::prefer_at_accessor);
const bool do_unwrap = ((is_Mat<T1>::value == true) && (is_Mat<T2>::value == true)) || prefer_at_accessor; const bool have_direct_mem = ((is_Mat<T1>::value || is_subview_col<T1>::v alue) && (is_Mat<T2>::value || is_subview_col<T2>::value));
if(do_unwrap == true) if(prefer_at_accessor || have_direct_mem)
{ {
const unwrap<T1> tmp1(X); const quasi_unwrap<T1> A(X);
const unwrap<T2> tmp2(Y); const quasi_unwrap<T2> B(Y);
const typename unwrap<T1>::stored_type& A = tmp1.M; arma_debug_check( (A.M.n_elem != B.M.n_elem), "dot(): objects must have
const typename unwrap<T2>::stored_type& B = tmp2.M; the same number of elements" );
arma_debug_check return op_dot::direct_dot(A.M.n_elem, A.M.memptr(), B.M.memptr());
(
(A.n_elem != B.n_elem),
"dot(): objects must have the same number of elements"
);
return op_dot::direct_dot(A.n_elem, A.memptr(), B.memptr());
} }
else else
{ {
if(is_subview_row<T1>::value && is_subview_row<T2>::value)
{
typedef typename T1::elem_type eT;
const subview_row<eT>& A = reinterpret_cast< const subview_row<eT>& >
(X);
const subview_row<eT>& B = reinterpret_cast< const subview_row<eT>& >
(Y);
if( (A.m.n_rows == 1) && (B.m.n_rows == 1) )
{
arma_debug_check( (A.n_elem != B.n_elem), "dot(): objects must have
the same number of elements" );
const eT* A_mem = A.m.memptr();
const eT* B_mem = B.m.memptr();
return op_dot::direct_dot(A.n_elem, &A_mem[A.aux_col1], &B_mem[B.au
x_col1]);
}
}
const Proxy<T1> PA(X); const Proxy<T1> PA(X);
const Proxy<T2> PB(Y); const Proxy<T2> PB(Y);
arma_debug_check( (PA.get_n_elem() != PB.get_n_elem()), "dot(): objects must have the same number of elements" ); arma_debug_check( (PA.get_n_elem() != PB.get_n_elem()), "dot(): objects must have the same number of elements" );
return op_dot::apply_proxy(PA,PB); return op_dot::apply_proxy(PA,PB);
} }
} }
template<typename T1, typename T2> template<typename T1, typename T2>
 End of changes. 6 change blocks. 
13 lines changed or deleted 29 lines changed or added


 op_max_bones.hpp   op_max_bones.hpp 
// Copyright (C) 2008-2012 Conrad Sanderson // Copyright (C) 2008-2014 Conrad Sanderson
// Copyright (C) 2008-2012 NICTA (www.nicta.com.au) // Copyright (C) 2008-2014 NICTA (www.nicta.com.au)
// //
// 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 op_max //! \addtogroup op_max
//! @{ //! @{
//! Class for finding maximum values in a matrix //! Class for finding maximum values in a matrix
class op_max class op_max
skipping to change at line 37 skipping to change at line 37
template<typename eT> template<typename eT>
inline static eT direct_max(const Mat<eT>& X, const uword row); inline static eT direct_max(const Mat<eT>& X, const uword row);
template<typename eT> template<typename eT>
inline static eT max(const subview<eT>& X); inline static eT max(const subview<eT>& X);
template<typename T1> template<typename T1>
inline static typename arma_not_cx<typename T1::elem_type>::result max(co nst Base<typename T1::elem_type, T1>& X); inline static typename arma_not_cx<typename T1::elem_type>::result max(co nst Base<typename T1::elem_type, T1>& X);
template<typename T1>
inline static typename arma_not_cx<typename T1::elem_type>::result max_wi
th_index(const Proxy<T1>& P, uword& index_of_max_val);
// //
// for complex numbers // for complex numbers
template<typename T> template<typename T>
inline static std::complex<T> direct_max(const std::complex<T>* const X, const uword n_elem); inline static std::complex<T> direct_max(const std::complex<T>* const X, const uword n_elem);
template<typename T> template<typename T>
inline static std::complex<T> direct_max(const std::complex<T>* const X, const uword n_elem, uword& index_of_max_val); inline static std::complex<T> direct_max(const std::complex<T>* const X, const uword n_elem, uword& index_of_max_val);
template<typename T> template<typename T>
inline static std::complex<T> direct_max(const Mat< std::complex<T> >& X, const uword row); inline static std::complex<T> direct_max(const Mat< std::complex<T> >& X, const uword row);
template<typename T> template<typename T>
inline static std::complex<T> max(const subview< std::complex<T> >& X); inline static std::complex<T> max(const subview< std::complex<T> >& X);
template<typename T1> template<typename T1>
inline static typename arma_cx_only<typename T1::elem_type>::result max(c onst Base<typename T1::elem_type, T1>& X); inline static typename arma_cx_only<typename T1::elem_type>::result max(c onst Base<typename T1::elem_type, T1>& X);
template<typename T1>
inline static typename arma_cx_only<typename T1::elem_type>::result max_w
ith_index(const Proxy<T1>& P, uword& index_of_max_val);
}; };
//! @} //! @}
 End of changes. 3 change blocks. 
2 lines changed or deleted 10 lines changed or added


 op_max_meat.hpp   op_max_meat.hpp 
skipping to change at line 320 skipping to change at line 320
if(tmp_i > max_val) { max_val = tmp_i; } if(tmp_i > max_val) { max_val = tmp_i; }
} }
} }
} }
} }
return max_val; return max_val;
} }
template<typename T1>
inline
typename arma_not_cx<typename T1::elem_type>::result
op_max::max_with_index(const Proxy<T1>& P, uword& index_of_max_val)
{
arma_extra_debug_sigprint();
typedef typename T1::elem_type eT;
const uword n_elem = P.get_n_elem();
arma_debug_check( (n_elem == 0), "max(): given object has no elements" );
eT best_val = priv::most_neg<eT>();
uword best_index = 0;
if(Proxy<T1>::prefer_at_accessor == false)
{
typedef typename Proxy<T1>::ea_type ea_type;
ea_type A = P.get_ea();
for(uword i=0; i<n_elem; ++i)
{
const eT tmp = A[i];
if(tmp > best_val) { best_val = tmp; best_index = i; }
}
}
else
{
const uword n_rows = P.get_n_rows();
const uword n_cols = P.get_n_cols();
if(n_rows == 1)
{
for(uword i=0; i < n_cols; ++i)
{
const eT tmp = P.at(0,i);
if(tmp > best_val) { best_val = tmp; best_index = i; }
}
}
else
if(n_cols == 1)
{
for(uword i=0; i < n_rows; ++i)
{
const eT tmp = P.at(i,0);
if(tmp > best_val) { best_val = tmp; best_index = i; }
}
}
else
{
uword count = 0;
for(uword col=0; col < n_cols; ++col)
for(uword row=0; row < n_rows; ++row)
{
const eT tmp = P.at(row,col);
if(tmp > best_val) { best_val = tmp; best_index = count; }
++count;
}
}
}
index_of_max_val = best_index;
return best_val;
}
template<typename T> template<typename T>
inline inline
std::complex<T> std::complex<T>
op_max::direct_max(const std::complex<T>* const X, const uword n_elem) op_max::direct_max(const std::complex<T>* const X, const uword n_elem)
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
uword index = 0; uword index = 0;
T max_val = priv::most_neg<T>(); T max_val = priv::most_neg<T>();
skipping to change at line 538 skipping to change at line 612
best_row = row; best_row = row;
best_col = col; best_col = col;
} }
} }
} }
return P.at(best_row, best_col); return P.at(best_row, best_col);
} }
} }
template<typename T1>
inline
typename arma_cx_only<typename T1::elem_type>::result
op_max::max_with_index(const Proxy<T1>& P, uword& index_of_max_val)
{
arma_extra_debug_sigprint();
typedef typename T1::elem_type eT;
typedef typename get_pod_type<eT>::result T;
const uword n_elem = P.get_n_elem();
arma_debug_check( (n_elem == 0), "max(): given object has no elements" );
T best_val = priv::most_neg<T>();
if(Proxy<T1>::prefer_at_accessor == false)
{
typedef typename Proxy<T1>::ea_type ea_type;
ea_type A = P.get_ea();
uword best_index = 0;
for(uword i=0; i<n_elem; ++i)
{
const T tmp = std::abs(A[i]);
if(tmp > best_val) { best_val = tmp; best_index = i; }
}
index_of_max_val = best_index;
return( A[best_index] );
}
else
{
const uword n_rows = P.get_n_rows();
const uword n_cols = P.get_n_cols();
uword best_row = 0;
uword best_col = 0;
uword best_index = 0;
if(n_rows == 1)
{
for(uword col=0; col < n_cols; ++col)
{
const T tmp = std::abs(P.at(0,col));
if(tmp > best_val) { best_val = tmp; best_col = col; }
}
best_index = best_col;
}
else
if(n_cols == 1)
{
for(uword row=0; row < n_rows; ++row)
{
const T tmp = std::abs(P.at(row,0));
if(tmp > best_val) { best_val = tmp; best_row = row; }
}
best_index = best_row;
}
else
{
uword count = 0;
for(uword col=0; col < n_cols; ++col)
for(uword row=0; row < n_rows; ++row)
{
const T tmp = std::abs(P.at(row,col));
if(tmp > best_val)
{
best_val = tmp;
best_row = row;
best_col = col;
best_index = count;
}
++count;
}
}
index_of_max_val = best_index;
return P.at(best_row, best_col);
}
}
//! @} //! @}
 End of changes. 2 change blocks. 
0 lines changed or deleted 170 lines changed or added


 op_min_bones.hpp   op_min_bones.hpp 
// Copyright (C) 2008-2012 Conrad Sanderson // Copyright (C) 2008-2014 Conrad Sanderson
// Copyright (C) 2008-2012 NICTA (www.nicta.com.au) // Copyright (C) 2008-2014 NICTA (www.nicta.com.au)
// //
// 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 op_min //! \addtogroup op_min
//! @{ //! @{
//! Class for finding minimum values in a matrix //! Class for finding minimum values in a matrix
class op_min class op_min
skipping to change at line 37 skipping to change at line 37
template<typename eT> template<typename eT>
inline static eT direct_min(const Mat<eT>& X, const uword row); inline static eT direct_min(const Mat<eT>& X, const uword row);
template<typename eT> template<typename eT>
inline static eT min(const subview<eT>& X); inline static eT min(const subview<eT>& X);
template<typename T1> template<typename T1>
inline static typename arma_not_cx<typename T1::elem_type>::result min(co nst Base<typename T1::elem_type, T1>& X); inline static typename arma_not_cx<typename T1::elem_type>::result min(co nst Base<typename T1::elem_type, T1>& X);
template<typename T1>
inline static typename arma_not_cx<typename T1::elem_type>::result min_wi
th_index(const Proxy<T1>& P, uword& index_of_min_val);
// //
// for complex numbers // for complex numbers
template<typename T> template<typename T>
inline static std::complex<T> direct_min(const std::complex<T>* const X, const uword n_elem); inline static std::complex<T> direct_min(const std::complex<T>* const X, const uword n_elem);
template<typename T> template<typename T>
inline static std::complex<T> direct_min(const std::complex<T>* const X, const uword n_elem, uword& index_of_min_val); inline static std::complex<T> direct_min(const std::complex<T>* const X, const uword n_elem, uword& index_of_min_val);
template<typename T> template<typename T>
inline static std::complex<T> direct_min(const Mat< std::complex<T> >& X, const uword row); inline static std::complex<T> direct_min(const Mat< std::complex<T> >& X, const uword row);
template<typename T> template<typename T>
inline static std::complex<T> min(const subview< std::complex<T> >&X); inline static std::complex<T> min(const subview< std::complex<T> >&X);
template<typename T1> template<typename T1>
inline static typename arma_cx_only<typename T1::elem_type>::result min(c onst Base<typename T1::elem_type, T1>& X); inline static typename arma_cx_only<typename T1::elem_type>::result min(c onst Base<typename T1::elem_type, T1>& X);
template<typename T1>
inline static typename arma_cx_only<typename T1::elem_type>::result min_w
ith_index(const Proxy<T1>& P, uword& index_of_min_val);
}; };
//! @} //! @}
 End of changes. 3 change blocks. 
2 lines changed or deleted 10 lines changed or added


 op_min_meat.hpp   op_min_meat.hpp 
// Copyright (C) 2008-2012 Conrad Sanderson // Copyright (C) 2008-2014 Conrad Sanderson
// Copyright (C) 2008-2012 NICTA (www.nicta.com.au) // Copyright (C) 2008-2014 NICTA (www.nicta.com.au)
// //
// 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 op_min //! \addtogroup op_min
//! @{ //! @{
//! \brief //! \brief
//! For each row or for each column, find the minimum value. //! For each row or for each column, find the minimum value.
skipping to change at line 316 skipping to change at line 316
if(tmp_i < min_val) { min_val = tmp_i; } if(tmp_i < min_val) { min_val = tmp_i; }
} }
} }
} }
} }
return min_val; return min_val;
} }
template<typename T1>
inline
typename arma_not_cx<typename T1::elem_type>::result
op_min::min_with_index(const Proxy<T1>& P, uword& index_of_min_val)
{
arma_extra_debug_sigprint();
typedef typename T1::elem_type eT;
const uword n_elem = P.get_n_elem();
arma_debug_check( (n_elem == 0), "min(): given object has no elements" );
eT best_val = priv::most_pos<eT>();
uword best_index = 0;
if(Proxy<T1>::prefer_at_accessor == false)
{
typedef typename Proxy<T1>::ea_type ea_type;
ea_type A = P.get_ea();
for(uword i=0; i<n_elem; ++i)
{
const eT tmp = A[i];
if(tmp < best_val) { best_val = tmp; best_index = i; }
}
}
else
{
const uword n_rows = P.get_n_rows();
const uword n_cols = P.get_n_cols();
if(n_rows == 1)
{
for(uword i=0; i < n_cols; ++i)
{
const eT tmp = P.at(0,i);
if(tmp < best_val) { best_val = tmp; best_index = i; }
}
}
else
if(n_cols == 1)
{
for(uword i=0; i < n_rows; ++i)
{
const eT tmp = P.at(i,0);
if(tmp < best_val) { best_val = tmp; best_index = i; }
}
}
else
{
uword count = 0;
for(uword col=0; col < n_cols; ++col)
for(uword row=0; row < n_rows; ++row)
{
const eT tmp = P.at(row,col);
if(tmp < best_val) { best_val = tmp; best_index = count; }
++count;
}
}
}
index_of_min_val = best_index;
return best_val;
}
template<typename T> template<typename T>
inline inline
std::complex<T> std::complex<T>
op_min::direct_min(const std::complex<T>* const X, const uword n_elem) op_min::direct_min(const std::complex<T>* const X, const uword n_elem)
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
uword index = 0; uword index = 0;
T min_val = priv::most_pos<T>(); T min_val = priv::most_pos<T>();
skipping to change at line 534 skipping to change at line 608
best_row = row; best_row = row;
best_col = col; best_col = col;
} }
} }
} }
return P.at(best_row, best_col); return P.at(best_row, best_col);
} }
} }
template<typename T1>
inline
typename arma_cx_only<typename T1::elem_type>::result
op_min::min_with_index(const Proxy<T1>& P, uword& index_of_min_val)
{
arma_extra_debug_sigprint();
typedef typename T1::elem_type eT;
typedef typename get_pod_type<eT>::result T;
const uword n_elem = P.get_n_elem();
arma_debug_check( (n_elem == 0), "min(): given object has no elements" );
T best_val = priv::most_pos<T>();
if(Proxy<T1>::prefer_at_accessor == false)
{
typedef typename Proxy<T1>::ea_type ea_type;
ea_type A = P.get_ea();
uword best_index = 0;
for(uword i=0; i<n_elem; ++i)
{
const T tmp = std::abs(A[i]);
if(tmp < best_val) { best_val = tmp; best_index = i; }
}
index_of_min_val = best_index;
return( A[best_index] );
}
else
{
const uword n_rows = P.get_n_rows();
const uword n_cols = P.get_n_cols();
uword best_row = 0;
uword best_col = 0;
uword best_index = 0;
if(n_rows == 1)
{
for(uword col=0; col < n_cols; ++col)
{
const T tmp = std::abs(P.at(0,col));
if(tmp < best_val) { best_val = tmp; best_col = col; }
}
best_index = best_col;
}
else
if(n_cols == 1)
{
for(uword row=0; row < n_rows; ++row)
{
const T tmp = std::abs(P.at(row,0));
if(tmp < best_val) { best_val = tmp; best_row = row; }
}
best_index = best_row;
}
else
{
uword count = 0;
for(uword col=0; col < n_cols; ++col)
for(uword row=0; row < n_rows; ++row)
{
const T tmp = std::abs(P.at(row,col));
if(tmp < best_val)
{
best_val = tmp;
best_row = row;
best_col = col;
best_index = count;
}
++count;
}
}
index_of_min_val = best_index;
return P.at(best_row, best_col);
}
}
//! @} //! @}
 End of changes. 3 change blocks. 
2 lines changed or deleted 172 lines changed or added


 spop_max_bones.hpp   spop_max_bones.hpp 
// Copyright (C) 2012 Conrad Sanderson // Copyright (C) 2012-2014 Conrad Sanderson
// Copyright (C) 2012-2014 Ryan Curtin
// //
// 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 spop_max //! \addtogroup spop_max
//! @{ //! @{
class spop_max class spop_max
{ {
public: public:
template<typename T1> template<typename T1>
inline static void apply(SpMat<typename T1::elem_type>& out, const SpOp<T 1, spop_max>& in); inline static void apply(SpMat<typename T1::elem_type>& out, const SpOp<T 1, spop_max>& in);
//
template<typename T1> template<typename T1>
inline static void apply_noalias(SpMat<typename T1::elem_type>& out, cons t SpProxy<T1>& p, const uword dim, const typename arma_not_cx<typename T1:: elem_type>::result* junk = 0); inline static void apply_noalias(SpMat<typename T1::elem_type>& out, cons t SpProxy<T1>& p, const uword dim, const typename arma_not_cx<typename T1:: elem_type>::result* junk = 0);
template<typename T1> template<typename T1>
inline static void apply_noalias(SpMat<typename T1::elem_type>& out, cons t SpProxy<T1>& p, const uword dim, const typename arma_cx_only<typename T1: :elem_type>::result* junk = 0); inline static typename T1::elem_type vector_max(const T1& X, const typena me arma_not_cx<typename T1::elem_type>::result* junk = 0);
template<typename T1> template<typename T1>
inline static typename T1::elem_type vector_max(const T1& X, const typena inline static typename arma_not_cx<typename T1::elem_type>::result max(co
me arma_not_cx<typename T1::elem_type>::result* junk = 0); nst SpBase<typename T1::elem_type, T1>& X);
template<typename T1>
inline static typename arma_not_cx<typename T1::elem_type>::result max_wi
th_index(const SpProxy<T1>& P, uword& index_of_max_val);
//
template<typename T1>
inline static void apply_noalias(SpMat<typename T1::elem_type>& out, cons
t SpProxy<T1>& p, const uword dim, const typename arma_cx_only<typename T1:
:elem_type>::result* junk = 0);
template<typename T1> template<typename T1>
inline static typename T1::elem_type vector_max(const T1& X, const typena me arma_cx_only<typename T1::elem_type>::result* junk = 0); inline static typename T1::elem_type vector_max(const T1& X, const typena me arma_cx_only<typename T1::elem_type>::result* junk = 0);
template<typename T1>
inline static typename arma_cx_only<typename T1::elem_type>::result max(c
onst SpBase<typename T1::elem_type, T1>& X);
template<typename T1>
inline static typename arma_cx_only<typename T1::elem_type>::result max_w
ith_index(const SpProxy<T1>& P, uword& index_of_max_val);
}; };
//! @} //! @}
 End of changes. 5 change blocks. 
4 lines changed or deleted 26 lines changed or added


 spop_max_meat.hpp   spop_max_meat.hpp 
// Copyright (C) 2012 Ryan Curtin // Copyright (C) 2012-2014 Ryan Curtin
// Copyright (C) 2012 Conrad Sanderson // Copyright (C) 2012-2014 Conrad Sanderson
// //
// 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 spop_max //! \addtogroup spop_max
//! @{ //! @{
template<typename T1> template<typename T1>
inline inline
skipping to change at line 60 skipping to change at line 60
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
arma_ignore(junk); arma_ignore(junk);
typedef typename T1::elem_type eT; typedef typename T1::elem_type eT;
if(dim == 0) if(dim == 0)
{ {
// maximum in each column // maximum in each column
result.set_size(1, p.get_n_cols()); result.set_size(1, p.get_n_cols());
if(p.get_n_nonzero() == 0) if(p.get_n_nonzero() == 0) { return; }
{
return;
}
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();
uword cur_col = it.col(); uword cur_col = it.col();
uword elem_in_col = 1; uword elem_in_col = 1;
eT cur_max = (*it); eT cur_max = (*it);
++it; ++it;
while(it != p.end()) while(it != it_end)
{ {
if(it.col() != cur_col) if(it.col() != cur_col)
{ {
// was the column full? // was the column full?
if(elem_in_col == p.get_n_rows()) if(elem_in_col == p.get_n_rows())
{ {
result.at(0, cur_col) = cur_max; result.at(0, cur_col) = cur_max;
} }
else else
{ {
result.at(0, cur_col) = std::max(eT(0), cur_max); result.at(0, cur_col) = std::max(eT(0), cur_max);
} }
cur_col = it.col(); cur_col = it.col();
elem_in_col = 0; elem_in_col = 0;
cur_max = (*it); cur_max = (*it);
} }
else else
{ {
cur_max = std::max(cur_max, *it); cur_max = std::max(cur_max, *it);
} }
++elem_in_col; ++elem_in_col;
++it; ++it;
} }
skipping to change at line 113 skipping to change at line 113
else else
{ {
result.at(0, cur_col) = std::max(eT(0), cur_max); result.at(0, cur_col) = std::max(eT(0), cur_max);
} }
} }
else else
{ {
// maximum in each row // maximum in each row
result.set_size(p.get_n_rows(), 1); result.set_size(p.get_n_rows(), 1);
if(p.get_n_nonzero() == 0) if(p.get_n_nonzero() == 0) { return; }
{
return;
}
typename SpProxy<T1>::const_row_iterator_type it = p.begin_row(); typename SpProxy<T1>::const_row_iterator_type it = p.begin_row();
uword cur_row = it.row(); uword cur_row = it.row();
uword elem_in_row = 1; uword elem_in_row = 1;
eT cur_max = (*it); eT cur_max = (*it);
++it; ++it;
while(it.pos() < p.get_n_nonzero()) while(it.pos() < p.get_n_nonzero())
{ {
if(it.row() != cur_row) if(it.row() != cur_row)
{ {
// was the row full? // was the row full?
if(elem_in_row == p.get_n_cols()) if(elem_in_row == p.get_n_cols())
{ {
result.at(cur_row, 0) = cur_max; result.at(cur_row, 0) = cur_max;
} }
else else
{ {
result.at(cur_row, 0) = std::max(eT(0), cur_max); result.at(cur_row, 0) = std::max(eT(0), cur_max);
} }
cur_row = it.row(); cur_row = it.row();
elem_in_row = 0; elem_in_row = 0;
cur_max = (*it); cur_max = (*it);
} }
else else
{ {
cur_max = std::max(cur_max, *it); cur_max = std::max(cur_max, *it);
} }
++elem_in_row; ++elem_in_row;
++it; ++it;
} }
skipping to change at line 165 skipping to change at line 164
} }
else else
{ {
result.at(cur_row, 0) = std::max(eT(0), cur_max); result.at(cur_row, 0) = std::max(eT(0), cur_max);
} }
} }
} }
template<typename T1> template<typename T1>
inline inline
typename T1::elem_type
spop_max::vector_max
(
const T1& x,
const typename arma_not_cx<typename T1::elem_type>::result* junk
)
{
arma_extra_debug_sigprint();
arma_ignore(junk);
typedef typename T1::elem_type eT;
const SpProxy<T1> p(x);
if(p.get_n_nonzero() == 0) { return eT(0); }
if(SpProxy<T1>::must_use_iterator == false)
{
// direct access of values
if(p.get_n_nonzero() == p.get_n_elem())
{
return op_max::direct_max(p.get_values(), p.get_n_nonzero());
}
else
{
return std::max(eT(0), op_max::direct_max(p.get_values(), p.get_n_non
zero()));
}
}
else
{
// use iterator
typename SpProxy<T1>::const_iterator_type it = p.begin();
typename SpProxy<T1>::const_iterator_type it_end = p.end();
eT result = (*it);
++it;
while(it != it_end)
{
if((*it) > result) { result = (*it); }
++it;
}
if(p.get_n_nonzero() == p.get_n_elem())
{
return result;
}
else
{
return std::max(eT(0), result);
}
}
}
template<typename T1>
inline
typename arma_not_cx<typename T1::elem_type>::result
spop_max::max(const SpBase<typename T1::elem_type, T1>& X)
{
arma_extra_debug_sigprint();
typedef typename T1::elem_type eT;
const SpProxy<T1> P(X.get_ref());
const uword n_elem = P.get_n_elem();
const uword n_nonzero = P.get_n_nonzero();
arma_debug_check( (n_elem == 0), "max(): given object has no elements");
eT max_val = priv::most_neg<eT>();
if(SpProxy<T1>::must_use_iterator == true)
{
// We have to iterate over the elements.
typedef typename SpProxy<T1>::const_iterator_type it_type;
it_type it = P.begin();
it_type it_end = P.end();
while (it != it_end)
{
if ((*it) > max_val) { max_val = *it; }
++it;
}
}
else
{
// We can do direct access of the values, row_indices, and col_ptrs.
// We don't need the location of the max value, so we can just call out
to
// other functions...
max_val = op_max::direct_max(P.get_values(), n_nonzero);
}
if(n_elem == n_nonzero)
{
return max_val;
}
else
{
return std::max(eT(0), max_val);
}
}
template<typename T1>
inline
typename arma_not_cx<typename T1::elem_type>::result
spop_max::max_with_index(const SpProxy<T1>& P, uword& index_of_max_val)
{
arma_extra_debug_sigprint();
typedef typename T1::elem_type eT;
const uword n_elem = P.get_n_elem();
const uword n_nonzero = P.get_n_nonzero();
const uword n_rows = P.get_n_rows();
arma_debug_check( (n_elem == 0), "max(): given object has no elements");
eT max_val = priv::most_neg<eT>();
if(SpProxy<T1>::must_use_iterator == true)
{
// We have to iterate over the elements.
typedef typename SpProxy<T1>::const_iterator_type it_type;
it_type it = P.begin();
it_type it_end = P.end();
while (it != it_end)
{
if ((*it) > max_val)
{
max_val = *it;
index_of_max_val = it.row() + it.col() * n_rows;
}
++it;
}
}
else
{
// We can do direct access.
max_val = op_max::direct_max(P.get_values(), n_nonzero, index_of_max_va
l);
// Convert to actual position in matrix.
const uword row = P.get_row_indices()[index_of_max_val];
uword col = 0;
while (P.get_col_ptrs()[++col] <= index_of_max_val) { }
index_of_max_val = (col - 1) * n_rows + row;
}
if(n_elem != n_nonzero)
{
max_val = std::max(eT(0), max_val);
// If the max_val is a nonzero element, we need its actual position in
the matrix.
if(max_val == eT(0))
{
// Find first zero element.
uword last_row = 0;
uword last_col = 0;
typedef typename SpProxy<T1>::const_iterator_type it_type;
it_type it = P.begin();
it_type it_end = P.end();
while (it != it_end)
{
// Have we moved more than one position from the last place?
if ((it.col() == last_col) && (it.row() - last_row > 1))
{
index_of_max_val = it.col() * n_rows + last_row + 1;
break;
}
else if ((it.col() >= last_col + 1) && (last_row < n_rows - 1))
{
index_of_max_val = last_col * n_rows + last_row + 1;
break;
}
else if ((it.col() == last_col + 1) && (it.row() > 0))
{
index_of_max_val = it.col() * n_rows;
break;
}
else if (it.col() > last_col + 1)
{
index_of_max_val = (last_col + 1) * n_rows;
break;
}
last_row = it.row();
last_col = it.col();
++it;
}
}
}
return max_val;
}
template<typename T1>
inline
void void
spop_max::apply_noalias spop_max::apply_noalias
( (
SpMat<typename T1::elem_type>& result, SpMat<typename T1::elem_type>& result,
const SpProxy<T1>& p, const SpProxy<T1>& p,
const uword dim, const uword dim,
const typename arma_cx_only<typename T1::elem_type>::result* junk const typename arma_cx_only<typename T1::elem_type>::result* junk
) )
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
arma_ignore(junk); arma_ignore(junk);
typedef typename T1::elem_type eT; typedef typename T1::elem_type eT;
typedef typename get_pod_type<eT>::result T; typedef typename get_pod_type<eT>::result T;
if(dim == 0) if(dim == 0)
{ {
// maximum in each column // maximum in each column
result.set_size(1, p.get_n_cols()); result.set_size(1, p.get_n_cols());
if(p.get_n_nonzero() == 0) if(p.get_n_nonzero() == 0) { return; }
{
return;
}
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();
uword cur_col = it.col(); uword cur_col = it.col();
uword elem_in_col = 1; uword elem_in_col = 1;
eT cur_max_orig = *it; eT cur_max_orig = *it;
T cur_max_abs = std::abs(cur_max_orig); T cur_max_abs = std::abs(cur_max_orig);
++it; ++it;
while(it != p.end()) while(it != it_end)
{ {
if(it.col() != cur_col) if(it.col() != cur_col)
{ {
// was the column full? // was the column full?
if(elem_in_col == p.get_n_rows()) if(elem_in_col == p.get_n_rows())
{ {
result.at(0, cur_col) = cur_max_orig; result.at(0, cur_col) = cur_max_orig;
} }
else else
{ {
eT val1 = eT(0); eT val1 = eT(0);
result.at(0, cur_col) = ( std::abs(val1) >= cur_max_abs ) ? val1 : cur_max_orig; result.at(0, cur_col) = ( std::abs(val1) >= cur_max_abs ) ? val1 : cur_max_orig;
} }
cur_col = it.col(); cur_col = it.col();
elem_in_col = 0; elem_in_col = 0;
cur_max_orig = *it; cur_max_orig = *it;
cur_max_abs = std::abs(cur_max_orig); cur_max_abs = std::abs(cur_max_orig);
} }
else else
{ {
eT val1_orig = *it; eT val1_orig = *it;
T val1_abs = std::abs(val1_orig); T val1_abs = std::abs(val1_orig);
skipping to change at line 254 skipping to change at line 457
eT val1 = eT(0); eT val1 = eT(0);
result.at(0, cur_col) = ( std::abs(val1) >= cur_max_abs ) ? val1 : cu r_max_orig; result.at(0, cur_col) = ( std::abs(val1) >= cur_max_abs ) ? val1 : cu r_max_orig;
} }
} }
else else
{ {
// maximum in each row // maximum in each row
result.set_size(p.get_n_rows(), 1); result.set_size(p.get_n_rows(), 1);
if(p.get_n_nonzero() == 0) if(p.get_n_nonzero() == 0) { return; }
{
return;
}
typename SpProxy<T1>::const_row_iterator_type it = p.begin_row(); typename SpProxy<T1>::const_row_iterator_type it = p.begin_row();
uword cur_row = it.row(); uword cur_row = it.row();
uword elem_in_row = 1; uword elem_in_row = 1;
eT cur_max_orig = *it; eT cur_max_orig = *it;
T cur_max_abs = std::abs(cur_max_orig); T cur_max_abs = std::abs(cur_max_orig);
++it; ++it;
while(it.pos() < p.get_n_nonzero()) while(it.pos() < p.get_n_nonzero())
{ {
if(it.row() != cur_row) if(it.row() != cur_row)
skipping to change at line 326 skipping to change at line 526
} }
} }
} }
template<typename T1> template<typename T1>
inline inline
typename T1::elem_type typename T1::elem_type
spop_max::vector_max spop_max::vector_max
( (
const T1& x, const T1& x,
const typename arma_not_cx<typename T1::elem_type>::result* junk const typename arma_cx_only<typename T1::elem_type>::result* junk
) )
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
arma_ignore(junk); arma_ignore(junk);
typedef typename T1::elem_type eT; typedef typename T1::elem_type eT;
typedef typename get_pod_type<eT>::result T;
const SpProxy<T1> p(x); const SpProxy<T1> p(x);
if(p.get_n_nonzero() == 0) if(p.get_n_nonzero() == 0) { return eT(0); }
{
return eT(0);
}
if(SpProxy<T1>::must_use_iterator == false) if(SpProxy<T1>::must_use_iterator == false)
{ {
// direct access of values // direct access of values
if(p.get_n_nonzero() == p.get_n_elem()) if(p.get_n_nonzero() == p.get_n_elem())
{ {
return op_max::direct_max(p.get_values(), p.get_n_nonzero()); return op_max::direct_max(p.get_values(), p.get_n_nonzero());
} }
else else
{ {
return std::max(eT(0), op_max::direct_max(p.get_values(), p.get_n_non const eT val1 = eT(0);
zero())); const eT val2 = op_max::direct_max(p.get_values(), p.get_n_nonzero())
;
return ( std::abs(val1) >= std::abs(val2) ) ? val1 : val2;
} }
} }
else else
{ {
// use iterator // use iterator
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();
eT best_val_orig = *it;
T best_val_abs = std::abs(best_val_orig);
eT result = (*it);
++it; ++it;
while(it != p.end()) while(it != it_end)
{ {
if((*it) > result) eT val_orig = *it;
T val_abs = std::abs(val_orig);
if(val_abs > best_val_abs)
{ {
result = (*it); best_val_abs = val_abs;
best_val_orig = val_orig;
} }
++it; ++it;
} }
if(p.get_n_nonzero() == p.get_n_elem()) if(p.get_n_nonzero() == p.get_n_elem())
{ {
return result; return best_val_orig;
} }
else else
{ {
return std::max(eT(0), result); const eT val1 = eT(0);
return ( std::abs(val1) >= best_val_abs ) ? val1 : best_val_orig;
} }
} }
} }
template<typename T1> template<typename T1>
inline inline
typename T1::elem_type typename arma_cx_only<typename T1::elem_type>::result
spop_max::vector_max spop_max::max(const SpBase<typename T1::elem_type, T1>& X)
(
const T1& x,
const typename arma_cx_only<typename T1::elem_type>::result* junk
)
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
arma_ignore(junk);
typedef typename T1::elem_type eT; typedef typename T1::elem_type eT;
typedef typename get_pod_type<eT>::result T; typedef typename get_pod_type<eT>::result T;
const SpProxy<T1> p(x); const SpProxy<T1> P(X.get_ref());
if(p.get_n_nonzero() == 0) const uword n_elem = P.get_n_elem();
{ const uword n_nonzero = P.get_n_nonzero();
return eT(0);
}
if(SpProxy<T1>::must_use_iterator == false) arma_debug_check( (n_elem == 0), "max(): given object has no elements");
T max_val = priv::most_neg<T>();
eT ret_val;
if(SpProxy<T1>::must_use_iterator == true)
{ {
// direct access of values // We have to iterate over the elements.
if(p.get_n_nonzero() == p.get_n_elem()) typedef typename SpProxy<T1>::const_iterator_type it_type;
{
return op_max::direct_max(p.get_values(), p.get_n_nonzero()); it_type it = P.begin();
} it_type it_end = P.end();
else
while (it != it_end)
{ {
const eT val1 = eT(0); const T tmp_val = std::abs(*it);
const eT val2 = op_max::direct_max(p.get_values(), p.get_n_nonzero())
;
return ( std::abs(val1) >= std::abs(val2) ) ? val1 : val2; if (tmp_val > max_val)
{
max_val = tmp_val;
ret_val = *it;
}
++it;
} }
} }
else else
{ {
// use iterator // We can do direct access of the values, row_indices, and col_ptrs.
typename SpProxy<T1>::const_iterator_type it = p.begin(); // We don't need the location of the max value, so we can just call out
to
// other functions...
ret_val = op_max::direct_max(P.get_values(), n_nonzero);
max_val = std::abs(ret_val);
}
eT best_val_orig = *it; if(n_elem == n_nonzero)
T best_val_abs = std::abs(best_val_orig); {
return max_val;
}
else
{
if (T(0) > max_val)
return eT(0);
else
return ret_val;
}
}
++it; template<typename T1>
inline
typename arma_cx_only<typename T1::elem_type>::result
spop_max::max_with_index(const SpProxy<T1>& P, uword& index_of_max_val)
{
arma_extra_debug_sigprint();
typedef typename T1::elem_type eT;
typedef typename get_pod_type<eT>::result T;
const uword n_elem = P.get_n_elem();
const uword n_nonzero = P.get_n_nonzero();
const uword n_rows = P.get_n_rows();
arma_debug_check( (n_elem == 0), "max(): given object has no elements");
T max_val = priv::most_neg<T>();
while(it != p.end()) if(SpProxy<T1>::must_use_iterator == true)
{
// We have to iterate over the elements.
typedef typename SpProxy<T1>::const_iterator_type it_type;
it_type it = P.begin();
it_type it_end = P.end();
while (it != it_end)
{ {
eT val_orig = *it; const T tmp_val = std::abs(*it);
T val_abs = std::abs(val_orig);
if(val_abs > best_val_abs) if (tmp_val > max_val)
{ {
best_val_abs = val_abs; max_val = tmp_val;
best_val_orig = val_orig; index_of_max_val = it.row() + it.col() * n_rows;
} }
++it; ++it;
} }
}
else
{
// We can do direct access.
max_val = std::abs(op_max::direct_max(P.get_values(), n_nonzero, index_
of_max_val));
if(p.get_n_nonzero() == p.get_n_elem()) // Convert to actual position in matrix.
{ const uword row = P.get_row_indices()[index_of_max_val];
return best_val_orig; uword col = 0;
} while (P.get_col_ptrs()[++col] <= index_of_max_val) { }
else index_of_max_val = (col - 1) * n_rows + row;
}
if(n_elem != n_nonzero)
{
max_val = std::max(T(0), max_val);
// If the max_val is a nonzero element, we need its actual position in
the matrix.
if(max_val == T(0))
{ {
const eT val1 = eT(0); // Find first zero element.
uword last_row = 0;
uword last_col = 0;
return ( std::abs(val1) >= best_val_abs ) ? val1 : best_val_orig; typedef typename SpProxy<T1>::const_iterator_type it_type;
it_type it = P.begin();
it_type it_end = P.end();
while (it != it_end)
{
// Have we moved more than one position from the last place?
if ((it.col() == last_col) && (it.row() - last_row > 1))
{
index_of_max_val = it.col() * n_rows + last_row + 1;
break;
}
else if ((it.col() >= last_col + 1) && (last_row < n_rows - 1))
{
index_of_max_val = last_col * n_rows + last_row + 1;
break;
}
else if ((it.col() == last_col + 1) && (it.row() > 0))
{
index_of_max_val = it.col() * n_rows;
break;
}
else if (it.col() > last_col + 1)
{
index_of_max_val = (last_col + 1) * n_rows;
break;
}
last_row = it.row();
last_col = it.col();
++it;
}
} }
} }
return P[index_of_max_val];
} }
//! @} //! @}
 End of changes. 52 change blocks. 
85 lines changed or deleted 391 lines changed or added


 spop_min_bones.hpp   spop_min_bones.hpp 
// Copyright (C) 2012 Conrad Sanderson // Copyright (C) 2012-2014 Conrad Sanderson
// Copyright (C) 2012-2014 Ryan Curtin
// //
// 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 spop_min //! \addtogroup spop_min
//! @{ //! @{
class spop_min class spop_min
{ {
public: public:
template<typename T1> template<typename T1>
inline static void apply(SpMat<typename T1::elem_type>& out, const SpOp<T 1, spop_min>& in); inline static void apply(SpMat<typename T1::elem_type>& out, const SpOp<T 1, spop_min>& in);
//
template<typename T1> template<typename T1>
inline static void apply_noalias(SpMat<typename T1::elem_type>& out, cons t SpProxy<T1>& p, const uword dim, const typename arma_not_cx<typename T1:: elem_type>::result* junk = 0); inline static void apply_noalias(SpMat<typename T1::elem_type>& out, cons t SpProxy<T1>& p, const uword dim, const typename arma_not_cx<typename T1:: elem_type>::result* junk = 0);
template<typename T1> template<typename T1>
inline static void apply_noalias(SpMat<typename T1::elem_type>& out, cons t SpProxy<T1>& p, const uword dim, const typename arma_cx_only<typename T1: :elem_type>::result* junk = 0); inline static typename T1::elem_type vector_min(const T1& X, const typena me arma_not_cx<typename T1::elem_type>::result* junk = 0);
template<typename T1> template<typename T1>
inline static typename T1::elem_type vector_min(const T1& X, const typena inline static typename arma_not_cx<typename T1::elem_type>::result min(co
me arma_not_cx<typename T1::elem_type>::result* junk = 0); nst SpBase<typename T1::elem_type, T1>& X);
template<typename T1>
inline static typename arma_not_cx<typename T1::elem_type>::result min_wi
th_index(const SpProxy<T1>& P, uword& index_of_min_val);
//
template<typename T1>
inline static void apply_noalias(SpMat<typename T1::elem_type>& out, cons
t SpProxy<T1>& p, const uword dim, const typename arma_cx_only<typename T1:
:elem_type>::result* junk = 0);
template<typename T1> template<typename T1>
inline static typename T1::elem_type vector_min(const T1& X, const typena me arma_cx_only<typename T1::elem_type>::result* junk = 0); inline static typename T1::elem_type vector_min(const T1& X, const typena me arma_cx_only<typename T1::elem_type>::result* junk = 0);
template<typename T1>
inline static typename arma_cx_only<typename T1::elem_type>::result min(c
onst SpBase<typename T1::elem_type, T1>& X);
template<typename T1>
inline static typename arma_cx_only<typename T1::elem_type>::result min_w
ith_index(const SpProxy<T1>& P, uword& index_of_min_val);
}; };
//! @} //! @}
 End of changes. 5 change blocks. 
4 lines changed or deleted 26 lines changed or added


 spop_min_meat.hpp   spop_min_meat.hpp 
// Copyright (C) 2012 Ryan Curtin // Copyright (C) 2012-2014 Ryan Curtin
// Copyright (C) 2012 Conrad Sanderson // Copyright (C) 2012-2014 Conrad Sanderson
// //
// 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 spop_min //! \addtogroup spop_min
//! @{ //! @{
template<typename T1> template<typename T1>
inline inline
skipping to change at line 60 skipping to change at line 60
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
arma_ignore(junk); arma_ignore(junk);
typedef typename T1::elem_type eT; typedef typename T1::elem_type eT;
if(dim == 0) if(dim == 0)
{ {
// minimum in each column // minimum in each column
result.set_size(1, p.get_n_cols()); result.set_size(1, p.get_n_cols());
if(p.get_n_nonzero() == 0) if(p.get_n_nonzero() == 0) { return; }
{
return;
}
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();
uword cur_col = it.col(); uword cur_col = it.col();
uword elem_in_col = 1; uword elem_in_col = 1;
eT cur_min = (*it); eT cur_min = (*it);
++it; ++it;
while(it != p.end()) while(it != it_end)
{ {
if(it.col() != cur_col) if(it.col() != cur_col)
{ {
// was the column full? // was the column full?
if(elem_in_col == p.get_n_rows()) if(elem_in_col == p.get_n_rows())
{ {
result.at(0, cur_col) = cur_min; result.at(0, cur_col) = cur_min;
} }
else else
{ {
result.at(0, cur_col) = std::min(eT(0), cur_min); result.at(0, cur_col) = std::min(eT(0), cur_min);
} }
cur_col = it.col(); cur_col = it.col();
elem_in_col = 0; elem_in_col = 0;
cur_min = (*it); cur_min = (*it);
} }
else else
{ {
cur_min = std::min(cur_min, *it); cur_min = std::min(cur_min, *it);
} }
++elem_in_col; ++elem_in_col;
++it; ++it;
} }
skipping to change at line 113 skipping to change at line 113
else else
{ {
result.at(0, cur_col) = std::min(eT(0), cur_min); result.at(0, cur_col) = std::min(eT(0), cur_min);
} }
} }
else else
{ {
// minimum in each row // minimum in each row
result.set_size(p.get_n_rows(), 1); result.set_size(p.get_n_rows(), 1);
if(p.get_n_nonzero() == 0) if(p.get_n_nonzero() == 0) { return; }
{
return;
}
typename SpProxy<T1>::const_row_iterator_type it = p.begin_row(); typename SpProxy<T1>::const_row_iterator_type it = p.begin_row();
uword cur_row = it.row(); uword cur_row = it.row();
uword elem_in_row = 1; uword elem_in_row = 1;
eT cur_min = (*it); eT cur_min = (*it);
++it; ++it;
while(it.pos() < p.get_n_nonzero()) while(it.pos() < p.get_n_nonzero())
{ {
if(it.row() != cur_row) if(it.row() != cur_row)
{ {
// was the row full? // was the row full?
if(elem_in_row == p.get_n_cols()) if(elem_in_row == p.get_n_cols())
{ {
result.at(cur_row, 0) = cur_min; result.at(cur_row, 0) = cur_min;
} }
else else
{ {
result.at(cur_row, 0) = std::min(eT(0), cur_min); result.at(cur_row, 0) = std::min(eT(0), cur_min);
} }
cur_row = it.row(); cur_row = it.row();
elem_in_row = 0; elem_in_row = 0;
cur_min = (*it); cur_min = (*it);
} }
else else
{ {
cur_min = std::min(cur_min, *it); cur_min = std::min(cur_min, *it);
} }
++elem_in_row; ++elem_in_row;
++it; ++it;
} }
skipping to change at line 165 skipping to change at line 164
} }
else else
{ {
result.at(cur_row, 0) = std::min(eT(0), cur_min); result.at(cur_row, 0) = std::min(eT(0), cur_min);
} }
} }
} }
template<typename T1> template<typename T1>
inline inline
typename T1::elem_type
spop_min::vector_min
(
const T1& x,
const typename arma_not_cx<typename T1::elem_type>::result* junk
)
{
arma_extra_debug_sigprint();
arma_ignore(junk);
typedef typename T1::elem_type eT;
const SpProxy<T1> p(x);
if(p.get_n_nonzero() == 0) { return eT(0); }
if(SpProxy<T1>::must_use_iterator == false)
{
// direct access of values
if(p.get_n_nonzero() == p.get_n_elem())
{
return op_min::direct_min(p.get_values(), p.get_n_nonzero());
}
else
{
return std::min(eT(0), op_min::direct_min(p.get_values(), p.get_n_non
zero()));
}
}
else
{
// use iterator
typename SpProxy<T1>::const_iterator_type it = p.begin();
typename SpProxy<T1>::const_iterator_type it_end = p.end();
eT result = (*it);
++it;
while(it != it_end)
{
if((*it) < result) { result = (*it); }
++it;
}
if(p.get_n_nonzero() == p.get_n_elem())
{
return result;
}
else
{
return std::min(eT(0), result);
}
}
}
template<typename T1>
inline
typename arma_not_cx<typename T1::elem_type>::result
spop_min::min(const SpBase<typename T1::elem_type, T1>& X)
{
arma_extra_debug_sigprint();
typedef typename T1::elem_type eT;
const SpProxy<T1> P(X.get_ref());
const uword n_elem = P.get_n_elem();
const uword n_nonzero = P.get_n_nonzero();
arma_debug_check( (n_elem == 0), "min(): given object has no elements");
eT min_val = priv::most_pos<eT>();
if(SpProxy<T1>::must_use_iterator == true)
{
// We have to iterate over the elements.
typedef typename SpProxy<T1>::const_iterator_type it_type;
it_type it = P.begin();
it_type it_end = P.end();
while (it != it_end)
{
if ((*it) < min_val) { min_val = *it; }
++it;
}
}
else
{
// We can do direct access of the values, row_indices, and col_ptrs.
// We don't need the location of the min value, so we can just call out
to
// other functions...
min_val = op_min::direct_min(P.get_values(), n_nonzero);
}
if(n_elem == n_nonzero)
{
return min_val;
}
else
{
return std::min(eT(0), min_val);
}
}
template<typename T1>
inline
typename arma_not_cx<typename T1::elem_type>::result
spop_min::min_with_index(const SpProxy<T1>& P, uword& index_of_min_val)
{
arma_extra_debug_sigprint();
typedef typename T1::elem_type eT;
const uword n_elem = P.get_n_elem();
const uword n_nonzero = P.get_n_nonzero();
const uword n_rows = P.get_n_rows();
arma_debug_check( (n_elem == 0), "min(): given object has no elements");
eT min_val = priv::most_pos<eT>();
if(SpProxy<T1>::must_use_iterator == true)
{
// We have to iterate over the elements.
typedef typename SpProxy<T1>::const_iterator_type it_type;
it_type it = P.begin();
it_type it_end = P.end();
while (it != it_end)
{
if ((*it) < min_val)
{
min_val = *it;
index_of_min_val = it.row() + it.col() * n_rows;
}
++it;
}
}
else
{
// We can do direct access.
min_val = op_min::direct_min(P.get_values(), n_nonzero, index_of_min_va
l);
// Convert to actual position in matrix.
const uword row = P.get_row_indices()[index_of_min_val];
uword col = 0;
while (P.get_col_ptrs()[++col] < index_of_min_val + 1) { }
index_of_min_val = (col - 1) * n_rows + row;
}
if(n_elem != n_nonzero)
{
min_val = std::min(eT(0), min_val);
// If the min_val is a nonzero element, we need its actual position in
the matrix.
if(min_val == eT(0))
{
// Find first zero element.
uword last_row = 0;
uword last_col = 0;
typedef typename SpProxy<T1>::const_iterator_type it_type;
it_type it = P.begin();
it_type it_end = P.end();
while (it != it_end)
{
// Have we moved more than one position from the last place?
if ((it.col() == last_col) && (it.row() - last_row > 1))
{
index_of_min_val = it.col() * n_rows + last_row + 1;
break;
}
else if ((it.col() >= last_col + 1) && (last_row < n_rows - 1))
{
index_of_min_val = last_col * n_rows + last_row + 1;
break;
}
else if ((it.col() == last_col + 1) && (it.row() > 0))
{
index_of_min_val = it.col() * n_rows;
break;
}
else if (it.col() > last_col + 1)
{
index_of_min_val = (last_col + 1) * n_rows;
break;
}
last_row = it.row();
last_col = it.col();
++it;
}
}
}
return min_val;
}
template<typename T1>
inline
void void
spop_min::apply_noalias spop_min::apply_noalias
( (
SpMat<typename T1::elem_type>& result, SpMat<typename T1::elem_type>& result,
const SpProxy<T1>& p, const SpProxy<T1>& p,
const uword dim, const uword dim,
const typename arma_cx_only<typename T1::elem_type>::result* junk const typename arma_cx_only<typename T1::elem_type>::result* junk
) )
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
arma_ignore(junk); arma_ignore(junk);
typedef typename T1::elem_type eT; typedef typename T1::elem_type eT;
typedef typename get_pod_type<eT>::result T; typedef typename get_pod_type<eT>::result T;
if(dim == 0) if(dim == 0)
{ {
// minimum in each column // minimum in each column
result.set_size(1, p.get_n_cols()); result.set_size(1, p.get_n_cols());
if(p.get_n_nonzero() == 0) if(p.get_n_nonzero() == 0) { return; }
{
return;
}
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();
uword cur_col = it.col(); uword cur_col = it.col();
uword elem_in_col = 1; uword elem_in_col = 1;
eT cur_min_orig = *it; eT cur_min_orig = *it;
T cur_min_abs = std::abs(cur_min_orig); T cur_min_abs = std::abs(cur_min_orig);
++it; ++it;
while(it != p.end()) while(it != it_end)
{ {
if(it.col() != cur_col) if(it.col() != cur_col)
{ {
// was the column full? // was the column full?
if(elem_in_col == p.get_n_rows()) if(elem_in_col == p.get_n_rows())
{ {
result.at(0, cur_col) = cur_min_orig; result.at(0, cur_col) = cur_min_orig;
} }
else else
{ {
eT val1 = eT(0); eT val1 = eT(0);
result.at(0, cur_col) = ( std::abs(val1) < cur_min_abs ) ? val1 : cur_min_orig; result.at(0, cur_col) = ( std::abs(val1) < cur_min_abs ) ? val1 : cur_min_orig;
} }
cur_col = it.col(); cur_col = it.col();
elem_in_col = 0; elem_in_col = 0;
cur_min_orig = *it; cur_min_orig = *it;
cur_min_abs = std::abs(cur_min_orig); cur_min_abs = std::abs(cur_min_orig);
} }
else else
{ {
eT val1_orig = *it; eT val1_orig = *it;
T val1_abs = std::abs(val1_orig); T val1_abs = std::abs(val1_orig);
skipping to change at line 254 skipping to change at line 457
eT val1 = eT(0); eT val1 = eT(0);
result.at(0, cur_col) = ( std::abs(val1) < cur_min_abs ) ? val1 : cur _min_orig; result.at(0, cur_col) = ( std::abs(val1) < cur_min_abs ) ? val1 : cur _min_orig;
} }
} }
else else
{ {
// minimum in each row // minimum in each row
result.set_size(p.get_n_rows(), 1); result.set_size(p.get_n_rows(), 1);
if(p.get_n_nonzero() == 0) if(p.get_n_nonzero() == 0) { return; }
{
return;
}
typename SpProxy<T1>::const_row_iterator_type it = p.begin_row(); typename SpProxy<T1>::const_row_iterator_type it = p.begin_row();
uword cur_row = it.row(); uword cur_row = it.row();
uword elem_in_row = 1; uword elem_in_row = 1;
eT cur_min_orig = *it; eT cur_min_orig = *it;
T cur_min_abs = std::abs(cur_min_orig); T cur_min_abs = std::abs(cur_min_orig);
++it; ++it;
while(it.pos() < p.get_n_nonzero()) while(it.pos() < p.get_n_nonzero())
{ {
if(it.row() != cur_row) if(it.row() != cur_row)
skipping to change at line 326 skipping to change at line 526
} }
} }
} }
template<typename T1> template<typename T1>
inline inline
typename T1::elem_type typename T1::elem_type
spop_min::vector_min spop_min::vector_min
( (
const T1& x, const T1& x,
const typename arma_not_cx<typename T1::elem_type>::result* junk const typename arma_cx_only<typename T1::elem_type>::result* junk
) )
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
arma_ignore(junk); arma_ignore(junk);
typedef typename T1::elem_type eT; typedef typename T1::elem_type eT;
typedef typename get_pod_type<eT>::result T;
const SpProxy<T1> p(x); const SpProxy<T1> p(x);
if(p.get_n_nonzero() == 0) if(p.get_n_nonzero() == 0) { return eT(0); }
{
return eT(0);
}
if(SpProxy<T1>::must_use_iterator == false) if(SpProxy<T1>::must_use_iterator == false)
{ {
// direct access of values // direct access of values
if(p.get_n_nonzero() == p.get_n_elem()) if(p.get_n_nonzero() == p.get_n_elem())
{ {
return op_min::direct_min(p.get_values(), p.get_n_nonzero()); return op_min::direct_min(p.get_values(), p.get_n_nonzero());
} }
else else
{ {
return std::min(eT(0), op_min::direct_min(p.get_values(), p.get_n_non const eT val1 = eT(0);
zero())); const eT val2 = op_min::direct_min(p.get_values(), p.get_n_nonzero())
;
return ( std::abs(val1) < std::abs(val2) ) ? val1 : val2;
} }
} }
else else
{ {
// use iterator // use iterator
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();
eT best_val_orig = *it;
T best_val_abs = std::abs(best_val_orig);
eT result = (*it);
++it; ++it;
while(it != p.end()) while(it != it_end)
{ {
if((*it) < result) eT val_orig = *it;
T val_abs = std::abs(val_orig);
if(val_abs < best_val_abs)
{ {
result = (*it); best_val_abs = val_abs;
best_val_orig = val_orig;
} }
++it; ++it;
} }
if(p.get_n_nonzero() == p.get_n_elem()) if(p.get_n_nonzero() == p.get_n_elem())
{ {
return result; return best_val_orig;
} }
else else
{ {
return std::min(eT(0), result); const eT val1 = eT(0);
return ( std::abs(val1) < best_val_abs ) ? val1 : best_val_orig;
} }
} }
} }
template<typename T1> template<typename T1>
inline inline
typename T1::elem_type typename arma_cx_only<typename T1::elem_type>::result
spop_min::vector_min spop_min::min(const SpBase<typename T1::elem_type, T1>& X)
(
const T1& x,
const typename arma_cx_only<typename T1::elem_type>::result* junk
)
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
arma_ignore(junk);
typedef typename T1::elem_type eT; typedef typename T1::elem_type eT;
typedef typename get_pod_type<eT>::result T; typedef typename get_pod_type<eT>::result T;
const SpProxy<T1> p(x); const SpProxy<T1> P(X.get_ref());
if(p.get_n_nonzero() == 0) const uword n_elem = P.get_n_elem();
{ const uword n_nonzero = P.get_n_nonzero();
return eT(0);
}
if(SpProxy<T1>::must_use_iterator == false) arma_debug_check( (n_elem == 0), "min(): given object has no elements");
T min_val = priv::most_pos<T>();
eT ret_val;
if(SpProxy<T1>::must_use_iterator == true)
{ {
// direct access of values // We have to iterate over the elements.
if(p.get_n_nonzero() == p.get_n_elem()) typedef typename SpProxy<T1>::const_iterator_type it_type;
{
return op_min::direct_min(p.get_values(), p.get_n_nonzero()); it_type it = P.begin();
} it_type it_end = P.end();
else
while (it != it_end)
{ {
const eT val1 = eT(0); const T tmp_val = std::abs(*it);
const eT val2 = op_min::direct_min(p.get_values(), p.get_n_nonzero())
;
return ( std::abs(val1) < std::abs(val2) ) ? val1 : val2; if (tmp_val < min_val)
{
min_val = tmp_val;
ret_val = *it;
}
++it;
} }
} }
else else
{ {
// use iterator // We can do direct access of the values, row_indices, and col_ptrs.
typename SpProxy<T1>::const_iterator_type it = p.begin(); // We don't need the location of the min value, so we can just call out
to
// other functions...
ret_val = op_min::direct_min(P.get_values(), n_nonzero);
min_val = std::abs(ret_val);
}
eT best_val_orig = *it; if(n_elem == n_nonzero)
T best_val_abs = std::abs(best_val_orig); {
return ret_val;
}
else
{
if (T(0) < min_val)
return eT(0);
else
return ret_val;
}
}
++it; template<typename T1>
inline
typename arma_cx_only<typename T1::elem_type>::result
spop_min::min_with_index(const SpProxy<T1>& P, uword& index_of_min_val)
{
arma_extra_debug_sigprint();
typedef typename T1::elem_type eT;
typedef typename get_pod_type<eT>::result T;
const uword n_elem = P.get_n_elem();
const uword n_nonzero = P.get_n_nonzero();
const uword n_rows = P.get_n_rows();
arma_debug_check( (n_elem == 0), "min(): given object has no elements");
T min_val = priv::most_pos<T>();
while(it != p.end()) if(SpProxy<T1>::must_use_iterator == true)
{
// We have to iterate over the elements.
typedef typename SpProxy<T1>::const_iterator_type it_type;
it_type it = P.begin();
it_type it_end = P.end();
while (it != it_end)
{ {
eT val_orig = *it; const T tmp_val = std::abs(*it);
T val_abs = std::abs(val_orig);
if(val_abs < best_val_abs) if (tmp_val < min_val)
{ {
best_val_abs = val_abs; min_val = tmp_val;
best_val_orig = val_orig; index_of_min_val = it.row() + it.col() * n_rows;
} }
++it; ++it;
} }
}
else
{
// We can do direct access.
min_val = std::abs(op_min::direct_min(P.get_values(), n_nonzero, index_
of_min_val));
if(p.get_n_nonzero() == p.get_n_elem()) // Convert to actual position in matrix.
{ const uword row = P.get_row_indices()[index_of_min_val];
return best_val_orig; uword col = 0;
} while (P.get_col_ptrs()[++col] < index_of_min_val + 1) { }
else index_of_min_val = (col - 1) * n_rows + row;
}
if(n_elem != n_nonzero)
{
min_val = std::min(T(0), min_val);
// If the min_val is a nonzero element, we need its actual position in
the matrix.
if(min_val == T(0))
{ {
const eT val1 = eT(0); // Find first zero element.
uword last_row = 0;
uword last_col = 0;
return ( std::abs(val1) < best_val_abs ) ? val1 : best_val_orig; typedef typename SpProxy<T1>::const_iterator_type it_type;
it_type it = P.begin();
it_type it_end = P.end();
while (it != it_end)
{
// Have we moved more than one position from the last place?
if ((it.col() == last_col) && (it.row() - last_row > 1))
{
index_of_min_val = it.col() * n_rows + last_row + 1;
break;
}
else if ((it.col() >= last_col + 1) && (last_row < n_rows - 1))
{
index_of_min_val = last_col * n_rows + last_row + 1;
break;
}
else if ((it.col() == last_col + 1) && (it.row() > 0))
{
index_of_min_val = it.col() * n_rows;
break;
}
else if (it.col() > last_col + 1)
{
index_of_min_val = (last_col + 1) * n_rows;
break;
}
last_row = it.row();
last_col = it.col();
++it;
}
} }
} }
return P[index_of_min_val];
} }
//! @} //! @}
 End of changes. 52 change blocks. 
85 lines changed or deleted 391 lines changed or added


 subview_cube_bones.hpp   subview_cube_bones.hpp 
// Copyright (C) 2008-2013 Conrad Sanderson // Copyright (C) 2008-2014 Conrad Sanderson
// Copyright (C) 2008-2013 NICTA (www.nicta.com.au) // Copyright (C) 2008-2014 NICTA (www.nicta.com.au)
// //
// 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 subview_cube //! \addtogroup subview_cube
//! @{ //! @{
//! Class for storing data required to construct or apply operations to a s ubcube //! Class for storing data required to construct or apply operations to a s ubcube
//! (i.e. where the subcube starts and ends as well as a reference/pointer to the original cube), //! (i.e. where the subcube starts and ends as well as a reference/pointer to the original cube),
skipping to change at line 87 skipping to change at line 87
template<typename functor> inline void transform(functor F); template<typename functor> inline void transform(functor F);
template<typename functor> inline void imbue(functor F); template<typename functor> inline void imbue(functor F);
inline void fill(const eT val); inline void fill(const eT val);
inline void zeros(); inline void zeros();
inline void ones(); inline void ones();
inline void randu(); inline void randu();
inline void randn(); inline void randn();
inline arma_warn_unused eT min() const;
inline arma_warn_unused eT max() const;
inline eT at_alt (const uword i) const; inline eT at_alt (const uword i) const;
inline eT& operator[](const uword i); inline eT& operator[](const uword i);
inline eT operator[](const uword i) const; inline eT operator[](const uword i) const;
inline eT& operator()(const uword i); inline eT& operator()(const uword i);
inline eT operator()(const uword i) const; inline eT operator()(const uword i) const;
arma_inline eT& operator()(const uword in_row, const uword in_col, const uword in_slice); arma_inline eT& operator()(const uword in_row, const uword in_col, const uword in_slice);
arma_inline eT operator()(const uword in_row, const uword in_col, const uword in_slice) const; arma_inline eT operator()(const uword in_row, const uword in_col, const uword in_slice) const;
 End of changes. 2 change blocks. 
2 lines changed or deleted 5 lines changed or added


 subview_cube_meat.hpp   subview_cube_meat.hpp 
skipping to change at line 284 skipping to change at line 284
{ {
arrayops::inplace_div( t.slice_colptr(slice,col), x.slice_colptr(slic e,col), t_n_rows ); arrayops::inplace_div( t.slice_colptr(slice,col), x.slice_colptr(slic e,col), t_n_rows );
} }
} }
} }
//! x.subcube(...) = y.subcube(...) //! x.subcube(...) = y.subcube(...)
template<typename eT> template<typename eT>
inline inline
void void
subview_cube<eT>::operator= (const subview_cube<eT>& x_in) subview_cube<eT>::operator= (const subview_cube<eT>& x)
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
const bool overlap = check_overlap(x_in); if(check_overlap(x))
{
const Cube<eT> tmp(x);
(*this).operator=(tmp);
Cube<eT>* tmp_cube = overlap ? new Cube<eT>(x_in.m) return;
: 0; }
const subview_cube<eT>* tmp_subview_cube = overlap ? new subview_cube<eT>
(*tmp_cube, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.n_rows, x_i
n.n_cols, x_in.n_slices) : 0;
const subview_cube<eT>& x = overlap ? (*tmp_subview_cube)
: x_in;
subview_cube<eT>& t = *this; subview_cube<eT>& t = *this;
arma_debug_assert_same_size(t, x, "copy into subcube"); arma_debug_assert_same_size(t, x, "copy into subcube");
const uword t_n_rows = t.n_rows; const uword t_n_rows = t.n_rows;
const uword t_n_cols = t.n_cols; const uword t_n_cols = t.n_cols;
const uword t_n_slices = t.n_slices; const uword t_n_slices = t.n_slices;
for(uword slice = 0; slice < t_n_slices; ++slice) for(uword slice = 0; slice < t_n_slices; ++slice)
{ {
for(uword col = 0; col < t_n_cols; ++col) for(uword col = 0; col < t_n_cols; ++col)
{ {
arrayops::copy( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows ); arrayops::copy( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
} }
} }
if(overlap)
{
delete tmp_subview_cube;
delete tmp_cube;
}
} }
template<typename eT> template<typename eT>
inline inline
void void
subview_cube<eT>::operator+= (const subview_cube<eT>& x_in) subview_cube<eT>::operator+= (const subview_cube<eT>& x)
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
const bool overlap = check_overlap(x_in); if(check_overlap(x))
{
const Cube<eT> tmp(x);
(*this).operator+=(tmp);
Cube<eT>* tmp_cube = overlap ? new Cube<eT>(x_in.m) return;
: 0; }
const subview_cube<eT>* tmp_subview_cube = overlap ? new subview_cube<eT>
(*tmp_cube, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.n_rows, x_i
n.n_cols, x_in.n_slices) : 0;
const subview_cube<eT>& x = overlap ? (*tmp_subview_cube)
: x_in;
subview_cube<eT>& t = *this; subview_cube<eT>& t = *this;
arma_debug_assert_same_size(t, x, "addition"); arma_debug_assert_same_size(t, x, "addition");
const uword t_n_rows = t.n_rows; const uword t_n_rows = t.n_rows;
const uword t_n_cols = t.n_cols; const uword t_n_cols = t.n_cols;
const uword t_n_slices = t.n_slices; const uword t_n_slices = t.n_slices;
for(uword slice = 0; slice < t_n_slices; ++slice) for(uword slice = 0; slice < t_n_slices; ++slice)
{ {
for(uword col = 0; col < t_n_cols; ++col) for(uword col = 0; col < t_n_cols; ++col)
{ {
arrayops::inplace_plus( t.slice_colptr(slice,col), x.slice_colptr(sli ce,col), t_n_rows ); arrayops::inplace_plus( t.slice_colptr(slice,col), x.slice_colptr(sli ce,col), t_n_rows );
} }
} }
if(overlap)
{
delete tmp_subview_cube;
delete tmp_cube;
}
} }
template<typename eT> template<typename eT>
inline inline
void void
subview_cube<eT>::operator-= (const subview_cube<eT>& x_in) subview_cube<eT>::operator-= (const subview_cube<eT>& x)
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
const bool overlap = check_overlap(x_in); if(check_overlap(x))
{
const Cube<eT> tmp(x);
(*this).operator-=(tmp);
Cube<eT>* tmp_cube = overlap ? new Cube<eT>(x_in.m) return;
: 0; }
const subview_cube<eT>* tmp_subview_cube = overlap ? new subview_cube<eT>
(*tmp_cube, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.n_rows, x_i
n.n_cols, x_in.n_slices) : 0;
const subview_cube<eT>& x = overlap ? (*tmp_subview_cube)
: x_in;
subview_cube<eT>& t = *this; subview_cube<eT>& t = *this;
arma_debug_assert_same_size(t, x, "subtraction"); arma_debug_assert_same_size(t, x, "subtraction");
const uword t_n_rows = t.n_rows; const uword t_n_rows = t.n_rows;
const uword t_n_cols = t.n_cols; const uword t_n_cols = t.n_cols;
const uword t_n_slices = t.n_slices; const uword t_n_slices = t.n_slices;
for(uword slice = 0; slice < t_n_slices; ++slice) for(uword slice = 0; slice < t_n_slices; ++slice)
{ {
for(uword col = 0; col < t_n_cols; ++col) for(uword col = 0; col < t_n_cols; ++col)
{ {
arrayops::inplace_minus( t.slice_colptr(slice,col), x.slice_colptr(sl ice,col), t_n_rows ); arrayops::inplace_minus( t.slice_colptr(slice,col), x.slice_colptr(sl ice,col), t_n_rows );
} }
} }
if(overlap)
{
delete tmp_subview_cube;
delete tmp_cube;
}
} }
template<typename eT> template<typename eT>
inline inline
void void
subview_cube<eT>::operator%= (const subview_cube<eT>& x_in) subview_cube<eT>::operator%= (const subview_cube<eT>& x)
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
const bool overlap = check_overlap(x_in); if(check_overlap(x))
{
const Cube<eT> tmp(x);
Cube<eT>* tmp_cube = overlap ? new Cube<eT>(x_in.m) (*this).operator%=(tmp);
: 0;
const subview_cube<eT>* tmp_subview_cube = overlap ? new subview_cube<eT> return;
(*tmp_cube, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.n_rows, x_i }
n.n_cols, x_in.n_slices) : 0;
const subview_cube<eT>& x = overlap ? (*tmp_subview_cube)
: x_in;
subview_cube<eT>& t = *this; subview_cube<eT>& t = *this;
arma_debug_assert_same_size(t, x, "element-wise multiplication"); arma_debug_assert_same_size(t, x, "element-wise multiplication");
const uword t_n_rows = t.n_rows; const uword t_n_rows = t.n_rows;
const uword t_n_cols = t.n_cols; const uword t_n_cols = t.n_cols;
const uword t_n_slices = t.n_slices; const uword t_n_slices = t.n_slices;
for(uword slice = 0; slice < t_n_slices; ++slice) for(uword slice = 0; slice < t_n_slices; ++slice)
{ {
for(uword col = 0; col < t_n_cols; ++col) for(uword col = 0; col < t_n_cols; ++col)
{ {
arrayops::inplace_mul( t.slice_colptr(slice,col), x.slice_colptr(slic e,col), t_n_rows ); arrayops::inplace_mul( t.slice_colptr(slice,col), x.slice_colptr(slic e,col), t_n_rows );
} }
} }
if(overlap)
{
delete tmp_subview_cube;
delete tmp_cube;
}
} }
template<typename eT> template<typename eT>
inline inline
void void
subview_cube<eT>::operator/= (const subview_cube<eT>& x_in) subview_cube<eT>::operator/= (const subview_cube<eT>& x)
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
const bool overlap = check_overlap(x_in); if(check_overlap(x))
{
const Cube<eT> tmp(x);
(*this).operator/=(tmp);
Cube<eT>* tmp_cube = overlap ? new Cube<eT>(x_in.m) return;
: 0; }
const subview_cube<eT>* tmp_subview_cube = overlap ? new subview_cube<eT>
(*tmp_cube, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.n_rows, x_i
n.n_cols, x_in.n_slices) : 0;
const subview_cube<eT>& x = overlap ? (*tmp_subview_cube)
: x_in;
subview_cube<eT>& t = *this; subview_cube<eT>& t = *this;
arma_debug_assert_same_size(t, x, "element-wise division"); arma_debug_assert_same_size(t, x, "element-wise division");
const uword t_n_rows = t.n_rows; const uword t_n_rows = t.n_rows;
const uword t_n_cols = t.n_cols; const uword t_n_cols = t.n_cols;
const uword t_n_slices = t.n_slices; const uword t_n_slices = t.n_slices;
for(uword slice = 0; slice < t_n_slices; ++slice) for(uword slice = 0; slice < t_n_slices; ++slice)
{ {
for(uword col = 0; col < t_n_cols; ++col) for(uword col = 0; col < t_n_cols; ++col)
{ {
arrayops::inplace_div( t.slice_colptr(slice,col), x.slice_colptr(slic e,col), t_n_rows ); arrayops::inplace_div( t.slice_colptr(slice,col), x.slice_colptr(slic e,col), t_n_rows );
} }
} }
if(overlap)
{
delete tmp_subview_cube;
delete tmp_cube;
}
} }
template<typename eT> template<typename eT>
template<typename T1> template<typename T1>
inline inline
void void
subview_cube<eT>::operator= (const Base<eT,T1>& in) subview_cube<eT>::operator= (const Base<eT,T1>& in)
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
skipping to change at line 1119 skipping to change at line 1099
{ {
for(uword col = 0; col < local_n_cols; ++col) for(uword col = 0; col < local_n_cols; ++col)
{ {
arma_rng::randn<eT>::fill( slice_colptr(slice,col), local_n_rows ); arma_rng::randn<eT>::fill( slice_colptr(slice,col), local_n_rows );
} }
} }
} }
template<typename eT> template<typename eT>
inline inline
arma_warn_unused
eT
subview_cube<eT>::min() const
{
arma_extra_debug_sigprint();
arma_debug_check( (n_elem == 0), "subview_cube::min(): object has no elem
ents" );
const uword local_n_rows = n_rows;
const uword local_n_cols = n_cols;
const uword local_n_slices = n_slices;
eT min_val = at(0,0,0);
for(uword si=0; si < local_n_slices; ++si)
for(uword ci=0; ci < local_n_cols; ++ci)
{
min_val = (std::min)( min_val, op_min::direct_min(slice_colptr(si,ci),
local_n_rows) );
}
return min_val;
}
template<typename eT>
inline
arma_warn_unused
eT
subview_cube<eT>::max() const
{
arma_extra_debug_sigprint();
arma_debug_check( (n_elem == 0), "subview_cube::max(): object has no elem
ents" );
const uword local_n_rows = n_rows;
const uword local_n_cols = n_cols;
const uword local_n_slices = n_slices;
eT max_val = at(0,0,0);
for(uword si=0; si < local_n_slices; ++si)
for(uword ci=0; ci < local_n_cols; ++ci)
{
max_val = (std::max)( max_val, op_max::direct_max(slice_colptr(si,ci),
local_n_rows) );
}
return max_val;
}
template<typename eT>
inline
eT eT
subview_cube<eT>::at_alt(const uword i) const subview_cube<eT>::at_alt(const uword i) const
{ {
return operator[](i); return operator[](i);
} }
template<typename eT> template<typename eT>
inline inline
eT& eT&
subview_cube<eT>::operator[](const uword i) subview_cube<eT>::operator[](const uword i)
 End of changes. 21 change blocks. 
80 lines changed or deleted 94 lines changed or added


 subview_field_meat.hpp   subview_field_meat.hpp 
skipping to change at line 98 skipping to change at line 98
{ {
t.at(row,col,slice) = x.at(row,col,slice); t.at(row,col,slice) = x.at(row,col,slice);
} }
} }
} }
//! x.subfield(...) = y.subfield(...) //! x.subfield(...) = y.subfield(...)
template<typename oT> template<typename oT>
inline inline
void void
subview_field<oT>::operator= (const subview_field<oT>& x_in) subview_field<oT>::operator= (const subview_field<oT>& x)
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
const bool overlap = check_overlap(x_in); if(check_overlap(x))
{
const field<oT> tmp(x);
(*this).operator=(tmp);
field<oT>* tmp_field = overlap ? new field<oT>(x_in.f) : return;
0; }
const subview_field<oT>* tmp_subview = overlap ? new subview_field<oT>(*t
mp_field, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.n_rows, x_in.
n_cols, x_in.n_slices) : 0;
const subview_field<oT>& x = overlap ? (*tmp_subview) : x_in;
subview_field<oT>& t = *this; subview_field<oT>& t = *this;
arma_debug_check( (t.n_rows != x.n_rows) || (t.n_cols != x.n_cols) || (t. n_slices != x.n_slices), "incompatible field dimensions"); arma_debug_check( (t.n_rows != x.n_rows) || (t.n_cols != x.n_cols) || (t. n_slices != x.n_slices), "incompatible field dimensions");
if(t.n_slices == 1) if(t.n_slices == 1)
{ {
for(uword col=0; col < t.n_cols; ++col) for(uword col=0; col < t.n_cols; ++col)
for(uword row=0; row < t.n_rows; ++row) for(uword row=0; row < t.n_rows; ++row)
{ {
skipping to change at line 129 skipping to change at line 132
} }
else else
{ {
for(uword slice=0; slice < t.n_slices; ++slice) for(uword slice=0; slice < t.n_slices; ++slice)
for(uword col=0; col < t.n_cols; ++col ) for(uword col=0; col < t.n_cols; ++col )
for(uword row=0; row < t.n_rows; ++row ) for(uword row=0; row < t.n_rows; ++row )
{ {
t.at(row,col,slice) = x.at(row,col,slice); t.at(row,col,slice) = x.at(row,col,slice);
} }
} }
if(overlap)
{
delete tmp_subview;
delete tmp_field;
}
} }
template<typename oT> template<typename oT>
arma_inline arma_inline
oT& oT&
subview_field<oT>::operator[](const uword i) subview_field<oT>::operator[](const uword i)
{ {
uword index; uword index;
if(n_slices == 1) if(n_slices == 1)
 End of changes. 4 change blocks. 
14 lines changed or deleted 8 lines changed or added


 subview_meat.hpp   subview_meat.hpp 
skipping to change at line 849 skipping to change at line 849
for (uword r = 0; r < n_rows; ++r) for (uword r = 0; r < n_rows; ++r)
{ {
at(r, c) /= p.at(r, c); at(r, c) /= p.at(r, c);
} }
} }
//! x.submat(...) = y.submat(...) //! x.submat(...) = y.submat(...)
template<typename eT> template<typename eT>
inline inline
void void
subview<eT>::operator= (const subview<eT>& x_in) subview<eT>::operator= (const subview<eT>& x)
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
const bool overlap = check_overlap(x_in); if(check_overlap(x))
{
const Mat<eT> tmp(x);
(*this).operator=(tmp);
Mat<eT>* tmp_mat = overlap ? new Mat<eT>(x_in.m) : 0; return;
const subview<eT>* tmp_subview = overlap ? new subview<eT>(*tmp_mat, x_in }
.aux_row1, x_in.aux_col1, x_in.n_rows, x_in.n_cols) : 0;
const subview<eT>& x = overlap ? (*tmp_subview) : x_in;
subview<eT>& s = *this; subview<eT>& s = *this;
arma_debug_assert_same_size(s, x, "copy into submatrix"); arma_debug_assert_same_size(s, x, "copy into submatrix");
const uword s_n_cols = s.n_cols; const uword s_n_cols = s.n_cols;
const uword s_n_rows = s.n_rows; const uword s_n_rows = s.n_rows;
if(s_n_rows == 1) if(s_n_rows == 1)
{ {
skipping to change at line 899 skipping to change at line 902
A.at(row_A, start_col_A + ii) = B.at(row_B, start_col_B + ii); A.at(row_A, start_col_A + ii) = B.at(row_B, start_col_B + ii);
} }
} }
else else
{ {
for(uword ucol=0; ucol < s_n_cols; ++ucol) for(uword ucol=0; ucol < s_n_cols; ++ucol)
{ {
arrayops::copy( s.colptr(ucol), x.colptr(ucol), s_n_rows ); arrayops::copy( s.colptr(ucol), x.colptr(ucol), s_n_rows );
} }
} }
if(overlap)
{
delete tmp_subview;
delete tmp_mat;
}
} }
template<typename eT> template<typename eT>
inline inline
void void
subview<eT>::operator+= (const subview<eT>& x_in) subview<eT>::operator+= (const subview<eT>& x)
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
const bool overlap = check_overlap(x_in); if(check_overlap(x))
{
const Mat<eT> tmp(x);
(*this).operator+=(tmp);
Mat<eT>* tmp_mat = overlap ? new Mat<eT>(x_in.m) : 0; return;
const subview<eT>* tmp_subview = overlap ? new subview(*tmp_mat, x_in.aux }
_row1, x_in.aux_col1, x_in.n_rows, x_in.n_cols) : 0;
const subview<eT>& x = overlap ? (*tmp_subview) : x_in;
subview<eT>& s = *this; subview<eT>& s = *this;
arma_debug_assert_same_size(s, x, "addition"); arma_debug_assert_same_size(s, x, "addition");
const uword s_n_rows = s.n_rows; const uword s_n_rows = s.n_rows;
const uword s_n_cols = s.n_cols; const uword s_n_cols = s.n_cols;
if(s_n_rows == 1) if(s_n_rows == 1)
{ {
skipping to change at line 961 skipping to change at line 961
A.at(row_A, start_col_A + ii) += B.at(row_B, start_col_B + ii); A.at(row_A, start_col_A + ii) += B.at(row_B, start_col_B + ii);
} }
} }
else else
{ {
for(uword ucol=0; ucol < s_n_cols; ++ucol) for(uword ucol=0; ucol < s_n_cols; ++ucol)
{ {
arrayops::inplace_plus( s.colptr(ucol), x.colptr(ucol), s_n_rows ); arrayops::inplace_plus( s.colptr(ucol), x.colptr(ucol), s_n_rows );
} }
} }
if(overlap)
{
delete tmp_subview;
delete tmp_mat;
}
} }
template<typename eT> template<typename eT>
inline inline
void void
subview<eT>::operator-= (const subview<eT>& x_in) subview<eT>::operator-= (const subview<eT>& x)
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
const bool overlap = check_overlap(x_in); if(check_overlap(x))
{
const Mat<eT> tmp(x);
(*this).operator-=(tmp);
Mat<eT>* tmp_mat = overlap ? new Mat<eT>(x_in.m) : 0; return;
const subview<eT>* tmp_subview = overlap ? new subview(*tmp_mat, x_in.aux }
_row1, x_in.aux_col1, x_in.n_rows, x_in.n_cols) : 0;
const subview<eT>& x = overlap ? (*tmp_subview) : x_in;
subview<eT>& s = *this; subview<eT>& s = *this;
arma_debug_assert_same_size(s, x, "subtraction"); arma_debug_assert_same_size(s, x, "subtraction");
const uword s_n_rows = s.n_rows; const uword s_n_rows = s.n_rows;
const uword s_n_cols = s.n_cols; const uword s_n_cols = s.n_cols;
if(s_n_rows == 1) if(s_n_rows == 1)
{ {
skipping to change at line 1022 skipping to change at line 1019
A.at(row_A, start_col_A + ii) -= B.at(row_B, start_col_B + ii); A.at(row_A, start_col_A + ii) -= B.at(row_B, start_col_B + ii);
} }
} }
else else
{ {
for(uword ucol=0; ucol < s_n_cols; ++ucol) for(uword ucol=0; ucol < s_n_cols; ++ucol)
{ {
arrayops::inplace_minus( s.colptr(ucol), x.colptr(ucol), s_n_rows ); arrayops::inplace_minus( s.colptr(ucol), x.colptr(ucol), s_n_rows );
} }
} }
if(overlap)
{
delete tmp_subview;
delete tmp_mat;
}
} }
template<typename eT> template<typename eT>
inline inline
void void
subview<eT>::operator%= (const subview& x_in) subview<eT>::operator%= (const subview& x)
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
const bool overlap = check_overlap(x_in); if(check_overlap(x))
{
const Mat<eT> tmp(x);
(*this).operator%=(tmp);
Mat<eT>* tmp_mat = overlap ? new Mat<eT>(x_in.m) : 0; return;
const subview<eT>* tmp_subview = overlap ? new subview(*tmp_mat, x_in.aux }
_row1, x_in.aux_col1, x_in.n_rows, x_in.n_cols) : 0;
const subview<eT>& x = overlap ? (*tmp_subview) : x_in;
subview<eT>& s = *this; subview<eT>& s = *this;
arma_debug_assert_same_size(s, x, "element-wise multiplication"); arma_debug_assert_same_size(s, x, "element-wise multiplication");
const uword s_n_rows = s.n_rows; const uword s_n_rows = s.n_rows;
const uword s_n_cols = s.n_cols; const uword s_n_cols = s.n_cols;
if(s_n_rows == 1) if(s_n_rows == 1)
{ {
skipping to change at line 1084 skipping to change at line 1077
A.at(row_A, start_col_A + ii) *= B.at(row_B, start_col_B + ii); A.at(row_A, start_col_A + ii) *= B.at(row_B, start_col_B + ii);
} }
} }
else else
{ {
for(uword ucol=0; ucol < s_n_cols; ++ucol) for(uword ucol=0; ucol < s_n_cols; ++ucol)
{ {
arrayops::inplace_mul( s.colptr(ucol), x.colptr(ucol), s_n_rows ); arrayops::inplace_mul( s.colptr(ucol), x.colptr(ucol), s_n_rows );
} }
} }
if(overlap)
{
delete tmp_subview;
delete tmp_mat;
}
} }
template<typename eT> template<typename eT>
inline inline
void void
subview<eT>::operator/= (const subview& x_in) subview<eT>::operator/= (const subview& x)
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
const bool overlap = check_overlap(x_in); if(check_overlap(x))
{
const Mat<eT> tmp(x);
(*this).operator/=(tmp);
Mat<eT>* tmp_mat = overlap ? new Mat<eT>(x_in.m) : 0; return;
const subview<eT>* tmp_subview = overlap ? new subview(*tmp_mat, x_in.aux }
_row1, x_in.aux_col1, x_in.n_rows, x_in.n_cols) : 0;
const subview<eT>& x = overlap ? (*tmp_subview) : x_in;
subview<eT>& s = *this; subview<eT>& s = *this;
arma_debug_assert_same_size(s, x, "element-wise division"); arma_debug_assert_same_size(s, x, "element-wise division");
const uword s_n_rows = s.n_rows; const uword s_n_rows = s.n_rows;
const uword s_n_cols = s.n_cols; const uword s_n_cols = s.n_cols;
if(s_n_rows == 1) if(s_n_rows == 1)
{ {
skipping to change at line 1146 skipping to change at line 1135
A.at(row_A, start_col_A + ii) /= B.at(row_B, start_col_B + ii); A.at(row_A, start_col_A + ii) /= B.at(row_B, start_col_B + ii);
} }
} }
else else
{ {
for(uword ucol=0; ucol < s_n_cols; ++ucol) for(uword ucol=0; ucol < s_n_cols; ++ucol)
{ {
arrayops::inplace_div( s.colptr(ucol), x.colptr(ucol), s_n_rows ); arrayops::inplace_div( s.colptr(ucol), x.colptr(ucol), s_n_rows );
} }
} }
if(overlap)
{
delete tmp_subview;
delete tmp_mat;
}
} }
template<typename eT> template<typename eT>
template<typename T1, typename gen_type> template<typename T1, typename gen_type>
inline inline
typename enable_if2< is_same_type<typename T1::elem_type, eT>::value, void> ::result typename enable_if2< is_same_type<typename T1::elem_type, eT>::value, void> ::result
subview<eT>::operator= (const Gen<T1,gen_type>& in) subview<eT>::operator= (const Gen<T1,gen_type>& in)
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
 End of changes. 20 change blocks. 
63 lines changed or deleted 40 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/