changeset 15305:4663cc835c65 stable

Special-case removing rows or columns from empty sparse matrices * Sparse.cc (Sparse<T>::delete_elements): Don't attempt to preserve elements if nnz = 0; simply reshape if number of rows or columns is zero.
author John W. Eaton <jwe@octave.org>
date Thu, 21 Jun 2012 14:42:05 -0400
parents f2e72944847b
children b135f013679e 197774b411ec
files liboctave/Sparse.cc
diffstat 1 files changed, 56 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/Sparse.cc
+++ b/liboctave/Sparse.cc
@@ -1240,16 +1240,31 @@
         gripe_del_index_out_of_range (false, idx_j.extent (nc), nc);
       else if (idx_j.is_cont_range (nc, lb, ub))
         {
-          const Sparse<T> tmp = *this;
-          octave_idx_type lbi = tmp.cidx(lb), ubi = tmp.cidx(ub), new_nz = nz - (ubi - lbi);
-          *this = Sparse<T> (nr, nc - (ub - lb), new_nz);
-          copy_or_memcpy (lbi, tmp.data (), data ());
-          copy_or_memcpy (lbi, tmp.ridx (), ridx ());
-          copy_or_memcpy (nz - ubi, tmp.data () + ubi, xdata () + lbi);
-          copy_or_memcpy (nz - ubi, tmp.ridx () + ubi, xridx () + lbi);
-          copy_or_memcpy (lb, tmp.cidx () + 1, cidx () + 1);
-          mx_inline_sub (nc - ub, xcidx () + lb + 1,
-                         tmp.cidx () + ub + 1, ubi - lbi);
+          if (lb == 0 && ub == nc)
+            {
+              // Delete all rows and columns.
+              *this = Sparse<T> (nr, 0);
+            }
+          else if (nz == 0)
+            {
+              // No elements to preserve; adjust dimensions.
+              *this = Sparse<T> (nr, nc - (ub - lb));
+            }
+          else
+            {
+              const Sparse<T> tmp = *this;
+              octave_idx_type lbi = tmp.cidx(lb), ubi = tmp.cidx(ub),
+                new_nz = nz - (ubi - lbi);
+
+              *this = Sparse<T> (nr, nc - (ub - lb), new_nz);
+              copy_or_memcpy (lbi, tmp.data (), data ());
+              copy_or_memcpy (lbi, tmp.ridx (), ridx ());
+              copy_or_memcpy (nz - ubi, tmp.data () + ubi, xdata () + lbi);
+              copy_or_memcpy (nz - ubi, tmp.ridx () + ubi, xridx () + lbi);
+              copy_or_memcpy (lb, tmp.cidx () + 1, cidx () + 1);
+              mx_inline_sub (nc - ub, xcidx () + lb + 1,
+                             tmp.cidx () + ub + 1, ubi - lbi);
+            }
         }
       else
         *this = index (idx_i, idx_j.complement (nc));
@@ -1262,24 +1277,40 @@
         gripe_del_index_out_of_range (false, idx_i.extent (nr), nr);
       else if (idx_i.is_cont_range (nr, lb, ub))
         {
-          // This is more memory-efficient than the approach below.
-          const Sparse<T> tmpl = index (idx_vector (0, lb), idx_j);
-          const Sparse<T> tmpu = index (idx_vector (ub, nr), idx_j);
-          *this = Sparse<T> (nr - (ub - lb), nc, tmpl.nnz () + tmpu.nnz ());
-          for (octave_idx_type j = 0, k = 0; j < nc; j++)
+          if (lb == 0 && ub == nr)
+            {
+              // Delete all rows and columns.
+              *this = Sparse<T> (0, nc);
+            }
+          else if (nz == 0)
             {
-              for (octave_idx_type i = tmpl.cidx(j); i < tmpl.cidx(j+1); i++)
+              // No elements to preserve; adjust dimensions.
+              *this = Sparse<T> (nr - (ub - lb), nc);
+            }
+          else
+            {
+              // This is more memory-efficient than the approach below.
+              const Sparse<T> tmpl = index (idx_vector (0, lb), idx_j);
+              const Sparse<T> tmpu = index (idx_vector (ub, nr), idx_j);
+              *this = Sparse<T> (nr - (ub - lb), nc,
+                                 tmpl.nnz () + tmpu.nnz ());
+              for (octave_idx_type j = 0, k = 0; j < nc; j++)
                 {
-                  xdata(k) = tmpl.data(i);
-                  xridx(k++) = tmpl.ridx(i);
+                  for (octave_idx_type i = tmpl.cidx(j); i < tmpl.cidx(j+1);
+                       i++)
+                    {
+                      xdata(k) = tmpl.data(i);
+                      xridx(k++) = tmpl.ridx(i);
+                    }
+                  for (octave_idx_type i = tmpu.cidx(j); i < tmpu.cidx(j+1);
+                       i++)
+                    {
+                      xdata(k) = tmpu.data(i);
+                      xridx(k++) = tmpu.ridx(i) + lb;
+                    }
+
+                  xcidx(j+1) = k;
                 }
-              for (octave_idx_type i = tmpu.cidx(j); i < tmpu.cidx(j+1); i++)
-                {
-                  xdata(k) = tmpu.data(i);
-                  xridx(k++) = tmpu.ridx(i) + lb;
-                }
-
-              xcidx(j+1) = k;
             }
         }
       else