changeset 7269:3fade00a6ac7

[project @ 2007-12-07 19:26:20 by jwe]
author jwe
date Fri, 07 Dec 2007 19:26:21 +0000
parents 47e4ebac1bfa
children 20b3ac39ee40
files liboctave/CSparse.cc liboctave/ChangeLog liboctave/Sparse-op-defs.h liboctave/dSparse.cc scripts/ChangeLog scripts/plot/__go_draw_axes__.m scripts/plot/__go_draw_figure__.m scripts/plot/drawnow.m scripts/plot/print.m scripts/plot/ribbon.m src/ChangeLog src/data.cc
diffstat 12 files changed, 396 insertions(+), 304 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/CSparse.cc	Fri Dec 07 17:11:28 2007 +0000
+++ b/liboctave/CSparse.cc	Fri Dec 07 19:26:21 2007 +0000
@@ -7637,7 +7637,13 @@
 SparseComplexMatrix
 SparseComplexMatrix::prod (int dim) const
 {
-  SPARSE_REDUCTION_OP (SparseComplexMatrix, Complex, *=, 1.0, 1.0);
+  if ((rows() == 1 && dim == -1) || dim == 1)
+    return transpose (). prod (0). transpose();
+  else
+    {
+      SPARSE_REDUCTION_OP (SparseComplexMatrix, Complex, *=, 
+			   (cidx(j+1) - cidx(j) < nc ? 0.0 : 1.0), 1.0);
+    }
 }
 
 SparseComplexMatrix
@@ -7650,11 +7656,11 @@
 SparseComplexMatrix::sumsq (int dim) const
 {
 #define ROW_EXPR \
-  Complex d = elem (i, j); \
-  tmp [i] += d * conj (d)
+  Complex d = data (i); \
+  tmp [ridx(i)] += d * conj (d)
 
 #define COL_EXPR \
-  Complex d = elem (i, j); \
+  Complex d = data (i); \
   tmp [j] += d * conj (d)
 
   SPARSE_BASE_REDUCTION_OP (SparseComplexMatrix, Complex, ROW_EXPR, 
--- a/liboctave/ChangeLog	Fri Dec 07 17:11:28 2007 +0000
+++ b/liboctave/ChangeLog	Fri Dec 07 19:26:21 2007 +0000
@@ -1,3 +1,23 @@
+2007-12-07  David Bateman  <dbateman@free.fr>
+
+	* Sparse-op-defs.h (SPARSE_SMS_CMP_OP, SPARSE_SMS_BOOL_OP,
+	SPARSE_SSM_CMP_OP, SPARSE_SSM_BOOL_OP, SPARSE_SMSM_CMP_OP, 
+	SPARSE_SMSM_BOOL_OP, SPARSE_BASE_REDUCTION_OP): Use sparse
+	indexing where possible rather than the elem method.
+	(SPARSE_REDUCTION_OP_ROW_EXPR, SPARSE_REDUCTION_OP_COL_EXPR,
+	SPARSE_ANY_ALL_OP_ROW_CODE, SPARSE_ANY_ALL_OP_COL_CODE):
+	Replace for new version of SPARSE_BASE_REDUCTION_OP.
+	(SPARSE_ALL_OP): Specialize the initial value, and only treat dim
+	= 0 directly.
+	* CSparse.cc (SparseComplexMatrix SparseComplexMatrix::sumsq (int)
+	const): Replace ROW_EXPR and COL_EXPR functions for new version of
+	SPARSE_BASE_REDUCTION_OP.
+	(SparseComplexMatrix SparseComplexMatrix::prod (int) const):
+	Specialize the initial value, and only treat dim = 0 directly.
+	* dSparse.cc (SparseMatrix SparseMatrix::sumsq (int) const):
+	ditto.
+	(SparseMatrix SparseMatrix::prod (int) const): ditto.
+
 2007-12-06  John W. Eaton  <jwe@octave.org>
 
 	* CMatrix.cc (ComplexMatrix::expm): Update pointers to internal
--- a/liboctave/Sparse-op-defs.h	Fri Dec 07 17:11:28 2007 +0000
+++ b/liboctave/Sparse-op-defs.h	Fri Dec 07 19:26:21 2007 +0000
@@ -103,58 +103,36 @@
   SparseBoolMatrix \
   F (const M& m, const S& s) \
   { \
-    /* Count num of non-zero elements */ \
-    octave_idx_type nel = 0; \
-    octave_idx_type nz = m.nnz (); \
-    if (MC (MZ) OP SC (s))   \
-      nel += m.numel() - nz; \
-    for (octave_idx_type i = 0; i < nz; i++) \
-      if (MC (m.data (i)) OP SC (s)) \
-        nel++;	\
-    \
     octave_idx_type nr = m.rows (); \
     octave_idx_type nc = m.cols (); \
-    SparseBoolMatrix r (nr, nc, nel); \
+    SparseBoolMatrix r; \
     \
-    if (nr > 0 && nc > 0) \
+    if (MC (MZ) OP SC (s)) \
+      { \
+        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 (! (MC (m.data (i)) OP SC (s))) \
+              r.data (m.ridx (i) + j * nr) = false; \
+        r.maybe_compress (true); \
+      } \
+    else \
       { \
-	if (MC (MZ) OP SC (s))	\
-	  { \
-	    octave_idx_type ii = 0; \
-	    r.cidx (0) = 0; \
-	    for (octave_idx_type j = 0; j < nc; j++) \
-	      { \
-		for (octave_idx_type i = 0; i < nr; i++) \
-		  { \
-		    bool el =  MC (m.elem(i, j)) OP SC (s); \
-		    if (el) \
-		      { \
-			r.data(ii) = el; \
-			r.ridx(ii++) = i; \
-		      } \
-		  } \
-		r.cidx(j+1) = ii; \
-	      } \
-	  } \
-	else \
-	  { \
-	    octave_idx_type ii = 0; \
-	    r.cidx (0) = 0; \
-	    for (octave_idx_type j = 0; j < nc; j++) \
-	      { \
-		for (octave_idx_type i = m.cidx(j); i < m.cidx(j+1); i++) \
-		  { \
-		    bool el =  MC (m.data(i)) OP SC (s); \
-		    if (el) \
-		      { \
-			r.data(ii) = el; \
-			r.ridx(ii++) = m.ridx(i); \
-		      } \
-		  } \
-		r.cidx(j+1) = ii; \
-	      } \
-	  } \
-      }	\
+        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 (MC (m.data (i)) OP SC (s)) \
+                { \
+                  r.ridx (nel) = m.ridx (i); \
+                  r.data (nel++) = true; \
+                } \
+            r.cidx (j + 1) = nel; \
+          } \
+        r.maybe_compress (false); \
+      } \
     return r; \
   }
 
@@ -178,57 +156,38 @@
   SparseBoolMatrix \
   F (const M& m, const S& s) \
   { \
-    /* Count num of non-zero elements */ \
-    octave_idx_type nel = 0; \
-    octave_idx_type nz = m.nnz (); \
-    if (LHS_ZERO OP (s != RHS_ZERO)) \
-      nel += m.numel() - nz; \
-    for (octave_idx_type i = 0; i < nz; i++) \
-      if ((m.data(i) != LHS_ZERO) OP (s != RHS_ZERO))\
-        nel++;	\
-    \
     octave_idx_type nr = m.rows (); \
     octave_idx_type nc = m.cols (); \
-    SparseBoolMatrix r (nr, nc, nel); \
+    SparseBoolMatrix r; \
     \
     if (nr > 0 && nc > 0) \
       { \
 	if (LHS_ZERO OP (s != RHS_ZERO)) \
 	  { \
-	    octave_idx_type ii = 0; \
-	    r.cidx (0) = 0; \
+            r = SparseBoolMatrix (nr, nc, true); \
 	    for (octave_idx_type j = 0; j < nc; j++) \
-	      { \
-		for (octave_idx_type i = 0; i < nr; i++) \
-		  { \
-		    bool el = (m.elem(i, j) != LHS_ZERO) OP (s != RHS_ZERO); \
-		    if (el) \
-		      { \
-			r.data(ii) = el; \
-			r.ridx(ii++) = i; \
-		      } \
-		  } \
-		r.cidx(j+1) = ii; \
-	      } \
-	  } \
+	      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); \
+          } \
 	else \
 	  { \
-	    octave_idx_type ii = 0; \
-	    r.cidx (0) = 0; \
+            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++) \
-		  { \
-		    bool el = (m.data(i) != LHS_ZERO) OP (s != RHS_ZERO); \
-		    if (el) \
-		      { \
-			r.data(ii) = el; \
-			r.ridx(ii++) = m.ridx(i); \
-		      } \
-		  } \
-		r.cidx(j+1) = ii; \
-	      } \
-	  } \
+              { \
+	        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.ridx (nel) = m.ridx (i); \
+                      r.data (nel++) = true; \
+                    } \
+                r.cidx (j + 1) = nel; \
+              } \
+            r.maybe_compress (false); \
+          } \
       }	\
     return r; \
   }
@@ -313,58 +272,36 @@
   SparseBoolMatrix \
   F (const S& s, const M& m) \
   { \
-    /* Count num of non-zero elements */ \
-    octave_idx_type nel = 0; \
-    octave_idx_type nz = m.nnz (); \
-    if (SC (s) OP MC (MZ))   \
-      nel += m.numel() - nz; \
-    for (octave_idx_type i = 0; i < nz; i++) \
-      if (SC (s) OP MC (m.data (i))) \
-        nel++;	\
-    \
     octave_idx_type nr = m.rows (); \
     octave_idx_type nc = m.cols (); \
-    SparseBoolMatrix r (nr, nc, nel); \
+    SparseBoolMatrix r; \
     \
-    if (nr > 0 && nc > 0) \
+    if (SC (s) OP SC (MZ)) \
+      { \
+        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 (! (SC (s) OP MC (m.data (i)))) \
+              r.data (m.ridx (i) + j * nr) = false; \
+        r.maybe_compress (true); \
+      } \
+    else \
       { \
-	if (SC (s) OP MC (MZ))\
-	  { \
-	    octave_idx_type ii = 0; \
-	    r.cidx (0) = 0; \
-	    for (octave_idx_type j = 0; j < nc; j++) \
-	      { \
-		for (octave_idx_type i = 0; i < nr; i++) \
-		  { \
-		    bool el = SC (s) OP MC (m.elem(i, j)); \
-		    if (el) \
-		      { \
-			r.data(ii) = el; \
-			r.ridx(ii++) = i; \
-		      } \
-		  } \
-		r.cidx(j+1) = ii; \
-	      } \
-	  } \
-	else \
-	  { \
-	    octave_idx_type ii = 0; \
-	    r.cidx (0) = 0; \
-	    for (octave_idx_type j = 0; j < nc; j++) \
-	      { \
-		for (octave_idx_type i = m.cidx(j); i < m.cidx(j+1); i++) \
-		  { \
-		    bool el =  SC (s) OP MC (m.data(i)); \
-		    if (el) \
-		      { \
-			r.data(ii) = el; \
-			r.ridx(ii++) = m.ridx(i); \
-		      } \
-		  } \
-		r.cidx(j+1) = ii; \
-	      } \
-	  } \
-      }	\
+        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 (SC (s) OP MC (m.data (i))) \
+                { \
+                  r.ridx (nel) = m.ridx (i); \
+                  r.data (nel++) = true; \
+                } \
+            r.cidx (j + 1) = nel; \
+          } \
+        r.maybe_compress (false); \
+      } \
     return r; \
   }
 
@@ -388,57 +325,38 @@
   SparseBoolMatrix \
   F (const S& s, const M& m) \
   { \
-    /* Count num of non-zero elements */ \
-    octave_idx_type nel = 0; \
-    octave_idx_type nz = m.nnz (); \
-    if ((s != LHS_ZERO) OP  RHS_ZERO) \
-      nel += m.numel() - nz; \
-    for (octave_idx_type i = 0; i < nz; i++) \
-      if ((s != LHS_ZERO) OP m.data(i) != RHS_ZERO) \
-        nel++;	\
-    \
     octave_idx_type nr = m.rows (); \
     octave_idx_type nc = m.cols (); \
-    SparseBoolMatrix r (nr, nc, nel); \
+    SparseBoolMatrix r; \
     \
     if (nr > 0 && nc > 0) \
       { \
 	if ((s != LHS_ZERO) OP RHS_ZERO) \
 	  { \
-	    octave_idx_type ii = 0; \
-	    r.cidx (0) = 0; \
+            r = SparseBoolMatrix (nr, nc, true); \
 	    for (octave_idx_type j = 0; j < nc; j++) \
-	      { \
-		for (octave_idx_type i = 0; i < nr; i++) \
-		  { \
-		    bool el = (s != LHS_ZERO) OP (m.elem(i, j) != RHS_ZERO); \
-		    if (el) \
-		      { \
-			r.data(ii) = el; \
-			r.ridx(ii++) = i; \
-		      } \
-		  } \
-		r.cidx(j+1) = ii; \
-	      } \
-	  } \
+	      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); \
+          } \
 	else \
 	  { \
-	    octave_idx_type ii = 0; \
-	    r.cidx (0) = 0; \
+            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++) \
-		  { \
-		    bool el = (s != LHS_ZERO) OP (m.data(i) != RHS_ZERO); \
-		    if (el) \
-		      { \
-			r.data(ii) = el; \
-			r.ridx(ii++) = m.ridx(i); \
-		      } \
-		  } \
-		r.cidx(j+1) = ii; \
-	      } \
-	  } \
+              { \
+	        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.ridx (nel) = m.ridx (i); \
+                      r.data (nel++) = true; \
+                    } \
+                r.cidx (j + 1) = nel; \
+              } \
+            r.maybe_compress (false); \
+          } \
       }	\
     return r; \
   }
@@ -816,7 +734,7 @@
   SPARSE_CMP_OP_DECL (mx_el_eq, M1, M2, API); \
   SPARSE_CMP_OP_DECL (mx_el_ne, M1, M2, API);
 
-#define SPARSE_SMSM_CMP_OP(F, OP, M1, C1, M2, C2)	\
+#define SPARSE_SMSM_CMP_OP(F, OP, M1, Z1, C1, M2, Z2, C2)	\
   SparseBoolMatrix \
   F (const M1& m1, const M2& m2) \
   { \
@@ -844,30 +762,86 @@
       { \
 	if (m1_nr != 0 || m1_nc != 0) \
 	  { \
-	    /* Count num of non-zero elements */ \
-	    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 (C1 (m1.elem(i, j)) OP C2 (m2.elem(i, j))) \
-		  nel++; \
-            \
-            r = SparseBoolMatrix (m1_nr, m1_nc, nel); \
-            \
-	    octave_idx_type ii = 0; \
-	    r.cidx (0) = 0; \
-	    for (octave_idx_type j = 0; j < m1_nc; j++) \
+            if (C1 (Z1) OP C2 (Z2)) \
 	      { \
-	        for (octave_idx_type i = 0; i < m1_nr; i++) \
-		  { \
-		    bool el = C1 (m1.elem(i, j)) OP C2 (m2.elem(i, j)); \
-		    if (el) \
-		      { \
-			r.data(ii) = el; \
-			r.ridx(ii++) = i; \
-		      } \
-		  } \
-		r.cidx(j+1) = ii; \
-	      } \
+                r = SparseBoolMatrix (m1_nr, m1_nc, true); \
+	        for (octave_idx_type j = 0; j < m1_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) \
+                       { \
+                         if (i1 == e1 || (i2 < e2 && m1.ridx(i1) > m2.ridx(i2))) \
+                           { \
+                             if (! (C1 (Z1) OP C2 (m2.data (i2)))) \
+                               r.data (m2.ridx (i2) + j * m1_nr) = false; \
+                             i2++; \
+                           } \
+                         else if (i2 == e2 || m1.ridx(i1) < m2.ridx(i2)) \
+                           { \
+                             if (! (C1 (m1.data (i1)) OP C2 (Z2))) \
+                               r.data (m1.ridx (i1) + j * m1_nr) = false; \
+                             i1++; \
+                           } \
+                         else \
+                           { \
+                             if (! (C1 (m1.data (i1)) OP C2 (m2.data (i2)))) \
+                               r.data (m1.ridx (i1) + j * m1_nr) = false; \
+                             i1++; \
+                             i2++; \
+                           } \
+                       } \
+                  } \
+                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++) \
+                  { \
+                     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) \
+                       { \
+                         if (i1 == e1 || (i2 < e2 && m1.ridx(i1) > m2.ridx(i2))) \
+                           { \
+                             if (C1 (Z1) OP C2 (m2.data (i2))) \
+                               { \
+                                 r.ridx (nel) = m2.ridx (i2); \
+                                 r.data (nel++) = true; \
+                               } \
+                             i2++; \
+                           } \
+                         else if (i2 == e2 || m1.ridx(i1) < m2.ridx(i2)) \
+                           { \
+                             if (C1 (m1.data (i1)) OP C2 (Z2)) \
+                               { \
+                                 r.ridx (nel) = m1.ridx (i1); \
+                                 r.data (nel++) = true; \
+                               } \
+                             i1++; \
+                           } \
+                         else \
+                           { \
+                             if (C1 (m1.data (i1)) OP C2 (m2.data (i2))) \
+                               { \
+                                 r.ridx (nel) = m1.ridx (i1); \
+                                 r.data (nel++) = true; \
+                               } \
+                             i1++; \
+                             i2++; \
+                           } \
+                       } \
+                     r.cidx (j + 1) = nel; \
+                  } \
+                r.maybe_compress (false); \
+              } \
 	  } \
       }	      \
     else \
@@ -879,16 +853,16 @@
   }
 
 #define SPARSE_SMSM_CMP_OPS(M1, Z1, C1, M2, Z2, C2)  \
-  SPARSE_SMSM_CMP_OP (mx_el_lt, <,  M1, C1, M2, C2) \
-  SPARSE_SMSM_CMP_OP (mx_el_le, <=, M1, C1, M2, C2) \
-  SPARSE_SMSM_CMP_OP (mx_el_ge, >=, M1, C1, M2, C2) \
-  SPARSE_SMSM_CMP_OP (mx_el_gt, >,  M1, C1, M2, C2) \
-  SPARSE_SMSM_CMP_OP (mx_el_eq, ==, M1,   , M2,   ) \
-  SPARSE_SMSM_CMP_OP (mx_el_ne, !=, M1,   , M2,   )
+  SPARSE_SMSM_CMP_OP (mx_el_lt, <,  M1, Z1, C1, M2, Z2, C2) \
+  SPARSE_SMSM_CMP_OP (mx_el_le, <=, M1, Z1, C1, M2, Z2, C2) \
+  SPARSE_SMSM_CMP_OP (mx_el_ge, >=, M1, Z1, C1, M2, Z2, C2) \
+  SPARSE_SMSM_CMP_OP (mx_el_gt, >,  M1, Z1, C1, M2, Z2, C2) \
+  SPARSE_SMSM_CMP_OP (mx_el_eq, ==, M1, Z1,   , M2, Z2,   ) \
+  SPARSE_SMSM_CMP_OP (mx_el_ne, !=, M1, Z1,   , M2, Z2,   )
 
 #define SPARSE_SMSM_EQNE_OPS(M1, Z1, C1, M2, Z2, C2)  \
-  SPARSE_SMSM_CMP_OP (mx_el_eq, ==, M1,   , M2,   ) \
-  SPARSE_SMSM_CMP_OP (mx_el_ne, !=, M1,   , M2,   )
+  SPARSE_SMSM_CMP_OP (mx_el_eq, ==, M1, Z1,   , M2, Z2,   ) \
+  SPARSE_SMSM_CMP_OP (mx_el_ne, !=, M1, Z1,   , M2, Z2,   )
 
 #define SPARSE_SMSM_BOOL_OP_DECLS(M1, M2, API) \
   SPARSE_BOOL_OP_DECL (mx_el_and, M1, M2, API); \
@@ -922,32 +896,49 @@
       { \
 	if (m1_nr != 0 || m1_nc != 0) \
 	  { \
-	    /* Count num of non-zero elements */ \
-	    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)) \
-		  nel++; \
-            \
-            r = SparseBoolMatrix (m1_nr, m1_nc, nel); \
-            \
-	    octave_idx_type ii = 0; \
-	    r.cidx (0) = 0; \
+            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++) \
-	      { \
-	        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);	  \
-		    if (el) \
-		      { \
-			r.data(ii) = el; \
-			r.ridx(ii++) = i; \
-		      } \
-		  } \
-		r.cidx(j+1) = ii; \
-	      } \
+              { \
+                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) \
+                  { \
+                    if (i1 == e1 || (i2 < e2 && m1.ridx(i1) > m2.ridx(i2))) \
+                      { \
+                        if (LHS_ZERO OP m2.data (i2) != RHS_ZERO) \
+                          { \
+                            r.ridx (nel) = m2.ridx (i2); \
+                            r.data (nel++) = true; \
+                          } \
+                        i2++; \
+                      } \
+                    else if (i2 == e2 || m1.ridx(i1) < m2.ridx(i2)) \
+                      { \
+                        if (m1.data (i1) != LHS_ZERO OP RHS_ZERO) \
+                          { \
+                            r.ridx (nel) = m1.ridx (i1); \
+                            r.data (nel++) = true; \
+                          } \
+                        i1++; \
+                      } \
+                    else \
+                      { \
+                        if (m1.data (i1) != LHS_ZERO OP m2.data(i2) != RHS_ZERO) \
+                          { \
+                            r.ridx (nel) = m1.ridx (i1); \
+                            r.data (nel++) = true; \
+                          } \
+                        i1++; \
+                        i2++; \
+                      } \
+                  } \
+                r.cidx (j + 1) = nel; \
+              } \
+            r.maybe_compress (false); \
 	  } \
       }	      \
     else \
@@ -1577,15 +1568,18 @@
     { \
       if ((nr == 1 && dim == -1) || dim == 1) \
 	{ \
+          /* Define j here to allow fancy definition for prod method */ \
+          octave_idx_type j = 0; \
 	  OCTAVE_LOCAL_BUFFER (EL_TYPE, tmp, nr); \
           \
 	  for (octave_idx_type i = 0; i < nr; i++) \
-	    { \
-	      tmp[i] = INIT_VAL; \
-	      for (octave_idx_type j = 0; j < nc; j++) \
-		{ \
-		  ROW_EXPR; \
-		} \
+	    tmp[i] = INIT_VAL; \
+	  for (j = 0; j < nc; j++) \
+            { \
+	      for (octave_idx_type i = cidx(j); i < cidx(j + 1); i++) \
+                { \
+	          ROW_EXPR; \
+                } \
 	    } \
 	  octave_idx_type nel = 0; \
 	  for (octave_idx_type i = 0; i < nr; i++) \
@@ -1609,10 +1603,10 @@
 	  for (octave_idx_type j = 0; j < nc; j++) \
 	    { \
 	      tmp[j] = INIT_VAL; \
-	      for (octave_idx_type i = 0; i < nr; i++) \
-		{ \
+	      for (octave_idx_type i = cidx(j); i < cidx(j + 1); i++) \
+                { \
 		  COL_EXPR; \
-		} \
+                } \
 	    } \
 	  octave_idx_type nel = 0; \
 	  for (octave_idx_type i = 0; i < nc; i++) \
@@ -1689,10 +1683,10 @@
   return retval
 
 #define SPARSE_REDUCTION_OP_ROW_EXPR(OP) \
-  tmp[i] OP elem (i, j)
+  tmp[ridx(i)] OP data (i)
 
 #define SPARSE_REDUCTION_OP_COL_EXPR(OP) \
-  tmp[j] OP elem (i, j)
+  tmp[j] OP data (i)
 
 #define SPARSE_REDUCTION_OP(RET_TYPE, EL_TYPE, OP, INIT_VAL, MT_RESULT)	\
   SPARSE_BASE_REDUCTION_OP (RET_TYPE, EL_TYPE, \
@@ -1701,28 +1695,35 @@
 			INIT_VAL, MT_RESULT)
 
 #define SPARSE_ANY_ALL_OP_ROW_CODE(TEST_OP, TEST_TRUE_VAL) \
-  if (elem (i, j) TEST_OP 0.0) \
+  if (data (i) TEST_OP 0.0) \
     { \
       tmp[i] = TEST_TRUE_VAL; \
       break; \
     }
 
 #define SPARSE_ANY_ALL_OP_COL_CODE(TEST_OP, TEST_TRUE_VAL) \
-  if (elem (i, j) TEST_OP 0.0) \
+  if (data (i) TEST_OP 0.0) \
     { \
       tmp[j] = TEST_TRUE_VAL; \
       break; \
     }
 
-#define SPARSE_ANY_ALL_OP(DIM, INIT_VAL, TEST_OP, TEST_TRUE_VAL) \
+#define SPARSE_ANY_ALL_OP(DIM, INIT_VAL, MT_RESULT, TEST_OP, TEST_TRUE_VAL) \
   SPARSE_BASE_REDUCTION_OP (SparseBoolMatrix, char, \
 			SPARSE_ANY_ALL_OP_ROW_CODE (TEST_OP, TEST_TRUE_VAL), \
 			SPARSE_ANY_ALL_OP_COL_CODE (TEST_OP, TEST_TRUE_VAL), \
-			INIT_VAL, INIT_VAL)
+			INIT_VAL, MT_RESULT)
 
-#define SPARSE_ALL_OP(DIM) SPARSE_ANY_ALL_OP (DIM, true, ==, false)
+#define SPARSE_ALL_OP(DIM) \
+  if ((rows() == 1 && dim == -1) || dim == 1) \
+    return transpose (). all (0). transpose(); \
+  else \
+    { \
+      SPARSE_ANY_ALL_OP (DIM, (cidx(j+1) - cidx(j) < nc ? false : true), \
+			 true, ==, false); \
+    }
 
-#define SPARSE_ANY_OP(DIM) SPARSE_ANY_ALL_OP (DIM, false, !=, true)
+#define SPARSE_ANY_OP(DIM) SPARSE_ANY_ALL_OP (DIM, false, false, !=, true)
 
 #define SPARSE_SPARSE_MUL( RET_TYPE, RET_EL_TYPE, EL_TYPE ) \
   octave_idx_type nr = m.rows (); \
--- a/liboctave/dSparse.cc	Fri Dec 07 17:11:28 2007 +0000
+++ b/liboctave/dSparse.cc	Fri Dec 07 19:26:21 2007 +0000
@@ -7710,7 +7710,13 @@
 SparseMatrix
 SparseMatrix::prod (int dim) const
 {
-  SPARSE_REDUCTION_OP (SparseMatrix, double, *=, 1.0, 1.0);
+  if ((rows() == 1 && dim == -1) || dim == 1)
+    return transpose (). prod (0). transpose();
+  else
+    {
+      SPARSE_REDUCTION_OP (SparseMatrix, double, *=, 
+			   (cidx(j+1) - cidx(j) < nc ? 0.0 : 1.0), 1.0);
+    }
 }
 
 SparseMatrix
@@ -7723,11 +7729,11 @@
 SparseMatrix::sumsq (int dim) const
 {
 #define ROW_EXPR \
-  double d = elem (i, j); \
-  tmp[i] += d * d
+  double d = data (i); \
+  tmp[ridx(i)] += d * d
 
 #define COL_EXPR \
-  double d = elem (i, j); \
+  double d = data (i); \
   tmp[j] += d * d
 
   SPARSE_BASE_REDUCTION_OP (SparseMatrix, double, ROW_EXPR, COL_EXPR, 
--- a/scripts/ChangeLog	Fri Dec 07 17:11:28 2007 +0000
+++ b/scripts/ChangeLog	Fri Dec 07 19:26:21 2007 +0000
@@ -1,5 +1,15 @@
+2007-12-07  David Bateman  <dbateman@free.fr>
+
+	* plot/surf.m: Don't set facecolor property.
+
 2007-12-06  John W. Eaton  <jwe@octave.org>
 
+	* plot/print.m: Pass mono to drawnow.
+	* plot/drawnow.m: New arg, mono.  Pass it to __go_draw_figure__.
+	* plot/__go_draw_figure__.m: New arg, mono.  Pass it to __go_draw_axes.
+	* plot/__go_draw_axes__.m: New arg, mono.  If mono is true,
+	disable color specifications.
+
 	* general/issymmetric.m: Move tests here from test/test_number.m
 
 2007-12-06  Jason Riedy  <ejr@cs.berkeley.edu>
--- a/scripts/plot/__go_draw_axes__.m	Fri Dec 07 17:11:28 2007 +0000
+++ b/scripts/plot/__go_draw_axes__.m	Fri Dec 07 19:26:21 2007 +0000
@@ -20,9 +20,9 @@
 
 ## Author: jwe
 
-function __go_draw_axes__ (h, plot_stream, enhanced)
+function __go_draw_axes__ (h, plot_stream, enhanced, mono)
 
-  if (nargin == 3)
+  if (nargin == 4)
 
     axis_obj = get (h);
 
@@ -87,7 +87,7 @@
     if (! isempty (axis_obj.xlabel))
       t = get (axis_obj.xlabel);
       angle = t.rotation;
-      colorspec = get_text_colorspec (axis_obj.xcolor);
+      colorspec = get_text_colorspec (axis_obj.xcolor, mono);
       if (isempty (t.string))
 	fprintf (plot_stream, "unset xlabel;\n");
 	fprintf (plot_stream, "unset x2label;\n");
@@ -123,7 +123,7 @@
     if (! isempty (axis_obj.ylabel))
       t = get (axis_obj.ylabel);
       angle = t.rotation;
-      colorspec = get_text_colorspec (axis_obj.ycolor);
+      colorspec = get_text_colorspec (axis_obj.ycolor, mono);
       if (isempty (t.string))
 	fprintf (plot_stream, "unset ylabel;\n");
 	fprintf (plot_stream, "unset y2label;\n");
@@ -157,7 +157,7 @@
     if (! isempty (axis_obj.zlabel))
       t = get (axis_obj.zlabel);
       angle = t.rotation;
-      colorspec = get_text_colorspec (axis_obj.zcolor);
+      colorspec = get_text_colorspec (axis_obj.zcolor, mono);
       if (isempty (t.string))
 	fputs (plot_stream, "unset zlabel;\n");
       else
@@ -233,7 +233,7 @@
       fputs (plot_stream, "set grid nomztics;\n");
     endif
 
-    do_tics (axis_obj, plot_stream, ymirror);
+    do_tics (axis_obj, plot_stream, ymirror, mono);
 
     xlogscale = strcmpi (axis_obj.xscale, "log");
     if (xlogscale)
@@ -360,7 +360,8 @@
 	    tmp = undo_string_escapes (__maybe_munge_text__ (enhanced, obj, "keylabel", have_newer_gnuplot));
 	    titlespec{data_idx} = strcat ("title \"", tmp, "\"");
 	  endif
-	  [style, typ, with] = do_linestyle_command (obj, data_idx, plot_stream);
+	  [style, typ, with] = do_linestyle_command (obj, data_idx,
+						     mono, plot_stream);
 	  usingclause{data_idx} = "";
 	  if (have_newer_gnuplot || isnan (typ))
 	    withclause{data_idx} = sprintf ("with %s linestyle %d",
@@ -551,9 +552,14 @@
                endif
 
 	       if (have_newer_gnuplot)
-		 withclause{data_idx} ...
-		     = sprintf ("with filledcurve lc rgb \"#%02x%02x%02x\"",
-				round (255*color));
+		 if (mono)
+		   colorspec = "";
+		 else
+		   colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"",
+					round (255*color));
+		 endif
+		 withclause{data_idx} = sprintf ("with filledcurve %s",
+						 colorspec);
 	       else
 		 if (isequal (color, [0,0,0]))
 		   typ = -1;
@@ -730,9 +736,14 @@
 	     endif
 
 	     if (have_newer_gnuplot)
-	       withclause{data_idx} ...
-		   = sprintf ("with %s %s %s lc rgb \"#%02x%02x%02x\"",
-			      style, pt, ps, round (255*color));
+	       if (mono)
+		 colorspec = "";
+	       else
+		 colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"",
+				      round (255*color));
+	       endif
+	       withclause{data_idx} = sprintf ("with %s %s %s %s",
+					       style, pt, ps, colorspec);
 	     else
 	       if (isequal (color, [0,0,0]))
 		 typ = -1;
@@ -785,7 +796,7 @@
 	    parametric(data_idx) = false;
 	    have_cdata(data_idx) = true;
 	    [style, typ, with] = do_linestyle_command (obj, data_idx,
-						       plot_stream);
+						       mono, plot_stream);
 	    if (isempty (obj.keylabel))
 	      titlespec{data_idx} = "title \"\"";
 	    else
@@ -899,9 +910,15 @@
 			 data_idx, interp_str, dord);
 
 		if (have_newer_gnuplot)
+		  if (mono)
+		    colorspec = "";
+		  else
+		    colorspec = sprintf ("linecolor rgb \"#%02x%02x%02x\"",
+					 round (255*edgecol));
+		  endif
                   fprintf (plot_stream,
-                           "set style line %d linecolor rgb \"#%02x%02x%02x\" lw %f;\n",
-                           data_idx, round (255*edgecol), obj.linewidth);
+                           "set style line %d %s lw %f;\n",
+                           data_idx, colorspec, obj.linewidth);
 		else
 		  if (isequal (edgecol, [0,0,0]))
 		    typ = -1;
@@ -950,7 +967,7 @@
           endif
 	  
 	  if (isnumeric (color))
-	    colorspec = get_text_colorspec (color);
+	    colorspec = get_text_colorspec (color, mono);
 	  endif
 
 	  if (nd == 3)
@@ -1182,7 +1199,7 @@
 
 endfunction
 
-function [style, typ, with] = do_linestyle_command (obj, idx, plot_stream)
+function [style, typ, with] = do_linestyle_command (obj, idx, mono, plot_stream)
 
   persistent have_newer_gnuplot ...
     = compare_versions (__gnuplot_version__ (), "4.0", ">");
@@ -1200,8 +1217,10 @@
     color = obj.color;
     if (isnumeric (color))
       if (have_newer_gnuplot)
-	fprintf (plot_stream, " linecolor rgb \"#%02x%02x%02x\"",
-		 round (255*color));
+	if (! mono)
+	  fprintf (plot_stream, " linecolor rgb \"#%02x%02x%02x\"",
+		   round (255*color));
+	endif
       else
 	if (isequal (color, [0,0,0]))
 	  typ = -1;
@@ -1398,35 +1417,36 @@
 
 endfunction
 
-function do_tics (obj, plot_stream, ymirror)
+function do_tics (obj, plot_stream, ymirror, mono)
   if (strcmpi (obj.xaxislocation, "top"))
     do_tics_1 (obj.xtickmode, obj.xtick, obj.xticklabelmode, obj.xticklabel,
-	       obj.xcolor, "x2", plot_stream, true);
+	       obj.xcolor, "x2", plot_stream, true, mono);
     do_tics_1 ("manual", [], obj.xticklabelmode, obj.xticklabel,
-	       obj.xcolor, "x", plot_stream, true);
+	       obj.xcolor, "x", plot_stream, true, mono);
   else
     do_tics_1 (obj.xtickmode, obj.xtick, obj.xticklabelmode, obj.xticklabel,
-	       obj.xcolor, "x", plot_stream, true);
+	       obj.xcolor, "x", plot_stream, true, mono);
     do_tics_1 ("manual", [], obj.xticklabelmode, obj.xticklabel,
-	       obj.xcolor, "x2", plot_stream, true);
+	       obj.xcolor, "x2", plot_stream, true, mono);
   endif
   if (strcmpi (obj.yaxislocation, "right"))
     do_tics_1 (obj.ytickmode, obj.ytick, obj.yticklabelmode, obj.yticklabel,
-	       obj.ycolor, "y2", plot_stream, ymirror);
+	       obj.ycolor, "y2", plot_stream, ymirror, mono);
     do_tics_1 ("manual", [], obj.yticklabelmode, obj.yticklabel,
-	       obj.ycolor, "y", plot_stream, ymirror);
+	       obj.ycolor, "y", plot_stream, ymirror, mono);
   else
     do_tics_1 (obj.ytickmode, obj.ytick, obj.yticklabelmode, obj.yticklabel,
-	       obj.ycolor, "y", plot_stream, ymirror);
+	       obj.ycolor, "y", plot_stream, ymirror, mono);
     do_tics_1 ("manual", [], obj.yticklabelmode, obj.yticklabel,
-	       obj.ycolor, "y2", plot_stream, ymirror);
+	       obj.ycolor, "y2", plot_stream, ymirror, mono);
   endif
   do_tics_1 (obj.ztickmode, obj.ztick, obj.zticklabelmode, obj.zticklabel,
-	     obj.zcolor, "z", plot_stream, true);
+	     obj.zcolor, "z", plot_stream, true, mono);
 endfunction
 
-function do_tics_1 (ticmode, tics, labelmode, labels, color, ax, plot_stream, mirror)
-  colorspec = get_text_colorspec (color);
+function do_tics_1 (ticmode, tics, labelmode, labels, color, ax,
+		    plot_stream, mirror, mono)
+  colorspec = get_text_colorspec (color, mono);
   if (strcmpi (ticmode, "manual"))
     if (isempty (tics))
       fprintf (plot_stream, "unset %stics;\n", ax);
@@ -1478,13 +1498,17 @@
   endif
 endfunction
 
-function colorspec = get_text_colorspec (color)
+function colorspec = get_text_colorspec (color, mono)
   persistent have_newer_gnuplot ...
       = compare_versions (__gnuplot_version__ (), "4.0", ">");
 
   if (have_newer_gnuplot)
-    colorspec = sprintf ("textcolor rgb \"#%02x%02x%02x\"",
-			 round (255*color));
+    if (mono)
+      colorspec = "";
+    else
+      colorspec = sprintf ("textcolor rgb \"#%02x%02x%02x\"",
+			   round (255*color));
+    endif
   else
     if (isequal (color, [0,0,0]))
       typ = -1;
--- a/scripts/plot/__go_draw_figure__.m	Fri Dec 07 17:11:28 2007 +0000
+++ b/scripts/plot/__go_draw_figure__.m	Fri Dec 07 19:26:21 2007 +0000
@@ -20,9 +20,9 @@
 
 ## Author: jwe
 
-function __go_draw_figure__ (f, plot_stream, enhanced)
+function __go_draw_figure__ (f, plot_stream, enhanced, mono)
 
-  if (nargin == 3)
+  if (nargin == 4)
     if (strcmp (f.type, "figure"))
 
       ## Set figure properties here?
@@ -56,7 +56,7 @@
 	  obj = get (kids(i));
 	  switch (obj.type)
 	    case "axes"
-	      __go_draw_axes__ (kids (i), plot_stream, enhanced);
+	      __go_draw_axes__ (kids (i), plot_stream, enhanced, mono);
 	    otherwise
 	      error ("__go_draw_figure__: unknown object class, %s",
 		     obj.type);
--- a/scripts/plot/drawnow.m	Fri Dec 07 17:11:28 2007 +0000
+++ b/scripts/plot/drawnow.m	Fri Dec 07 19:26:21 2007 +0000
@@ -27,7 +27,7 @@
 
 ## Author: jwe
 
-function drawnow (term, file, debug_file)
+function drawnow (term, file, mono, debug_file)
 
   persistent drawnow_executing = 0;
 
@@ -38,7 +38,11 @@
       return;
     endif
 
-    if (nargin == 2 || nargin == 3)
+    if (nargin < 3)
+      mono = false;
+    endif
+
+    if (nargin >= 2 && nargin <= 4)
       h = get (0, "currentfigure");
       if (h)
 	f = get (h);
@@ -46,11 +50,11 @@
 	fid = [];
 	unwind_protect
 	  [plot_stream, enhanced] = open_gnuplot_stream ([], term, file);
-	  __go_draw_figure__ (f, plot_stream, enhanced);	
-	  if (nargin == 3)
+	  __go_draw_figure__ (f, plot_stream, enhanced, mono);
+	  if (nargin == 4)
 	    fid = fopen (debug_file, "wb");
 	    enhanced = init_plot_stream (fid, [], term, file);
-	    __go_draw_figure__ (f, fid, enhanced);
+	    __go_draw_figure__ (f, fid, enhanced, mono);
 	  endif
 	unwind_protect_cleanup
 	  if (! isempty (plot_stream))
@@ -77,7 +81,7 @@
 	      else
 		enhanced = f.__enhanced__;
 	      endif
-	      __go_draw_figure__ (f, plot_stream, enhanced);
+	      __go_draw_figure__ (f, plot_stream, enhanced, mono);
 	    elseif (! isempty (plot_stream))
 	      pclose (plot_stream);
 	      set (h, "__plot_stream__", []);
--- a/scripts/plot/print.m	Fri Dec 07 17:11:28 2007 +0000
+++ b/scripts/plot/print.m	Fri Dec 07 19:26:21 2007 +0000
@@ -372,10 +372,12 @@
 
   endif
 
+  mono = use_color < 0;
+
   if (debug)
-    drawnow (new_terminal, name, debug_file);
+    drawnow (new_terminal, name, mono, debug_file);
   else
-    drawnow (new_terminal, name);
+    drawnow (new_terminal, name, mono);
   endif
 
   if (! isempty (convertname))
--- a/scripts/plot/ribbon.m	Fri Dec 07 17:11:28 2007 +0000
+++ b/scripts/plot/ribbon.m	Fri Dec 07 19:26:21 2007 +0000
@@ -84,3 +84,8 @@
   endif
 
 endfunction
+
+%!demo
+%! [x, y, z] = sombrero ();
+%! [x, y] = meshgrid (x, y);
+%! ribbon (y, z);
--- a/src/ChangeLog	Fri Dec 07 17:11:28 2007 +0000
+++ b/src/ChangeLog	Fri Dec 07 19:26:21 2007 +0000
@@ -1,5 +1,8 @@
 2007-12-07  David Bateman  <dbateman@free.fr>
 
+	* data.cc (Fnorm): Don't return a scalar stored as a sparse
+	matrix. Convert it to a scalar.
+
 	* graphics.cc (check_limit_val): Delete.
 	(check_limit_vals): Simplify and no longer use check_limit_val.
 
--- a/src/data.cc	Fri Dec 07 17:11:28 2007 +0000
+++ b/src/data.cc	Fri Dec 07 19:26:21 2007 +0000
@@ -2877,6 +2877,17 @@
   else
     print_usage ();
 
+  // Should not return a sparse type
+  if (retval(0).is_sparse_type ())
+    {
+      if (retval(0).type_name () == "sparse matrix") 
+	retval(0) = retval(0).matrix_value ();
+      else if (retval(0).type_name () == "sparse complex matrix")
+	retval(0) = retval(0).complex_matrix_value ();
+      else if (retval(0).type_name () == "sparse bool matrix")
+	retval(0) = retval(0).bool_matrix_value ();
+    }
+
   return retval;
 }