changeset 6221:8e0f1eda266b

[project @ 2007-01-03 17:23:33 by jwe]
author jwe
date Wed, 03 Jan 2007 17:23:34 +0000
parents 0c3537d2a844
children 07d967f75dba
files liboctave/ChangeLog liboctave/MSparse.cc liboctave/Sparse-op-defs.h src/ChangeLog src/OPERATORS/op-cm-scm.cc src/OPERATORS/op-cm-sm.cc src/OPERATORS/op-cs-scm.cc src/OPERATORS/op-cs-sm.cc src/OPERATORS/op-m-scm.cc src/OPERATORS/op-m-sm.cc src/OPERATORS/op-s-scm.cc src/OPERATORS/op-s-sm.cc src/OPERATORS/op-scm-cm.cc src/OPERATORS/op-scm-cs.cc src/OPERATORS/op-scm-m.cc src/OPERATORS/op-scm-s.cc src/OPERATORS/op-scm-scm.cc src/OPERATORS/op-scm-sm.cc src/OPERATORS/op-sm-cm.cc src/OPERATORS/op-sm-cs.cc src/OPERATORS/op-sm-m.cc src/OPERATORS/op-sm-s.cc src/OPERATORS/op-sm-scm.cc src/OPERATORS/op-sm-sm.cc src/dynamic-ld.cc src/ov-bool-sparse.cc src/ov-cx-sparse.cc src/ov-re-sparse.cc
diffstat 28 files changed, 882 insertions(+), 163 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/ChangeLog	Sat Dec 30 17:29:35 2006 +0000
+++ b/liboctave/ChangeLog	Wed Jan 03 17:23:34 2007 +0000
@@ -1,3 +1,19 @@
+2007-01-03  David Bateman  <dbateman@free.fr>
+
+	* MSparse.cc (SPARSE_A2A2_OP, SPARSE_A2A2_FCN_1,
+	SPARSE_A2A2_FCN_1): Modify macros so that scalars stored as
+	sparse matrices are special cased.
+
+	* Sparse-op-defs.h: Include mx-ops.h to have access to mixed
+	matrix, sparse matrix operations.
+	(SPARSE_SMSM_BIN_OP_1, SPARSE_SMSM_BIN_OP_2, SPARSE_SMSM_BIN_OP_3,
+	SPARSE_SMSM_CMP_OP, SPARSE_SMSM_BOOL_OP, SPARSE_MSM_BIN_OP_1,
+	SPARSE_MSM_BIN_OP_2, SPARSE_MSM_CMP_OP, SPARSE_MSM_BOOL_OP,
+	SPARSE_SMM_BIN_OP_1, SPARSE_SMM_BIN_OP_2, SPARSE_SMM_CMP_OP, 
+	SPARSE_SMM_BOOL_OP, SPARSE_SPARSE_MUL, SPARSE_FULL_MUL, 
+	FULL_SPARSE_MUL): Modify macros so that scalars stored as
+	sparse matrices are special cased.
+
 2006-12-22  David Bateman  <dbateman@free.fr>
 
 	* boolSparse.cc (SparseBoolMatrix::operator !): Fix off-by-one error.
--- a/liboctave/MSparse.cc	Sat Dec 30 17:29:35 2006 +0000
+++ b/liboctave/MSparse.cc	Wed Jan 03 17:23:34 2007 +0000
@@ -288,7 +288,49 @@
     octave_idx_type b_nr = b.rows (); \
     octave_idx_type b_nc = b.cols (); \
  \
-    if (a_nr != b_nr || a_nc != b_nc) \
+    if (a_nr == 1 && a_nc == 1) \
+      { \
+        if (a.elem(0,0) == 0.) \
+          r = MSparse<T> (b); \
+        else \
+          { \
+	    r = MSparse<T> (b_nr, b_nc, a.data(0) OP 0.); \
+            \
+            for (octave_idx_type j = 0 ; j < b_nc ; j++) \
+              { \
+                OCTAVE_QUIT; \
+                octave_idx_type idxj = j * b_nr; \
+                for (octave_idx_type i = b.cidx(j) ; i < b.cidx(j+1) ; i++) \
+                  { \
+                   OCTAVE_QUIT; \
+                   r.data(idxj + b.ridx(i)) = a.data(0) OP b.data(i); \
+		  } \
+              } \
+            r.maybe_compress (); \
+          } \
+      } \
+    else if (b_nr == 1 && b_nc == 1) \
+      { \
+        if (b.elem(0,0) == 0.) \
+          r = MSparse<T> (a); \
+        else \
+          { \
+	    r = MSparse<T> (a_nr, a_nc, 0. OP b.data(0)); \
+            \
+            for (octave_idx_type j = 0 ; j < a_nc ; j++) \
+              { \
+                OCTAVE_QUIT; \
+                octave_idx_type idxj = j * a_nr; \
+                for (octave_idx_type i = a.cidx(j) ; i < a.cidx(j+1) ; i++) \
+                  { \
+                    OCTAVE_QUIT; \
+                    r.data(idxj + a.ridx(i)) = a.data(i) OP b.data(0); \
+		  } \
+              } \
+            r.maybe_compress (); \
+          } \
+      } \
+    else if (a_nr != b_nr || a_nc != b_nc) \
       gripe_nonconformant ("operator " # OP, a_nr, a_nc, b_nr, b_nc); \
     else \
       { \
@@ -363,7 +405,41 @@
     octave_idx_type b_nr = b.rows (); \
     octave_idx_type b_nc = b.cols (); \
  \
-    if (a_nr != b_nr || a_nc != b_nc) \
+    if (a_nr == 1 && a_nc == 1) \
+      { \
+        if (a.elem(0,0) == 0.) \
+          r = MSparse<T> (b_nr, b_nc); \
+        else \
+          { \
+	    r = MSparse<T> (b); \
+            octave_idx_type b_nnz = b.nnz(); \
+            \
+            for (octave_idx_type i = 0 ; i < b_nnz ; i++) \
+              { \
+                OCTAVE_QUIT; \
+                r.data (i) = a.data(0) OP r.data(i); \
+              } \
+            r.maybe_compress (); \
+          } \
+      } \
+    else if (b_nr == 1 && b_nc == 1) \
+      { \
+        if (b.elem(0,0) == 0.) \
+          r = MSparse<T> (a_nr, a_nc); \
+        else \
+          { \
+	    r = MSparse<T> (a); \
+            octave_idx_type a_nnz = a.nnz(); \
+            \
+            for (octave_idx_type i = 0 ; i < a_nnz ; i++) \
+              { \
+                OCTAVE_QUIT; \
+                r.data (i) = r.data(i) OP b.data(0); \
+              } \
+            r.maybe_compress (); \
+          } \
+      } \
+    else if (a_nr != b_nr || a_nc != b_nc) \
       gripe_nonconformant (#FCN, a_nr, a_nc, b_nr, b_nc); \
     else \
       { \
@@ -429,7 +505,63 @@
     octave_idx_type b_nr = b.rows (); \
     octave_idx_type b_nc = b.cols (); \
  \
-    if (a_nr != b_nr || a_nc != b_nc) \
+    if (a_nr == 1 && a_nc == 1) \
+      { \
+        T val = a.elem (0,0); \
+        T fill = val OP T(); \
+        if (fill == T()) \
+          { \
+            octave_idx_type b_nnz = b.nnz(); \
+            r = MSparse<T> (b); \
+            for (octave_idx_type i = 0 ; i < b_nnz ; i++) \
+              r.data (i) = val OP r.data(i); \
+            r.maybe_compress (); \
+          } \
+        else \
+          { \
+            r = MSparse<T> (b_nr, b_nc, fill); \
+            for (octave_idx_type j = 0 ; j < b_nc ; j++) \
+              { \
+                OCTAVE_QUIT; \
+                octave_idx_type idxj = j * b_nr; \
+                for (octave_idx_type i = b.cidx(j) ; i < b.cidx(j+1) ; i++) \
+                  { \
+                    OCTAVE_QUIT; \
+                    r.data(idxj + b.ridx(i)) = val OP b.data(i); \
+		  } \
+              } \
+            r.maybe_compress (); \
+          } \
+      } \
+    else if (b_nr == 1 && b_nc == 1) \
+      { \
+        T val = b.elem (0,0); \
+        T fill = T() OP val; \
+        if (fill == T()) \
+          { \
+            octave_idx_type a_nnz = a.nnz(); \
+            r = MSparse<T> (a); \
+            for (octave_idx_type i = 0 ; i < a_nnz ; i++) \
+              r.data (i) = r.data(i) OP val; \
+            r.maybe_compress (); \
+          } \
+        else \
+          { \
+            r = MSparse<T> (a_nr, a_nc, fill); \
+            for (octave_idx_type j = 0 ; j < a_nc ; j++) \
+              { \
+                OCTAVE_QUIT; \
+                octave_idx_type idxj = j * a_nr; \
+                for (octave_idx_type i = a.cidx(j) ; i < a.cidx(j+1) ; i++) \
+                  { \
+                    OCTAVE_QUIT; \
+                    r.data(idxj + a.ridx(i)) = a.data(i) OP val; \
+		  } \
+              } \
+            r.maybe_compress (); \
+          } \
+      } \
+    else if (a_nr != b_nr || a_nc != b_nc) \
       gripe_nonconformant (#FCN, a_nr, a_nc, b_nr, b_nc); \
     else \
       { \
--- a/liboctave/Sparse-op-defs.h	Sat Dec 30 17:29:35 2006 +0000
+++ b/liboctave/Sparse-op-defs.h	Wed Jan 03 17:23:34 2007 +0000
@@ -24,6 +24,7 @@
 #define octave_sparse_op_defs_h 1
 
 #include "Array-util.h"
+#include "mx-ops.h"
 
 #define SPARSE_BIN_OP_DECL(R, OP, X, Y) \
   extern OCTAVE_API R OP (const X&, const Y&)
@@ -473,7 +474,49 @@
     octave_idx_type m2_nr = m2.rows (); \
     octave_idx_type m2_nc = m2.cols (); \
  \
-    if (m1_nr != m2_nr || m1_nc != m2_nc) \
+    if (m1_nr == 1 && m1_nc == 1) \
+      { \
+        if (m1.elem(0,0) == 0.) \
+          r = R (m2); \
+        else \
+          { \
+	    r = R (m2_nr, m2_nc, m1.data(0) OP 0.); \
+            \
+            for (octave_idx_type j = 0 ; j < m2_nc ; j++) \
+              { \
+                OCTAVE_QUIT; \
+                octave_idx_type idxj = j * m2_nr; \
+                for (octave_idx_type i = m2.cidx(j) ; i < m2.cidx(j+1) ; i++) \
+                  { \
+                    OCTAVE_QUIT; \
+                    r.data(idxj + m2.ridx(i)) = m1.data(0) OP m2.data(i); \
+		  } \
+              } \
+            r.maybe_compress (); \
+          } \
+      } \
+    else if (m2_nr == 1 && m2_nc == 1) \
+      { \
+        if (m2.elem(0,0) == 0.) \
+          r = R (m1); \
+        else \
+          { \
+	    r = R (m1_nr, m1_nc, 0. OP m2.data(0)); \
+            \
+            for (octave_idx_type j = 0 ; j < m1_nc ; j++) \
+              { \
+                OCTAVE_QUIT; \
+                octave_idx_type idxj = j * m1_nr; \
+                for (octave_idx_type i = m1.cidx(j) ; i < m1.cidx(j+1) ; i++) \
+                  { \
+                    OCTAVE_QUIT; \
+                    r.data(idxj + m1.ridx(i)) = m1.data(i) OP m2.data(0); \
+		  } \
+              } \
+            r.maybe_compress (); \
+          } \
+      } \
+    else if (m1_nr != m2_nr || m1_nc != m2_nc) \
       gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \
     else \
       { \
@@ -547,7 +590,41 @@
     octave_idx_type m2_nr = m2.rows (); \
     octave_idx_type m2_nc = m2.cols (); \
  \
-    if (m1_nr != m2_nr || m1_nc != m2_nc) \
+    if (m1_nr == 1 && m1_nc == 1) \
+      { \
+        if (m1.elem(0,0) == 0.) \
+          r = R (m2_nr, m2_nc); \
+        else \
+          { \
+	    r = R (m2); \
+            octave_idx_type m2_nnz = m2.nnz(); \
+            \
+            for (octave_idx_type i = 0 ; i < m2_nnz ; i++) \
+              { \
+                OCTAVE_QUIT; \
+                r.data (i) = m1.data(0) OP r.data(i); \
+              } \
+            r.maybe_compress (); \
+          } \
+      } \
+    else if (m2_nr == 1 && m2_nc == 1) \
+      { \
+        if (m2.elem(0,0) == 0.) \
+          r = R (m1_nr, m1_nc); \
+        else \
+          { \
+	    r = R (m1); \
+            octave_idx_type m1_nnz = m1.nnz(); \
+            \
+            for (octave_idx_type i = 0 ; i < m1_nnz ; i++) \
+              { \
+                OCTAVE_QUIT; \
+                r.data (i) = r.data(i) OP m2.data(0); \
+              } \
+            r.maybe_compress (); \
+          } \
+      } \
+    else if (m1_nr != m2_nr || m1_nc != m2_nc) \
       gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \
     else \
       { \
@@ -611,7 +688,59 @@
     octave_idx_type m2_nr = m2.rows (); \
     octave_idx_type m2_nc = m2.cols (); \
  \
-    if (m1_nr != m2_nr || m1_nc != m2_nc) \
+    if (m1_nr == 1 && m1_nc == 1) \
+      { \
+        if ((m1.elem (0,0) OP Complex()) == Complex()) \
+          { \
+            octave_idx_type m2_nnz = m2.nnz(); \
+            r = R (m2); \
+            for (octave_idx_type i = 0 ; i < m2_nnz ; i++) \
+              r.data (i) = m1.elem(0,0) OP r.data(i); \
+            r.maybe_compress (); \
+          } \
+        else \
+          { \
+            r = R (m2_nr, m2_nc, m1.elem(0,0) OP Complex ()); \
+            for (octave_idx_type j = 0 ; j < m2_nc ; j++) \
+              { \
+                OCTAVE_QUIT; \
+                octave_idx_type idxj = j * m2_nr; \
+                for (octave_idx_type i = m2.cidx(j) ; i < m2.cidx(j+1) ; i++) \
+                  { \
+                    OCTAVE_QUIT; \
+                    r.data(idxj + m2.ridx(i)) = m1.elem(0,0) OP m2.data(i); \
+		  } \
+              } \
+            r.maybe_compress (); \
+          } \
+      } \
+    else if (m2_nr == 1 && m2_nc == 1) \
+      { \
+        if ((Complex() OP m1.elem (0,0)) == Complex()) \
+          { \
+            octave_idx_type m1_nnz = m1.nnz(); \
+            r = R (m1); \
+            for (octave_idx_type i = 0 ; i < m1_nnz ; i++) \
+              r.data (i) = r.data(i) OP m2.elem(0,0); \
+            r.maybe_compress (); \
+          } \
+        else \
+          { \
+            r = R (m1_nr, m1_nc, Complex() OP m2.elem(0,0)); \
+            for (octave_idx_type j = 0 ; j < m1_nc ; j++) \
+              { \
+                OCTAVE_QUIT; \
+                octave_idx_type idxj = j * m1_nr; \
+                for (octave_idx_type i = m1.cidx(j) ; i < m1.cidx(j+1) ; i++) \
+                  { \
+                    OCTAVE_QUIT; \
+                    r.data(idxj + m1.ridx(i)) = m1.data(i) OP m2.elem(0,0); \
+		  } \
+              } \
+            r.maybe_compress (); \
+          } \
+      } \
+    else if (m1_nr != m2_nr || m1_nc != m2_nc) \
       gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \
     else \
       { \
@@ -698,7 +827,19 @@
     octave_idx_type m2_nr = m2.rows (); \
     octave_idx_type m2_nc = m2.cols (); \
     \
-    if (m1_nr == m2_nr && m1_nc == m2_nc) \
+    if (m1_nr == 1 && m1_nc == 1) \
+      { \
+        extern OCTAVE_API SparseBoolMatrix F (const double&, const M2&); \
+        extern OCTAVE_API SparseBoolMatrix F (const Complex&, const M2&); \
+        r = F (m1.elem(0,0), m2); \
+      } \
+    else if (m2_nr == 1 && m2_nc == 1) \
+      { \
+        extern OCTAVE_API SparseBoolMatrix F (const M1&, const double&); \
+        extern OCTAVE_API SparseBoolMatrix F (const M1&, const Complex&); \
+        r = F (m1, m2.elem(0,0)); \
+      } \
+    else if (m1_nr == m2_nr && m1_nc == m2_nc) \
       { \
 	if (m1_nr != 0 || m1_nc != 0) \
 	  { \
@@ -764,7 +905,19 @@
     octave_idx_type m2_nr = m2.rows (); \
     octave_idx_type m2_nc = m2.cols (); \
     \
-    if (m1_nr == m2_nr && m1_nc == m2_nc) \
+    if (m1_nr == 1 && m1_nc == 1) \
+      { \
+        extern OCTAVE_API SparseBoolMatrix F (const double&, const M2&); \
+        extern OCTAVE_API SparseBoolMatrix F (const Complex&, const M2&); \
+        r = F (m1.elem(0,0), m2); \
+      } \
+    else if (m2_nr == 1 && m2_nc == 1) \
+      { \
+        extern OCTAVE_API SparseBoolMatrix F (const M1&, const double&); \
+        extern OCTAVE_API SparseBoolMatrix F (const M1&, const Complex&); \
+        r = F (m1, m2.elem(0,0)); \
+      } \
+    else if (m1_nr == m2_nr && m1_nc == m2_nc) \
       { \
 	if (m1_nr != 0 || m1_nc != 0) \
 	  { \
@@ -836,7 +989,9 @@
     octave_idx_type m2_nr = m2.rows (); \
     octave_idx_type m2_nc = m2.cols (); \
  \
-    if (m1_nr != m2_nr || m1_nc != m2_nc) \
+    if (m2_nr == 1 && m2_nc == 1) \
+      r = R (m1 OP m2.elem(0,0)); \
+    else if (m1_nr != m2_nr || m1_nc != m2_nc) \
       gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \
     else \
       { \
@@ -861,7 +1016,9 @@
     octave_idx_type m2_nr = m2.rows (); \
     octave_idx_type m2_nc = m2.cols (); \
  \
-    if (m1_nr != m2_nr || m1_nc != m2_nc) \
+    if (m2_nr == 1 && m2_nc == 1) \
+      r = R (m1 OP m2.elem(0,0)); \
+    else if (m1_nr != m2_nr || m1_nc != m2_nc) \
       gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \
     else \
       { \
@@ -924,7 +1081,9 @@
     octave_idx_type m2_nr = m2.rows (); \
     octave_idx_type m2_nc = m2.cols (); \
     \
-    if (m1_nr == m2_nr && m1_nc == m2_nc) \
+    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) \
       { \
 	if (m1_nr != 0 || m1_nc != 0) \
 	  { \
@@ -990,7 +1149,9 @@
     octave_idx_type m2_nr = m2.rows (); \
     octave_idx_type m2_nc = m2.cols (); \
     \
-    if (m1_nr == m2_nr && m1_nc == m2_nc) \
+    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) \
       { \
 	if (m1_nr != 0 || m1_nc != 0) \
 	  { \
@@ -1062,7 +1223,9 @@
     octave_idx_type m2_nr = m2.rows (); \
     octave_idx_type m2_nc = m2.cols (); \
  \
-    if (m1_nr != m2_nr || m1_nc != m2_nc) \
+    if (m1_nr == 1 && m1_nc == 1) \
+      r = R (m1.elem(0,0) OP m2); \
+    else if (m1_nr != m2_nr || m1_nc != m2_nc) \
       gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \
     else \
       { \
@@ -1087,7 +1250,9 @@
     octave_idx_type m2_nr = m2.rows (); \
     octave_idx_type m2_nc = m2.cols (); \
  \
-    if (m1_nr != m2_nr || m1_nc != m2_nc) \
+    if (m1_nr == 1 && m1_nc == 1) \
+      r = R (m1.elem(0,0) OP m2); \
+    else if (m1_nr != m2_nr || m1_nc != m2_nc) \
       gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \
     else \
       { \
@@ -1150,7 +1315,9 @@
     octave_idx_type m2_nr = m2.rows (); \
     octave_idx_type m2_nc = m2.cols (); \
     \
-    if (m1_nr == m2_nr && m1_nc == m2_nc) \
+    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) \
       { \
 	if (m1_nr != 0 || m1_nc != 0) \
 	  { \
@@ -1216,7 +1383,9 @@
     octave_idx_type m2_nr = m2.rows (); \
     octave_idx_type m2_nc = m2.cols (); \
     \
-    if (m1_nr == m2_nr && m1_nc == m2_nc) \
+    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) \
       { \
 	if (m1_nr != 0 || m1_nc != 0) \
 	  { \
@@ -1540,7 +1709,49 @@
   octave_idx_type a_nr = a.rows (); \
   octave_idx_type a_nc = a.cols (); \
   \
-  if (nc != a_nr) \
+  if (nr == 1 && nc == 1) \
+   { \
+     RET_EL_TYPE s = m.elem(0,0); \
+     octave_idx_type nz = a.nnz(); \
+     RET_TYPE r (a_nr, a_nc, nz); \
+     \
+     for (octave_idx_type i = 0; i < nz; i++) \
+       { \
+         OCTAVE_QUIT; \
+	 r.data(i) = s * a.data(i); \
+	 r.ridx(i) = a.ridx(i); \
+       } \
+     for (octave_idx_type i = 0; i < a_nc + 1; i++) \
+       { \
+         OCTAVE_QUIT; \
+         r.cidx(i) = a.cidx(i); \
+       } \
+     \
+     r.maybe_compress (true); \
+     return r; \
+   } \
+  else if (a_nr == 1 && a_nc == 1) \
+   { \
+     RET_EL_TYPE s = a.elem(0,0); \
+     octave_idx_type nz = m.nnz(); \
+     RET_TYPE r (nr, nc, nz); \
+     \
+     for (octave_idx_type i = 0; i < nz; i++) \
+       { \
+         OCTAVE_QUIT; \
+	 r.data(i) = m.data(i) * s; \
+	 r.ridx(i) = m.ridx(i); \
+       } \
+     for (octave_idx_type i = 0; i < nc + 1; i++) \
+       { \
+         OCTAVE_QUIT; \
+         r.cidx(i) = m.cidx(i); \
+       } \
+     \
+     r.maybe_compress (true); \
+     return r; \
+   } \
+  else if (nc != a_nr) \
     { \
       gripe_nonconformant ("operator *", nr, nc, a_nr, a_nc); \
       return RET_TYPE (); \
@@ -1667,7 +1878,20 @@
   octave_idx_type a_nr = a.rows (); \
   octave_idx_type a_nc = a.cols (); \
   \
-  if (nc != a_nr) \
+  if (nr == 1 && nc == 1) \
+    { \
+      RET_TYPE retval (a_nr, a_nc, ZERO); \
+      for (octave_idx_type i = 0; i < a_nc ; i++) \
+	{ \
+	  for (octave_idx_type j = 0; j < a_nr; j++) \
+	    { \
+              OCTAVE_QUIT; \
+	      retval.elem (j,i) += a.elem(j,i) * m.elem(0,0); \
+	    } \
+        } \
+      return retval; \
+    } \
+  else if (nc != a_nr) \
     { \
       gripe_nonconformant ("operator *", nr, nc, a_nr, a_nc); \
       return RET_TYPE (); \
@@ -1697,7 +1921,20 @@
   octave_idx_type a_nr = a.rows (); \
   octave_idx_type a_nc = a.cols (); \
   \
-  if (nc != a_nr) \
+  if (a_nr == 1 && a_nc == 1) \
+    { \
+      RET_TYPE retval (nr, nc, ZERO); \
+      for (octave_idx_type i = 0; i < nc ; i++) \
+	{ \
+	  for (octave_idx_type j = 0; j < nr; j++) \
+	    { \
+              OCTAVE_QUIT; \
+	      retval.elem (j,i) += a.elem(0,0) * m.elem(j,i); \
+	    } \
+        } \
+      return retval; \
+    } \
+  else if (nc != a_nr) \
     { \
       gripe_nonconformant ("operator *", nr, nc, a_nr, a_nc); \
       return RET_TYPE (); \
--- a/src/ChangeLog	Sat Dec 30 17:29:35 2006 +0000
+++ b/src/ChangeLog	Wed Jan 03 17:23:34 2007 +0000
@@ -1,3 +1,29 @@
+2007-01-03  David Bateman  <dbateman@free.fr>
+
+	* (OPERATORS/op-cm-scm.cc, OPERATORS/op-cm-sm.cc, 
+	OPERATORS/op-cs-scm.cc, OPERATORS/op-cs-sm.cc, 
+	OPERATORS/op-m-scm.cc, OPERATORS/op-m-sm.cc, 
+	OPERATORS/op-scm-cm.cc, OPERATORS/op-scm-cs.cc, 
+	OPERATORS/op-scm-m.cc, OPERATORS/op-scm-s.cc, 
+	OPERATORS/op-scm-scm.cc, OPERATORS/op-scm-sm.cc, 
+	OPERATORS/op-sm-cm.cc, OPERATORS/op-sm-cs.cc, 
+	OPERATORS/op-sm-m.cc, OPERATORS/op-sm-s.cc, 
+	OPERATORS/op-sm-scm.cc, OPERATORS/op-sm-sm.cc, 
+	OPERATORS/op-s-scm.cc, OPERATORS/op-s-sm.cc):
+	Modify div and ldiv functions so that scalars stored as sparse 
+	matrices are special cased.
+
+	* ov-re-sparse.cc (double_value, complex_value): Scalar can be
+	stored as a sparse matrix and so don't warn on implicit conversion
+	to a scalar.
+	* ov-cx-sparse.cc (double_value, complex_value): ditto.
+	* ov-bool-sparse.cc (double_value, complex_value): ditto.
+
+2007-01-03  John W. Eaton  <jwe@octave.org>
+
+	* dynamic-ld.cc (octave_dynamic_loader::do_load_mex): Also check
+	for _mexFunction.
+
 2006-12-30  John W. Eaton  <jwe@octave.org>
 
 	* ov-fcn-inline.cc: For compatibility, class id is
--- a/src/OPERATORS/op-cm-scm.cc	Sat Dec 30 17:29:35 2006 +0000
+++ b/src/OPERATORS/op-cm-scm.cc	Wed Jan 03 17:23:34 2007 +0000
@@ -40,8 +40,8 @@
 
 // complex matrix by sparse complex matrix ops.
 
-DEFBINOP_OP (add, complex_matrix, sparse_complex_matrix,+)
-DEFBINOP_OP (sub, complex_matrix, sparse_complex_matrix,-)
+DEFBINOP_OP (add, complex_matrix, sparse_complex_matrix, +)
+DEFBINOP_OP (sub, complex_matrix, sparse_complex_matrix, -)
 
 DEFBINOP_OP (mul, complex_matrix, sparse_complex_matrix, *)
 
@@ -49,14 +49,26 @@
 {
   CAST_BINOP_ARGS (const octave_complex_matrix&,
 		   const octave_sparse_complex_matrix&);
-  
-  MatrixType typ = v2.matrix_type ();
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    {
+      Complex d = v2.complex_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
 
-  ComplexMatrix ret = xdiv (v1.complex_matrix_value (), 
-			    v2.sparse_complex_matrix_value (), typ);
+      return octave_value (v1.complex_array_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
 
-  v2.matrix_type (typ);
-  return ret;
+      ComplexMatrix ret = xdiv (v1.complex_matrix_value (), 
+				v2.sparse_complex_matrix_value (), typ);
+
+      v2.matrix_type (typ);
+      return ret;
+    }
 }
 
 DEFBINOPX (pow, complex_matrix, sparse_complex_matrix)
--- a/src/OPERATORS/op-cm-sm.cc	Sat Dec 30 17:29:35 2006 +0000
+++ b/src/OPERATORS/op-cm-sm.cc	Wed Jan 03 17:23:34 2007 +0000
@@ -49,13 +49,25 @@
 {
   CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_sparse_matrix&);
   
-  MatrixType typ = v2.matrix_type ();
+  if (v2.rows() == 1 && v2.columns() == 1)
+    {
+      double d = v2.scalar_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
 
-  ComplexMatrix ret = xdiv (v1.complex_matrix_value (), 
-			    v2.sparse_matrix_value (), typ);
+      return octave_value (v1.complex_array_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
 
-  v2.matrix_type (typ);
-  return ret;
+      ComplexMatrix ret = xdiv (v1.complex_matrix_value (), 
+				v2.sparse_matrix_value (), typ);
+
+      v2.matrix_type (typ);
+      return ret;
+    }
 }
 
 DEFBINOPX (pow, complex_matrix, sparse_matrix)
--- a/src/OPERATORS/op-cs-scm.cc	Sat Dec 30 17:29:35 2006 +0000
+++ b/src/OPERATORS/op-cs-scm.cc	Wed Jan 03 17:23:34 2007 +0000
@@ -47,13 +47,24 @@
 {
   CAST_BINOP_ARGS (const octave_complex&, const octave_sparse_complex_matrix&);
 
-  MatrixType typ = v2.matrix_type ();
-  ComplexMatrix m1 = ComplexMatrix (1, 1, v1.complex_value ());
-  SparseComplexMatrix m2 = v2.sparse_complex_matrix_value ();
-  ComplexMatrix ret = xdiv (m1, m2, typ);
-  v2.matrix_type (typ);
+  if (v2.rows() == 1 && v2.columns() == 1)
+    {
+      Complex d = v2.complex_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
 
-  return ret;
+      return octave_value (v1.complex_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
+      ComplexMatrix m1 = ComplexMatrix (1, 1, v1.complex_value ());
+      SparseComplexMatrix m2 = v2.sparse_complex_matrix_value ();
+      ComplexMatrix ret = xdiv (m1, m2, typ);
+      v2.matrix_type (typ);
+      return ret;
+    }
 }
 
 DEFBINOP (pow, complex, sparse_complex_matrix)
--- a/src/OPERATORS/op-cs-sm.cc	Sat Dec 30 17:29:35 2006 +0000
+++ b/src/OPERATORS/op-cs-sm.cc	Wed Jan 03 17:23:34 2007 +0000
@@ -49,13 +49,24 @@
 {
   CAST_BINOP_ARGS (const octave_complex&, const octave_sparse_matrix&);
 
-  MatrixType typ = v2.matrix_type ();
-  ComplexMatrix m1 = ComplexMatrix (1, 1, v1.complex_value ());
-  SparseMatrix m2 = v2.sparse_matrix_value ();
-  ComplexMatrix ret = xdiv (m1, m2, typ);
-  v2.matrix_type (typ);
+  if (v2.rows() == 1 && v2.columns() == 1)
+    {
+      double d = v2.scalar_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
 
-  return ret;
+      return octave_value (v1.complex_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
+      ComplexMatrix m1 = ComplexMatrix (1, 1, v1.complex_value ());
+      SparseMatrix m2 = v2.sparse_matrix_value ();
+      ComplexMatrix ret = xdiv (m1, m2, typ);
+      v2.matrix_type (typ);
+      return ret;
+    }
 }
 
 DEFBINOP (pow, complex, sparse_matrix)
--- a/src/OPERATORS/op-m-scm.cc	Sat Dec 30 17:29:35 2006 +0000
+++ b/src/OPERATORS/op-m-scm.cc	Wed Jan 03 17:23:34 2007 +0000
@@ -50,13 +50,25 @@
 {
   CAST_BINOP_ARGS (const octave_matrix&, const octave_sparse_complex_matrix&);
 
-  MatrixType typ = v2.matrix_type ();
+  if (v2.rows() == 1 && v2.columns() == 1)
+    {
+      Complex d = v2.complex_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
 
-  ComplexMatrix ret = xdiv (v1.matrix_value (), 
-			    v2.sparse_complex_matrix_value (), typ);
+      return octave_value (v1.array_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
 
-  v2.matrix_type (typ);
-  return ret;
+      ComplexMatrix ret = xdiv (v1.matrix_value (), 
+				v2.sparse_complex_matrix_value (), typ);
+
+      v2.matrix_type (typ);
+      return ret;
+    }
 }
 
 DEFBINOPX (pow, matrix, sparse_complex_matrix)
--- a/src/OPERATORS/op-m-sm.cc	Sat Dec 30 17:29:35 2006 +0000
+++ b/src/OPERATORS/op-m-sm.cc	Wed Jan 03 17:23:34 2007 +0000
@@ -48,12 +48,25 @@
 DEFBINOP (div, matrix, sparse_matrix)
 {
   CAST_BINOP_ARGS (const octave_matrix&, const octave_sparse_matrix&);
-  MatrixType typ = v2.matrix_type ();
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    {
+      double d = v2.scalar_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
 
-  Matrix ret = xdiv (v1.matrix_value (), v2.sparse_matrix_value (), typ);
+      return octave_value (v1.array_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
 
-  v2.matrix_type (typ);
-  return ret;
+      Matrix ret = xdiv (v1.matrix_value (), v2.sparse_matrix_value (), typ);
+
+      v2.matrix_type (typ);
+      return ret;
+    }
 }
 
 DEFBINOPX (pow, matrix, sparse_matrix)
--- a/src/OPERATORS/op-s-scm.cc	Sat Dec 30 17:29:35 2006 +0000
+++ b/src/OPERATORS/op-s-scm.cc	Wed Jan 03 17:23:34 2007 +0000
@@ -50,13 +50,24 @@
 {
   CAST_BINOP_ARGS (const octave_scalar&, const octave_sparse_complex_matrix&);
 
-  MatrixType typ = v2.matrix_type ();
-  Matrix m1 = Matrix (1, 1, v1.scalar_value ());
-  SparseComplexMatrix m2 = v2.sparse_complex_matrix_value ();
-  ComplexMatrix ret = xdiv (m1, m2, typ);
-  v2.matrix_type (typ);
+  if (v2.rows() == 1 && v2.columns() == 1)
+    {
+      Complex d = v2.complex_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
 
-  return ret;
+      return octave_value (v1.scalar_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
+      Matrix m1 = Matrix (1, 1, v1.scalar_value ());
+      SparseComplexMatrix m2 = v2.sparse_complex_matrix_value ();
+      ComplexMatrix ret = xdiv (m1, m2, typ);
+      v2.matrix_type (typ);
+      return ret;
+    }
 }
 
 DEFBINOP (pow, scalar, sparse_complex_matrix)
--- a/src/OPERATORS/op-s-sm.cc	Sat Dec 30 17:29:35 2006 +0000
+++ b/src/OPERATORS/op-s-sm.cc	Wed Jan 03 17:23:34 2007 +0000
@@ -46,13 +46,24 @@
 {
   CAST_BINOP_ARGS (const octave_scalar&, const octave_sparse_matrix&);
 
-  MatrixType typ = v2.matrix_type ();
-  Matrix m1 = Matrix (1, 1, v1.double_value ());
-  SparseMatrix m2 = v2.sparse_matrix_value ();
-  Matrix ret = xdiv (m1, m2, typ);
-  v2.matrix_type (typ);
+  if (v2.rows() == 1 && v2.columns() == 1)
+    {
+      double d = v2.scalar_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
 
-  return ret;
+      return octave_value (v1.scalar_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
+      Matrix m1 = Matrix (1, 1, v1.double_value ());
+      SparseMatrix m2 = v2.sparse_matrix_value ();
+      Matrix ret = xdiv (m1, m2, typ);
+      v2.matrix_type (typ);
+      return ret;
+    }
 }
 
 DEFBINOP (pow, scalar, sparse_matrix)
--- a/src/OPERATORS/op-scm-cm.cc	Sat Dec 30 17:29:35 2006 +0000
+++ b/src/OPERATORS/op-scm-cm.cc	Wed Jan 03 17:23:34 2007 +0000
@@ -67,13 +67,26 @@
 DEFBINOP (ldiv, sparse_complex_matrix, complex_matrix)
 {
   CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, const octave_complex_matrix&);
-  MatrixType typ = v1.matrix_type ();
+
+  if (v1.rows() == 1 && v1.columns() == 1)
+    {
+      Complex d = v1.complex_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
 
-  ComplexMatrix ret = xleftdiv (v1.sparse_complex_matrix_value (), 
-				v2.complex_matrix_value (), typ);
+      return octave_value (v2.complex_array_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v1.matrix_type ();
 
-  v1.matrix_type (typ);
-  return ret;
+      ComplexMatrix ret = xleftdiv (v1.sparse_complex_matrix_value (), 
+		      v2.complex_matrix_value (), typ);
+
+      v1.matrix_type (typ);
+      return ret;
+    }
 }
 
 DEFBINOP_FN (lt, sparse_complex_matrix, complex_matrix, mx_el_lt)
--- a/src/OPERATORS/op-scm-cs.cc	Sat Dec 30 17:29:35 2006 +0000
+++ b/src/OPERATORS/op-scm-cs.cc	Wed Jan 03 17:23:34 2007 +0000
@@ -74,13 +74,24 @@
 {
   CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, const octave_complex&);
 
-  MatrixType typ = v1.matrix_type ();
-  SparseComplexMatrix m1 = v1.sparse_complex_matrix_value ();
-  ComplexMatrix m2 = ComplexMatrix (1, 1, v2.complex_value ());
-  ComplexMatrix ret = xleftdiv (m1, m2, typ);
-  v1.matrix_type (typ);
+  if (v1.rows() == 1 && v1.columns() == 1)
+    {
+      Complex d = v1.complex_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
 
-  return ret;
+      return octave_value (v2.complex_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v1.matrix_type ();
+      SparseComplexMatrix m1 = v1.sparse_complex_matrix_value ();
+      ComplexMatrix m2 = ComplexMatrix (1, 1, v2.complex_value ());
+      ComplexMatrix ret = xleftdiv (m1, m2, typ);
+      v1.matrix_type (typ);
+      return ret;
+    }
 }
 
 DEFBINOP_FN (lt, sparse_complex_matrix, complex, mx_el_lt)
--- a/src/OPERATORS/op-scm-m.cc	Sat Dec 30 17:29:35 2006 +0000
+++ b/src/OPERATORS/op-scm-m.cc	Wed Jan 03 17:23:34 2007 +0000
@@ -69,13 +69,25 @@
 {
   CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, const octave_matrix&);
   
-  MatrixType typ = v1.matrix_type ();
+  if (v1.rows() == 1 && v1.columns() == 1)
+    {
+      Complex d = v1.complex_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
 
-  ComplexMatrix ret = xleftdiv (v1.sparse_complex_matrix_value (), 
-				v2.matrix_value (), typ);
+      return octave_value (v2.array_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v1.matrix_type ();
 
-  v1.matrix_type (typ);
-  return ret;
+      ComplexMatrix ret = xleftdiv (v1.sparse_complex_matrix_value (), 
+				    v2.matrix_value (), typ);
+
+      v1.matrix_type (typ);
+      return ret;
+    }
 }
 
 DEFBINOP_FN (lt, sparse_complex_matrix, matrix, mx_el_lt)
--- a/src/OPERATORS/op-scm-s.cc	Sat Dec 30 17:29:35 2006 +0000
+++ b/src/OPERATORS/op-scm-s.cc	Wed Jan 03 17:23:34 2007 +0000
@@ -82,13 +82,24 @@
 {
   CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, const octave_scalar&);
 
-  MatrixType typ = v1.matrix_type ();
-  SparseComplexMatrix m1 = v1.sparse_complex_matrix_value ();
-  Matrix m2 = Matrix (1, 1, v2.scalar_value ());
-  ComplexMatrix ret = xleftdiv (m1, m2, typ);
-  v1.matrix_type (typ);
+  if (v1.rows() == 1 && v1.columns() == 1)
+    {
+      Complex d = v1.complex_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
 
-  return ret;
+      return octave_value (v2.scalar_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v1.matrix_type ();
+      SparseComplexMatrix m1 = v1.sparse_complex_matrix_value ();
+      Matrix m2 = Matrix (1, 1, v2.scalar_value ());
+      ComplexMatrix ret = xleftdiv (m1, m2, typ);
+      v1.matrix_type (typ);
+      return ret;
+    }
 }
 
 DEFBINOP_FN (lt, sparse_complex_matrix, scalar, mx_el_lt)
--- a/src/OPERATORS/op-scm-scm.cc	Sat Dec 30 17:29:35 2006 +0000
+++ b/src/OPERATORS/op-scm-scm.cc	Wed Jan 03 17:23:34 2007 +0000
@@ -97,12 +97,25 @@
 {
   CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, 
 		   const octave_sparse_complex_matrix&);
-  MatrixType typ = v2.matrix_type ();
-  SparseComplexMatrix ret = xdiv (v1.sparse_complex_matrix_value (), 
-				  v2.sparse_complex_matrix_value (), typ);
+ 
+  if (v2.rows() == 1 && v2.columns() == 1)
+    {
+      Complex d = v2.complex_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (v1.sparse_complex_matrix_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
+      SparseComplexMatrix ret = xdiv (v1.sparse_complex_matrix_value (), 
+				      v2.sparse_complex_matrix_value (), typ);
   
-  v2.matrix_type (typ);
-  return ret;
+      v2.matrix_type (typ);
+      return ret;
+    }
 }
 
 DEFBINOPX (pow, sparse_complex_matrix, sparse_complex_matrix)
@@ -115,13 +128,27 @@
 {
   CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, 
 		   const octave_sparse_complex_matrix&);
-  MatrixType typ = v1.matrix_type ();
+
+  if (v1.rows() == 1 && v1.columns() == 1)
+    {
+      Complex d = v1.complex_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
 
-  SparseComplexMatrix ret = xleftdiv (v1.sparse_complex_matrix_value (), 
-				      v2.sparse_complex_matrix_value (), typ);
+      return octave_value (v2.sparse_complex_matrix_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v1.matrix_type ();
 
-  v1.matrix_type (typ);
-  return ret;
+      SparseComplexMatrix ret = 
+	xleftdiv (v1.sparse_complex_matrix_value (), 
+		  v2.sparse_complex_matrix_value (), typ);
+
+      v1.matrix_type (typ);
+      return ret;
+    }
 }
 
 DEFBINOP_FN (lt, sparse_complex_matrix, sparse_complex_matrix, mx_el_lt)
--- a/src/OPERATORS/op-scm-sm.cc	Sat Dec 30 17:29:35 2006 +0000
+++ b/src/OPERATORS/op-scm-sm.cc	Wed Jan 03 17:23:34 2007 +0000
@@ -47,12 +47,25 @@
 DEFBINOP (div, sparse_complex_matrix, sparse_matrix)
 {
   CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, const octave_sparse_matrix&);
-  MatrixType typ = v2.matrix_type ();
-  SparseComplexMatrix ret = xdiv (v1.sparse_complex_matrix_value (), 
-				  v2.sparse_matrix_value (), typ);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    {
+      double d = v2.scalar_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (v1.sparse_complex_matrix_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
+      SparseComplexMatrix ret = xdiv (v1.sparse_complex_matrix_value (), 
+				      v2.sparse_matrix_value (), typ);
   
-  v2.matrix_type (typ);
-  return ret;
+      v2.matrix_type (typ);
+      return ret;
+    }
 }
 
 DEFBINOPX (pow, sparse_complex_matrix, sparse_matrix)
@@ -64,13 +77,26 @@
 DEFBINOP (ldiv, sparse_complex_matrix, sparse_matrix)
 {
   CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, const octave_sparse_matrix&);
-  MatrixType typ = v1.matrix_type ();
+
+  if (v1.rows() == 1 && v1.columns() == 1)
+    {
+      Complex d = v1.complex_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
 
-  SparseComplexMatrix ret = xleftdiv (v1.sparse_complex_matrix_value (), 
-				      v2.sparse_matrix_value (), typ);
+      return octave_value (v2.sparse_matrix_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v1.matrix_type ();
 
-  v1.matrix_type (typ);
-  return ret;
+      SparseComplexMatrix ret = xleftdiv (v1.sparse_complex_matrix_value (), 
+					  v2.sparse_matrix_value (), typ);
+
+      v1.matrix_type (typ);
+      return ret;
+    }
 }
 
 DEFBINOP_FN (lt, sparse_complex_matrix, sparse_matrix, mx_el_lt)
--- a/src/OPERATORS/op-sm-cm.cc	Sat Dec 30 17:29:35 2006 +0000
+++ b/src/OPERATORS/op-sm-cm.cc	Wed Jan 03 17:23:34 2007 +0000
@@ -67,13 +67,26 @@
 DEFBINOP (ldiv, sparse_matrix, complex_matrix)
 {
   CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_complex_matrix&);
-  MatrixType typ = v1.matrix_type ();
+
+  if (v1.rows() == 1 && v1.columns() == 1)
+    {
+      double d = v1.scalar_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
 
-  ComplexMatrix ret = xleftdiv (v1.sparse_matrix_value (), 
-				v2.complex_matrix_value (), typ);
+      return octave_value (v2.complex_array_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v1.matrix_type ();
 
-  v1.matrix_type (typ);
-  return ret;
+      ComplexMatrix ret = xleftdiv (v1.sparse_matrix_value (), 
+				    v2.complex_matrix_value (), typ);
+
+      v1.matrix_type (typ);
+      return ret;
+    }
 }
 
 DEFBINOP_FN (lt, sparse_matrix, complex_matrix, mx_el_lt)
--- a/src/OPERATORS/op-sm-cs.cc	Sat Dec 30 17:29:35 2006 +0000
+++ b/src/OPERATORS/op-sm-cs.cc	Wed Jan 03 17:23:34 2007 +0000
@@ -74,13 +74,24 @@
 {
   CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_complex&);
 
-  MatrixType typ = v1.matrix_type ();
-  SparseMatrix m1 = v1.sparse_matrix_value ();
-  ComplexMatrix m2 = ComplexMatrix (1, 1, v2.complex_value ());
-  ComplexMatrix ret = xleftdiv (m1, m2, typ);
-  v1.matrix_type (typ);
+  if (v1.rows() == 1 && v1.columns() == 1)
+    {
+      double d = v1.scalar_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
 
-  return ret;
+      return octave_value (v2.complex_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v1.matrix_type ();
+      SparseMatrix m1 = v1.sparse_matrix_value ();
+      ComplexMatrix m2 = ComplexMatrix (1, 1, v2.complex_value ());
+      ComplexMatrix ret = xleftdiv (m1, m2, typ);
+      v1.matrix_type (typ);
+      return ret;
+    }
 }
 
 DEFBINOP_FN (lt, sparse_matrix, complex, mx_el_lt)
--- a/src/OPERATORS/op-sm-m.cc	Sat Dec 30 17:29:35 2006 +0000
+++ b/src/OPERATORS/op-sm-m.cc	Wed Jan 03 17:23:34 2007 +0000
@@ -65,13 +65,26 @@
 DEFBINOP (ldiv, sparse_matrix, matrix)
 {
   CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_matrix&);
-  MatrixType typ = v1.matrix_type ();
+
+  if (v1.rows() == 1 && v1.columns() == 1)
+    {
+      double d = v1.scalar_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
 
-  Matrix ret = xleftdiv (v1.sparse_matrix_value (), 
-			       v2.matrix_value (), typ);
+      return octave_value (v2.array_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v1.matrix_type ();
 
-  v1.matrix_type (typ);
-  return ret;
+      Matrix ret = xleftdiv (v1.sparse_matrix_value (), 
+			     v2.matrix_value (), typ);
+
+      v1.matrix_type (typ);
+      return ret;
+    }
 }
 
 DEFBINOP_FN (lt, sparse_matrix, matrix, mx_el_lt)
--- a/src/OPERATORS/op-sm-s.cc	Sat Dec 30 17:29:35 2006 +0000
+++ b/src/OPERATORS/op-sm-s.cc	Wed Jan 03 17:23:34 2007 +0000
@@ -76,13 +76,24 @@
 {
   CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_scalar&);
 
-  MatrixType typ = v1.matrix_type ();
-  SparseMatrix m1 = v1.sparse_matrix_value ();
-  Matrix m2 = Matrix (1, 1, v2.scalar_value ());
-  Matrix ret = xleftdiv (m1, m2, typ);
-  v1.matrix_type (typ);
+  if (v1.rows() == 1 && v1.columns() == 1)
+    {
+      double d = v1.scalar_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
 
-  return ret;
+      return octave_value (v2.scalar_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v1.matrix_type ();
+      SparseMatrix m1 = v1.sparse_matrix_value ();
+      Matrix m2 = Matrix (1, 1, v2.scalar_value ());
+      Matrix ret = xleftdiv (m1, m2, typ);
+      v1.matrix_type (typ);
+      return ret;
+    }
 }
 
 DEFBINOP_FN (lt, sparse_matrix, scalar, mx_el_lt)
--- a/src/OPERATORS/op-sm-scm.cc	Sat Dec 30 17:29:35 2006 +0000
+++ b/src/OPERATORS/op-sm-scm.cc	Wed Jan 03 17:23:34 2007 +0000
@@ -47,12 +47,25 @@
 DEFBINOP (div, sparse_matrix, sparse_complex_matrix)
 {
   CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_sparse_complex_matrix&);
-  MatrixType typ = v2.matrix_type ();
-  SparseComplexMatrix ret = xdiv (v1.sparse_matrix_value (), 
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    {
+      Complex d = v2.complex_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (v1.sparse_matrix_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
+      SparseComplexMatrix ret = xdiv (v1.sparse_matrix_value (), 
 				  v2.sparse_complex_matrix_value (), typ);
   
-  v2.matrix_type (typ);
-  return ret;
+      v2.matrix_type (typ);
+      return ret;
+    }
 }
 
 DEFBINOPX (pow, sparse_matrix, sparse_complex_matrix)
@@ -64,13 +77,27 @@
 DEFBINOP (ldiv, sparse_matrix, sparse_complex_matrix)
 {
   CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_sparse_complex_matrix&);
-  MatrixType typ = v1.matrix_type ();
+
+  if (v1.rows() == 1 && v1.columns() == 1)
+    {
+      double d = v1.scalar_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
 
-  SparseComplexMatrix ret = xleftdiv (v1.sparse_matrix_value (), 
-				      v2.sparse_complex_matrix_value (), typ);
+      return octave_value (v2.sparse_complex_matrix_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v1.matrix_type ();
 
-  v1.matrix_type (typ);
-  return ret;
+      SparseComplexMatrix ret = 
+	xleftdiv (v1.sparse_matrix_value (), 
+		  v2.sparse_complex_matrix_value (), typ);
+
+      v1.matrix_type (typ);
+      return ret;
+    }
 }
 
 DEFBINOP_FN (lt, sparse_matrix, sparse_complex_matrix, mx_el_lt)
--- a/src/OPERATORS/op-sm-sm.cc	Sat Dec 30 17:29:35 2006 +0000
+++ b/src/OPERATORS/op-sm-sm.cc	Wed Jan 03 17:23:34 2007 +0000
@@ -57,12 +57,25 @@
 DEFBINOP (div, sparse_matrix, sparse_matrix)
 {
   CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_sparse_matrix&);
-  MatrixType typ = v2.matrix_type ();
-  SparseMatrix ret = xdiv (v1.sparse_matrix_value (), 
-			   v2.sparse_matrix_value (), typ);
+
+  if (v2.rows() == 1 && v2.columns() == 1)
+    {
+      double d = v2.scalar_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
+
+      return octave_value (v1.sparse_matrix_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v2.matrix_type ();
+      SparseMatrix ret = xdiv (v1.sparse_matrix_value (), 
+			       v2.sparse_matrix_value (), typ);
   
-  v2.matrix_type (typ);
-  return ret;
+      v2.matrix_type (typ);
+      return ret;
+    }
 }
 
 DEFBINOPX (pow, sparse_matrix, sparse_matrix)
@@ -74,13 +87,26 @@
 DEFBINOP (ldiv, sparse_matrix, sparse_matrix)
 {
   CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_sparse_matrix&);
-  MatrixType typ = v1.matrix_type ();
+
+  if (v1.rows() == 1 && v1.columns() == 1)
+    {
+      double d = v1.double_value ();
+
+      if (d == 0.0)
+	gripe_divide_by_zero ();
 
-  SparseMatrix ret = xleftdiv (v1.sparse_matrix_value (), 
-			       v2.sparse_matrix_value (), typ);
+      return octave_value (v2.sparse_matrix_value () / d);
+    }
+  else
+    {
+      MatrixType typ = v1.matrix_type ();
 
-  v1.matrix_type (typ);
-  return ret;
+      SparseMatrix ret = xleftdiv (v1.sparse_matrix_value (), 
+				   v2.sparse_matrix_value (), typ);
+
+      v1.matrix_type (typ);
+      return ret;
+    }
 }
 
 DEFBINOP_FN (lt, sparse_matrix, sparse_matrix, mx_el_lt)
--- a/src/dynamic-ld.cc	Sat Dec 30 17:29:35 2006 +0000
+++ b/src/dynamic-ld.cc	Wed Jan 03 17:23:34 2007 +0000
@@ -413,9 +413,17 @@
 
 	      if (! function)
 		{
-		  function = mex_file.search (STRINGIFY (F77_FUNC (mexfunction, MEXFUNCTION)));
-		  if (function)
-		    have_fmex = true;
+		  // FIXME -- can we determine this C mangling scheme
+		  // automatically at run time or configure time?
+
+		  function = mex_file.search ("_mexFunction");
+
+		  if (! function)
+		    {
+		      function = mex_file.search (STRINGIFY (F77_FUNC (mexfunction, MEXFUNCTION)));
+		      if (function)
+			have_fmex = true;
+		    }
 		}
 	    }
 	  else
--- a/src/ov-bool-sparse.cc	Sat Dec 30 17:29:35 2006 +0000
+++ b/src/ov-bool-sparse.cc	Wed Jan 03 17:23:34 2007 +0000
@@ -100,8 +100,9 @@
 
   if (numel () > 0)
     {
-      gripe_implicit_conversion ("Octave:array-as-scalar",
-				 "bool sparse matrix", "real scalar");
+      if (numel () > 1)
+	gripe_implicit_conversion ("Octave:array-as-scalar",
+				   "bool sparse matrix", "real scalar");
 
       retval = matrix (0, 0);
     }
@@ -120,8 +121,9 @@
 
   if (rows () > 0 && columns () > 0)
     {
-      gripe_implicit_conversion ("Octave:array-as-scalar",
-				 "bool sparse matrix", "complex scalar");
+      if (numel () > 1)
+	gripe_implicit_conversion ("Octave:array-as-scalar",
+				   "bool sparse matrix", "complex scalar");
 
       retval = matrix (0, 0);
     }
--- a/src/ov-cx-sparse.cc	Sat Dec 30 17:29:35 2006 +0000
+++ b/src/ov-cx-sparse.cc	Wed Jan 03 17:23:34 2007 +0000
@@ -126,8 +126,9 @@
   // FIXME -- maybe this should be a function, valid_as_scalar()
   if (numel () > 0)
     {
-      gripe_implicit_conversion ("Octave:array-as-scalar",
-				 "complex sparse matrix", "real scalar");
+      if (numel () > 1)
+	gripe_implicit_conversion ("Octave:array-as-scalar",
+				   "complex sparse matrix", "real scalar");
 
       retval = std::real (matrix (0, 0));
     }
@@ -161,8 +162,9 @@
   // FIXME -- maybe this should be a function, valid_as_scalar()
   if (numel () > 0)
     {
-      gripe_implicit_conversion ("Octave:array-as-scalar",
-				 "complex sparse matrix", "real scalar");
+      if (numel () > 1)
+	gripe_implicit_conversion ("Octave:array-as-scalar",
+				   "complex sparse matrix", "real scalar");
 
       retval = matrix (0, 0);
     }
--- a/src/ov-re-sparse.cc	Sat Dec 30 17:29:35 2006 +0000
+++ b/src/ov-re-sparse.cc	Wed Jan 03 17:23:34 2007 +0000
@@ -98,8 +98,9 @@
 
   if (numel () > 0)
     {
-      gripe_implicit_conversion ("Octave:array-as-scalar",
-				 "real sparse matrix", "real scalar");
+      if (numel () > 1)
+	gripe_implicit_conversion ("Octave:array-as-scalar",
+				   "real sparse matrix", "real scalar");
 
       retval = matrix (0, 0);
     }
@@ -119,8 +120,9 @@
   // FIXME -- maybe this should be a function, valid_as_scalar()
   if (rows () > 0 && columns () > 0)
     {
-      gripe_implicit_conversion ("Octave:array-as-scalar",
-				 "real sparse matrix", "complex scalar");
+      if (numel () > 1)
+	gripe_implicit_conversion ("Octave:array-as-scalar",
+				   "real sparse matrix", "complex scalar");
 
       retval = matrix (0, 0);
     }