[Rcpp-commits] r3780 - in pkg/RcppArmadillo: . inst inst/include/armadillo_bits man

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Tue Sep 25 13:52:40 CEST 2012


Author: edd
Date: 2012-09-25 13:52:39 +0200 (Tue, 25 Sep 2012)
New Revision: 3780

Modified:
   pkg/RcppArmadillo/ChangeLog
   pkg/RcppArmadillo/DESCRIPTION
   pkg/RcppArmadillo/inst/NEWS.Rd
   pkg/RcppArmadillo/inst/include/armadillo_bits/Mat_meat.hpp
   pkg/RcppArmadillo/inst/include/armadillo_bits/SpMat_bones.hpp
   pkg/RcppArmadillo/inst/include/armadillo_bits/SpMat_iterators_meat.hpp
   pkg/RcppArmadillo/inst/include/armadillo_bits/SpMat_meat.hpp
   pkg/RcppArmadillo/inst/include/armadillo_bits/SpSubview_bones.hpp
   pkg/RcppArmadillo/inst/include/armadillo_bits/SpSubview_iterators_meat.hpp
   pkg/RcppArmadillo/inst/include/armadillo_bits/SpSubview_meat.hpp
   pkg/RcppArmadillo/inst/include/armadillo_bits/arma_ostream_meat.hpp
   pkg/RcppArmadillo/inst/include/armadillo_bits/arma_version.hpp
   pkg/RcppArmadillo/inst/include/armadillo_bits/diskio_meat.hpp
   pkg/RcppArmadillo/inst/include/armadillo_bits/fn_accu.hpp
   pkg/RcppArmadillo/inst/include/armadillo_bits/fn_dot.hpp
   pkg/RcppArmadillo/inst/include/armadillo_bits/fn_n_unique.hpp
   pkg/RcppArmadillo/inst/include/armadillo_bits/fn_trace.hpp
   pkg/RcppArmadillo/inst/include/armadillo_bits/operator_div.hpp
   pkg/RcppArmadillo/inst/include/armadillo_bits/operator_minus.hpp
   pkg/RcppArmadillo/inst/include/armadillo_bits/operator_plus.hpp
   pkg/RcppArmadillo/inst/include/armadillo_bits/operator_schur.hpp
   pkg/RcppArmadillo/inst/include/armadillo_bits/operator_times.hpp
   pkg/RcppArmadillo/inst/include/armadillo_bits/span.hpp
   pkg/RcppArmadillo/inst/include/armadillo_bits/spglue_minus_meat.hpp
   pkg/RcppArmadillo/inst/include/armadillo_bits/spglue_plus_meat.hpp
   pkg/RcppArmadillo/inst/include/armadillo_bits/spglue_times_meat.hpp
   pkg/RcppArmadillo/inst/include/armadillo_bits/spop_max_meat.hpp
   pkg/RcppArmadillo/inst/include/armadillo_bits/spop_min_meat.hpp
   pkg/RcppArmadillo/inst/include/armadillo_bits/spop_sum_meat.hpp
   pkg/RcppArmadillo/man/RcppArmadillo-package.Rd
Log:
Release 0.3.4.2 with Armadillo 3.4.2


Modified: pkg/RcppArmadillo/ChangeLog
===================================================================
--- pkg/RcppArmadillo/ChangeLog	2012-09-22 19:25:15 UTC (rev 3779)
+++ pkg/RcppArmadillo/ChangeLog	2012-09-25 11:52:39 UTC (rev 3780)
@@ -1,3 +1,9 @@
+2012-09-25  Dirk Eddelbuettel  <edd at debian.org>
+
+	* DESCRIPTION: Release 0.3.4.2
+
+	* inst/include/*: Upgraded to new release 3.4.2 of Armadillo
+
 2012-09-18  Dirk Eddelbuettel  <edd at debian.org>
 
 	* DESCRIPTION: Release 0.3.4.1

Modified: pkg/RcppArmadillo/DESCRIPTION
===================================================================
--- pkg/RcppArmadillo/DESCRIPTION	2012-09-22 19:25:15 UTC (rev 3779)
+++ pkg/RcppArmadillo/DESCRIPTION	2012-09-25 11:52:39 UTC (rev 3780)
@@ -1,7 +1,7 @@
 Package: RcppArmadillo
 Type: Package
 Title: Rcpp integration for Armadillo templated linear algebra library
-Version: 0.3.4.1
+Version: 0.3.4.2
 Date: $Date$
 Author: Romain Francois, Dirk Eddelbuettel and Doug Bates
 Maintainer: Dirk Eddelbuettel <edd at debian.org>
@@ -21,7 +21,7 @@
  (due to speed and/or integration capabilities), rather than another language.
  .
  The RcppArmadillo package includes the header files from the templated
- Armadillo library (currently version 3.4.1). Thus users do not need to
+ Armadillo library (currently version 3.4.2). Thus users do not need to
  install Armadillo itself in order to use RcppArmadillo.
  .
  This Armadillo integration provides a nice illustration of the 

Modified: pkg/RcppArmadillo/inst/NEWS.Rd
===================================================================
--- pkg/RcppArmadillo/inst/NEWS.Rd	2012-09-22 19:25:15 UTC (rev 3779)
+++ pkg/RcppArmadillo/inst/NEWS.Rd	2012-09-25 11:52:39 UTC (rev 3780)
@@ -2,6 +2,16 @@
 \title{News for Package 'RcppArmadillo'}
 \newcommand{\cpkg}{\href{http://CRAN.R-project.org/package=#1}{\pkg{#1}}}
 
+\section{Changes in RcppArmadillo version 0.3.4.2 (2012-09-25)}{
+  \itemize{
+    \item Upgraded to Armadillo release 3.4.2
+    \itemize{
+      \item minor fixes for handling sparse submatrix views
+      \item minor speedups for sparse matrices
+    }
+  }
+}
+
 \section{Changes in RcppArmadillo version 0.3.4.1 (2012-09-18)}{
   \itemize{
     \item Upgraded to Armadillo release 3.4.1

Modified: pkg/RcppArmadillo/inst/include/armadillo_bits/Mat_meat.hpp
===================================================================
--- pkg/RcppArmadillo/inst/include/armadillo_bits/Mat_meat.hpp	2012-09-22 19:25:15 UTC (rev 3779)
+++ pkg/RcppArmadillo/inst/include/armadillo_bits/Mat_meat.hpp	2012-09-25 11:52:39 UTC (rev 3780)
@@ -1991,7 +1991,7 @@
   fill(eT(0));
 
   // Iterate over each nonzero element and set it.
-  for(typename SpProxy<T1>::const_iterator_type it = p.begin(); it.pos() < p.get_n_nonzero(); ++it)
+  for(typename SpProxy<T1>::const_iterator_type it = p.begin(); it != p.end(); ++it)
     {
     at(it.row(), it.col()) = (*it);
     }
@@ -2013,7 +2013,7 @@
 
   fill(eT(0));
 
-  for(typename SpProxy<T1>::const_iterator_type it = p.begin(); it.pos() < p.get_n_nonzero(); ++it)
+  for(typename SpProxy<T1>::const_iterator_type it = p.begin(); it != p.end(); ++it)
     {
     at(it.row(), it.col()) = (*it);
     }
@@ -2035,7 +2035,7 @@
 
   arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "addition");
 
-  for(typename SpProxy<T1>::const_iterator_type it = p.begin(); it.pos() < p.get_n_nonzero(); ++it)
+  for(typename SpProxy<T1>::const_iterator_type it = p.begin(); it != p.end(); ++it)
     {
     at(it.row(), it.col()) += (*it);
     }
@@ -2057,7 +2057,7 @@
 
   arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "subtraction");
 
-  for(typename SpProxy<T1>::const_iterator_type it = p.begin(); it.pos() < p.get_n_nonzero(); ++it)
+  for(typename SpProxy<T1>::const_iterator_type it = p.begin(); it != p.end(); ++it)
     {
     at(it.row(), it.col()) -= (*it);
     }
@@ -2101,7 +2101,7 @@
   // We have to zero everything that isn't being used.
   arrayops::inplace_set(memptr(), eT(0), (it.col() * n_rows) + it.row());
 
-  while(it.pos() < p.get_n_nonzero())
+  while(it != p.end())
     {
     const uword cur_loc = (it.col() * n_rows) + it.row();
 
@@ -2109,7 +2109,7 @@
 
     ++it;
 
-    const uword next_loc = (it.pos() == p.get_n_nonzero())
+    const uword next_loc = (it == p.end())
       ? (p.get_n_cols() * n_rows)
       : (it.col() * n_rows) + it.row();
 

Modified: pkg/RcppArmadillo/inst/include/armadillo_bits/SpMat_bones.hpp
===================================================================
--- pkg/RcppArmadillo/inst/include/armadillo_bits/SpMat_bones.hpp	2012-09-22 19:25:15 UTC (rev 3779)
+++ pkg/RcppArmadillo/inst/include/armadillo_bits/SpMat_bones.hpp	2012-09-25 11:52:39 UTC (rev 3780)
@@ -47,6 +47,8 @@
   
   /**
    * 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.
    */
   const uword* const row_indices;
   
@@ -305,13 +307,13 @@
     inline iterator_base(const SpMat& in_M);
     inline iterator_base(const SpMat& in_M, const uword col, const uword pos);
 
-    inline eT operator*() const;
+    inline arma_hot eT operator*() const;
 
-    inline bool operator==(const iterator_base& rhs) const;
-    inline bool operator!=(const iterator_base& rhs) const;
+    inline arma_hot bool operator==(const iterator_base& rhs) const;
+    inline arma_hot bool operator!=(const iterator_base& rhs) const;
 
-    inline bool operator==(const typename SpSubview<eT>::iterator_base& rhs) const;
-    inline bool operator!=(const typename SpSubview<eT>::iterator_base& rhs) const;
+    inline arma_hot bool operator==(const typename SpSubview<eT>::iterator_base& rhs) const;
+    inline arma_hot bool operator!=(const typename SpSubview<eT>::iterator_base& rhs) const;
     
     // Don't hold location internally; call "dummy" methods to get that information.
     arma_inline uword row() const { return M.row_indices[internal_pos]; }
@@ -330,13 +332,15 @@
     inline const_iterator(const SpMat& in_M, uword initial_pos = 0); // Assumes initial_pos is valid.
     //! Once initialized, will be at the first nonzero value after the given position (using forward columnwise traversal).
     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.
+    inline const_iterator(const SpMat& in_M, uword in_row, uword in_col, uword in_pos);
     inline const_iterator(const const_iterator& other);
 
-    inline const_iterator& operator++();
-    inline void            operator++(int);
+    inline arma_hot const_iterator& operator++();
+    inline arma_hot void            operator++(int);
     
-    inline const_iterator& operator--();
-    inline void            operator--(int);
+    inline arma_hot const_iterator& operator--();
+    inline arma_hot void            operator--(int);
     };
 
   /**
@@ -351,16 +355,17 @@
 
     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_iterator(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(const const_iterator& other) : const_iterator(other) { }
 
-    inline SpValProxy<SpMat<eT> > operator*();
+    inline arma_hot SpValProxy<SpMat<eT> > operator*();
 
     // overloads needed for return type correctness
-    inline iterator& operator++();
-    inline void      operator++(int);
+    inline arma_hot iterator& operator++();
+    inline arma_hot void      operator++(int);
 
-    inline iterator& operator--();
-    inline void      operator--(int);
+    inline arma_hot iterator& operator--();
+    inline arma_hot void      operator--(int);
     };
 
   class const_row_iterator : public iterator_base
@@ -372,11 +377,11 @@
     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& operator++();
-    inline void                operator++(int);
+    inline arma_hot const_row_iterator& operator++();
+    inline arma_hot void                operator++(int);
     
-    inline const_row_iterator& operator--();
-    inline void                operator--(int);
+    inline arma_hot const_row_iterator& operator--();
+    inline arma_hot void                operator--(int);
 
     uword internal_row; // Hold row internally because we use internal_pos differently.
     uword actual_pos; // Actual position in matrix.
@@ -395,21 +400,21 @@
     inline row_iterator(SpMat& in_M, uword in_row, uword in_col) : const_row_iterator(in_M, in_row, in_col) { }
     inline row_iterator(const row_iterator& other) : const_row_iterator(other) { }
     
-    inline SpValProxy<SpMat<eT> > operator*();
+    inline arma_hot SpValProxy<SpMat<eT> > operator*();
 
     // overloads required for return type correctness
-    inline row_iterator& operator++();
-    inline void          operator++(int);
+    inline arma_hot row_iterator& operator++();
+    inline arma_hot void          operator++(int);
 
-    inline row_iterator& operator--();
-    inline void          operator--(int);
+    inline arma_hot row_iterator& operator--();
+    inline arma_hot void          operator--(int);
     };
   
   inline       iterator     begin();
   inline const_iterator     begin() const;
   
-  inline       iterator     end();
-  inline const_iterator     end() const;
+  inline       iterator end();
+  inline const_iterator end() const;
   
   inline       iterator     begin_col(const uword col_num);
   inline const_iterator     begin_col(const uword col_num) const;

Modified: pkg/RcppArmadillo/inst/include/armadillo_bits/SpMat_iterators_meat.hpp
===================================================================
--- pkg/RcppArmadillo/inst/include/armadillo_bits/SpMat_iterators_meat.hpp	2012-09-22 19:25:15 UTC (rev 3779)
+++ pkg/RcppArmadillo/inst/include/armadillo_bits/SpMat_iterators_meat.hpp	2012-09-25 11:52:39 UTC (rev 3780)
@@ -44,6 +44,7 @@
 
 template<typename eT>
 inline
+arma_hot
 eT
 SpMat<eT>::iterator_base::operator*() const
   {
@@ -54,6 +55,7 @@
 
 template<typename eT>
 inline
+arma_hot
 bool
 SpMat<eT>::iterator_base::operator==(const iterator_base& rhs) const
   {
@@ -64,6 +66,7 @@
 
 template<typename eT>
 inline
+arma_hot
 bool
 SpMat<eT>::iterator_base::operator!=(const iterator_base& rhs) const
   {
@@ -74,6 +77,7 @@
 
 template<typename eT>
 inline
+arma_hot
 bool
 SpMat<eT>::iterator_base::operator==(const typename SpSubview<eT>::iterator_base& rhs) const
   {
@@ -84,6 +88,7 @@
 
 template<typename eT>
 inline
+arma_hot
 bool
 SpMat<eT>::iterator_base::operator!=(const typename SpSubview<eT>::iterator_base& rhs) const
   {
@@ -101,6 +106,13 @@
 SpMat<eT>::const_iterator::const_iterator(const SpMat<eT>& in_M, uword initial_pos)
   : iterator_base(in_M, 0, initial_pos)
   {
+  // Corner case for empty matrices.
+  if(in_M.n_nonzero == 0)
+    {
+    iterator_base::internal_col = in_M.n_cols;
+    return;
+    }
+
   // Determine which column we should be in.
   while(iterator_base::M.col_ptrs[iterator_base::internal_col + 1] <= iterator_base::internal_pos)
     {
@@ -135,6 +147,16 @@
 
 template<typename eT>
 inline
+SpMat<eT>::const_iterator::const_iterator(const SpMat<eT>& in_M, const uword /* in_row */, const uword in_col, const uword in_pos)
+  : iterator_base(in_M, in_col, in_pos)
+  {
+  // Nothing to do.
+  }
+
+
+
+template<typename eT>
+inline
 SpMat<eT>::const_iterator::const_iterator(const typename SpMat<eT>::const_iterator& other)
   : iterator_base(other.M, other.internal_col, other.internal_pos)
   {
@@ -145,6 +167,7 @@
 
 template<typename eT>
 inline
+arma_hot
 typename SpMat<eT>::const_iterator&
 SpMat<eT>::const_iterator::operator++()
   {
@@ -169,6 +192,7 @@
 
 template<typename eT>
 inline
+arma_hot
 void
 SpMat<eT>::const_iterator::operator++(int)
   {
@@ -179,10 +203,11 @@
 
 template<typename eT>
 inline
+arma_hot
 typename SpMat<eT>::const_iterator&
 SpMat<eT>::const_iterator::operator--()
   {
-  iterator_base::M.print("M");
+  //iterator_base::M.print("M");
   
   // printf("decrement from %d, %d, %d\n", iterator_base::internal_pos, iterator_base::internal_col, iterator_base::row());
   
@@ -206,6 +231,7 @@
 
 template<typename eT>
 inline
+arma_hot
 void
 SpMat<eT>::const_iterator::operator--(int)
   {
@@ -220,6 +246,7 @@
 
 template<typename eT>
 inline
+arma_hot
 SpValProxy<SpMat<eT> >
 SpMat<eT>::iterator::operator*()
   {
@@ -234,6 +261,7 @@
 
 template<typename eT>
 inline
+arma_hot
 typename SpMat<eT>::iterator&
 SpMat<eT>::iterator::operator++()
   {
@@ -245,6 +273,7 @@
 
 template<typename eT>
 inline
+arma_hot
 void
 SpMat<eT>::iterator::operator++(int)
   {
@@ -255,6 +284,7 @@
 
 template<typename eT>
 inline
+arma_hot
 typename SpMat<eT>::iterator&
 SpMat<eT>::iterator::operator--()
   {
@@ -266,6 +296,7 @@
 
 template<typename eT>
 inline
+arma_hot
 void
 SpMat<eT>::iterator::operator--(int)
   {
@@ -288,6 +319,13 @@
   , internal_row(0)
   , actual_pos(0)
   {
+  // Corner case for empty matrix.
+  if(in_M.n_nonzero == 0)
+    {
+    iterator_base::internal_col = in_M.n_cols;
+    return;
+    }
+
   // We don't count zeroes in our position count, so we have to find the nonzero
   // value corresponding to the given initial position.  We assume initial_pos
   // is valid.
@@ -385,6 +423,7 @@
  */
 template<typename eT>
 inline
+arma_hot
 typename SpMat<eT>::const_row_iterator&
 SpMat<eT>::const_row_iterator::operator++()
   {
@@ -436,6 +475,7 @@
  */
 template<typename eT>
 inline
+arma_hot
 void
 SpMat<eT>::const_row_iterator::operator++(int)
   {
@@ -449,6 +489,7 @@
  */
 template<typename eT>
 inline
+arma_hot
 typename SpMat<eT>::const_row_iterator&
 SpMat<eT>::const_row_iterator::operator--()
   {
@@ -490,6 +531,7 @@
  */
 template<typename eT>
 inline
+arma_hot
 void
 SpMat<eT>::const_row_iterator::operator--(int)
   {
@@ -502,6 +544,7 @@
 
 template<typename eT>
 inline
+arma_hot
 SpValProxy<SpMat<eT> >
 SpMat<eT>::row_iterator::operator*()
   {
@@ -516,6 +559,7 @@
 
 template<typename eT>
 inline
+arma_hot
 typename SpMat<eT>::row_iterator&
 SpMat<eT>::row_iterator::operator++()
   {
@@ -527,6 +571,7 @@
 
 template<typename eT>
 inline
+arma_hot
 void
 SpMat<eT>::row_iterator::operator++(int)
   {
@@ -537,6 +582,7 @@
 
 template<typename eT>
 inline
+arma_hot
 typename SpMat<eT>::row_iterator&
 SpMat<eT>::row_iterator::operator--()
   {
@@ -548,6 +594,7 @@
 
 template<typename eT>
 inline
+arma_hot
 void
 SpMat<eT>::row_iterator::operator--(int)
   {

Modified: pkg/RcppArmadillo/inst/include/armadillo_bits/SpMat_meat.hpp
===================================================================
--- pkg/RcppArmadillo/inst/include/armadillo_bits/SpMat_meat.hpp	2012-09-22 19:25:15 UTC (rev 3779)
+++ pkg/RcppArmadillo/inst/include/armadillo_bits/SpMat_meat.hpp	2012-09-25 11:52:39 UTC (rev 3780)
@@ -25,12 +25,15 @@
   , n_elem(0)
   , n_nonzero(0)
   , vec_state(0)
-  , values(NULL)
-  , row_indices(NULL)
+  , values(memory::acquire_chunked<eT>(1))
+  , row_indices(memory::acquire_chunked<uword>(1))
   , col_ptrs(memory::acquire<uword>(1))
   {
   arma_extra_debug_sigprint_this(this);
-  
+
+  access::rw(values[0]) = 0;
+  access::rw(row_indices[0]) = 0;
+
   access::rw(col_ptrs[0]) = 0; // No elements.
   }
 
@@ -264,7 +267,7 @@
   arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "addition");
   
   // Iterate over nonzero values of other matrix.
-  for (const_iterator it = x.begin(); it.pos() < x.n_nonzero; it++)
+  for (const_iterator it = x.begin(); it != x.end(); it++)
     {
     get_value(it.row(), it.col()) += *it;
     }
@@ -284,7 +287,7 @@
   arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "subtraction");
   
   // Iterate over nonzero values of other matrix.
-  for (const_iterator it = x.begin(); it.pos() < x.n_nonzero; it++)
+  for (const_iterator it = x.begin(); it != x.end(); it++)
     {
     get_value(it.row(), it.col()) -= *it;
     }
@@ -326,7 +329,7 @@
         iterator it    = begin();
   const_iterator x_it  = x.begin();
   
-  while (it.pos() < n_nonzero && x_it.pos() < x.n_nonzero)
+  while (it != end() && x_it != x.end())
     {
     // One of these will be further advanced than the other (or they will be at the same place).
     if ((it.row() == x_it.row()) && (it.col() == x_it.col()))
@@ -362,7 +365,7 @@
     }
 
   // If we are not at the end of our matrix, then we must terminate the remaining elements.
-  while (it.pos() < n_nonzero)
+  while (it != end())
     {
     (*it) = 0;
 
@@ -390,7 +393,7 @@
   , n_elem(0)
   , n_nonzero(0)
   , vec_state(0)
-  , values(NULL)
+  , values(NULL) // extra element is set when mem_resize is called
   , row_indices(NULL)
   , col_ptrs(NULL)
   {
@@ -424,7 +427,7 @@
   typename SpMat<T>::const_iterator y_it = Y.begin();
   uword cur_pos = 0;
 
-  while ((x_it.pos() < X.n_nonzero) || (y_it.pos() < Y.n_nonzero))
+  while ((x_it != X.end()) || (y_it != Y.end()))
     {
     if(x_it == y_it) // if we are at the same place
       {
@@ -501,7 +504,7 @@
   , n_elem(0)
   , n_nonzero(0)
   , vec_state(0)
-  , values(NULL)
+  , values(NULL) // extra element is set when mem_resize is called in operator=()
   , row_indices(NULL)
   , col_ptrs(NULL)
   {
@@ -518,21 +521,63 @@
 const SpMat<eT>&
 SpMat<eT>::operator=(const Base<eT, T1>& x)
   {
-  //No easy init function, will have to generate matrix manually.
   arma_extra_debug_sigprint();
   
   const Proxy<T1> p(x.get_ref());
   
   const uword x_n_rows = p.get_n_rows();
   const uword x_n_cols = p.get_n_cols();
-  
+  const uword x_n_elem = p.get_n_elem();
+
   init(x_n_rows, x_n_cols);
-  
+
+  // Count number of nonzero elements in base object.
+  uword n = 0;
+  if(Proxy<T1>::prefer_at_accessor == true)
+    {
+    for(uword j = 0; j < x_n_cols; ++j)
+      {
+      for(uword i = 0; i < x_n_rows; ++i)
+        {
+        if(p.at(i, j) != eT(0))
+          ++n;
+        }
+      }
+    }
+  else
+    {
+    for(uword i = 0; i < x_n_elem; ++i)
+      {
+      if(p[i] != eT(0))
+        {
+        ++n;
+        }
+      }
+    }
+
+  mem_resize(n);
+
+  // Now the memory is resized correctly; add nonzero elements.
+  n = 0;
   for(uword j = 0; j < x_n_cols; ++j)
-  for(uword i = 0; i < x_n_rows; ++i)
     {
-    at(i,j) = p.at(i,j); // let SpValProxy handle 0's.
+    for(uword i = 0; i < x_n_rows; ++i)
+      {
+      if(p.at(i, j) != eT(0))
+        {
+        access::rw(values[n]) = p.at(i, j);
+        access::rw(row_indices[n]) = i;
+        access::rw(col_ptrs[j + 1])++;
+        ++n;
+        }
+      }
     }
+
+  // Sum column counts to be column pointers.
+  for(uword c = 1; c <= n_cols; ++c)
+    {
+    access::rw(col_ptrs[c]) += col_ptrs[c - 1];
+    }
   
   return *this;
   }
@@ -592,7 +637,7 @@
     {
     const_iterator it = begin();
 
-    while(it.pos() < n_nonzero)
+    while(it != end())
       {
       const eT value = (*it);
 
@@ -604,7 +649,7 @@
     // Now add all partial sums to the matrix.
     for(uword i = 0; i < n_rows; ++i)
       {
-      if(partial_sums[i] != 0)
+      if(partial_sums[i] != eT(0))
         {
         access::rw(z.values[cur_pos]) = partial_sums[i];
         access::rw(z.row_indices[cur_pos]) = i;
@@ -677,10 +722,10 @@
   const_iterator it = begin();
   uword new_n_nonzero = 0;
 
-  while(it.pos() < n_nonzero())
+  while(it != end())
     {
     // prefer_at_accessor == false can't save us any work here
-    if(((*it) * x.at(it.row(), it.col())) != 0)
+    if(((*it) * p.at(it.row(), it.col())) != eT(0))
       {
       ++new_n_nonzero;
       }
@@ -692,11 +737,11 @@
 
   const_iterator c_it = begin();
   uword cur_pos = 0;
-  while(c_it.pos() < n_nonzero)
+  while(c_it != end())
     {
     // prefer_at_accessor == false can't save us any work here
-    const eT val = (*c_it) * x(c_it.row(), c_it.col());
-    if(val != 0)
+    const eT val = (*c_it) * p.at(c_it.row(), c_it.col());
+    if(val != eT(0))
       {
       access::rw(tmp.values[cur_pos]) = val;
       access::rw(tmp.row_indices[cur_pos]) = c_it.row();
@@ -731,7 +776,7 @@
   , n_elem(0)
   , n_nonzero(0)
   , vec_state(0)
-  , values(NULL)
+  , values(NULL) // extra element added when mem_resize is called
   , row_indices(NULL)
   , col_ptrs(NULL)
   {
@@ -757,14 +802,26 @@
   if(alias == false)
     {
     init(in_n_rows, in_n_cols);
-  
+
+    const uword x_n_nonzero = X.n_nonzero;
+
+    mem_resize(x_n_nonzero);
+
     typename SpSubview<eT>::const_iterator it = X.begin();
 
-    while(it.pos() < X.n_nonzero)
+    while(it != X.end())
       {
-      at(it.row(), it.col()) = (*it);
+      access::rw(row_indices[it.pos()]) = it.row();
+      access::rw(values[it.pos()]) = (*it);
+      ++access::rw(col_ptrs[it.col() + 1]);
       ++it;
       }
+
+    // Now sum column pointers.
+    for(uword c = 1; c <= n_cols; ++c)
+      {
+      access::rw(col_ptrs[c]) += col_ptrs[c - 1];
+      }
     }
   else
     {
@@ -788,19 +845,11 @@
   
   arma_debug_assert_same_size(n_rows, n_cols, X.n_rows, X.n_cols, "addition");
   
-  const uword in_n_cols = X.n_cols;
-  const uword in_n_rows = X.n_rows;
+  typename SpSubview<eT>::const_iterator it = X.begin();
 
-  const_iterator it = const_iterator(X.m, X.aux_row1, X.aux_col1);
-
-  while(it.col < (X.aux_col1 + in_n_cols))
+  while(it != X.end())
     {
-    // Is it within the proper range?
-    if((it.row >= X.aux_row1) && (it.row < (X.aux_row1 + in_n_rows)))
-      {
-      at(it.row - X.aux_row1, it.col - X.aux_col1) += (*it);
-      }
-
+    at(it.row(), it.col()) += (*it);
     ++it;
     }
 
@@ -818,19 +867,11 @@
   
   arma_debug_assert_same_size(n_rows, n_cols, X.n_rows, X.n_cols, "subtraction");
   
-  const uword in_n_cols = X.n_cols;
-  const uword in_n_rows = X.n_rows;
+  typename SpSubview<eT>::const_iterator it = X.begin();
   
-  const_iterator it = const_iterator(X.m, X.aux_row1, X.aux_col1);
-  
-  while(it.col < (X.aux_col1 + in_n_cols))
+  while(it != X.end())
     {
-    // Is it within the proper range?
-    if((it.row >= X.aux_row1) && (it.row < (X.aux_row1 + in_n_rows)))
-      {
-      at(it.row - X.aux_row1, it.col - X.aux_col1) -= (*it);
-      }
-
+    at(it.row(), it.col()) -= (*it);
     ++it;
     }
   
@@ -865,28 +906,32 @@
   arma_extra_debug_sigprint();
   
   arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "element-wise multiplication");
-  
-  // We want to iterate over whichever has fewer nonzero points.
-  if (n_nonzero <= x.n_nonzero)
+
+  iterator it = begin();
+  typename SpSubview<eT>::const_iterator xit = x.begin();
+
+  while((it != end()) || (xit != x.end()))
     {
-    // Use our iterator.
-    for (iterator it = begin(); it.pos() < n_nonzero; it++)
+    if((xit.row() == it.row()) && (xit.col() == it.col()))
       {
-      (*it) *= x(it.row(), it.col());
+      (*it) *= (*xit);
+      ++it;
+      ++xit;
       }
-    }
-  else
-    {
-    // Use their iterator.  A little more complex...
-    const_iterator it = const_iterator(x.m, x.aux_row1, x.aux_col1);
-    while((it.col() < (x.aux_col1 + x.n_cols)))
+    else
       {
-      if((it.row() >= x.aux_row1) && (it.row() < (x.aux_row1 + x.n_rows)))
+      if((xit.col() > it.col()) || ((xit.col() == it.col()) && (xit.row() > it.row())))
         {
-        at(it.row() - x.aux_row1, it.col() - x.aux_col1) *= (*it);
+        // xit is "ahead"
+        (*it) = eT(0); // erase element; x has a zero here
+        it.internal_pos--; // update iterator so it still works
+        ++it;
         }
-
-      ++it;
+      else
+        {
+        // it is "ahead"
+        ++xit;
+        }
       }
     }
 
@@ -925,7 +970,7 @@
   , n_elem(0)
   , n_nonzero(0)
   , vec_state(0)
-  , values(NULL)
+  , values(NULL) // extra value set in operator=()
   , row_indices(NULL)
   , col_ptrs(NULL)
   {
@@ -943,17 +988,50 @@
   {
   arma_extra_debug_sigprint();
   
+  const uword x_n_rows = x.n_rows;
+  const uword x_n_cols = x.n_cols;
+  
   // Set the size correctly.
-  init(x.n_rows, x.n_cols);
-  
-  for(uword col = 0; col < x.n_cols; col++)
+  init(x_n_rows, x_n_cols);
+
+  // Count number of nonzero elements.
+  uword n = 0;
+  for(uword c = 0; c < x_n_cols; ++c)
     {
-    for(uword row = 0; row < x.n_rows; row++)
+    for(uword r = 0; r < x_n_rows; ++r)
       {
-      // Add any nonzero values.
-      at(row, col) = x.at(row, col);
+      if(x.at(r, c) != eT(0))
+        {
+        ++n;
+        }
       }
     }
+
+  // Resize memory appropriately.
+  mem_resize(n);
+
+  n = 0;
+  for(uword c = 0; c < x_n_cols; ++c)
+    {
+    for(uword r = 0; r < x_n_rows; ++r)
+      {
+      const eT val = x.at(r, c);
+      
+      if(val != eT(0))
+        {
+        access::rw(values[n]) = val;
+        access::rw(row_indices[n]) = r;
+        ++access::rw(col_ptrs[c + 1]);
+        ++n;
+        }
+      }
+    }
+
+  // Fix column counts into column pointers.
+  for(uword c = 1; c <= n_cols; ++c)
+    {
+    access::rw(col_ptrs[c]) += col_ptrs[c - 1];
+    }
   
   return *this;
   }
@@ -977,7 +1055,7 @@
     {
     for(uword row = 0; row < n_rows; ++row)
       {
-      at(row, col) += x(row, col);
+      at(row, col) += x.at(row, col);
       }
     }
   
@@ -1000,7 +1078,7 @@
     {
     for(uword row = 0; row < n_rows; ++row)
       {
-      at(row, col) -= x(row, col);
+      at(row, col) -= x.at(row, col);
       }
     }
   
@@ -1053,7 +1131,7 @@
     {
     for(uword row = 0; row < n_rows; ++row)
       {
-      at(row, col) *= x(row, col);
+      at(row, col) *= x.at(row, col);
       }
     }
 
@@ -1076,7 +1154,7 @@
     {
     for(uword row = 0; row < n_rows; ++row)
       {
-      at(row, col) /= x(row, col);
+      at(row, col) /= x.at(row, col);
       }
     }
 
@@ -1094,7 +1172,7 @@
   , n_elem(0)
   , n_nonzero(0)
   , vec_state(0)
-  , values(NULL)
+  , values(NULL) // set in application of sparse operation
   , row_indices(NULL)
   , col_ptrs(NULL)
   {
@@ -1218,7 +1296,7 @@
   , n_elem(0)
   , n_nonzero(0)
   , vec_state(0)
-  , values(NULL)
+  , values(NULL) // extra element set in application of sparse glue
   , row_indices(NULL)
   , col_ptrs(NULL)
   {
@@ -1363,8 +1441,25 @@
 SpMat<eT>::operator()(const uword row_num, const span& col_span)
   {
   arma_extra_debug_sigprint();
-
-  return SpSubview<eT>(*this, row_num, col_span.a, col_span.b - col_span.a + 1);
+  
+  const bool col_all = col_span.whole;
+  
+  const uword local_n_cols = n_cols;
+  
+  const uword in_col1       = col_all ? 0            : col_span.a;
+  const uword in_col2       =                          col_span.b;
+  const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
+  
+  arma_debug_check
+    (
+    (row_num >= n_rows)
+    ||
+    ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
+    ,
+    "SpMat::operator(): indices out of bounds or incorrectly used"
+    );
+  
+  return SpSubview<eT>(*this, row_num, in_col1, 1, submat_n_cols);
   }
 
 
@@ -1375,8 +1470,25 @@
 SpMat<eT>::operator()(const uword row_num, const span& col_span) const
   {
   arma_extra_debug_sigprint();
-
-  return SpSubview<eT>(*this, row_num, col_span.a, col_span.b - col_span.a + 1);
+  
+  const bool col_all = col_span.whole;
+  
+  const uword local_n_cols = n_cols;
+  
+  const uword in_col1       = col_all ? 0            : col_span.a;
+  const uword in_col2       =                          col_span.b;
+  const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
+  
+  arma_debug_check
+    (
+    (row_num >= n_rows)
+    ||
+    ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
+    ,
+    "SpMat::operator(): indices out of bounds or incorrectly used"
+    );
+  
+  return SpSubview<eT>(*this, row_num, in_col1, 1, submat_n_cols);
   }
 
 
@@ -1411,8 +1523,25 @@
 SpMat<eT>::operator()(const span& row_span, const uword col_num)
   {
   arma_extra_debug_sigprint();
-
-  return SpSubview<eT>(*this, row_span.a, col_num, row_span.b - row_span.a + 1, 0);
+  
+  const bool row_all = row_span.whole;
+  
+  const uword local_n_rows = n_rows;
+  
+  const uword in_row1       = row_all ? 0            : row_span.a;
+  const uword in_row2       =                          row_span.b;
+  const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
+  
+  arma_debug_check
+    (
+    (col_num >= n_cols)
+    ||
+    ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
+    ,
+    "SpMat::operator(): indices out of bounds or incorrectly used"
+    );
+  
+  return SpSubview<eT>(*this, in_row1, col_num, submat_n_rows, 1);
   }
 
 
@@ -1423,8 +1552,25 @@
 SpMat<eT>::operator()(const span& row_span, const uword col_num) const
   {
   arma_extra_debug_sigprint();
-
-  return SpSubview<eT>(*this, row_span.a, col_num, row_span.b - row_span.a + 1, 0);
+  
+  const bool row_all = row_span.whole;
+  
+  const uword local_n_rows = n_rows;
+  
+  const uword in_row1       = row_all ? 0            : row_span.a;
+  const uword in_row2       =                          row_span.b;
+  const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
+  
+  arma_debug_check
+    (
+    (col_num >= n_cols)
+    ||
+    ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
+    ,
+    "SpMat::operator(): indices out of bounds or incorrectly used"
+    );
+  
+  return SpSubview<eT>(*this, in_row1, col_num, submat_n_rows, 1);
   }
 
 
@@ -1722,7 +1868,6 @@
   uword cur_col = in_col1;
   for (uword i = in_col2 + 1; i <= n_cols; ++i, ++cur_col)
     {
-    std::cout << "i " << i << " n_cols " << n_cols << std::endl;
     new_col_ptrs[cur_col] = col_ptrs[i] - diff;
     }
   
@@ -2499,11 +2644,12 @@
     // columns and rows. We'll have to store a new set of column vectors.
     uword* new_col_ptrs    = memory::acquire<uword>(in_cols + 1);
     
-    uword* new_row_indices = memory::acquire_chunked<uword>(n_nonzero);
+    uword* new_row_indices = memory::acquire_chunked<uword>(n_nonzero + 1);
+    access::rw(new_row_indices[n_nonzero]) = 0;
 
     arrayops::inplace_set(new_col_ptrs, uword(0), in_cols + 1);
 
-    for(const_iterator it = begin(); it.pos() < n_nonzero; it++)
+    for(const_iterator it = begin(); it != end(); it++)
       {
       uword vector_position = (it.col() * n_rows) + it.row();
       new_row_indices[it.pos()] = vector_position % in_rows;
@@ -2557,8 +2703,11 @@
     memory::release(values);
     memory::release(row_indices);
 
-    access::rw(values)      = NULL;
-    access::rw(row_indices) = NULL;
+    access::rw(values)      = memory::acquire_chunked<eT>(1);
+    access::rw(row_indices) = memory::acquire_chunked<uword>(1);
+
+    access::rw(values[0]) = 0;
+    access::rw(row_indices[0]) = 0;
     }
 
   access::rw(n_nonzero) = 0;
@@ -3123,11 +3272,14 @@
     {
     memory::release(values);
     memory::release(row_indices);
-
-    access::rw(values) = NULL;
-    access::rw(row_indices) = NULL;
     }
 
+  access::rw(values) = memory::acquire_chunked<eT>(1);
+  access::rw(row_indices) = memory::acquire_chunked<uword>(1);
+
+  access::rw(values[0]) = 0;
+  access::rw(row_indices[0]) = 0;
+
   memory::release(col_ptrs);
 
   // Set the new size accordingly.
@@ -3226,7 +3378,7 @@
     while (line_stream >> val)
       {
       // Only add nonzero elements.
-      if (val != 0)
+      if (val != eT(0))
         {
         get_value(row, col) = val;
         }
@@ -3256,13 +3408,19 @@
     {
     init(x.n_rows, x.n_cols);
 
-    // values and row_indices are null.
-    access::rw(values)      = memory::acquire_chunked<eT>   (x.n_nonzero);
-    access::rw(row_indices) = memory::acquire_chunked<uword>(x.n_nonzero);
+    // values and row_indices may not be null.
+    if (values != NULL)
+      {
+      memory::release(values);
+      memory::release(row_indices);
+      }
 
+    access::rw(values)      = memory::acquire_chunked<eT>   (x.n_nonzero + 1);
+    access::rw(row_indices) = memory::acquire_chunked<uword>(x.n_nonzero + 1);
+
     // Now copy over the elements.
-    arrayops::copy(access::rwp(values),      x.values,      x.n_nonzero);
-    arrayops::copy(access::rwp(row_indices), x.row_indices, x.n_nonzero);
+    arrayops::copy(access::rwp(values),      x.values,      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);
     
     access::rw(n_nonzero) = x.n_nonzero;
@@ -3285,8 +3443,11 @@
       memory::release(values);
       memory::release(row_indices);
       
-      access::rw(values)      = NULL;
-      access::rw(row_indices) = NULL;
+      access::rw(values)      = memory::acquire_chunked<eT>   (1);
+      access::rw(row_indices) = memory::acquire_chunked<uword>(1);
+
+      access::rw(values[0]) = 0;
+      access::rw(row_indices[0]) = 0;
       }
     else
       {
@@ -3296,8 +3457,11 @@
       
       if(n_alloc < new_n_nonzero)
         {
-        eT*    new_values      = memory::acquire_chunked<eT>   (new_n_nonzero);
-        uword* new_row_indices = memory::acquire_chunked<uword>(new_n_nonzero);
+        eT*    new_values      = memory::acquire_chunked<eT>   (new_n_nonzero + 1);
+        uword* new_row_indices = memory::acquire_chunked<uword>(new_n_nonzero + 1);
+
+        access::rw(new_values[new_n_nonzero]) = 0;
+        access::rw(new_row_indices[new_n_nonzero]) = 0;
         
         if(n_nonzero > 0)
           {
@@ -3391,7 +3555,7 @@
 typename SpMat<eT>::iterator
 SpMat<eT>::end()
   {
-  return iterator(*this, n_nonzero);
+  return iterator(*this, 0, n_cols, n_nonzero);
   }
 
 
@@ -3401,7 +3565,7 @@
[TRUNCATED]

To get the complete diff run:
    svnlook diff /svnroot/rcpp -r 3780


More information about the Rcpp-commits mailing list