changeset 25663:2de707ae8de4

eliminate LHS_ZERO and RHS_ZERO args from sparse macros * Sparse-op-defs.h (SPARSE_SMS_BOOL_OR_OP, SPARSE_SMS_BOOL_AND_OP): New macros based on SPARSE_SMS_BOOL_OP. Eliminate LHS_ZERO and RHS_ZERO arguments. (SPARSE_SMS_BOOL_OP, SPARSE_SMS_BOOL_OPS2): Delete. (SPARSE_SMS_BOOL_OPS): Eliminate ZERO argument. Define using SPARSE_SMS_BOOL_AND_OP and SPARSE_SMS_BOOL_OR_OP. Change all uses. * Sparse-op-defs.h (SPARSE_SSM_BOOL_OR_OP, SPARSE_SSM_BOOL_AND_OP): New macros based on SPARSE_SSM_BOOL_OP. Eliminate LHS_ZERO and RHS_ZERO arguments. (SPARSE_SSM_BOOL_OP, SPARSE_SSM_BOOL_OPS2): Delete. (SPARSE_SSM_BOOL_OPS): Eliminate ZERO argument. Define using SPARSE_SSM_BOOL_AND_OP and SPARSE_SSM_BOOL_OR_OP. Change all uses. * Sparse-op-defs.h (SPARSE_SMSM_BOOL_OR_OP, SPARSE_SMSM_BOOL_AND_OP): New macros based on SPARSE_SMSM_BOOL_OP. Eliminate LHS_ZERO and RHS_ZERO arguments. (SPARSE_SMSM_BOOL_OP, SPARSE_SMSM_BOOL_OPS2): Delete. (SPARSE_SMSM_BOOL_OPS): Eliminate ZERO argument. Define using SPARSE_SMSM_BOOL_AND_OP and SPARSE_SMSM_BOOL_OR_OP. Change all uses. * Sparse-op-defs.h (SPARSE_MSM_BOOL_OP): Eliminate LHS_ZERO and RHS_ZERO arguments. (SPARSE_MSM_BOOL_OPS2): Delete. (SPARSE_MSM_BOOL_OPS): Eliminate ZERO arguments. Change all uses. * Sparse-op-defs.h (SPARSE_SMM_BOOL_OP): Eliminate LHS_ZERO and RHS_ZERO arguments. (SPARSE_SMM_BOOL_OPS2): Delete. (SPARSE_SMM_BOOL_OPS): Eliminate ZERO arguments. Change all uses. * mx-op-defs.h (MDM_MULTIPLY, MDM_BIN_OPS, DMM_MULTIPLY, DMM_BIN_OPS): Eliminate R_ZERO argument. Change all uses. * mk-ops.awk: Simplify and eliminate unnecessary zero values from generated code.
author John W. Eaton <jwe@octave.org>
date Wed, 02 Nov 2016 23:12:22 -0400
parents 924689a356e8
children fc6081e9607b
files liboctave/array/CSparse.cc liboctave/array/boolSparse.cc liboctave/array/dSparse.cc liboctave/operators/Sparse-op-defs.h liboctave/operators/mk-ops.awk liboctave/operators/mx-op-defs.h
diffstat 6 files changed, 217 insertions(+), 160 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/array/CSparse.cc	Tue Nov 01 11:57:27 2016 -0400
+++ b/liboctave/array/CSparse.cc	Wed Nov 02 23:12:22 2016 -0400
@@ -7935,12 +7935,13 @@
 
 SPARSE_SMS_CMP_OPS (SparseComplexMatrix, 0.0, real, Complex,
                     0.0, real)
-SPARSE_SMS_BOOL_OPS (SparseComplexMatrix, Complex, 0.0)
+SPARSE_SMS_BOOL_OPS (SparseComplexMatrix, Complex)
 
 SPARSE_SSM_CMP_OPS (Complex, 0.0, real, SparseComplexMatrix,
                     0.0, real)
-SPARSE_SSM_BOOL_OPS (Complex, SparseComplexMatrix, 0.0)
+SPARSE_SSM_BOOL_OPS (Complex, SparseComplexMatrix)
 
 SPARSE_SMSM_CMP_OPS (SparseComplexMatrix, 0.0, real, SparseComplexMatrix,
                      0.0, real)
-SPARSE_SMSM_BOOL_OPS (SparseComplexMatrix, SparseComplexMatrix, 0.0)
+
+SPARSE_SMSM_BOOL_OPS (SparseComplexMatrix, SparseComplexMatrix)
--- a/liboctave/array/boolSparse.cc	Tue Nov 01 11:57:27 2016 -0400
+++ b/liboctave/array/boolSparse.cc	Wed Nov 02 23:12:22 2016 -0400
@@ -322,10 +322,10 @@
 }
 
 SPARSE_SMS_EQNE_OPS (SparseBoolMatrix, false, , bool, false, )
-SPARSE_SMS_BOOL_OPS (SparseBoolMatrix, bool, false)
+SPARSE_SMS_BOOL_OPS (SparseBoolMatrix, bool)
 
 SPARSE_SSM_EQNE_OPS (bool, false, , SparseBoolMatrix, false, )
-SPARSE_SSM_BOOL_OPS (bool, SparseBoolMatrix, false)
+SPARSE_SSM_BOOL_OPS (bool, SparseBoolMatrix)
 
 SPARSE_SMSM_EQNE_OPS (SparseBoolMatrix, false, , SparseBoolMatrix, false, )
-SPARSE_SMSM_BOOL_OPS (SparseBoolMatrix, SparseBoolMatrix, false)
+SPARSE_SMSM_BOOL_OPS (SparseBoolMatrix, SparseBoolMatrix)
--- a/liboctave/array/dSparse.cc	Tue Nov 01 11:57:27 2016 -0400
+++ b/liboctave/array/dSparse.cc	Wed Nov 02 23:12:22 2016 -0400
@@ -7925,10 +7925,10 @@
 }
 
 SPARSE_SMS_CMP_OPS (SparseMatrix, 0.0, , double, 0.0, )
-SPARSE_SMS_BOOL_OPS (SparseMatrix, double, 0.0)
+SPARSE_SMS_BOOL_OPS (SparseMatrix, double)
 
 SPARSE_SSM_CMP_OPS (double, 0.0, , SparseMatrix, 0.0, )
-SPARSE_SSM_BOOL_OPS (double, SparseMatrix, 0.0)
+SPARSE_SSM_BOOL_OPS (double, SparseMatrix)
 
 SPARSE_SMSM_CMP_OPS (SparseMatrix, 0.0, , SparseMatrix, 0.0, )
-SPARSE_SMSM_BOOL_OPS (SparseMatrix, SparseMatrix, 0.0)
+SPARSE_SMSM_BOOL_OPS (SparseMatrix, SparseMatrix)
--- a/liboctave/operators/Sparse-op-defs.h	Tue Nov 01 11:57:27 2016 -0400
+++ b/liboctave/operators/Sparse-op-defs.h	Wed Nov 02 23:12:22 2016 -0400
@@ -126,25 +126,21 @@
   SPARSE_SMS_CMP_OP (mx_el_eq, ==, M, MZ,   , S, SZ,   )        \
   SPARSE_SMS_CMP_OP (mx_el_ne, !=, M, MZ,   , S, SZ,   )
 
-#define SPARSE_SMS_BOOL_OP(F, OP, M, S, LHS_ZERO, RHS_ZERO)             \
+#define SPARSE_SMS_BOOL_OR_OP(M, S)                                     \
   SparseBoolMatrix                                                      \
-  F (const M& m, const S& s)                                            \
+  mx_el_or (const M& m, const S& s)                                     \
   {                                                                     \
     octave_idx_type nr = m.rows ();                                     \
     octave_idx_type nc = m.cols ();                                     \
     SparseBoolMatrix r;                                                 \
                                                                         \
+    M::element_type lhs_zero = M::element_type ();                      \
+    S rhs_zero = S ();                                                  \
+                                                                        \
     if (nr > 0 && nc > 0)                                               \
       {                                                                 \
-        if (LHS_ZERO OP (s != RHS_ZERO))                                \
-          {                                                             \
-            r = SparseBoolMatrix (nr, nc, true);                        \
-            for (octave_idx_type j = 0; j < nc; j++)                    \
-              for (octave_idx_type i = m.cidx (j); i < m.cidx (j+1); i++) \
-                if (! ((m.data (i) != LHS_ZERO) OP (s != RHS_ZERO)))    \
-                  r.data (m.ridx (i) + j * nr) = false;                 \
-            r.maybe_compress (true);                                    \
-          }                                                             \
+        if (s != rhs_zero)                                              \
+          r = SparseBoolMatrix (nr, nc, true);                          \
         else                                                            \
           {                                                             \
             r = SparseBoolMatrix (nr, nc, m.nnz ());                    \
@@ -153,7 +149,7 @@
             for (octave_idx_type j = 0; j < nc; j++)                    \
               {                                                         \
                 for (octave_idx_type i = m.cidx (j); i < m.cidx (j+1); i++) \
-                  if ((m.data (i) != LHS_ZERO) OP (s != RHS_ZERO))      \
+                  if (m.data (i) != lhs_zero)                           \
                     {                                                   \
                       r.ridx (nel) = m.ridx (i);                        \
                       r.data (nel++) = true;                            \
@@ -166,12 +162,45 @@
     return r;                                                           \
   }
 
-#define SPARSE_SMS_BOOL_OPS2(M, S, LHS_ZERO, RHS_ZERO)          \
-  SPARSE_SMS_BOOL_OP (mx_el_and, &&, M, S, LHS_ZERO, RHS_ZERO)  \
-  SPARSE_SMS_BOOL_OP (mx_el_or,  ||, M, S, LHS_ZERO, RHS_ZERO)
+#define SPARSE_SMS_BOOL_AND_OP(M, S)                                    \
+  SparseBoolMatrix                                                      \
+  mx_el_and (const M& m, const S& s)                                    \
+  {                                                                     \
+    octave_idx_type nr = m.rows ();                                     \
+    octave_idx_type nc = m.cols ();                                     \
+    SparseBoolMatrix r;                                                 \
+                                                                        \
+    M::element_type lhs_zero = M::element_type ();                      \
+    S rhs_zero = S ();                                                  \
+                                                                        \
+    if (nr > 0 && nc > 0)                                               \
+      {                                                                 \
+        if (s != rhs_zero)                                              \
+          {                                                             \
+            r = SparseBoolMatrix (nr, nc, m.nnz ());                    \
+            r.cidx (0) = static_cast<octave_idx_type> (0);              \
+            octave_idx_type nel = 0;                                    \
+            for (octave_idx_type j = 0; j < nc; j++)                    \
+              {                                                         \
+                for (octave_idx_type i = m.cidx (j); i < m.cidx (j+1); i++) \
+                  if (m.data (i) != lhs_zero)                           \
+                    {                                                   \
+                      r.ridx (nel) = m.ridx (i);                        \
+                      r.data (nel++) = true;                            \
+                    }                                                   \
+                r.cidx (j + 1) = nel;                                   \
+              }                                                         \
+            r.maybe_compress (false);                                   \
+          }                                                             \
+        else                                                            \
+          r = SparseBoolMatrix (nr, nc);                                \
+      }                                                                 \
+    return r;                                                           \
+  }
 
-#define SPARSE_SMS_BOOL_OPS(M, S, ZERO)         \
-  SPARSE_SMS_BOOL_OPS2(M, S, ZERO, ZERO)
+#define SPARSE_SMS_BOOL_OPS(M, S)               \
+  SPARSE_SMS_BOOL_AND_OP (M, S)                 \
+  SPARSE_SMS_BOOL_OR_OP (M, S)
 
 // scalar by sparse matrix operations.
 
@@ -268,25 +297,21 @@
   SPARSE_SSM_CMP_OP (mx_el_eq, ==, S, SZ,   , M, MZ,   )        \
   SPARSE_SSM_CMP_OP (mx_el_ne, !=, S, SZ,   , M, MZ,   )
 
-#define SPARSE_SSM_BOOL_OP(F, OP, S, M, LHS_ZERO, RHS_ZERO)             \
+#define SPARSE_SSM_BOOL_OR_OP(S, M)                                     \
   SparseBoolMatrix                                                      \
-  F (const S& s, const M& m)                                            \
+  mx_el_or (const S& s, const M& m)                                     \
   {                                                                     \
     octave_idx_type nr = m.rows ();                                     \
     octave_idx_type nc = m.cols ();                                     \
     SparseBoolMatrix r;                                                 \
                                                                         \
+    S lhs_zero = S ();                                                  \
+    M::element_type rhs_zero = M::element_type ();                      \
+                                                                        \
     if (nr > 0 && nc > 0)                                               \
       {                                                                 \
-        if ((s != LHS_ZERO) OP RHS_ZERO)                                \
-          {                                                             \
-            r = SparseBoolMatrix (nr, nc, true);                        \
-            for (octave_idx_type j = 0; j < nc; j++)                    \
-              for (octave_idx_type i = m.cidx (j); i < m.cidx (j+1); i++) \
-                if (! ((s != LHS_ZERO) OP (m.data (i) != RHS_ZERO)))    \
-                  r.data (m.ridx (i) + j * nr) = false;                 \
-            r.maybe_compress (true);                                    \
-          }                                                             \
+        if (s != lhs_zero)                                              \
+          r = SparseBoolMatrix (nr, nc, true);                          \
         else                                                            \
           {                                                             \
             r = SparseBoolMatrix (nr, nc, m.nnz ());                    \
@@ -295,7 +320,7 @@
             for (octave_idx_type j = 0; j < nc; j++)                    \
               {                                                         \
                 for (octave_idx_type i = m.cidx (j); i < m.cidx (j+1); i++) \
-                  if ((s != LHS_ZERO) OP (m.data (i) != RHS_ZERO))      \
+                  if (m.data (i) != rhs_zero)                           \
                     {                                                   \
                       r.ridx (nel) = m.ridx (i);                        \
                       r.data (nel++) = true;                            \
@@ -308,12 +333,45 @@
     return r;                                                           \
   }
 
-#define SPARSE_SSM_BOOL_OPS2(S, M, LHS_ZERO, RHS_ZERO)          \
-  SPARSE_SSM_BOOL_OP (mx_el_and, &&, S, M, LHS_ZERO, RHS_ZERO)  \
-  SPARSE_SSM_BOOL_OP (mx_el_or,  ||, S, M, LHS_ZERO, RHS_ZERO)
+#define SPARSE_SSM_BOOL_AND_OP(S, M)                                    \
+  SparseBoolMatrix                                                      \
+  mx_el_and (const S& s, const M& m)                                    \
+  {                                                                     \
+    octave_idx_type nr = m.rows ();                                     \
+    octave_idx_type nc = m.cols ();                                     \
+    SparseBoolMatrix r;                                                 \
+                                                                        \
+    S lhs_zero = S ();                                                  \
+    M::element_type rhs_zero = M::element_type ();                      \
+                                                                        \
+    if (nr > 0 && nc > 0)                                               \
+      {                                                                 \
+        if (s != lhs_zero)                                              \
+          {                                                             \
+            r = SparseBoolMatrix (nr, nc, m.nnz ());                    \
+            r.cidx (0) = static_cast<octave_idx_type> (0);              \
+            octave_idx_type nel = 0;                                    \
+            for (octave_idx_type j = 0; j < nc; j++)                    \
+              {                                                         \
+                for (octave_idx_type i = m.cidx (j); i < m.cidx (j+1); i++) \
+                  if (m.data (i) != rhs_zero)                           \
+                    {                                                   \
+                      r.ridx (nel) = m.ridx (i);                        \
+                      r.data (nel++) = true;                            \
+                    }                                                   \
+                r.cidx (j + 1) = nel;                                   \
+              }                                                         \
+            r.maybe_compress (false);                                   \
+          }                                                             \
+        else                                                            \
+          r = SparseBoolMatrix (nr, nc);                                \
+      }                                                                 \
+    return r;                                                           \
+  }
 
-#define SPARSE_SSM_BOOL_OPS(S, M, ZERO)         \
-  SPARSE_SSM_BOOL_OPS2(S, M, ZERO, ZERO)
+#define SPARSE_SSM_BOOL_OPS(S, M)               \
+  SPARSE_SSM_BOOL_AND_OP (S, M)                 \
+  SPARSE_SSM_BOOL_OR_OP (S, M)
 
 // sparse matrix by sparse matrix operations.
 
@@ -836,12 +894,11 @@
   SPARSE_SMSM_CMP_OP (mx_el_eq, ==, M1, Z1,   , M2, Z2,   )     \
   SPARSE_SMSM_CMP_OP (mx_el_ne, !=, M1, Z1,   , M2, Z2,   )
 
-// FIXME: this macro duplicates the bodies of the template functions
-// defined in the SPARSE_SSM_BOOL_OP and SPARSE_SMS_BOOL_OP macros.
-
-#define SPARSE_SMSM_BOOL_OP(F, OP, M1, M2, LHS_ZERO, RHS_ZERO)          \
+#define SPARSE_SMSM_BOOL_AND_OP(M1, M2)                                 \
+  extern SparseBoolMatrix mx_el_and (const M1&, const M2::element_type&); \
+  extern SparseBoolMatrix mx_el_and (const M1::element_type&, const M2&); \
   SparseBoolMatrix                                                      \
-  F (const M1& m1, const M2& m2)                                        \
+  mx_el_and (const M1& m1, const M2& m2)                                \
   {                                                                     \
     SparseBoolMatrix r;                                                 \
                                                                         \
@@ -851,70 +908,77 @@
     octave_idx_type m2_nr = m2.rows ();                                 \
     octave_idx_type m2_nc = m2.cols ();                                 \
                                                                         \
+    M1::element_type lhs_zero = M1::element_type ();                    \
+    M2::element_type rhs_zero = M2::element_type ();                    \
+                                                                        \
     if (m1_nr == 1 && m1_nc == 1)                                       \
+      return mx_el_and (m1.elem (0,0), m2);                             \
+    else if (m2_nr == 1 && m2_nc == 1)                                  \
+      return mx_el_and (m1, m2.elem (0,0));                             \
+    else if (m1_nr == m2_nr && m1_nc == m2_nc)                          \
       {                                                                 \
-        if (m2_nr > 0 && m2_nc > 0)                                     \
+        if (m1_nr != 0 || m1_nc != 0)                                   \
           {                                                             \
-            if ((m1.elem (0,0) != LHS_ZERO) OP RHS_ZERO)                \
-              {                                                         \
-                r = SparseBoolMatrix (m2_nr, m2_nc, true);              \
-                for (octave_idx_type j = 0; j < m2_nc; j++)             \
-                  for (octave_idx_type i = m2.cidx (j); i < m2.cidx (j+1); i++) \
-                    if (! ((m1.elem (0,0) != LHS_ZERO) OP (m2.data (i) != RHS_ZERO))) \
-                      r.data (m2.ridx (i) + j * m2_nr) = false;         \
-                r.maybe_compress (true);                                \
-              }                                                         \
-            else                                                        \
+            r = SparseBoolMatrix (m1_nr, m1_nc, m1.nnz () + m2.nnz ()); \
+            r.cidx (0) = static_cast<octave_idx_type> (0);              \
+            octave_idx_type nel = 0;                                    \
+            for (octave_idx_type j = 0; j < m1_nc; j++)                 \
               {                                                         \
-                r = SparseBoolMatrix (m2_nr, m2_nc, m2.nnz ());         \
-                r.cidx (0) = static_cast<octave_idx_type> (0);          \
-                octave_idx_type nel = 0;                                \
-                for (octave_idx_type j = 0; j < m2_nc; j++)             \
+                octave_idx_type i1 = m1.cidx (j);                       \
+                octave_idx_type e1 = m1.cidx (j+1);                     \
+                octave_idx_type i2 = m2.cidx (j);                       \
+                octave_idx_type e2 = m2.cidx (j+1);                     \
+                while (i1 < e1 || i2 < e2)                              \
                   {                                                     \
-                    for (octave_idx_type i = m2.cidx (j); i < m2.cidx (j+1); i++) \
-                      if ((m1.elem (0,0) != LHS_ZERO) OP (m2.data (i) != RHS_ZERO)) \
-                        {                                               \
-                          r.ridx (nel) = m2.ridx (i);                   \
-                          r.data (nel++) = true;                        \
-                        }                                               \
-                    r.cidx (j + 1) = nel;                               \
+                    if (i1 == e1 || (i2 < e2 && m1.ridx (i1) > m2.ridx (i2))) \
+                      i2++;                                             \
+                    else if (i2 == e2 || m1.ridx (i1) < m2.ridx (i2))   \
+                      i1++;                                             \
+                    else                                                \
+                      {                                                 \
+                        if (m1.data (i1) != lhs_zero && m2.data (i2) != rhs_zero) \
+                          {                                             \
+                            r.ridx (nel) = m1.ridx (i1);                \
+                            r.data (nel++) = true;                      \
+                          }                                             \
+                        i1++;                                           \
+                        i2++;                                           \
+                      }                                                 \
                   }                                                     \
-                r.maybe_compress (false);                               \
+                r.cidx (j + 1) = nel;                                   \
               }                                                         \
+            r.maybe_compress (false);                                   \
           }                                                             \
       }                                                                 \
-    else if (m2_nr == 1 && m2_nc == 1)                                  \
+    else                                                                \
       {                                                                 \
-        if (m1_nr > 0 && m1_nc > 0)                                     \
-          {                                                             \
-            if (LHS_ZERO OP (m2.elem (0,0) != RHS_ZERO))                \
-              {                                                         \
-                r = SparseBoolMatrix (m1_nr, m1_nc, true);              \
-                for (octave_idx_type j = 0; j < m1_nc; j++)             \
-                  for (octave_idx_type i = m1.cidx (j); i < m1.cidx (j+1); i++) \
-                    if (! ((m1.data (i) != LHS_ZERO) OP (m2.elem (0,0) != RHS_ZERO))) \
-                      r.data (m1.ridx (i) + j * m1_nr) = false;         \
-                r.maybe_compress (true);                                \
-              }                                                         \
-            else                                                        \
-              {                                                         \
-                r = SparseBoolMatrix (m1_nr, m1_nc, m1.nnz ());         \
-                r.cidx (0) = static_cast<octave_idx_type> (0);          \
-                octave_idx_type nel = 0;                                \
-                for (octave_idx_type j = 0; j < m1_nc; j++)             \
-                  {                                                     \
-                    for (octave_idx_type i = m1.cidx (j); i < m1.cidx (j+1); i++) \
-                      if ((m1.data (i) != LHS_ZERO) OP (m2.elem (0,0) != RHS_ZERO)) \
-                        {                                               \
-                          r.ridx (nel) = m1.ridx (i);                   \
-                          r.data (nel++) = true;                        \
-                        }                                               \
-                    r.cidx (j + 1) = nel;                               \
-                  }                                                     \
-                r.maybe_compress (false);                               \
-              }                                                         \
-          }                                                             \
+        if ((m1_nr != 0 || m1_nc != 0) && (m2_nr != 0 || m2_nc != 0))   \
+          octave::err_nonconformant ("mx_el_and_", m1_nr, m1_nc, m2_nr, m2_nc); \
       }                                                                 \
+    return r;                                                           \
+  }
+
+#define SPARSE_SMSM_BOOL_OR_OP(M1, M2)                                  \
+  extern SparseBoolMatrix mx_el_or (const M1&, const M2::element_type&); \
+  extern SparseBoolMatrix mx_el_or (const M1::element_type&, const M2&); \
+  SparseBoolMatrix                                                      \
+  mx_el_or (const M1& m1, const M2& m2)                                 \
+  {                                                                     \
+    SparseBoolMatrix r;                                                 \
+                                                                        \
+    octave_idx_type m1_nr = m1.rows ();                                 \
+    octave_idx_type m1_nc = m1.cols ();                                 \
+                                                                        \
+    octave_idx_type m2_nr = m2.rows ();                                 \
+    octave_idx_type m2_nc = m2.cols ();                                 \
+                                                                        \
+    M1::element_type lhs_zero = M1::element_type ();                    \
+    M2::element_type rhs_zero = M2::element_type ();                    \
+                                                                        \
+    if (m1_nr == 1 && m1_nc == 1)                                       \
+      return mx_el_or (m1.elem (0,0), m2);                              \
+    else if (m2_nr == 1 && m2_nc == 1)                                  \
+      return mx_el_or (m1, m2.elem (0,0));                              \
     else if (m1_nr == m2_nr && m1_nc == m2_nc)                          \
       {                                                                 \
         if (m1_nr != 0 || m1_nc != 0)                                   \
@@ -932,7 +996,7 @@
                   {                                                     \
                     if (i1 == e1 || (i2 < e2 && m1.ridx (i1) > m2.ridx (i2))) \
                       {                                                 \
-                        if (LHS_ZERO OP m2.data (i2) != RHS_ZERO)       \
+                        if (m2.data (i2) != rhs_zero)                   \
                           {                                             \
                             r.ridx (nel) = m2.ridx (i2);                \
                             r.data (nel++) = true;                      \
@@ -941,7 +1005,7 @@
                       }                                                 \
                     else if (i2 == e2 || m1.ridx (i1) < m2.ridx (i2))   \
                       {                                                 \
-                        if (m1.data (i1) != LHS_ZERO OP RHS_ZERO)       \
+                        if (m1.data (i1) != lhs_zero)                   \
                           {                                             \
                             r.ridx (nel) = m1.ridx (i1);                \
                             r.data (nel++) = true;                      \
@@ -950,7 +1014,7 @@
                       }                                                 \
                     else                                                \
                       {                                                 \
-                        if (m1.data (i1) != LHS_ZERO OP m2.data (i2) != RHS_ZERO) \
+                        if (m1.data (i1) != lhs_zero || m2.data (i2) != rhs_zero) \
                           {                                             \
                             r.ridx (nel) = m1.ridx (i1);                \
                             r.data (nel++) = true;                      \
@@ -967,17 +1031,14 @@
     else                                                                \
       {                                                                 \
         if ((m1_nr != 0 || m1_nc != 0) && (m2_nr != 0 || m2_nc != 0))   \
-          octave::err_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc);           \
+          octave::err_nonconformant ("mx_el_or", m1_nr, m1_nc, m2_nr, m2_nc); \
       }                                                                 \
     return r;                                                           \
   }
 
-#define SPARSE_SMSM_BOOL_OPS2(M1, M2, LHS_ZERO, RHS_ZERO)               \
-  SPARSE_SMSM_BOOL_OP (mx_el_and, &&, M1, M2, LHS_ZERO, RHS_ZERO)       \
-  SPARSE_SMSM_BOOL_OP (mx_el_or,  ||, M1, M2, LHS_ZERO, RHS_ZERO)
-
-#define SPARSE_SMSM_BOOL_OPS(M1, M2, ZERO)      \
-  SPARSE_SMSM_BOOL_OPS2(M1, M2, ZERO, ZERO)
+#define SPARSE_SMSM_BOOL_OPS(M1, M2)            \
+  SPARSE_SMSM_BOOL_AND_OP (M1, M2)              \
+  SPARSE_SMSM_BOOL_OR_OP (M1, M2)
 
 // matrix by sparse matrix operations.
 
@@ -1124,7 +1185,7 @@
   SPARSE_MSM_CMP_OP (mx_el_eq, ==, M1,   , M2,   )      \
   SPARSE_MSM_CMP_OP (mx_el_ne, !=, M1,   , M2,   )
 
-#define SPARSE_MSM_BOOL_OP(F, OP, M1, M2, LHS_ZERO, RHS_ZERO)           \
+#define SPARSE_MSM_BOOL_OP(F, OP, M1, M2)                               \
   SparseBoolMatrix                                                      \
   F (const M1& m1, const M2& m2)                                        \
   {                                                                     \
@@ -1136,6 +1197,9 @@
     octave_idx_type m2_nr = m2.rows ();                                 \
     octave_idx_type m2_nc = m2.cols ();                                 \
                                                                         \
+    M1::element_type lhs_zero = M1::element_type ();                    \
+    M2::element_type rhs_zero = M2::element_type ();                    \
+                                                                        \
     if (m2_nr == 1 && m2_nc == 1)                                       \
       r = SparseBoolMatrix (F (m1, m2.elem (0,0)));                     \
     else if (m1_nr == m2_nr && m1_nc == m2_nc)                          \
@@ -1146,8 +1210,8 @@
             octave_idx_type nel = 0;                                    \
             for (octave_idx_type j = 0; j < m1_nc; j++)                 \
               for (octave_idx_type i = 0; i < m1_nr; i++)               \
-                if ((m1.elem (i, j) != LHS_ZERO)                        \
-                    OP (m2.elem (i, j) != RHS_ZERO))                    \
+                if ((m1.elem (i, j) != lhs_zero)                        \
+                    OP (m2.elem (i, j) != rhs_zero))                    \
                   nel++;                                                \
                                                                         \
             r = SparseBoolMatrix (m1_nr, m1_nc, nel);                   \
@@ -1158,8 +1222,8 @@
               {                                                         \
                 for (octave_idx_type i = 0; i < m1_nr; i++)             \
                   {                                                     \
-                    bool el = (m1.elem (i, j) != LHS_ZERO)              \
-                      OP (m2.elem (i, j) != RHS_ZERO);                  \
+                    bool el = (m1.elem (i, j) != lhs_zero)              \
+                      OP (m2.elem (i, j) != rhs_zero);                  \
                     if (el)                                             \
                       {                                                 \
                         r.data (ii) = el;                               \
@@ -1178,12 +1242,9 @@
     return r;                                                           \
   }
 
-#define SPARSE_MSM_BOOL_OPS2(M1, M2, LHS_ZERO, RHS_ZERO)                \
-  SPARSE_MSM_BOOL_OP (mx_el_and, &&, M1, M2, LHS_ZERO, RHS_ZERO)        \
-  SPARSE_MSM_BOOL_OP (mx_el_or,  ||, M1, M2, LHS_ZERO, RHS_ZERO)
-
-#define SPARSE_MSM_BOOL_OPS(M1, M2, ZERO)       \
-  SPARSE_MSM_BOOL_OPS2(M1, M2, ZERO, ZERO)
+#define SPARSE_MSM_BOOL_OPS(M1, M2)             \
+  SPARSE_MSM_BOOL_OP (mx_el_and, &&, M1, M2)    \
+  SPARSE_MSM_BOOL_OP (mx_el_or,  ||, M1, M2)
 
 // sparse matrix by matrix operations.
 
@@ -1337,7 +1398,7 @@
   SPARSE_SMM_CMP_OP (mx_el_eq, ==, M1,   , M2,   )      \
   SPARSE_SMM_CMP_OP (mx_el_ne, !=, M1,   , M2,   )
 
-#define SPARSE_SMM_BOOL_OP(F, OP, M1, M2, LHS_ZERO, RHS_ZERO)           \
+#define SPARSE_SMM_BOOL_OP(F, OP, M1, M2)                               \
   SparseBoolMatrix                                                      \
   F (const M1& m1, const M2& m2)                                        \
   {                                                                     \
@@ -1349,6 +1410,9 @@
     octave_idx_type m2_nr = m2.rows ();                                 \
     octave_idx_type m2_nc = m2.cols ();                                 \
                                                                         \
+    M1::element_type lhs_zero = M1::element_type ();                    \
+    M2::element_type rhs_zero = M2::element_type ();                    \
+                                                                        \
     if (m1_nr == 1 && m1_nc == 1)                                       \
       r = SparseBoolMatrix (F (m1.elem (0,0), m2));                     \
     else if (m1_nr == m2_nr && m1_nc == m2_nc)                          \
@@ -1359,8 +1423,8 @@
             octave_idx_type nel = 0;                                    \
             for (octave_idx_type j = 0; j < m1_nc; j++)                 \
               for (octave_idx_type i = 0; i < m1_nr; i++)               \
-                if ((m1.elem (i, j) != LHS_ZERO)                        \
-                    OP (m2.elem (i, j) != RHS_ZERO))                    \
+                if ((m1.elem (i, j) != lhs_zero)                        \
+                    OP (m2.elem (i, j) != rhs_zero))                    \
                   nel++;                                                \
                                                                         \
             r = SparseBoolMatrix (m1_nr, m1_nc, nel);                   \
@@ -1371,8 +1435,8 @@
               {                                                         \
                 for (octave_idx_type i = 0; i < m1_nr; i++)             \
                   {                                                     \
-                    bool el = (m1.elem (i, j) != LHS_ZERO)              \
-                      OP (m2.elem (i, j) != RHS_ZERO);                  \
+                    bool el = (m1.elem (i, j) != lhs_zero)              \
+                      OP (m2.elem (i, j) != rhs_zero);                  \
                     if (el)                                             \
                       {                                                 \
                         r.data (ii) = el;                               \
@@ -1391,12 +1455,9 @@
     return r;                                                           \
   }
 
-#define SPARSE_SMM_BOOL_OPS2(M1, M2, LHS_ZERO, RHS_ZERO)                \
-  SPARSE_SMM_BOOL_OP (mx_el_and, &&, M1, M2, LHS_ZERO, RHS_ZERO)        \
-  SPARSE_SMM_BOOL_OP (mx_el_or,  ||, M1, M2, LHS_ZERO, RHS_ZERO)
-
-#define SPARSE_SMM_BOOL_OPS(M1, M2, ZERO)       \
-  SPARSE_SMM_BOOL_OPS2(M1, M2, ZERO, ZERO)
+#define SPARSE_SMM_BOOL_OPS(M1, M2)             \
+  SPARSE_SMM_BOOL_OP (mx_el_and, &&, M1, M2)    \
+  SPARSE_SMM_BOOL_OP (mx_el_or,  ||, M1, M2)
 
 // Avoid some code duplication.  Maybe we should use templates.
 
--- a/liboctave/operators/mk-ops.awk	Tue Nov 01 11:57:27 2016 -0400
+++ b/liboctave/operators/mk-ops.awk	Wed Nov 02 23:12:22 2016 -0400
@@ -180,9 +180,6 @@
           lhs_core_type = core_type[lhs_num];
           rhs_core_type = core_type[rhs_num];
 
-          result_scalar_zero_val_1 = scalar_zero_val[result_num_1];
-          if (sparse)
-            result_scalar_zero_val_2 = scalar_zero_val[result_num_2];
           lhs_scalar_zero_val = scalar_zero_val[lhs_num];
           rhs_scalar_zero_val = scalar_zero_val[rhs_num];
 
@@ -392,8 +389,7 @@
 
               if (bin_ops)
                 emit_bin_ops(sparse, lhs_class, rhs_class,
-                             result_type_1, result_type_2,
-                             lhs_type, rhs_type, result_scalar_zero_val_1);
+                             result_type_1, result_type_2, lhs_type, rhs_type);
 
               if (cmp_ops)
                 emit_cmp_ops(sparse, lhs_class, rhs_class,
@@ -407,8 +403,7 @@
 
               if (bool_ops)
                 emit_bool_ops(sparse, lhs_class, rhs_class,
-                              lhs_type, rhs_type,
-                              lhs_scalar_zero_val, rhs_scalar_zero_val);
+                              lhs_type, rhs_type);
 
               exit (0);
             }
@@ -619,11 +614,10 @@
 }
 
 function emit_dm_bin_ops (lhs_class, rhs_class, result_type_1,
-                          lhs_type, rhs_type, result_scalar_zero_val_1)
+                          lhs_type, rhs_type)
 {
-  printf ("%s%s_BIN_OPS (%s, %s, %s, %s)\n",
-          lhs_class, rhs_class, result_type_1,
-          lhs_type, rhs_type, result_scalar_zero_val_1);
+  printf ("%s%s_BIN_OPS (%s, %s, %s)\n",
+          lhs_class, rhs_class, result_type_1, lhs_type, rhs_type);
 }
 
 function emit_mm_bin_op (result_t, op, lhs_t, rhs_t, fcn)
@@ -647,8 +641,7 @@
 }
 
 function emit_bin_ops (sparse, lhs_class, rhs_class,
-                       result_type_1, result_type_2,
-                       lhs_type, rhs_type, result_scalar_zero_val_1)
+                       result_type_1, result_type_2, lhs_type, rhs_type)
 {
   if (sparse)
     emit_sparse_bin_ops(lhs_class, rhs_class, result_type_1,
@@ -656,7 +649,7 @@
  else if ((lhs_class == "DM" && rhs_class == "M") \
           || (lhs_class == "M" && rhs_class == "DM"))
     emit_dm_bin_ops(lhs_class, rhs_class, result_type_1,
-                    lhs_type, rhs_type, result_scalar_zero_val_1);
+                    lhs_type, rhs_type);
   else if (lhs_class == "M" && rhs_class == "M")
     emit_mm_bin_ops(result_type_1, lhs_type, rhs_type);
   else
@@ -691,13 +684,11 @@
   ## No separate eqne ops for full-matrix or vector.
 }
 
-function emit_bool_ops (sparse, lhs_class, rhs_class, lhs_type, rhs_type,
-                        lhs_scalar_zero_val, rhs_scalar_zero_val)
+function emit_bool_ops (sparse, lhs_class, rhs_class, lhs_type, rhs_type)
 {
   if (sparse)
-    printf ("SPARSE_%s%s_BOOL_OPS2 (%s, %s, %s, %s)\n",
-            lhs_class, rhs_class, lhs_type, rhs_type,
-            lhs_scalar_zero_val, rhs_scalar_zero_val);
+    printf ("SPARSE_%s%s_BOOL_OPS (%s, %s)\n",
+            lhs_class, rhs_class, lhs_type, rhs_type);
   else
     printf ("%s%s_BOOL_OPS (%s, %s)\n",
             lhs_class, rhs_class, lhs_type, rhs_type);
--- a/liboctave/operators/mx-op-defs.h	Tue Nov 01 11:57:27 2016 -0400
+++ b/liboctave/operators/mx-op-defs.h	Wed Nov 02 23:12:22 2016 -0400
@@ -421,12 +421,14 @@
     return r;                                                   \
   }
 
-#define MDM_MULTIPLY_OP(R, M, DM, R_ZERO)                               \
+#define MDM_MULTIPLY_OP(R, M, DM)                                       \
   R                                                                     \
   operator * (const M& m, const DM& dm)                                 \
   {                                                                     \
     R r;                                                                \
                                                                         \
+    R::element_type r_zero = R::element_type ();                        \
+                                                                        \
     octave_idx_type m_nr = m.rows ();                                   \
     octave_idx_type m_nc = m.cols ();                                   \
                                                                         \
@@ -447,15 +449,15 @@
         mx_inline_mul (m_nr, rd, md, dd[i]);                            \
         rd += m_nr; md += m_nr;                                         \
       }                                                                 \
-    mx_inline_fill (m_nr * (dm_nc - len), rd, R_ZERO);                  \
+    mx_inline_fill (m_nr * (dm_nc - len), rd, r_zero);                  \
                                                                         \
     return r;                                                           \
   }
 
-#define MDM_BIN_OPS(R, M, DM, R_ZERO)           \
+#define MDM_BIN_OPS(R, M, DM)                   \
   MDM_BIN_OP (R, operator +, M, DM, +=)         \
   MDM_BIN_OP (R, operator -, M, DM, -=)         \
-  MDM_MULTIPLY_OP (R, M, DM, R_ZERO)
+  MDM_MULTIPLY_OP (R, M, DM)
 
 // diagonal matrix by matrix operations.
 
@@ -491,12 +493,14 @@
     return r;                                                   \
   }
 
-#define DMM_MULTIPLY_OP(R, DM, M, R_ZERO)                               \
+#define DMM_MULTIPLY_OP(R, DM, M)                                       \
   R                                                                     \
   operator * (const DM& dm, const M& m)                                 \
   {                                                                     \
     R r;                                                                \
                                                                         \
+    R::element_type r_zero = R::element_type ();                        \
+                                                                        \
     octave_idx_type dm_nr = dm.rows ();                                 \
     octave_idx_type dm_nc = dm.cols ();                                 \
                                                                         \
@@ -516,17 +520,17 @@
       {                                                                 \
         mx_inline_mul (len, rd, md, dd);                                \
         rd += len; md += m_nr;                                          \
-        mx_inline_fill (dm_nr - len, rd, R_ZERO);                       \
+        mx_inline_fill (dm_nr - len, rd, r_zero);                       \
         rd += dm_nr - len;                                              \
       }                                                                 \
                                                                         \
     return r;                                                           \
   }
 
-#define DMM_BIN_OPS(R, DM, M, R_ZERO)           \
+#define DMM_BIN_OPS(R, DM, M)                   \
   DMM_BIN_OP (R, operator +, DM, M, +=, )       \
   DMM_BIN_OP (R, operator -, DM, M, +=, -)      \
-  DMM_MULTIPLY_OP (R, DM, M, R_ZERO)
+  DMM_MULTIPLY_OP (R, DM, M)
 
 // diagonal matrix by diagonal matrix operations.