changeset 18080:35464baa7d99

Overhaul max/min implementations for Sparse matrices to fix bug #40743. * CSparse.cc (max, min): Declare variables for matrix A, rows and columns, and B, rows and columns. Test A & B sizes and if there is a mismatch check that one of them is not a null matrix before issuing an error. * dSparse.cc (max, min): Declare variables for matrix A, rows and columns, and B, rows and columns. Test A & B sizes and if there is a mismatch check that one of them is not a null matrix before issuing an error.
author Rik <rik@octave.org>
date Wed, 04 Dec 2013 14:15:01 -0800
parents b06a9768b643
children 938f01339043
files liboctave/array/CSparse.cc liboctave/array/dSparse.cc
diffstat 2 files changed, 272 insertions(+), 278 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/array/CSparse.cc	Wed Dec 04 12:05:43 2013 -0800
+++ b/liboctave/array/CSparse.cc	Wed Dec 04 14:15:01 2013 -0800
@@ -7682,87 +7682,85 @@
 {
   SparseComplexMatrix r;
 
-  if ((a.rows () == b.rows ()) && (a.cols () == b.cols ()))
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (a_nr == b_nr && a_nc == b_nc)
     {
-      octave_idx_type a_nr = a.rows ();
-      octave_idx_type a_nc = a.cols ();
-
-      octave_idx_type b_nr = b.rows ();
-      octave_idx_type b_nc = b.cols ();
-
-      if (a_nr == 0 || b_nc == 0 || a.nnz () == 0 || b.nnz () == 0)
-        return SparseComplexMatrix (a_nr, a_nc);
-
-      if (a_nr != b_nr || a_nc != b_nc)
-        gripe_nonconformant ("min", a_nr, a_nc, b_nr, b_nc);
-      else
+      r = SparseComplexMatrix (a_nr, a_nc, (a.nnz () + b.nnz ()));
+
+      octave_idx_type jx = 0;
+      r.cidx (0) = 0;
+      for (octave_idx_type i = 0 ; i < a_nc ; i++)
         {
-          r = SparseComplexMatrix (a_nr, a_nc, (a.nnz () + b.nnz ()));
-
-          octave_idx_type jx = 0;
-          r.cidx (0) = 0;
-          for (octave_idx_type i = 0 ; i < a_nc ; i++)
-            {
-              octave_idx_type  ja = a.cidx (i);
-              octave_idx_type  ja_max = a.cidx (i+1);
-              bool ja_lt_max= ja < ja_max;
-
-              octave_idx_type  jb = b.cidx (i);
-              octave_idx_type  jb_max = b.cidx (i+1);
-              bool jb_lt_max = jb < jb_max;
-
-              while (ja_lt_max || jb_lt_max )
-                {
-                  octave_quit ();
-                  if ((! jb_lt_max) ||
-                      (ja_lt_max && (a.ridx (ja) < b.ridx (jb))))
+          octave_idx_type  ja = a.cidx (i);
+          octave_idx_type  ja_max = a.cidx (i+1);
+          bool ja_lt_max= ja < ja_max;
+
+          octave_idx_type  jb = b.cidx (i);
+          octave_idx_type  jb_max = b.cidx (i+1);
+          bool jb_lt_max = jb < jb_max;
+
+          while (ja_lt_max || jb_lt_max )
+            {
+              octave_quit ();
+              if ((! jb_lt_max) ||
+                  (ja_lt_max && (a.ridx (ja) < b.ridx (jb))))
+                {
+                  Complex tmp = xmin (a.data (ja), 0.);
+                  if (tmp != 0.)
                     {
-                      Complex tmp = xmin (a.data (ja), 0.);
-                      if (tmp != 0.)
-                        {
-                          r.ridx (jx) = a.ridx (ja);
-                          r.data (jx) = tmp;
-                          jx++;
-                        }
-                      ja++;
-                      ja_lt_max= ja < ja_max;
+                      r.ridx (jx) = a.ridx (ja);
+                      r.data (jx) = tmp;
+                      jx++;
                     }
-                  else if (( !ja_lt_max ) ||
-                           (jb_lt_max && (b.ridx (jb) < a.ridx (ja)) ) )
+                  ja++;
+                  ja_lt_max= ja < ja_max;
+                }
+              else if (( !ja_lt_max ) ||
+                       (jb_lt_max && (b.ridx (jb) < a.ridx (ja)) ) )
+                {
+                  Complex tmp = xmin (0., b.data (jb));
+                  if (tmp != 0.)
                     {
-                      Complex tmp = xmin (0., b.data (jb));
-                      if (tmp != 0.)
-                        {
-                          r.ridx (jx) = b.ridx (jb);
-                          r.data (jx) = tmp;
-                          jx++;
-                        }
-                      jb++;
-                      jb_lt_max= jb < jb_max;
+                      r.ridx (jx) = b.ridx (jb);
+                      r.data (jx) = tmp;
+                      jx++;
                     }
-                  else
+                  jb++;
+                  jb_lt_max= jb < jb_max;
+                }
+              else
+                {
+                  Complex tmp = xmin (a.data (ja), b.data (jb));
+                  if (tmp != 0.)
                     {
-                      Complex tmp = xmin (a.data (ja), b.data (jb));
-                      if (tmp != 0.)
-                        {
-                          r.data (jx) = tmp;
-                          r.ridx (jx) = a.ridx (ja);
-                          jx++;
-                        }
-                      ja++;
-                      ja_lt_max= ja < ja_max;
-                      jb++;
-                      jb_lt_max= jb < jb_max;
+                      r.data (jx) = tmp;
+                      r.ridx (jx) = a.ridx (ja);
+                      jx++;
                     }
-                }
-              r.cidx (i+1) = jx;
-            }
-
-          r.maybe_compress ();
+                  ja++;
+                  ja_lt_max= ja < ja_max;
+                  jb++;
+                  jb_lt_max= jb < jb_max;
+                }
+            }
+          r.cidx (i+1) = jx;
         }
+
+      r.maybe_compress ();
     }
   else
-    (*current_liboctave_error_handler) ("matrix size mismatch");
+    {
+      if (a_nr == 0 || a_nc == 0)
+        r.resize (a_nr, a_nc);
+      else if (b_nr == 0 || b_nc == 0)
+        r.resize (b_nr, b_nc);
+      else
+        gripe_nonconformant ("min", a_nr, a_nc, b_nr, b_nc);
+    }
 
   return r;
 }
@@ -7802,91 +7800,85 @@
 {
   SparseComplexMatrix r;
 
-  if ((a.rows () == b.rows ()) && (a.cols () == b.cols ()))
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (a_nr == b_nr && a_nc == b_nc)
     {
-      octave_idx_type a_nr = a.rows ();
-      octave_idx_type a_nc = a.cols ();
-
-      octave_idx_type b_nr = b.rows ();
-      octave_idx_type b_nc = b.cols ();
-
-      if (a_nr == 0 || b_nc == 0)
-        return SparseComplexMatrix (a_nr, a_nc);
-      if (a.nnz () == 0)
-        return SparseComplexMatrix (b);
-      if (b.nnz () == 0)
-        return SparseComplexMatrix (a);
-
-      if (a_nr != b_nr || a_nc != b_nc)
-        gripe_nonconformant ("min", a_nr, a_nc, b_nr, b_nc);
-      else
+      r = SparseComplexMatrix (a_nr, a_nc, (a.nnz () + b.nnz ()));
+
+      octave_idx_type jx = 0;
+      r.cidx (0) = 0;
+      for (octave_idx_type i = 0 ; i < a_nc ; i++)
         {
-          r = SparseComplexMatrix (a_nr, a_nc, (a.nnz () + b.nnz ()));
-
-          octave_idx_type jx = 0;
-          r.cidx (0) = 0;
-          for (octave_idx_type i = 0 ; i < a_nc ; i++)
-            {
-              octave_idx_type  ja = a.cidx (i);
-              octave_idx_type  ja_max = a.cidx (i+1);
-              bool ja_lt_max= ja < ja_max;
-
-              octave_idx_type  jb = b.cidx (i);
-              octave_idx_type  jb_max = b.cidx (i+1);
-              bool jb_lt_max = jb < jb_max;
-
-              while (ja_lt_max || jb_lt_max )
-                {
-                  octave_quit ();
-                  if ((! jb_lt_max) ||
-                      (ja_lt_max && (a.ridx (ja) < b.ridx (jb))))
+          octave_idx_type  ja = a.cidx (i);
+          octave_idx_type  ja_max = a.cidx (i+1);
+          bool ja_lt_max= ja < ja_max;
+
+          octave_idx_type  jb = b.cidx (i);
+          octave_idx_type  jb_max = b.cidx (i+1);
+          bool jb_lt_max = jb < jb_max;
+
+          while (ja_lt_max || jb_lt_max )
+            {
+              octave_quit ();
+              if ((! jb_lt_max) ||
+                  (ja_lt_max && (a.ridx (ja) < b.ridx (jb))))
+                {
+                  Complex tmp = xmax (a.data (ja), 0.);
+                  if (tmp != 0.)
                     {
-                      Complex tmp = xmax (a.data (ja), 0.);
-                      if (tmp != 0.)
-                        {
-                          r.ridx (jx) = a.ridx (ja);
-                          r.data (jx) = tmp;
-                          jx++;
-                        }
-                      ja++;
-                      ja_lt_max= ja < ja_max;
+                      r.ridx (jx) = a.ridx (ja);
+                      r.data (jx) = tmp;
+                      jx++;
                     }
-                  else if (( !ja_lt_max ) ||
-                           (jb_lt_max && (b.ridx (jb) < a.ridx (ja)) ) )
+                  ja++;
+                  ja_lt_max= ja < ja_max;
+                }
+              else if (( !ja_lt_max ) ||
+                       (jb_lt_max && (b.ridx (jb) < a.ridx (ja)) ) )
+                {
+                  Complex tmp = xmax (0., b.data (jb));
+                  if (tmp != 0.)
                     {
-                      Complex tmp = xmax (0., b.data (jb));
-                      if (tmp != 0.)
-                        {
-                          r.ridx (jx) = b.ridx (jb);
-                          r.data (jx) = tmp;
-                          jx++;
-                        }
-                      jb++;
-                      jb_lt_max= jb < jb_max;
+                      r.ridx (jx) = b.ridx (jb);
+                      r.data (jx) = tmp;
+                      jx++;
                     }
-                  else
+                  jb++;
+                  jb_lt_max= jb < jb_max;
+                }
+              else
+                {
+                  Complex tmp = xmax (a.data (ja), b.data (jb));
+                  if (tmp != 0.)
                     {
-                      Complex tmp = xmax (a.data (ja), b.data (jb));
-                      if (tmp != 0.)
-                        {
-                          r.data (jx) = tmp;
-                          r.ridx (jx) = a.ridx (ja);
-                          jx++;
-                        }
-                      ja++;
-                      ja_lt_max= ja < ja_max;
-                      jb++;
-                      jb_lt_max= jb < jb_max;
+                      r.data (jx) = tmp;
+                      r.ridx (jx) = a.ridx (ja);
+                      jx++;
                     }
-                }
-              r.cidx (i+1) = jx;
-            }
-
-          r.maybe_compress ();
+                  ja++;
+                  ja_lt_max= ja < ja_max;
+                  jb++;
+                  jb_lt_max= jb < jb_max;
+                }
+            }
+          r.cidx (i+1) = jx;
         }
+
+      r.maybe_compress ();
     }
   else
-    (*current_liboctave_error_handler) ("matrix size mismatch");
+    {
+      if (a_nr == 0 || a_nc == 0)
+        r.resize (a_nr, a_nc);
+      else if (b_nr == 0 || b_nc == 0)
+        r.resize (b_nr, b_nc);
+      else
+        gripe_nonconformant ("max", a_nr, a_nc, b_nr, b_nc);
+    }
 
   return r;
 }
--- a/liboctave/array/dSparse.cc	Wed Dec 04 12:05:43 2013 -0800
+++ b/liboctave/array/dSparse.cc	Wed Dec 04 14:15:01 2013 -0800
@@ -7795,84 +7795,85 @@
 {
   SparseMatrix r;
 
-  if ((a.rows () == b.rows ()) && (a.cols () == b.cols ()))
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (a_nr == b_nr && a_nc == b_nc)
     {
-      octave_idx_type a_nr = a.rows ();
-      octave_idx_type a_nc = a.cols ();
-
-      octave_idx_type b_nr = b.rows ();
-      octave_idx_type b_nc = b.cols ();
-
-      if (a_nr != b_nr || a_nc != b_nc)
-        gripe_nonconformant ("min", a_nr, a_nc, b_nr, b_nc);
-      else
+      r = SparseMatrix (a_nr, a_nc, (a.nnz () + b.nnz ()));
+
+      octave_idx_type jx = 0;
+      r.cidx (0) = 0;
+      for (octave_idx_type i = 0 ; i < a_nc ; i++)
         {
-          r = SparseMatrix (a_nr, a_nc, (a.nnz () + b.nnz ()));
-
-          octave_idx_type jx = 0;
-          r.cidx (0) = 0;
-          for (octave_idx_type i = 0 ; i < a_nc ; i++)
-            {
-              octave_idx_type  ja = a.cidx (i);
-              octave_idx_type  ja_max = a.cidx (i+1);
-              bool ja_lt_max= ja < ja_max;
-
-              octave_idx_type  jb = b.cidx (i);
-              octave_idx_type  jb_max = b.cidx (i+1);
-              bool jb_lt_max = jb < jb_max;
-
-              while (ja_lt_max || jb_lt_max )
-                {
-                  octave_quit ();
-                  if ((! jb_lt_max) ||
-                      (ja_lt_max && (a.ridx (ja) < b.ridx (jb))))
+          octave_idx_type  ja = a.cidx (i);
+          octave_idx_type  ja_max = a.cidx (i+1);
+          bool ja_lt_max= ja < ja_max;
+
+          octave_idx_type  jb = b.cidx (i);
+          octave_idx_type  jb_max = b.cidx (i+1);
+          bool jb_lt_max = jb < jb_max;
+
+          while (ja_lt_max || jb_lt_max )
+            {
+              octave_quit ();
+              if ((! jb_lt_max) ||
+                  (ja_lt_max && (a.ridx (ja) < b.ridx (jb))))
+                {
+                  double tmp = xmin (a.data (ja), 0.);
+                  if (tmp != 0.)
                     {
-                      double tmp = xmin (a.data (ja), 0.);
-                      if (tmp != 0.)
-                        {
-                          r.ridx (jx) = a.ridx (ja);
-                          r.data (jx) = tmp;
-                          jx++;
-                        }
-                      ja++;
-                      ja_lt_max= ja < ja_max;
+                      r.ridx (jx) = a.ridx (ja);
+                      r.data (jx) = tmp;
+                      jx++;
                     }
-                  else if (( !ja_lt_max ) ||
-                           (jb_lt_max && (b.ridx (jb) < a.ridx (ja)) ) )
+                  ja++;
+                  ja_lt_max= ja < ja_max;
+                }
+              else if (( !ja_lt_max ) ||
+                       (jb_lt_max && (b.ridx (jb) < a.ridx (ja)) ) )
+                {
+                  double tmp = xmin (0., b.data (jb));
+                  if (tmp != 0.)
                     {
-                      double tmp = xmin (0., b.data (jb));
-                      if (tmp != 0.)
-                        {
-                          r.ridx (jx) = b.ridx (jb);
-                          r.data (jx) = tmp;
-                          jx++;
-                        }
-                      jb++;
-                      jb_lt_max= jb < jb_max;
+                      r.ridx (jx) = b.ridx (jb);
+                      r.data (jx) = tmp;
+                      jx++;
                     }
-                  else
+                  jb++;
+                  jb_lt_max= jb < jb_max;
+                }
+              else
+                {
+                  double tmp = xmin (a.data (ja), b.data (jb));
+                  if (tmp != 0.)
                     {
-                      double tmp = xmin (a.data (ja), b.data (jb));
-                      if (tmp != 0.)
-                        {
-                          r.data (jx) = tmp;
-                          r.ridx (jx) = a.ridx (ja);
-                          jx++;
-                        }
-                      ja++;
-                      ja_lt_max= ja < ja_max;
-                      jb++;
-                      jb_lt_max= jb < jb_max;
+                      r.data (jx) = tmp;
+                      r.ridx (jx) = a.ridx (ja);
+                      jx++;
                     }
-                }
-              r.cidx (i+1) = jx;
-            }
-
-          r.maybe_compress ();
+                  ja++;
+                  ja_lt_max= ja < ja_max;
+                  jb++;
+                  jb_lt_max= jb < jb_max;
+                }
+            }
+          r.cidx (i+1) = jx;
         }
+
+      r.maybe_compress ();
     }
   else
-    (*current_liboctave_error_handler) ("matrix size mismatch");
+    {
+      if (a_nr == 0 || a_nc == 0)
+        r.resize (a_nr, a_nc);
+      else if (b_nr == 0 || b_nc == 0)
+        r.resize (b_nr, b_nc);
+      else
+        gripe_nonconformant ("min", a_nr, a_nc, b_nr, b_nc);
+    }
 
   return r;
 }
@@ -7945,84 +7946,85 @@
 {
   SparseMatrix r;
 
-  if ((a.rows () == b.rows ()) && (a.cols () == b.cols ()))
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (a_nr == b_nr && a_nc == b_nc)
     {
-      octave_idx_type a_nr = a.rows ();
-      octave_idx_type a_nc = a.cols ();
-
-      octave_idx_type b_nr = b.rows ();
-      octave_idx_type b_nc = b.cols ();
-
-      if (a_nr != b_nr || a_nc != b_nc)
-        gripe_nonconformant ("min", a_nr, a_nc, b_nr, b_nc);
-      else
+      r = SparseMatrix (a_nr, a_nc, (a.nnz () + b.nnz ()));
+
+      octave_idx_type jx = 0;
+      r.cidx (0) = 0;
+      for (octave_idx_type i = 0 ; i < a_nc ; i++)
         {
-          r = SparseMatrix (a_nr, a_nc, (a.nnz () + b.nnz ()));
-
-          octave_idx_type jx = 0;
-          r.cidx (0) = 0;
-          for (octave_idx_type i = 0 ; i < a_nc ; i++)
-            {
-              octave_idx_type  ja = a.cidx (i);
-              octave_idx_type  ja_max = a.cidx (i+1);
-              bool ja_lt_max= ja < ja_max;
-
-              octave_idx_type  jb = b.cidx (i);
-              octave_idx_type  jb_max = b.cidx (i+1);
-              bool jb_lt_max = jb < jb_max;
-
-              while (ja_lt_max || jb_lt_max )
-                {
-                  octave_quit ();
-                  if ((! jb_lt_max) ||
-                      (ja_lt_max && (a.ridx (ja) < b.ridx (jb))))
+          octave_idx_type  ja = a.cidx (i);
+          octave_idx_type  ja_max = a.cidx (i+1);
+          bool ja_lt_max= ja < ja_max;
+
+          octave_idx_type  jb = b.cidx (i);
+          octave_idx_type  jb_max = b.cidx (i+1);
+          bool jb_lt_max = jb < jb_max;
+
+          while (ja_lt_max || jb_lt_max )
+            {
+              octave_quit ();
+              if ((! jb_lt_max) ||
+                  (ja_lt_max && (a.ridx (ja) < b.ridx (jb))))
+                {
+                  double tmp = xmax (a.data (ja), 0.);
+                  if (tmp != 0.)
                     {
-                      double tmp = xmax (a.data (ja), 0.);
-                      if (tmp != 0.)
-                        {
-                          r.ridx (jx) = a.ridx (ja);
-                          r.data (jx) = tmp;
-                          jx++;
-                        }
-                      ja++;
-                      ja_lt_max= ja < ja_max;
+                      r.ridx (jx) = a.ridx (ja);
+                      r.data (jx) = tmp;
+                      jx++;
                     }
-                  else if (( !ja_lt_max ) ||
-                           (jb_lt_max && (b.ridx (jb) < a.ridx (ja)) ) )
+                  ja++;
+                  ja_lt_max= ja < ja_max;
+                }
+              else if (( !ja_lt_max ) ||
+                       (jb_lt_max && (b.ridx (jb) < a.ridx (ja)) ) )
+                {
+                  double tmp = xmax (0., b.data (jb));
+                  if (tmp != 0.)
                     {
-                      double tmp = xmax (0., b.data (jb));
-                      if (tmp != 0.)
-                        {
-                          r.ridx (jx) = b.ridx (jb);
-                          r.data (jx) = tmp;
-                          jx++;
-                        }
-                      jb++;
-                      jb_lt_max= jb < jb_max;
+                      r.ridx (jx) = b.ridx (jb);
+                      r.data (jx) = tmp;
+                      jx++;
                     }
-                  else
+                  jb++;
+                  jb_lt_max= jb < jb_max;
+                }
+              else
+                {
+                  double tmp = xmax (a.data (ja), b.data (jb));
+                  if (tmp != 0.)
                     {
-                      double tmp = xmax (a.data (ja), b.data (jb));
-                      if (tmp != 0.)
-                        {
-                          r.data (jx) = tmp;
-                          r.ridx (jx) = a.ridx (ja);
-                          jx++;
-                        }
-                      ja++;
-                      ja_lt_max= ja < ja_max;
-                      jb++;
-                      jb_lt_max= jb < jb_max;
+                      r.data (jx) = tmp;
+                      r.ridx (jx) = a.ridx (ja);
+                      jx++;
                     }
-                }
-              r.cidx (i+1) = jx;
-            }
-
-          r.maybe_compress ();
+                  ja++;
+                  ja_lt_max= ja < ja_max;
+                  jb++;
+                  jb_lt_max= jb < jb_max;
+                }
+            }
+          r.cidx (i+1) = jx;
         }
+
+      r.maybe_compress ();
     }
   else
-    (*current_liboctave_error_handler) ("matrix size mismatch");
+    {
+      if (a_nr == 0 || a_nc == 0)
+        r.resize (a_nr, a_nc);
+      else if (b_nr == 0 || b_nc == 0)
+        r.resize (b_nr, b_nc);
+      else
+        gripe_nonconformant ("max", a_nr, a_nc, b_nr, b_nc);
+    }
 
   return r;
 }