changeset 4543:79df15d4470c

[project @ 2003-10-18 03:53:52 by jwe]
author jwe
date Sat, 18 Oct 2003 03:53:53 +0000
parents 2633831cbeb5
children 74c92e375b54
files liboctave/Array.cc liboctave/ArrayN.cc liboctave/ArrayN.h liboctave/CNDArray.cc liboctave/CNDArray.h liboctave/ChangeLog liboctave/MArray-defs.h liboctave/MArray-misc.cc liboctave/MArrayN.cc liboctave/boolMatrix.cc liboctave/boolNDArray.cc liboctave/boolNDArray.h liboctave/dNDArray.cc liboctave/dNDArray.h liboctave/dim-vector.h liboctave/mx-cm-m.cc liboctave/mx-cm-m.h liboctave/mx-cm-s.cc liboctave/mx-cm-s.h liboctave/mx-cs-m.cc liboctave/mx-cs-m.h liboctave/mx-defs.h liboctave/mx-m-cm.cc liboctave/mx-m-cm.h liboctave/mx-m-cs.cc liboctave/mx-m-cs.h liboctave/mx-op-defs.h liboctave/mx-s-cm.cc liboctave/mx-s-cm.h liboctave/oct-rand.cc liboctave/oct-rand.h src/ChangeLog src/DLD-FUNCTIONS/rand.cc src/OPERATORS/op-bm-bm.cc src/OPERATORS/op-cm-cm.cc src/OPERATORS/op-cm-cs.cc src/OPERATORS/op-cm-m.cc src/OPERATORS/op-cm-s.cc src/OPERATORS/op-cs-cm.cc src/OPERATORS/op-cs-m.cc src/OPERATORS/op-m-cm.cc src/OPERATORS/op-m-cs.cc src/OPERATORS/op-m-m.cc src/OPERATORS/op-m-nd.cc src/OPERATORS/op-m-s.cc src/OPERATORS/op-nd-m.cc src/OPERATORS/op-nd-nd.cc src/OPERATORS/op-nd-s.cc src/OPERATORS/op-s-cm.cc src/OPERATORS/op-s-m.cc src/OPERATORS/op-s-nd.cc src/ops.h src/ov-bool-mat.h src/ov-ch-mat.h src/ov-cx-mat.h src/ov-re-mat.h src/xdiv.cc src/xdiv.h src/xpow.cc src/xpow.h test/octave.test/matrix/matrix.exp test/octave.test/matrix/rand-2.m test/octave.test/matrix/randn-2.m
diffstat 63 files changed, 1648 insertions(+), 735 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/Array.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/Array.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -410,8 +410,6 @@
 
   rep = new typename Array<T>::ArrayRep (get_size (dims));
 
-  dim_vector old_dimensions = dimensions;
-
   dimensions = dims;
 
   Array<int> ra_idx (dimensions.length (), 0);
@@ -696,8 +694,6 @@
 
   rep = new typename Array<T>::ArrayRep (len);
 
-  dim_vector old_dimensions = dimensions;
-
   dimensions = dims;
 
   Array<int> ra_idx (dimensions.length (), 0);
--- a/liboctave/ArrayN.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/ArrayN.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -52,14 +52,7 @@
   os << n_dims << "-dimensional array";
 
   if (n_dims)
-    {
-      os << " (";
-
-      for (int i = 0; i < n_dims - 1; i++)
-	os << a_dims(i) << "x";
-
-      os << a_dims(n_dims-1) << ")";
-    }
+    os << " (" << a_dims.str () << ")";
 
   os <<"\n\n";
 
--- a/liboctave/ArrayN.h	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/ArrayN.h	Sat Oct 18 03:53:53 2003 +0000
@@ -86,7 +86,7 @@
     }
 
   void resize (const dim_vector& dims)
-    { Array<T>resize_no_fill (dims); }
+    { Array<T>::resize_no_fill (dims); }
 
   void resize (const dim_vector& dims, const T& val)
     { Array<T>::resize (dims, val); }
--- a/liboctave/CNDArray.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/CNDArray.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -35,6 +35,43 @@
 
 #include "ArrayN-inline.h"
 
+// XXX FIXME XXX -- could we use a templated mixed-type copy function
+// here?
+
+ComplexNDArray::ComplexNDArray (const NDArray& a)
+  : MArrayN<Complex> (a.dims ())
+{
+  for (int i = 0; i < a.length (); i++)
+    elem (i) = a.elem (i);
+}
+
+ComplexNDArray::ComplexNDArray (const boolNDArray& a)
+  : MArrayN<Complex> (a.dims ())
+{
+  for (int i = 0; i < a.length (); i++)
+    elem (i) = a.elem (i);
+}
+
+ComplexNDArray::ComplexNDArray (const charNDArray& a)
+  : MArrayN<Complex> (a.dims ())
+{
+  for (int i = 0; i < a.length (); i++)
+    elem (i) = a.elem (i);
+}
+
+// unary operations
+
+boolNDArray
+ComplexNDArray::operator ! (void) const
+{
+  boolNDArray b (dims ());
+
+  for (int i = 0; i < length (); i++)
+    b.elem (i) = elem (i) != 0.0;
+
+  return b;
+}
+
 // XXX FIXME XXX -- this is not quite the right thing.
 
 boolMatrix
@@ -106,6 +143,15 @@
   ::increment_index (ra_idx, dimensions, start_dimension);
 }
 
+NDS_CMP_OPS(ComplexNDArray, real, Complex, real)
+NDS_BOOL_OPS(ComplexNDArray, Complex, 0.0)
+
+SND_CMP_OPS(Complex, real, ComplexNDArray, real)
+SND_BOOL_OPS(Complex, ComplexNDArray, 0.0)
+
+NDND_CMP_OPS(ComplexNDArray, real, ComplexNDArray, real)
+NDND_BOOL_OPS(ComplexNDArray, ComplexNDArray, 0.0)
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/liboctave/CNDArray.h	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/CNDArray.h	Sat Oct 18 03:53:53 2003 +0000
@@ -43,9 +43,9 @@
   
   ComplexNDArray (void) : MArrayN<Complex> () { }
 
-  ComplexNDArray (dim_vector& dims) : MArrayN<Complex> (dims) { }
+  ComplexNDArray (const dim_vector& dims) : MArrayN<Complex> (dims) { }
 
-  ComplexNDArray (dim_vector& dims, const Complex& val)
+  ComplexNDArray (const dim_vector& dims, const Complex& val)
     : MArrayN<Complex> (dims, val) { }
   
   ComplexNDArray (const ComplexNDArray& a) : MArrayN<Complex> (a) { }
@@ -56,12 +56,22 @@
 
   ComplexNDArray (const ArrayN<Complex>& a) : MArrayN<Complex> (a) { }
 
+  explicit ComplexNDArray (const NDArray& a);
+
+  explicit ComplexNDArray (const boolNDArray& a);
+
+  explicit ComplexNDArray (const charNDArray& a);
+
   ComplexNDArray& operator = (const ComplexNDArray& a)
     {
       MArrayN<Complex>::operator = (a);
       return *this;
     }
 
+  // unary operations
+
+  boolNDArray operator ! (void) const;
+
   // XXX FIXME XXX -- this is not quite the right thing.
 
   boolMatrix all (int dim = -1) const;
@@ -91,6 +101,15 @@
     : MArrayN<Complex> (d, dims) { }
 };
 
+NDS_CMP_OP_DECLS (ComplexNDArray, Complex)
+NDS_BOOL_OP_DECLS (ComplexNDArray, Complex)
+
+SND_CMP_OP_DECLS (Complex, ComplexNDArray)
+SND_BOOL_OP_DECLS (Complex, ComplexNDArray)
+
+NDND_CMP_OP_DECLS (ComplexNDArray, ComplexNDArray)
+NDND_BOOL_OP_DECLS (ComplexNDArray, ComplexNDArray)
+
 MARRAY_FORWARD_DEFS (MArrayN, ComplexNDArray, Complex)
 
 #endif
--- a/liboctave/ChangeLog	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/ChangeLog	Sat Oct 18 03:53:53 2003 +0000
@@ -1,3 +1,57 @@
+2003-10-17  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* NDArray.cc (NDArray::NDArray (const boolNDArray),
+	NDArray::NDArray (const charNDArray)): New constructors.
+	(NDArray::operator !): New function.
+	Provide NDS_CMP_OPS, NDS_BOOL_OPS, SND_CMP_OPS, SND_BOOL_OPS,
+	NDND_CMP_OPS, NDND_BOOL_OPS.
+
+	* CNDArray.cc (ComplexNDArray::ComplexNDArray (const NDArray&),
+	ComplexNDArray::ComplexNDArray (const boolNDArray&),
+	ComplexNDArray::ComplexNDArray (const charNDArray&)):
+	New constructors.
+	(ComplexNDArray::operator !): New function.
+	Provide NDS_CMP_OPS, NDS_BOOL_OPS, SND_CMP_OPS, SND_BOOL_OPS,
+	NDND_CMP_OPS, NDND_BOOL_OPS.
+
+	* ArrayN.h (resize (const dim_vector&)): Fix typo.
+
+	* boolNDArray.cc (boolNDArray::operator !): New function.
+	Provide NDND_CMP_OPS.
+
+	* MArrayN.cc (operator +=, operator -=): New functions.
+	Provide product and quotient functions.
+
+	* MArray-misc.cc (gripe_nonconformant (const char *, dim_vector&,
+	dim_vector&)): New function.
+
+	* dim-vector.h (dim_vector::str, dim_vector::all_zero,
+	operator ==, operator !=): New functions.
+	* ArrayN.cc (operator <<): Use dim_vector::str here.
+
+	* Array.cc (Array<T>::resize_no_fill, Array<T>::resize_and_fill):
+	No need to save old dimensions.
+
+	* oct-rand.cc (MAKE_RAND_ND_ARRAY): New macro.
+	(octave_rand::nd_array): New function.
+	* oct-rand.h (octave_rand::nd_array): Provide decl.
+
+	* mx-op-defs.h (NDCMP_OP_DECL, NDBOOL_OP_DECL, NDS_BIN_OP_DECLS,
+	NDS_BIN_OP, NDS_BIN_OPS, NDS_CMP_OP_DECLS, NDS_CMP_OP,
+	NDS_CMP_OPS, NDS_BOOL_OP_DECLS, NDS_BOOL_OP, NDS_BOOL_OPS,
+	NDS_OP_DECLS, SND_BIN_OP_DECLS, SND_BIN_OP, SND_BIN_OPS,
+	SND_CMP_OP_DECLS, SND_CMP_OP, SND_CMP_OPS, SND_BOOL_OP_DECLS,
+	SND_BOOL_OP, SND_BOOL_OPS, SND_OP_DECLS, NDND_BIN_OP_DECLS,
+	NDND_BIN_OP, NDND_BIN_OPS, NDND_CMP_OP_DECLS, NDND_CMP_OP,
+	NDND_CMP_OPS, NDND_BOOL_OP_DECLS, NDND_BOOL_OP, NDND_BOOL_OPS,
+	NDND_OP_DECLS): New macros.
+	* mx-cm-m.h, mx-cm-s.h, mx-cs-m.h, mx-m-cm.h, mx-m-cs.h,
+	mx-s-cm.h, mx-cm-m.cc, mx-cm-s.cc, mx-cs-m.cc, mx-m-cm.cc,
+	mx-m-cs.cc, mx-s-cm.cc: Use them.
+
+	* mx-defs.h (class NDArray, class ComplexNDArray, class
+	boolNDArray, class charNDArray): New forward decls.
+
 2003-10-15  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
 	* Array.cc (assign2): No error (but don't do anything either) for
--- a/liboctave/MArray-defs.h	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/MArray-defs.h	Sat Oct 18 03:53:53 2003 +0000
@@ -271,10 +271,10 @@
 
 // Instantiate all the MArrayN friends for MArrayN element type T.
 #define INSTANTIATE_MARRAYN_FRIENDS(T) \
-  MARRAY_OP_ASSIGN_DEFS (MArrayN, T, T) /* \
-  MARRAY_OP_ASSIGN_DEFS (MArray2, T, MArray2<T>) \
-  MARRAY_UNOP_DEFS (MArray2, T) \
-  MARRAY_BINOP_DEFS (MArray2, T)  */
+  MARRAY_OP_ASSIGN_DEFS (MArrayN, T, T) \
+  MARRAY_OP_ASSIGN_DEFS (MArrayN, T, MArrayN<T>) \
+  MARRAY_UNOP_DEFS (MArrayN, T) \
+  MARRAY_BINOP_DEFS (MArrayN, T)
 
 // Instantiate all the MDiagArray2 friends for MDiagArray2 element type T.
 #define INSTANTIATE_MDIAGARRAY2_FRIENDS(T) \
--- a/liboctave/MArray-misc.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/MArray-misc.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -26,6 +26,7 @@
 
 #include "MArray.h"
 #include "MArray2.h"
+#include "dim-vector.h"
 #include "lo-error.h"
 
 void
@@ -45,6 +46,19 @@
      op, op1_nr, op1_nc, op2_nr, op2_nc);
 }
 
+void
+gripe_nonconformant (const char *op, dim_vector& op1_dims,
+		     dim_vector& op2_dims)
+{
+  std::string op1_dims_str = op1_dims.str ();
+  std::string op2_dims_str = op2_dims.str ();
+
+  (*current_liboctave_error_handler)
+    ("%s: nonconformant arguments (op1 is %s, op2 is %s)",
+     op, op1_dims_str.c_str (), op2_dims_str.c_str ());
+}
+
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/liboctave/MArrayN.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/MArrayN.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -54,7 +54,42 @@
   return a;
 }
 
-#if 0
+// Element by element MArrayN by MArrayN ops.
+
+template <class T>
+MArrayN<T>&
+operator += (MArrayN<T>& a, const MArrayN<T>& b)
+{
+  int l = a.length ();
+  if (l > 0)
+    {
+      int bl = b.length ();
+      if (l != bl)
+	gripe_nonconformant ("operator +=", l, bl);
+      else
+	DO_VV_OP2 (+=);
+    }
+  return a;
+}
+
+template <class T>
+MArrayN<T>&
+operator -= (MArrayN<T>& a, const MArrayN<T>& b)
+{
+  int l = a.length ();
+  if (l > 0)
+    {
+      int bl = b.length ();
+      if (l != bl)
+	gripe_nonconformant ("operator -=", l, bl);
+      else
+	DO_VV_OP2 (-=);
+    }
+  return a;
+}
+
+// Element by element MArrayN by scalar ops.
+
 #define MARRAYN_NDS_OP(OP) \
   template <class T> \
   MArrayN<T> \
@@ -132,6 +167,8 @@
 
 MARRAY_NDND_OP (operator +, +)
 MARRAY_NDND_OP (operator -, -)
+MARRAY_NDND_OP (product,    *)
+MARRAY_NDND_OP (quotient,   /)
 
 template <class T>
 MArrayN<T>
@@ -152,8 +189,6 @@
   return result;
 }
 
-#endif
- 
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/liboctave/boolMatrix.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/boolMatrix.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -94,7 +94,7 @@
   MX_ANY_OP (dim);
 }
 
-MM_CMP_OPS(boolMatrix, , boolMatrix, )
+MM_CMP_OPS (boolMatrix, , boolMatrix, )
 
 /*
 ;;; Local Variables: ***
--- a/liboctave/boolNDArray.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/boolNDArray.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -35,6 +35,19 @@
 
 #include "ArrayN-inline.h"
 
+// unary operations
+
+boolNDArray
+boolNDArray::operator ! (void) const
+{
+  boolNDArray b (dims ());
+
+  for (int i = 0; i < length (); i++)
+    b.elem (i) = ! elem (i);
+
+  return b;
+}
+
 // XXX FIXME XXX -- this is not quite the right thing.
 
 boolMatrix
@@ -106,6 +119,8 @@
   ::increment_index (ra_idx, dimensions, start_dimension);
 }
 
+NDND_CMP_OPS (boolNDArray, , boolNDArray, )
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/liboctave/boolNDArray.h	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/boolNDArray.h	Sat Oct 18 03:53:53 2003 +0000
@@ -62,6 +62,10 @@
       return *this;
     }
 
+  // unary operations
+
+  boolNDArray operator ! (void) const;
+
   // XXX FIXME XXX -- this is not quite the right thing.
 
   boolMatrix all (int dim = -1) const;
@@ -90,6 +94,8 @@
   boolNDArray (bool *d, dim_vector& dims) : ArrayN<bool> (d, dims) { }
 };
 
+NDND_CMP_OP_DECLS (boolNDArray, boolNDArray)
+
 #endif
 
 /*
--- a/liboctave/dNDArray.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/dNDArray.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -36,6 +36,33 @@
 
 #include "ArrayN-inline.h"
 
+NDArray::NDArray (const boolNDArray& a)
+  : MArrayN<double> (a.dims ())
+{
+  for (int i = 0; i < a.length (); i++)
+    elem (i) = a.elem (i);
+}
+
+NDArray::NDArray (const charNDArray& a)
+  : MArrayN<double> (a.dims ())
+{
+  for (int i = 0; i < a.length (); i++)
+    elem (i) = a.elem (i);
+}
+
+// unary operations
+
+boolNDArray
+NDArray::operator ! (void) const
+{
+  boolNDArray b (dims ());
+
+  for (int i = 0; i < length (); i++)
+    b.elem (i) = ! elem (i);
+
+  return b;
+}
+
 // XXX FIXME XXX -- this is not quite the right thing.
 
 boolMatrix
@@ -156,6 +183,15 @@
   return true;
 }
 
+NDS_CMP_OPS(NDArray, , double, )
+NDS_BOOL_OPS(NDArray, double, 0.0)
+
+SND_CMP_OPS(double, , NDArray, )
+SND_BOOL_OPS(double, NDArray, 0.0)
+
+NDND_CMP_OPS(NDArray, , NDArray, )
+NDND_BOOL_OPS(NDArray, NDArray, 0.0)
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/liboctave/dNDArray.h	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/dNDArray.h	Sat Oct 18 03:53:53 2003 +0000
@@ -43,9 +43,10 @@
   
   NDArray (void) : MArrayN<double> () { }
 
-  NDArray (dim_vector& dims) : MArrayN<double> (dims) { }
+  NDArray (const dim_vector& dims) : MArrayN<double> (dims) { }
 
-  NDArray (dim_vector& dims, double val) : MArrayN<double> (dims, val) { }
+  NDArray (const dim_vector& dims, double val)
+    : MArrayN<double> (dims, val) { }
   
   NDArray (const NDArray& a) : MArrayN<double> (a) { }
 
@@ -55,12 +56,20 @@
 
   NDArray (const ArrayN<double>& a) : MArrayN<double> (a) { }
 
+  explicit NDArray (const boolNDArray& a);
+
+  explicit NDArray (const charNDArray& a);
+
   NDArray& operator = (const NDArray& a)
     {
       MArrayN<double>::operator = (a);
       return *this;
     }
 
+  // unary operations
+
+  boolNDArray operator ! (void) const;
+
   // XXX FIXME XXX -- this is not quite the right thing.
 
   boolMatrix all (int dim = -1) const;
@@ -89,6 +98,15 @@
   NDArray (double *d, dim_vector& dims) : MArrayN<double> (d, dims) { }
 };
 
+NDS_CMP_OP_DECLS (NDArray, double)
+NDS_BOOL_OP_DECLS (NDArray, double)
+
+SND_CMP_OP_DECLS (double, NDArray)
+SND_BOOL_OP_DECLS (double, NDArray)
+
+NDND_CMP_OP_DECLS (NDArray, NDArray)
+NDND_BOOL_OP_DECLS (NDArray, NDArray)
+
 MARRAY_FORWARD_DEFS (MArrayN, NDArray, double)
 
 #endif
--- a/liboctave/dim-vector.h	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/dim-vector.h	Sat Oct 18 03:53:53 2003 +0000
@@ -28,6 +28,9 @@
 #endif
 
 #include <cassert>
+#include <string>
+
+#include "lo-sstream.h"
 
 class
 dim_vector
@@ -116,12 +119,80 @@
 	ndims = n;
     }
 
+  std::string str (void) const
+    {
+      OSSTREAM buf;
+
+      for (int i = 0; i < ndims; i++)
+	{
+	  buf << dims[i];
+
+	  if (i < ndims - 1)
+	    buf << "x";
+	}
+
+      buf << OSSTREAM_ENDS;
+
+      std::string retval = OSSTREAM_STR (buf);
+
+      OSSTREAM_FREEZE (buf);
+
+      return retval;
+    }
+
+  bool all_zero (void) const
+    {
+      bool retval = true;
+
+      for (int i = 0; i < ndims; i++)
+	{
+	  if (dims[i] != 0)
+	    {
+	      retval = false;
+	      break;
+	    }
+	}
+
+      return retval;
+    }
+
 private:
 
   int ndims;
   int *dims;
 };
 
+static inline bool
+operator == (const dim_vector& a, const dim_vector& b)
+{
+  bool retval = true;
+
+  int a_len = a.length ();
+  int b_len = b.length ();
+
+  if (a_len != b_len)
+    retval = false;
+  else
+    {
+      for (int i = 0; i < a_len; i++)
+	{
+	  if (a(i) != b(i))
+	    {
+	      retval = false;
+	      break;
+	    }
+	}
+    }
+
+  return retval;
+}
+
+static inline bool
+operator != (const dim_vector& a, const dim_vector& b)
+{
+  return ! operator == (a, b);
+}
+
 #endif
 
 /*
--- a/liboctave/mx-cm-m.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/mx-cm-m.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -29,12 +29,18 @@
 #include "boolMatrix.h"
 #include "dMatrix.h"
 #include "CMatrix.h"
+#include "boolNDArray.h"
+#include "dNDArray.h"
+#include "CNDArray.h"
 
 MM_BIN_OPS (ComplexMatrix, ComplexMatrix, Matrix)
+NDND_BIN_OPS (ComplexNDArray, ComplexNDArray, NDArray)
 
 MM_CMP_OPS (ComplexMatrix, real, Matrix, )
+NDND_CMP_OPS (ComplexNDArray, real, NDArray, )
 
 MM_BOOL_OPS (ComplexMatrix, Matrix, 0.0)
+NDND_BOOL_OPS (ComplexNDArray, NDArray, 0.0)
 
 /*
 ;;; Local Variables: ***
--- a/liboctave/mx-cm-m.h	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/mx-cm-m.h	Sat Oct 18 03:53:53 2003 +0000
@@ -25,10 +25,13 @@
 
 class Matrix;
 class ComplexMatrix;
+class NDArray;
+class ComplexNDArray;
 
 #include "mx-op-defs.h"
 
 MM_OP_DECLS (ComplexMatrix, ComplexMatrix, Matrix)
+NDND_OP_DECLS (ComplexNDArray, ComplexNDArray, NDArray)
 
 #endif
 
--- a/liboctave/mx-cm-s.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/mx-cm-s.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -28,12 +28,17 @@
 
 #include "boolMatrix.h"
 #include "CMatrix.h"
+#include "boolNDArray.h"
+#include "CNDArray.h"
 
 MS_BIN_OPS (ComplexMatrix, ComplexMatrix, double)
+NDS_BIN_OPS (ComplexNDArray, ComplexNDArray, double)
 
 MS_CMP_OPS (ComplexMatrix, real, double, )
+NDS_CMP_OPS (ComplexNDArray, real, double, )
 
 MS_BOOL_OPS (ComplexMatrix, double, 0.0)
+NDS_BOOL_OPS (ComplexNDArray, double, 0.0)
 
 /*
 ;;; Local Variables: ***
--- a/liboctave/mx-cm-s.h	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/mx-cm-s.h	Sat Oct 18 03:53:53 2003 +0000
@@ -24,10 +24,12 @@
 #define octave_cm_s_h 1
 
 class ComplexMatrix;
+class ComplexNDArray;
 
 #include "mx-op-defs.h"
 
 MS_OP_DECLS (ComplexMatrix, ComplexMatrix, double)
+NDS_OP_DECLS (ComplexNDArray, ComplexNDArray, double)
 
 #endif
 
--- a/liboctave/mx-cs-m.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/mx-cs-m.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -29,12 +29,18 @@
 #include "boolMatrix.h"
 #include "dMatrix.h"
 #include "CMatrix.h"
+#include "boolNDArray.h"
+#include "dNDArray.h"
+#include "CNDArray.h"
 
 SM_BIN_OPS (ComplexMatrix, Complex, Matrix)
+SND_BIN_OPS (ComplexNDArray, Complex, NDArray)
 
 SM_CMP_OPS (Complex, real, Matrix, )
+SND_CMP_OPS (Complex, real, NDArray, )
 
 SM_BOOL_OPS (Complex, Matrix, 0.0)
+SND_BOOL_OPS (Complex, NDArray, 0.0)
 
 /*
 ;;; Local Variables: ***
--- a/liboctave/mx-cs-m.h	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/mx-cs-m.h	Sat Oct 18 03:53:53 2003 +0000
@@ -25,12 +25,15 @@
 
 class Matrix;
 class ComplexMatrix;
+class NDArray;
+class ComplexNDArray;
 
 #include "oct-cmplx.h"
 
 #include "mx-op-defs.h"
 
 SM_OP_DECLS (ComplexMatrix, Complex, Matrix)
+SND_OP_DECLS (ComplexNDArray, Complex, NDArray)
 
 #endif
 
--- a/liboctave/mx-defs.h	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/mx-defs.h	Sat Oct 18 03:53:53 2003 +0000
@@ -30,6 +30,11 @@
 class boolMatrix;
 class charMatrix;
 
+class NDArray;
+class ComplexNDArray;
+class boolNDArray;
+class charNDArray;
+
 class ColumnVector;
 class ComplexColumnVector;
 
--- a/liboctave/mx-m-cm.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/mx-m-cm.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -29,12 +29,18 @@
 #include "boolMatrix.h"
 #include "dMatrix.h"
 #include "CMatrix.h"
+#include "boolNDArray.h"
+#include "dNDArray.h"
+#include "CNDArray.h"
 
 MM_BIN_OPS (ComplexMatrix, Matrix, ComplexMatrix)
+NDND_BIN_OPS (ComplexNDArray, NDArray, ComplexNDArray)
 
 MM_CMP_OPS (Matrix, , ComplexMatrix, real)
+NDND_CMP_OPS (NDArray, , ComplexNDArray, real)
 
 MM_BOOL_OPS (Matrix, ComplexMatrix, 0.0)
+NDND_BOOL_OPS (NDArray, ComplexNDArray, 0.0)
 
 /*
 ;;; Local Variables: ***
--- a/liboctave/mx-m-cm.h	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/mx-m-cm.h	Sat Oct 18 03:53:53 2003 +0000
@@ -25,10 +25,13 @@
 
 class Matrix;
 class ComplexMatrix;
+class NDArray;
+class ComplexNDArray;
 
 #include "mx-op-defs.h"
 
 MM_OP_DECLS (ComplexMatrix, Matrix, ComplexMatrix)
+NDND_OP_DECLS (ComplexNDArray, NDArray, ComplexNDArray)
 
 #endif
 
--- a/liboctave/mx-m-cs.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/mx-m-cs.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -29,12 +29,18 @@
 #include "boolMatrix.h"
 #include "dMatrix.h"
 #include "CMatrix.h"
+#include "boolNDArray.h"
+#include "dNDArray.h"
+#include "CNDArray.h"
 
 MS_BIN_OPS (ComplexMatrix, Matrix, Complex)
+NDS_BIN_OPS (ComplexNDArray, NDArray, Complex)
 
 MS_CMP_OPS (Matrix, , Complex, real)
+NDS_CMP_OPS (NDArray, , Complex, real)
 
 MS_BOOL_OPS (Matrix, Complex, 0.0)
+NDS_BOOL_OPS (NDArray, Complex, 0.0)
 
 /*
 ;;; Local Variables: ***
--- a/liboctave/mx-m-cs.h	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/mx-m-cs.h	Sat Oct 18 03:53:53 2003 +0000
@@ -25,12 +25,15 @@
 
 class Matrix;
 class ComplexMatrix;
+class NDArray;
+class ComplexNDArray;
 
 #include "oct-cmplx.h"
 
 #include "mx-op-defs.h"
 
 MS_OP_DECLS (ComplexMatrix, Matrix, Complex)
+NDS_OP_DECLS (ComplexNDArray, NDArray, Complex)
 
 #endif
 
--- a/liboctave/mx-op-defs.h	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/mx-op-defs.h	Sat Oct 18 03:53:53 2003 +0000
@@ -29,13 +29,20 @@
   extern R OP (const X&, const Y&)
 
 class boolMatrix;
+class boolNDArray;
 
 #define CMP_OP_DECL(OP, X, Y) \
   extern boolMatrix OP (const X&, const Y&)
 
+#define NDCMP_OP_DECL(OP, X, Y) \
+  extern boolNDArray OP (const X&, const Y&)
+
 #define BOOL_OP_DECL(OP, X, Y) \
   extern boolMatrix OP (const X&, const Y&)
 
+#define NDBOOL_OP_DECL(OP, X, Y) \
+  extern boolNDArray OP (const X&, const Y&)
+
 #define TBM boolMatrix (1, 1, true)
 #define FBM boolMatrix (1, 1, false)
 #define NBM boolMatrix ()
@@ -482,6 +489,324 @@
   MM_CMP_OP_DECLS (M1, M2) \
   MM_BOOL_OP_DECLS (M1, M2)
 
+// N-d matrix by scalar operations.
+
+#define NDS_BIN_OP_DECLS(R, ND, S) \
+  BIN_OP_DECL (R, operator +, ND, S); \
+  BIN_OP_DECL (R, operator -, ND, S); \
+  BIN_OP_DECL (R, operator *, ND, S); \
+  BIN_OP_DECL (R, operator /, ND, S);
+
+#define NDS_BIN_OP(R, OP, ND, S, F) \
+  R \
+  OP (const ND& m, const S& s) \
+  { \
+    R r (m.dims ()); \
+ \
+    int len = m.length (); \
+ \
+    if (len > 0) \
+      F ## _vs (r.fortran_vec (), m.data (), len, s); \
+ \
+    return r; \
+  }
+
+#define NDS_BIN_OPS(R, ND, S) \
+  NDS_BIN_OP (R, operator +, ND, S, mx_inline_add) \
+  NDS_BIN_OP (R, operator -, ND, S, mx_inline_subtract) \
+  NDS_BIN_OP (R, operator *, ND, S, mx_inline_multiply) \
+  NDS_BIN_OP (R, operator /, ND, S, mx_inline_divide)
+
+#define NDS_CMP_OP_DECLS(ND, S) \
+  NDCMP_OP_DECL (mx_el_lt, ND, S); \
+  NDCMP_OP_DECL (mx_el_le, ND, S); \
+  NDCMP_OP_DECL (mx_el_ge, ND, S); \
+  NDCMP_OP_DECL (mx_el_gt, ND, S); \
+  NDCMP_OP_DECL (mx_el_eq, ND, S); \
+  NDCMP_OP_DECL (mx_el_ne, ND, S);
+
+#define NDS_CMP_OP(F, OP, ND, NDC, S, SC, EMPTY_RESULT) \
+  boolNDArray \
+  F (const ND& m, const S& s) \
+  { \
+    boolNDArray r; \
+ \
+    int len = m.length (); \
+ \
+    if (len == 0) \
+      r = EMPTY_RESULT; \
+    else \
+      { \
+	r.resize (m.dims ()); \
+ \
+	for (int i = 0; i < len; i++) \
+	  r.elem(i) = NDC (m.elem(i)) OP SC (s); \
+      } \
+ \
+    return r; \
+  }
+
+#define NDS_CMP_OPS(ND, NDC, S, SC) \
+  NDS_CMP_OP (mx_el_lt, <,  ND, NDC, S, SC, NBM) \
+  NDS_CMP_OP (mx_el_le, <=, ND, NDC, S, SC, NBM) \
+  NDS_CMP_OP (mx_el_ge, >=, ND, NDC, S, SC, NBM) \
+  NDS_CMP_OP (mx_el_gt, >,  ND, NDC, S, SC, NBM) \
+  NDS_CMP_OP (mx_el_eq, ==, ND,    , S,   , FBM) \
+  NDS_CMP_OP (mx_el_ne, !=, ND,    , S,   , TBM)
+
+#define NDS_BOOL_OP_DECLS(ND, S) \
+  NDBOOL_OP_DECL (mx_el_and, ND, S); \
+  NDBOOL_OP_DECL (mx_el_or,  ND, S);
+
+#define NDS_BOOL_OP(F, OP, ND, S, ZERO) \
+  boolNDArray \
+  F (const ND& m, const S& s) \
+  { \
+    boolNDArray r; \
+ \
+    int len = m.length (); \
+ \
+    if (len > 0) \
+      { \
+        r.resize (m.dims ()); \
+ \
+        for (int i = 0; i < len; i++) \
+	  r.elem(i) = (m.elem(i) != ZERO) OP (s != ZERO); \
+      } \
+ \
+    return r; \
+  }
+
+#define NDS_BOOL_OPS(ND, S, ZERO) \
+  NDS_BOOL_OP (mx_el_and, &&, ND, S, ZERO) \
+  NDS_BOOL_OP (mx_el_or,  ||, ND, S, ZERO)
+
+#define NDS_OP_DECLS(R, ND, S) \
+  NDS_BIN_OP_DECLS (R, ND, S) \
+  NDS_CMP_OP_DECLS (ND, S) \
+  NDS_BOOL_OP_DECLS (ND, S)
+
+// scalar by N-d matrix operations.
+
+#define SND_BIN_OP_DECLS(R, S, ND) \
+  BIN_OP_DECL (R, operator +, S, ND); \
+  BIN_OP_DECL (R, operator -, S, ND); \
+  BIN_OP_DECL (R, operator *, S, ND); \
+  BIN_OP_DECL (R, operator /, S, ND);
+
+#define SND_BIN_OP(R, OP, S, ND, F) \
+  R \
+  OP (const S& s, const ND& m) \
+  { \
+    R r (m.dims ()); \
+ \
+    int len = m.length (); \
+ \
+    if (len > 0) \
+      F ## _sv (r.fortran_vec (), s, m.data (), len); \
+ \
+    return r; \
+  }
+
+#define SND_BIN_OPS(R, S, ND) \
+  SND_BIN_OP (R, operator +, S, ND, mx_inline_add) \
+  SND_BIN_OP (R, operator -, S, ND, mx_inline_subtract) \
+  SND_BIN_OP (R, operator *, S, ND, mx_inline_multiply) \
+  SND_BIN_OP (R, operator /, S, ND, mx_inline_divide)
+
+#define SND_CMP_OP_DECLS(S, ND) \
+  NDCMP_OP_DECL (mx_el_lt, S, ND); \
+  NDCMP_OP_DECL (mx_el_le, S, ND); \
+  NDCMP_OP_DECL (mx_el_ge, S, ND); \
+  NDCMP_OP_DECL (mx_el_gt, S, ND); \
+  NDCMP_OP_DECL (mx_el_eq, S, ND); \
+  NDCMP_OP_DECL (mx_el_ne, S, ND);
+
+#define SND_CMP_OP(F, OP, S, SC, ND, NDC, EMPTY_RESULT) \
+  boolNDArray \
+  F (const S& s, const ND& m) \
+  { \
+    boolNDArray r; \
+ \
+    int len = m.length (); \
+ \
+    if (len == 0) \
+      r = EMPTY_RESULT; \
+    else \
+      { \
+        r.resize (m.dims ()); \
+ \
+        for (int i = 0; i < len; i++) \
+	    r.elem(i) = SC (s) OP NDC (m.elem(i)); \
+      } \
+ \
+    return r; \
+  }
+
+#define SND_CMP_OPS(S, CS, ND, CND) \
+  SND_CMP_OP (mx_el_lt, <,  S, CS, ND, CND, NBM) \
+  SND_CMP_OP (mx_el_le, <=, S, CS, ND, CND, NBM) \
+  SND_CMP_OP (mx_el_ge, >=, S, CS, ND, CND, NBM) \
+  SND_CMP_OP (mx_el_gt, >,  S, CS, ND, CND, NBM) \
+  SND_CMP_OP (mx_el_eq, ==, S,   , ND,    , FBM) \
+  SND_CMP_OP (mx_el_ne, !=, S,   , ND,    , TBM)
+
+#define SND_BOOL_OP_DECLS(S, ND) \
+  NDBOOL_OP_DECL (mx_el_and, S, ND); \
+  NDBOOL_OP_DECL (mx_el_or,  S, ND);
+
+#define SND_BOOL_OP(F, OP, S, ND, ZERO) \
+  boolNDArray \
+  F (const S& s, const ND& m) \
+  { \
+    boolNDArray r; \
+ \
+    int len = m.length (); \
+ \
+    if (len > 0) \
+      { \
+        r.resize (m.dims ()); \
+ \
+        for (int i = 0; i < len; i++) \
+	    r.elem(i) = (s != ZERO) OP (m.elem(i) != ZERO); \
+      } \
+ \
+    return r; \
+  }
+
+#define SND_BOOL_OPS(S, ND, ZERO) \
+  SND_BOOL_OP (mx_el_and, &&, S, ND, ZERO) \
+  SND_BOOL_OP (mx_el_or,  ||, S, ND, ZERO)
+
+#define SND_OP_DECLS(R, S, ND) \
+  SND_BIN_OP_DECLS (R, S, ND) \
+  SND_CMP_OP_DECLS (S, ND) \
+  SND_BOOL_OP_DECLS (S, ND)
+
+// N-d matrix by N-d matrix operations.
+
+#define NDND_BIN_OP_DECLS(R, ND1, ND2) \
+  BIN_OP_DECL (R, operator +, ND1, ND2); \
+  BIN_OP_DECL (R, operator -, ND1, ND2); \
+  BIN_OP_DECL (R, product,    ND1, ND2); \
+  BIN_OP_DECL (R, quotient,   ND1, ND2);
+
+#define NDND_BIN_OP(R, OP, ND1, ND2, F) \
+  R \
+  OP (const ND1& m1, const ND2& m2) \
+  { \
+    R r; \
+ \
+    dim_vector m1_dims = m1.dims (); \
+    dim_vector m2_dims = m2.dims (); \
+ \
+    if (m1_dims != m2_dims) \
+      gripe_nonconformant (#OP, m1_dims, m2_dims); \
+    else \
+      { \
+	r.resize (m1_dims); \
+ \
+	int len = m1.length (); \
+ \
+	if (len > 0) \
+	  F ## _vv (r.fortran_vec (), m1.data (), m2.data (), len); \
+      } \
+ \
+    return r; \
+  }
+
+#define NDND_BIN_OPS(R, ND1, ND2) \
+  NDND_BIN_OP (R, operator +, ND1, ND2, mx_inline_add) \
+  NDND_BIN_OP (R, operator -, ND1, ND2, mx_inline_subtract) \
+  NDND_BIN_OP (R, product,    ND1, ND2, mx_inline_multiply) \
+  NDND_BIN_OP (R, quotient,   ND1, ND2, mx_inline_divide)
+
+#define NDND_CMP_OP_DECLS(ND1, ND2) \
+  NDCMP_OP_DECL (mx_el_lt, ND1, ND2); \
+  NDCMP_OP_DECL (mx_el_le, ND1, ND2); \
+  NDCMP_OP_DECL (mx_el_ge, ND1, ND2); \
+  NDCMP_OP_DECL (mx_el_gt, ND1, ND2); \
+  NDCMP_OP_DECL (mx_el_eq, ND1, ND2); \
+  NDCMP_OP_DECL (mx_el_ne, ND1, ND2);
+
+#define NDND_CMP_OP(F, OP, ND1, C1, ND2, C2, ONE_MT_RESULT, TWO_MT_RESULT) \
+  boolNDArray \
+  F (const ND1& m1, const ND2& m2) \
+  { \
+    boolNDArray r; \
+ \
+    dim_vector m1_dims = m1.dims (); \
+    dim_vector m2_dims = m2.dims (); \
+ \
+    if (m1_dims == m2_dims) \
+      { \
+	if (m1_dims.all_zero ()) \
+	  r = TWO_MT_RESULT; \
+	else \
+	  { \
+	    r.resize (m1_dims); \
+ \
+	    for (int i = 0; i < m1.length (); i++) \
+	      r.elem(i) = C1 (m1.elem(i)) OP C2 (m2.elem(i)); \
+	  } \
+      } \
+    else \
+      { \
+	if (m1_dims.all_zero () || m2_dims.all_zero ()) \
+	  r = ONE_MT_RESULT; \
+	else \
+	  gripe_nonconformant (#F, m1_dims, m2_dims); \
+      } \
+ \
+    return r; \
+  }
+
+#define NDND_CMP_OPS(ND1, C1, ND2, C2) \
+  NDND_CMP_OP (mx_el_lt, <,  ND1, C1, ND2, C2, NBM, NBM) \
+  NDND_CMP_OP (mx_el_le, <=, ND1, C1, ND2, C2, NBM, NBM) \
+  NDND_CMP_OP (mx_el_ge, >=, ND1, C1, ND2, C2, NBM, NBM) \
+  NDND_CMP_OP (mx_el_gt, >,  ND1, C1, ND2, C2, NBM, NBM) \
+  NDND_CMP_OP (mx_el_eq, ==, ND1,   , ND2,   , FBM, TBM) \
+  NDND_CMP_OP (mx_el_ne, !=, ND1,   , ND2,   , TBM, FBM)
+
+#define NDND_BOOL_OP_DECLS(ND1, ND2) \
+  NDBOOL_OP_DECL (mx_el_and, ND1, ND2); \
+  NDBOOL_OP_DECL (mx_el_or,  ND1, ND2);
+
+#define NDND_BOOL_OP(F, OP, ND1, ND2, ZERO) \
+  boolNDArray \
+  F (const ND1& m1, const ND2& m2) \
+  { \
+    boolNDArray r; \
+ \
+    dim_vector m1_dims = m1.dims (); \
+    dim_vector m2_dims = m2.dims (); \
+ \
+    if (m1_dims == m2_dims) \
+      { \
+	if (! m1_dims.all_zero ()) \
+	  { \
+	    r.resize (m1_dims); \
+ \
+	    for (int i = 0; i < m1.length (); i++) \
+	      r.elem(i) = (m1.elem(i) != ZERO) OP (m2.elem(i) != ZERO); \
+	  } \
+      } \
+    else \
+      gripe_nonconformant (#F, m1_dims, m2_dims); \
+ \
+    return r; \
+  }
+
+#define NDND_BOOL_OPS(ND1, ND2, ZERO) \
+  NDND_BOOL_OP (mx_el_and, &&, ND1, ND2, ZERO) \
+  NDND_BOOL_OP (mx_el_or,  ||, ND1, ND2, ZERO)
+
+#define NDND_OP_DECLS(R, ND1, ND2) \
+  NDND_BIN_OP_DECLS (R, ND1, ND2) \
+  NDND_CMP_OP_DECLS (ND1, ND2) \
+  NDND_BOOL_OP_DECLS (ND1, ND2)
+
 // scalar by diagonal matrix operations.
 
 #define SDM_BIN_OP_DECLS(R, S, DM) \
@@ -497,9 +822,7 @@
  \
     R r (nr, nc, s); \
  \
-    int len = dm.length (); \
- \
-    for (int i = 0; i < len; i++) \
+    for (int i = 0; i < dm.length (); i++) \
       r.elem(i, i) OPEQ dm.elem(i, i); \
  \
     return r; \
@@ -527,9 +850,7 @@
  \
     R r (nr, nc, SGN s); \
  \
-    int len = dm.length (); \
- \
-    for (int i = 0; i < len; i++) \
+    for (int i = 0; i < dm.length (); i++) \
       r.elem(i, i) += dm.elem(i, i); \
  \
     return r; \
@@ -601,7 +922,9 @@
  \
       if (m_nr > 0 && m_nc > 0 && dm_nc > 0) \
 	{ \
-	  for (int j = 0; j < dm.length (); j++) \
+	  int len = dm.length (); \
+ \
+	  for (int j = 0; j < len; j++) \
 	    { \
 	      if (dm.elem(j, j) == 1.0) \
 		{ \
@@ -687,7 +1010,9 @@
  \
       if (dm_nr > 0 && dm_nc > 0 && m_nc > 0) \
 	{ \
-	  for (int i = 0; i < dm.length (); i++) \
+	  int len = dm.length (); \
+ \
+	  for (int i = 0; i < len; i++) \
 	    { \
 	      if (dm.elem(i, i) == 1.0) \
 		{ \
--- a/liboctave/mx-s-cm.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/mx-s-cm.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -28,12 +28,17 @@
 
 #include "boolMatrix.h"
 #include "CMatrix.h"
+#include "boolNDArray.h"
+#include "CNDArray.h"
 
 SM_BIN_OPS (ComplexMatrix, double, ComplexMatrix)
+SND_BIN_OPS (ComplexNDArray, double, ComplexNDArray)
 
 SM_CMP_OPS (double, , ComplexMatrix, real)
+SND_CMP_OPS (double, , ComplexNDArray, real)
 
 SM_BOOL_OPS (double, ComplexMatrix, 0.0)
+SND_BOOL_OPS (double, ComplexNDArray, 0.0)
 
 /*
 ;;; Local Variables: ***
--- a/liboctave/mx-s-cm.h	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/mx-s-cm.h	Sat Oct 18 03:53:53 2003 +0000
@@ -24,10 +24,12 @@
 #define octave_s_cm_h 1
 
 class ComplexMatrix;
+class ComplexNDArray;
 
 #include "mx-op-defs.h"
 
 SM_OP_DECLS (ComplexMatrix, double, ComplexMatrix)
+SND_OP_DECLS (ComplexNDArray, double, ComplexNDArray)
 
 #endif
 
--- a/liboctave/oct-rand.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/oct-rand.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -249,6 +249,51 @@
   return retval;
 }
 
+#define MAKE_RAND_ND_ARRAY(mat, len, f, F) \
+  do \
+    { \
+      double val; \
+      for (volatile int i = 0; i < len; i++) \
+	{ \
+	  OCTAVE_QUIT; \
+	  F77_FUNC (f, F) (0.0, 1.0, val); \
+	  mat(i) = val; \
+	} \
+    } \
+  while (0)
+
+NDArray
+octave_rand::nd_array (const dim_vector& dims)
+{
+  maybe_initialize ();
+
+  NDArray retval;
+
+  if (! dims.all_zero ())
+    {
+      retval.resize (dims);
+
+      int len = retval.length ();
+
+      switch (current_distribution)
+	{
+	case uniform_dist:
+	  MAKE_RAND_ND_ARRAY (retval, len, dgenunf, DGENUNF);
+	  break;
+
+	case normal_dist:
+	  MAKE_RAND_ND_ARRAY (retval, len, dgennor, DGENNOR);
+	  break;
+
+	default:
+	  abort ();
+	  break;
+	}
+    }
+
+  return retval;
+}
+
 #define MAKE_RAND_ARRAY(array, n, f, F) \
   do \
     { \
--- a/liboctave/oct-rand.h	Fri Oct 17 04:41:36 2003 +0000
+++ b/liboctave/oct-rand.h	Sat Oct 18 03:53:53 2003 +0000
@@ -26,6 +26,7 @@
 #include <string>
 
 #include "dMatrix.h"
+#include "dNDArray.h"
 
 struct
 octave_rand
@@ -54,6 +55,10 @@
   // major order.
   static Matrix matrix (int r, int c);
 
+  // Return an N-dimensional array of numbers from the sequence,
+  // filled in column major order.
+  static NDArray nd_array (const dim_vector& dims);
+
   // Return an array of numbers from the sequence.
   static Array<double> vector (int n);
 };
--- a/src/ChangeLog	Fri Oct 17 04:41:36 2003 +0000
+++ b/src/ChangeLog	Sat Oct 18 03:53:53 2003 +0000
@@ -1,3 +1,45 @@
+2003-10-17  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* ops.h (DEFNDUNOP_OP, DEFNDUNOP_FN, DEFNDBINOP_OP,
+	DEFNDBINOP_FN): New N-dimensional macros.
+	* src/OPERATORS/op-bm-bm.cc, src/OPERATORS/op-cm-cm.cc,
+	src/OPERATORS/op-cm-cs.cc, src/OPERATORS/op-cm-m.cc,
+	src/OPERATORS/op-cm-s.cc, src/OPERATORS/op-cs-cm.cc,
+	src/OPERATORS/op-cs-m.cc, src/OPERATORS/op-m-cm.cc,
+	src/OPERATORS/op-m-cs.cc, src/OPERATORS/op-m-m.cc,
+	src/OPERATORS/op-m-s.cc, src/OPERATORS/op-s-cm.cc,
+	src/OPERATORS/op-s-m.cc: Use N-dimensional macros as appropriate.
+
+	* DLD-FUNCTIONS/rand.cc (do_rand, Frand, Frandn):
+	Handle N-dimensions.
+
+	* xpow.cc (elem_xpow (double, const NDArray&),
+	elem_xpow (double, const ComplexNDArray&),
+	elem_xpow (const NDArray&, double),
+	elem_xpow (const NDArray&, const NDArray&),
+	elem_xpow (const NDArray&, const Complex&),
+	elem_xpow (const NDArray&, const ComplexNDArray&),
+	elem_xpow (const Complex&, const NDArray&),
+	elem_xpow (const Complex&, const ComplexNDArray&),
+	elem_xpow (const ComplexNDArray&, double),
+	elem_xpow (const ComplexNDArray&, const NDArray&),
+	elem_xpow (const ComplexNDArray&, const Complex&),
+	elem_xpow (const ComplexNDArray&, const ComplexNDArray&):
+	New functions.
+	* xpow.h: Provide decls.
+
+	* xdiv.cc (x_el_div (double, const NDArray&),
+	x_el_div (double, const ComplexNDArray&),
+	x_el_div (const Complex, const NDArray&),
+	x_el_div (const Complex, const ComplexNDArray&)): New functions.
+	* xdiv.h: Provide decls.
+
+	* ov-bool-mat.h (boolNDArray::array_value): New function.
+	* ov-ch-mat.h (charNDArray::array_value): New function.
+	* ov-cx-mat.h (ComplexNDArray::array_value): New function.
+	* ov-re-mat.h (NDArray::array_value): New function.
+	(NDArray::double_nd_array_value): Delete.
+
 2003-10-16  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
 	* parse.y (text_getc): New static function.
--- a/src/DLD-FUNCTIONS/rand.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/src/DLD-FUNCTIONS/rand.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -41,146 +41,183 @@
 #include "utils.h"
 
 static octave_value
-do_rand (const octave_value_list& args, int nargin)
+do_rand (const octave_value_list& args, int nargin, const char *fcn)
 {
   octave_value retval;
 
-  volatile int n = 0;
-  volatile int m = 0;
+  dim_vector dims;
 
-  if (nargin == 0)
+  switch (nargin)
     {
-      n = 1;
-      m = 1;
+    case 0:
+      {
+	dims.resize (2);
+
+	dims(0) = 1;
+	dims(1) = 1;
 
-      goto gen_matrix;
-    }
-  else if (nargin == 1)
-    {
-      octave_value tmp = args(0);
+	goto gen_matrix;
+      }
+      break;
 
-      if (tmp.is_string ())
-	{
-	  std::string s_arg = tmp.string_value ();
+    case 1:
+      {
+	octave_value tmp = args(0);
+
+	if (tmp.is_string ())
+	  {
+	    std::string s_arg = tmp.string_value ();
 
-	  if (s_arg == "dist")
-	    {
-	      retval = octave_rand::distribution ();
-	    }
-	  else if (s_arg == "seed")
-	    {
-	      retval = octave_rand::seed ();
-	    }
-	  else if (s_arg == "uniform")
-	    {
-	      octave_rand::uniform_distribution ();
-	    }
-	  else if (s_arg == "normal")
-	    {
-	      octave_rand::normal_distribution ();
-	    }
-	  else
-	    error ("rand: unrecognized string argument");
-	}
-      else if (tmp.is_scalar_type ())
-	{
-	  double dval = tmp.double_value ();
+	    if (s_arg == "dist")
+	      {
+		retval = octave_rand::distribution ();
+	      }
+	    else if (s_arg == "seed")
+	      {
+		retval = octave_rand::seed ();
+	      }
+	    else if (s_arg == "uniform")
+	      {
+		octave_rand::uniform_distribution ();
+	      }
+	    else if (s_arg == "normal")
+	      {
+		octave_rand::normal_distribution ();
+	      }
+	    else
+	      error ("rand: unrecognized string argument");
+	  }
+	else if (tmp.is_scalar_type ())
+	  {
+	    double dval = tmp.double_value ();
 
-	  if (xisnan (dval))
-	    {
-	      error ("rand: NaN is invalid a matrix dimension");
-	    }
-	  else
-	    {
-	      m = n = NINT (tmp.double_value ());
+	    if (xisnan (dval))
+	      {
+		error ("rand: NaN is invalid a matrix dimension");
+	      }
+	    else
+	      {
+		dims.resize (2);
+
+		dims(0) = NINT (tmp.double_value ());
+		dims(1) = NINT (tmp.double_value ());
 
-	      if (! error_state)
-		goto gen_matrix;
-	    }
-	}
-      else if (tmp.is_range ())
-	{
-	  Range r = tmp.range_value ();
-	  n = 1;
-	  m = r.nelem ();
-	  goto gen_matrix;
-	}
-      else if (tmp.is_matrix_type ())
-	{
-	  // XXX FIXME XXX -- this should probably use the function
-	  // from data.cc.
+		if (! error_state)
+		  goto gen_matrix;
+	      }
+	  }
+	else if (tmp.is_range ())
+	  {
+	    Range r = tmp.range_value ();
+
+	    if (r.all_elements_are_ints ())
+	      {
+		int n = r.nelem ();
+
+		dims.resize (n);
+
+		int base = NINT (r.base ());
+		int incr = NINT (r.inc ());
+		int lim = NINT (r.limit ());
 
-	  Matrix a = args(0).matrix_value ();
+		if (base < 0 || lim < 0)
+		  error ("rand: all dimensions must be nonnegative");
+		else
+		  {
+		    for (int i = 0; i < n; i++)
+		      {
+			dims(i) = base;
+			base += incr;
+		      }
 
-	  if (error_state)
-	    return retval;
+		    goto gen_matrix;
+		  }
+	      }
+	    else
+	      error ("rand: expecting all elements of range to be integers");
+	  }
+	else if (tmp.is_matrix_type ())
+	  {
+	    Array<int> iv = tmp.int_vector_value (true);
+
+	    if (! error_state)
+	      {
+		int len = iv.length ();
 
-	  n = a.rows ();
-	  m = a.columns ();
+		dims.resize (len);
+
+		for (int i = 0; i < len; i++)
+		  {
+		    int elt = iv(i);
+
+		    if (elt < 0)
+		      {
+			error ("rand: all dimensions must be nonnegative");
+			goto done;
+		      }
+
+		    dims(i) = iv(i);
+		  }
 
-	  if (n == 1 && m == 2)
-	    {
-	      n = NINT (a (0, 0));
-	      m = NINT (a (0, 1));
-	    }
-	  else if (n == 2 && m == 1)
-	    {
-	      n = NINT (a (0, 0));
-	      m = NINT (a (1, 0));
-	    }
-	  else
-	    warning ("rand (A): use rand (size (A)) instead");
+		goto gen_matrix;
+	      }
+	    else
+	      error ("rand: expecting integer vector");
+	  }
+	else
+	  {
+	    gripe_wrong_type_arg ("rand", tmp);
+	    return retval;
+	  }
+      }
+      break;
+
+    default:
+      {
+	octave_value tmp = args(0);
+
+	if (nargin == 2 && tmp.is_string ())
+	  {
+	    if (tmp.string_value () == "seed")
+	      {
+		double d = args(1).double_value ();
 
-	  goto gen_matrix;
-	}
-      else
-	{
-	  gripe_wrong_type_arg ("rand", tmp);
-	  return retval;
-	}
+		if (! error_state)
+		  octave_rand::seed (d);
+	      }
+	    else
+	      error ("rand: unrecognized string argument");
+	  }
+	else
+	  {
+	    int nargin = args.length ();
+
+	    dims.resize (nargin);
+
+	    for (int i = 0; i < nargin; i++)
+	      {
+		dims(i) = args(i).int_value ();
+
+		if (error_state)
+		  {
+		    error ("rand: expecting integer arguments");
+		    goto done;
+		  }
+	      }
+
+	    goto gen_matrix;
+	  }
+      }
+      break;
     }
-  else if (nargin == 2)
-    {
-      if (args(0).is_string ())
-	{
-	  if (args(0).string_value () == "seed")
-	    {
-	      double d = args(1).double_value ();
 
-	      if (! error_state)
-		octave_rand::seed (d);
-	    }
-	  else
-	    error ("rand: unrecognized string argument");
-	}
-      else
-	{
-	  double dval = args(0).double_value ();
-
-	  if (xisnan (dval))
-	    {
-	      error ("rand: NaN is invalid as a matrix dimension");
-	    }
-	  else
-	    {
-	      n = NINT (dval);
-
-	      if (! error_state)
-		{
-		  m = NINT (args(1).double_value ());
-
-		  if (! error_state)
-		    goto gen_matrix;
-		}
-	    }
-	}
-    }
+ done:
 
   return retval;
 
  gen_matrix:
 
-  return octave_rand::matrix (n, m);
+  return octave_rand::nd_array (dims);
 }
 
 DEFUN_DLD (rand, args, nargout,
@@ -213,10 +250,7 @@
 
   int nargin = args.length ();
 
-  if (nargin > 2 || nargout > 1)
-    print_usage ("rand");
-  else
-    retval = do_rand (args, nargin);
+  retval = do_rand (args, nargin, "rand");
 
   return retval;
 }
@@ -258,28 +292,23 @@
 
   int nargin = args.length ();
 
-  if (nargin > 2 || nargout > 1)
-    print_usage ("randn");
-  else
-    {
-      unwind_protect::begin_frame ("randn");
+  unwind_protect::begin_frame ("randn");
 
-      // This relies on the fact that elements are popped from the
-      // unwind stack in the reverse of the order they are pushed
-      // (i.e. current_distribution will be reset before calling
-      // reset_rand_generator()).
+  // This relies on the fact that elements are popped from the unwind
+  // stack in the reverse of the order they are pushed
+  // (i.e. current_distribution will be reset before calling
+  // reset_rand_generator()).
 
-      unwind_protect::add (reset_rand_generator, 0);
-      unwind_protect_str (current_distribution);
+  unwind_protect::add (reset_rand_generator, 0);
+  unwind_protect_str (current_distribution);
 
-      current_distribution = "normal";
+  current_distribution = "normal";
 
-      octave_rand::distribution (current_distribution);
+  octave_rand::distribution (current_distribution);
 
-      retval = do_rand (args, nargin);
+  retval = do_rand (args, nargin, "randn");
 
-      unwind_protect::run_frame ("randn");
-    }
+  unwind_protect::run_frame ("randn");
 
   return retval;
 }
--- a/src/OPERATORS/op-bm-bm.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/src/OPERATORS/op-bm-bm.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -39,7 +39,7 @@
 
 // unary bool matrix ops.
 
-DEFUNOP_OP (not, bool_matrix, !)
+DEFNDUNOP_OP (not, bool_matrix, !)
 
 DEFUNOP (transpose, bool_matrix)
 {
@@ -50,8 +50,8 @@
 
 // bool matrix by bool matrix ops.
 
-DEFBINOP_FN (eq, bool_matrix, bool_matrix, mx_el_eq)
-DEFBINOP_FN (ne, bool_matrix, bool_matrix, mx_el_ne)
+DEFNDBINOP_FN (eq, bool_matrix, bool_matrix, array, array, mx_el_eq)
+DEFNDBINOP_FN (ne, bool_matrix, bool_matrix, array, array, mx_el_ne)
 
 void
 install_bm_bm_ops (void)
--- a/src/OPERATORS/op-cm-cm.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/src/OPERATORS/op-cm-cm.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -39,8 +39,8 @@
 
 // unary complex matrix ops.
 
-DEFUNOP_OP (not, complex_matrix, !)
-DEFUNOP_OP (uminus, complex_matrix, -)
+DEFNDUNOP_OP (not, complex_matrix, !)
+DEFNDUNOP_OP (uminus, complex_matrix, -)
 
 DEFUNOP (transpose, complex_matrix)
 {
@@ -61,8 +61,9 @@
 
 // complex matrix by complex matrix ops.
 
-DEFBINOP_OP (add, complex_matrix, complex_matrix, +)
-DEFBINOP_OP (sub, complex_matrix, complex_matrix, -)
+DEFNDBINOP_OP (add, complex_matrix, complex_matrix, array, array, +)
+DEFNDBINOP_OP (sub, complex_matrix, complex_matrix, array, array, -)
+
 DEFBINOP_OP (mul, complex_matrix, complex_matrix, *)
 DEFBINOP_FN (div, complex_matrix, complex_matrix, xdiv)
 
@@ -74,27 +75,26 @@
 
 DEFBINOP_FN (ldiv, complex_matrix, complex_matrix, xleftdiv)
 
-DEFBINOP_FN (lt, complex_matrix, complex_matrix, mx_el_lt)
-DEFBINOP_FN (le, complex_matrix, complex_matrix, mx_el_le)
-DEFBINOP_FN (eq, complex_matrix, complex_matrix, mx_el_eq)
-DEFBINOP_FN (ge, complex_matrix, complex_matrix, mx_el_ge)
-DEFBINOP_FN (gt, complex_matrix, complex_matrix, mx_el_gt)
-DEFBINOP_FN (ne, complex_matrix, complex_matrix, mx_el_ne)
+DEFNDBINOP_FN (lt, complex_matrix, complex_matrix, array, array, mx_el_lt)
+DEFNDBINOP_FN (le, complex_matrix, complex_matrix, array, array, mx_el_le)
+DEFNDBINOP_FN (eq, complex_matrix, complex_matrix, array, array, mx_el_eq)
+DEFNDBINOP_FN (ge, complex_matrix, complex_matrix, array, array, mx_el_ge)
+DEFNDBINOP_FN (gt, complex_matrix, complex_matrix, array, array, mx_el_gt)
+DEFNDBINOP_FN (ne, complex_matrix, complex_matrix, array, array, mx_el_ne)
 
-DEFBINOP_FN (el_mul, complex_matrix, complex_matrix, product)
-DEFBINOP_FN (el_div, complex_matrix, complex_matrix, quotient)
-DEFBINOP_FN (el_pow, complex_matrix, complex_matrix, elem_xpow)
+DEFNDBINOP_FN (el_mul, complex_matrix, complex_matrix, array, array, product)
+DEFNDBINOP_FN (el_div, complex_matrix, complex_matrix, array, array, quotient)
+DEFNDBINOP_FN (el_pow, complex_matrix, complex_matrix, array, array, elem_xpow)
 
 DEFBINOP (el_ldiv, complex_matrix, complex_matrix)
 {
   CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_complex_matrix&);
 
-  return octave_value (quotient (v2.complex_matrix_value (),
-				 v1.complex_matrix_value ()));
+  return octave_value (quotient (v2.array_value (), v1.array_value ()));
 }
 
-DEFBINOP_FN (el_and, complex_matrix, complex_matrix, mx_el_and)
-DEFBINOP_FN (el_or, complex_matrix, complex_matrix, mx_el_or)
+DEFNDBINOP_FN (el_and, complex_matrix, complex_matrix, array, array, mx_el_and)
+DEFNDBINOP_FN (el_or,  complex_matrix, complex_matrix, array, array, mx_el_or)
 
 DEFASSIGNOP_FN (assign, complex_matrix, complex_matrix, assign)
 
--- a/src/OPERATORS/op-cm-cs.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/src/OPERATORS/op-cm-cs.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -40,9 +40,9 @@
 
 // complex matrix by complex scalar ops.
 
-DEFBINOP_OP (add, complex_matrix, complex, +)
-DEFBINOP_OP (sub, complex_matrix, complex, -)
-DEFBINOP_OP (mul, complex_matrix, complex, *)
+DEFNDBINOP_OP (add, complex_matrix, complex, array, complex, +)
+DEFNDBINOP_OP (sub, complex_matrix, complex, array, complex, -)
+DEFNDBINOP_OP (mul, complex_matrix, complex, array, complex, *)
 
 DEFBINOP (div, complex_matrix, complex)
 {
@@ -53,7 +53,7 @@
   if (d == 0.0)
     gripe_divide_by_zero ();
 
-  return octave_value (v1.complex_matrix_value () / d);
+  return octave_value (v1.array_value () / d);
 }
 
 DEFBINOP_FN (pow, complex_matrix, complex, xpow)
@@ -68,14 +68,14 @@
   return octave_value (xleftdiv (m1, m2));
 }
 
-DEFBINOP_FN (lt, complex_matrix, complex, mx_el_lt)
-DEFBINOP_FN (le, complex_matrix, complex, mx_el_le)
-DEFBINOP_FN (eq, complex_matrix, complex, mx_el_eq)
-DEFBINOP_FN (ge, complex_matrix, complex, mx_el_ge)
-DEFBINOP_FN (gt, complex_matrix, complex, mx_el_gt)
-DEFBINOP_FN (ne, complex_matrix, complex, mx_el_ne)
+DEFNDBINOP_FN (lt, complex_matrix, complex, array, complex, mx_el_lt)
+DEFNDBINOP_FN (le, complex_matrix, complex, array, complex, mx_el_le)
+DEFNDBINOP_FN (eq, complex_matrix, complex, array, complex, mx_el_eq)
+DEFNDBINOP_FN (ge, complex_matrix, complex, array, complex, mx_el_ge)
+DEFNDBINOP_FN (gt, complex_matrix, complex, array, complex, mx_el_gt)
+DEFNDBINOP_FN (ne, complex_matrix, complex, array, complex, mx_el_ne)
 
-DEFBINOP_OP (el_mul, complex_matrix, complex, *)
+DEFNDBINOP_OP (el_mul, complex_matrix, complex, array, complex, *)
 
 DEFBINOP (el_div, complex_matrix, complex)
 {
@@ -86,20 +86,20 @@
   if (d == 0.0)
     gripe_divide_by_zero ();
 
-  return octave_value (v1.complex_matrix_value () / d);
+  return octave_value (v1.array_value () / d);
 }
 
-DEFBINOP_FN (el_pow, complex_matrix, complex, elem_xpow)
+DEFNDBINOP_FN (el_pow, complex_matrix, complex, array, complex, elem_xpow)
 
 DEFBINOP (el_ldiv, complex_matrix, complex)
 {
   CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_complex&);
 
-  return x_el_div (v2.complex_value (), v1.complex_matrix_value ());
+  return x_el_div (v2.complex_value (), v1.array_value ());
 }
 
-DEFBINOP_FN (el_and, complex_matrix, complex, mx_el_and)
-DEFBINOP_FN (el_or, complex_matrix, complex, mx_el_or)
+DEFNDBINOP_FN (el_and, complex_matrix, complex, array, complex, mx_el_and)
+DEFNDBINOP_FN (el_or,  complex_matrix, complex, array, complex, mx_el_or)
 
 DEFASSIGNOP_FN (assign, complex_matrix, complex, assign)
 
--- a/src/OPERATORS/op-cm-m.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/src/OPERATORS/op-cm-m.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -43,8 +43,9 @@
 
 // complex matrix by matrix ops.
 
-DEFBINOP_OP (add, complex_matrix, matrix, +)
-DEFBINOP_OP (sub, complex_matrix, matrix, -)
+DEFNDBINOP_OP (add, complex_matrix, matrix, array, array, +)
+DEFNDBINOP_OP (sub, complex_matrix, matrix, array, array, -)
+
 DEFBINOP_OP (mul, complex_matrix, matrix, *)
 DEFBINOP_FN (div, complex_matrix, matrix, xdiv)
 
@@ -56,26 +57,26 @@
 
 DEFBINOP_FN (ldiv, complex_matrix, matrix, xleftdiv)
 
-DEFBINOP_FN (lt, complex_matrix, matrix, mx_el_lt)
-DEFBINOP_FN (le, complex_matrix, matrix, mx_el_le)
-DEFBINOP_FN (eq, complex_matrix, matrix, mx_el_eq)
-DEFBINOP_FN (ge, complex_matrix, matrix, mx_el_ge)
-DEFBINOP_FN (gt, complex_matrix, matrix, mx_el_gt)
-DEFBINOP_FN (ne, complex_matrix, matrix, mx_el_ne)
+DEFNDBINOP_FN (lt, complex_matrix, matrix, array, array, mx_el_lt)
+DEFNDBINOP_FN (le, complex_matrix, matrix, array, array, mx_el_le)
+DEFNDBINOP_FN (eq, complex_matrix, matrix, array, array, mx_el_eq)
+DEFNDBINOP_FN (ge, complex_matrix, matrix, array, array, mx_el_ge)
+DEFNDBINOP_FN (gt, complex_matrix, matrix, array, array, mx_el_gt)
+DEFNDBINOP_FN (ne, complex_matrix, matrix, array, array, mx_el_ne)
 
-DEFBINOP_FN (el_mul, complex_matrix, matrix, product)
-DEFBINOP_FN (el_div, complex_matrix, matrix, quotient)
-DEFBINOP_FN (el_pow, complex_matrix, matrix, elem_xpow)
+DEFNDBINOP_FN (el_mul, complex_matrix, matrix, array, array, product)
+DEFNDBINOP_FN (el_div, complex_matrix, matrix, array, array, quotient)
+DEFNDBINOP_FN (el_pow, complex_matrix, matrix, array, array, elem_xpow)
 
 DEFBINOP (el_ldiv, complex_matrix, matrix)
 {
   CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_matrix&);
 
-  return quotient (v2.matrix_value (), v1.complex_matrix_value ());
+  return quotient (v2.array_value (), v1.array_value ());
 }
 
-DEFBINOP_FN (el_and, complex_matrix, matrix, mx_el_and)
-DEFBINOP_FN (el_or, complex_matrix, matrix, mx_el_or)
+DEFNDBINOP_FN (el_and, complex_matrix, matrix, array, array, mx_el_and)
+DEFNDBINOP_FN (el_or,  complex_matrix, matrix, array, array, mx_el_or)
 
 DEFASSIGNOP_FN (assign, complex_matrix, matrix, assign)
 
--- a/src/OPERATORS/op-cm-s.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/src/OPERATORS/op-cm-s.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -43,9 +43,9 @@
 
 // complex matrix by scalar ops.
 
-DEFBINOP_OP (add, complex_matrix, scalar, +)
-DEFBINOP_OP (sub, complex_matrix, scalar, -)
-DEFBINOP_OP (mul, complex_matrix, scalar, *)
+DEFNDBINOP_OP (add, complex_matrix, scalar, array, scalar, +)
+DEFNDBINOP_OP (sub, complex_matrix, scalar, array, scalar, -)
+DEFNDBINOP_OP (mul, complex_matrix, scalar, array, scalar, *)
 
 DEFBINOP (div, complex_matrix, scalar)
 {
@@ -56,7 +56,7 @@
   if (d == 0.0)
     gripe_divide_by_zero ();
 
-  return octave_value (v1.complex_matrix_value () / d);
+  return octave_value (v1.array_value () / d);
 }
 
 DEFBINOP_FN (pow, complex_matrix, scalar, xpow)
@@ -71,12 +71,12 @@
   return octave_value (xleftdiv (m1, m2));
 }
 
-DEFBINOP_FN (lt, complex_matrix, scalar, mx_el_lt)
-DEFBINOP_FN (le, complex_matrix, scalar, mx_el_le)
-DEFBINOP_FN (eq, complex_matrix, scalar, mx_el_eq)
-DEFBINOP_FN (ge, complex_matrix, scalar, mx_el_ge)
-DEFBINOP_FN (gt, complex_matrix, scalar, mx_el_gt)
-DEFBINOP_FN (ne, complex_matrix, scalar, mx_el_ne)
+DEFNDBINOP_FN (lt, complex_matrix, scalar, array, scalar, mx_el_lt)
+DEFNDBINOP_FN (le, complex_matrix, scalar, array, scalar, mx_el_le)
+DEFNDBINOP_FN (eq, complex_matrix, scalar, array, scalar, mx_el_eq)
+DEFNDBINOP_FN (ge, complex_matrix, scalar, array, scalar, mx_el_ge)
+DEFNDBINOP_FN (gt, complex_matrix, scalar, array, scalar, mx_el_gt)
+DEFNDBINOP_FN (ne, complex_matrix, scalar, array, scalar, mx_el_ne)
 
 DEFBINOP_OP (el_mul, complex_matrix, scalar, *)
 
@@ -89,20 +89,20 @@
   if (d == 0.0)
     gripe_divide_by_zero ();
 
-  return octave_value (v1.complex_matrix_value () / d);
+  return octave_value (v1.array_value () / d);
 }
 
-DEFBINOP_FN (el_pow, complex_matrix, scalar, elem_xpow)
+DEFNDBINOP_FN (el_pow, complex_matrix, scalar, array, scalar, elem_xpow)
 
 DEFBINOP (el_ldiv, complex_matrix, scalar)
 {
   CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_scalar&);
 
-  return x_el_div (v2.double_value (), v1.complex_matrix_value ());
+  return x_el_div (v2.double_value (), v1.array_value ());
 }
 
-DEFBINOP_FN (el_and, complex_matrix, scalar, mx_el_and)
-DEFBINOP_FN (el_or, complex_matrix, scalar, mx_el_or)
+DEFNDBINOP_FN (el_and, complex_matrix, scalar, array, scalar, mx_el_and)
+DEFNDBINOP_FN (el_or,  complex_matrix, scalar, array, scalar, mx_el_or)
 
 DEFASSIGNOP_FN (assign, complex_matrix, scalar, assign)
 
--- a/src/OPERATORS/op-cs-cm.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/src/OPERATORS/op-cs-cm.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -40,9 +40,9 @@
 
 // complex scalar by complex matrix ops.
 
-DEFBINOP_OP (add, complex, complex_matrix, +)
-DEFBINOP_OP (sub, complex, complex_matrix, -)
-DEFBINOP_OP (mul, complex, complex_matrix, *)
+DEFNDBINOP_OP (add, complex, complex_matrix, complex, array, +)
+DEFNDBINOP_OP (sub, complex, complex_matrix, complex, array, -)
+DEFNDBINOP_OP (mul, complex, complex_matrix, complex, array, *)
 
 DEFBINOP (div, complex, complex_matrix)
 {
@@ -65,19 +65,19 @@
   if (d == 0.0)
     gripe_divide_by_zero ();
 
-  return octave_value (v2.complex_matrix_value () / d);
+  return octave_value (v2.array_value () / d);
 }
 
-DEFBINOP_FN (lt, complex, complex_matrix, mx_el_lt)
-DEFBINOP_FN (le, complex, complex_matrix, mx_el_le)
-DEFBINOP_FN (eq, complex, complex_matrix, mx_el_eq)
-DEFBINOP_FN (ge, complex, complex_matrix, mx_el_ge)
-DEFBINOP_FN (gt, complex, complex_matrix, mx_el_gt)
-DEFBINOP_FN (ne, complex, complex_matrix, mx_el_ne)
+DEFNDBINOP_FN (lt, complex, complex_matrix, complex, array, mx_el_lt)
+DEFNDBINOP_FN (le, complex, complex_matrix, complex, array, mx_el_le)
+DEFNDBINOP_FN (eq, complex, complex_matrix, complex, array, mx_el_eq)
+DEFNDBINOP_FN (ge, complex, complex_matrix, complex, array, mx_el_ge)
+DEFNDBINOP_FN (gt, complex, complex_matrix, complex, array, mx_el_gt)
+DEFNDBINOP_FN (ne, complex, complex_matrix, complex, array, mx_el_ne)
 
-DEFBINOP_OP (el_mul, complex, complex_matrix, *)
-DEFBINOP_FN (el_div, complex, complex_matrix, x_el_div)
-DEFBINOP_FN (el_pow, complex, complex_matrix, elem_xpow)
+DEFNDBINOP_OP (el_mul, complex, complex_matrix, complex, array, *)
+DEFNDBINOP_FN (el_div, complex, complex_matrix, complex, array, x_el_div)
+DEFNDBINOP_FN (el_pow, complex, complex_matrix, complex, array, elem_xpow)
 
 DEFBINOP (el_ldiv, complex, complex_matrix)
 {
@@ -88,11 +88,11 @@
   if (d == 0.0)
     gripe_divide_by_zero ();
 
-  return octave_value (v2.complex_matrix_value () / d);
+  return octave_value (v2.array_value () / d);
 }
 
-DEFBINOP_FN (el_and, complex, complex_matrix, mx_el_and)
-DEFBINOP_FN (el_or, complex, complex_matrix, mx_el_or)
+DEFNDBINOP_FN (el_and, complex, complex_matrix, complex, array, mx_el_and)
+DEFNDBINOP_FN (el_or,  complex, complex_matrix, complex, array, mx_el_or)
 
 DEFCONV (complex_matrix_conv, complex, complex_matrix)
 {
--- a/src/OPERATORS/op-cs-m.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/src/OPERATORS/op-cs-m.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -44,9 +44,9 @@
 
 // complex scalar by matrix ops.
 
-DEFBINOP_OP (add, complex, matrix, +)
-DEFBINOP_OP (sub, complex, matrix, -)
-DEFBINOP_OP (mul, complex, matrix, *)
+DEFNDBINOP_OP (add, complex, matrix, complex, array, +)
+DEFNDBINOP_OP (sub, complex, matrix, complex, array, -)
+DEFNDBINOP_OP (mul, complex, matrix, complex, array, *)
 
 DEFBINOP (div, complex, matrix)
 {
@@ -69,19 +69,19 @@
   if (d == 0.0)
     gripe_divide_by_zero ();
 
-  return octave_value (v2.matrix_value () / d);
+  return octave_value (v2.array_value () / d);
 }
 
-DEFBINOP_FN (lt, complex, matrix, mx_el_lt)
-DEFBINOP_FN (le, complex, matrix, mx_el_le)
-DEFBINOP_FN (eq, complex, matrix, mx_el_eq)
-DEFBINOP_FN (ge, complex, matrix, mx_el_ge)
-DEFBINOP_FN (gt, complex, matrix, mx_el_gt)
-DEFBINOP_FN (ne, complex, matrix, mx_el_ne)
+DEFNDBINOP_FN (lt, complex, matrix, complex, array, mx_el_lt)
+DEFNDBINOP_FN (le, complex, matrix, complex, array, mx_el_le)
+DEFNDBINOP_FN (eq, complex, matrix, complex, array, mx_el_eq)
+DEFNDBINOP_FN (ge, complex, matrix, complex, array, mx_el_ge)
+DEFNDBINOP_FN (gt, complex, matrix, complex, array, mx_el_gt)
+DEFNDBINOP_FN (ne, complex, matrix, complex, array, mx_el_ne)
 
-DEFBINOP_OP (el_mul, complex, matrix, *)
-DEFBINOP_FN (el_div, complex, matrix, x_el_div)
-DEFBINOP_FN (el_pow, complex, matrix, elem_xpow)
+DEFNDBINOP_OP (el_mul, complex, matrix, complex, array, *)
+DEFNDBINOP_FN (el_div, complex, matrix, complex, array, x_el_div)
+DEFNDBINOP_FN (el_pow, complex, matrix, complex, array, elem_xpow)
 
 DEFBINOP (el_ldiv, complex, matrix)
 {
@@ -92,11 +92,11 @@
   if (d == 0.0)
     gripe_divide_by_zero ();
 
-  return octave_value (v2.matrix_value () / d);
+  return octave_value (v2.array_value () / d);
 }
 
-DEFBINOP_FN (el_and, complex, matrix, mx_el_and)
-DEFBINOP_FN (el_or, complex, matrix, mx_el_or)
+DEFNDBINOP_FN (el_and, complex, matrix, complex, array, mx_el_and)
+DEFNDBINOP_FN (el_or,  complex, matrix, complex, array, mx_el_or)
 
 void
 install_cs_m_ops (void)
--- a/src/OPERATORS/op-m-cm.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/src/OPERATORS/op-m-cm.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -43,8 +43,9 @@
 
 // matrix by complex matrix ops.
 
-DEFBINOP_OP (add, matrix, complex_matrix, +)
-DEFBINOP_OP (sub, matrix, complex_matrix, -)
+DEFNDBINOP_OP (add, matrix, complex_matrix, array, array, +)
+DEFNDBINOP_OP (sub, matrix, complex_matrix, array, array, -)
+
 DEFBINOP_OP (mul, matrix, complex_matrix, *)
 DEFBINOP_FN (div, matrix, complex_matrix, xdiv)
 
@@ -56,32 +57,32 @@
 
 DEFBINOP_FN (ldiv, matrix, complex_matrix, xleftdiv)
 
-DEFBINOP_FN (lt, matrix, complex_matrix, mx_el_lt)
-DEFBINOP_FN (le, matrix, complex_matrix, mx_el_le)
-DEFBINOP_FN (eq, matrix, complex_matrix, mx_el_eq)
-DEFBINOP_FN (ge, matrix, complex_matrix, mx_el_ge)
-DEFBINOP_FN (gt, matrix, complex_matrix, mx_el_gt)
-DEFBINOP_FN (ne, matrix, complex_matrix, mx_el_ne)
+DEFNDBINOP_FN (lt, matrix, complex_matrix, array, array, mx_el_lt)
+DEFNDBINOP_FN (le, matrix, complex_matrix, array, array, mx_el_le)
+DEFNDBINOP_FN (eq, matrix, complex_matrix, array, array, mx_el_eq)
+DEFNDBINOP_FN (ge, matrix, complex_matrix, array, array, mx_el_ge)
+DEFNDBINOP_FN (gt, matrix, complex_matrix, array, array, mx_el_gt)
+DEFNDBINOP_FN (ne, matrix, complex_matrix, array, array, mx_el_ne)
 
-DEFBINOP_FN (el_mul, matrix, complex_matrix, product)
-DEFBINOP_FN (el_div, matrix, complex_matrix, quotient)
-DEFBINOP_FN (el_pow, matrix, complex_matrix, elem_xpow)
+DEFNDBINOP_FN (el_mul, matrix, complex_matrix, array, array, product)
+DEFNDBINOP_FN (el_div, matrix, complex_matrix, array, array, quotient)
+DEFNDBINOP_FN (el_pow, matrix, complex_matrix, array, array, elem_xpow)
 
 DEFBINOP (el_ldiv, matrix, complex_matrix)
 {
   CAST_BINOP_ARGS (const octave_matrix&, const octave_complex_matrix&);
 
-  return quotient (v2.complex_matrix_value (), v1.matrix_value ());
+  return quotient (v2.array_value (), v1.array_value ());
 }
 
-DEFBINOP_FN (el_and, matrix, complex_matrix, mx_el_and)
-DEFBINOP_FN (el_or, matrix, complex_matrix, mx_el_or)
+DEFNDBINOP_FN (el_and, matrix, complex_matrix, array, array, mx_el_and)
+DEFNDBINOP_FN (el_or,  matrix, complex_matrix, array, array, mx_el_or)
 
 DEFCONV (complex_matrix_conv, matrix, complex_matrix)
 {
   CAST_CONV_ARG (const octave_matrix&);
 
-  return new octave_complex_matrix (ComplexMatrix (v.matrix_value ()));
+  return new octave_complex_matrix (ComplexNDArray (v.array_value ()));
 }
 
 void
--- a/src/OPERATORS/op-m-cs.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/src/OPERATORS/op-m-cs.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -44,9 +44,9 @@
 
 // matrix by complex scalar ops.
 
-DEFBINOP_OP (add, matrix, complex, +)
-DEFBINOP_OP (sub, matrix, complex, -)
-DEFBINOP_OP (mul, matrix, complex, *)
+DEFNDBINOP_OP (add, matrix, complex, array, complex, +)
+DEFNDBINOP_OP (sub, matrix, complex, array, complex, -)
+DEFNDBINOP_OP (mul, matrix, complex, array, complex, *)
 
 DEFBINOP (div, matrix, complex)
 {
@@ -57,7 +57,7 @@
   if (d == 0.0)
     gripe_divide_by_zero ();
 
-  return octave_value (v1.matrix_value () / d);
+  return octave_value (v1.array_value () / d);
 }
 
 DEFBINOP_FN (pow, matrix, complex, xpow)
@@ -72,14 +72,14 @@
   return octave_value (xleftdiv (m1, m2));
 }
 
-DEFBINOP_FN (lt, matrix, complex, mx_el_lt)
-DEFBINOP_FN (le, matrix, complex, mx_el_le)
-DEFBINOP_FN (eq, matrix, complex, mx_el_eq)
-DEFBINOP_FN (ge, matrix, complex, mx_el_ge)
-DEFBINOP_FN (gt, matrix, complex, mx_el_gt)
-DEFBINOP_FN (ne, matrix, complex, mx_el_ne)
+DEFNDBINOP_FN (lt, matrix, complex, array, complex, mx_el_lt)
+DEFNDBINOP_FN (le, matrix, complex, array, complex, mx_el_le)
+DEFNDBINOP_FN (eq, matrix, complex, array, complex, mx_el_eq)
+DEFNDBINOP_FN (ge, matrix, complex, array, complex, mx_el_ge)
+DEFNDBINOP_FN (gt, matrix, complex, array, complex, mx_el_gt)
+DEFNDBINOP_FN (ne, matrix, complex, array, complex, mx_el_ne)
 
-DEFBINOP_OP (el_mul, matrix, complex, *)
+DEFNDBINOP_OP (el_mul, matrix, complex, array, complex, *)
 
 DEFBINOP (el_div, matrix, complex)
 {
@@ -90,20 +90,20 @@
   if (d == 0.0)
     gripe_divide_by_zero ();
 
-  return octave_value (v1.matrix_value () / d);
+  return octave_value (v1.array_value () / d);
 }
 
-DEFBINOP_FN (el_pow, matrix, complex, elem_xpow)
+DEFNDBINOP_FN (el_pow, matrix, complex, array, complex, elem_xpow)
 
 DEFBINOP (el_ldiv, matrix, complex)
 {
   CAST_BINOP_ARGS (const octave_matrix&, const octave_complex&);
 
-  return x_el_div (v2.complex_value (), v1.matrix_value ());
+  return x_el_div (v2.complex_value (), v1.array_value ());
 }
 
-DEFBINOP_FN (el_and, matrix, complex, mx_el_and)
-DEFBINOP_FN (el_or, matrix, complex, mx_el_or)
+DEFNDBINOP_FN (el_and, matrix, complex, array, complex, mx_el_and)
+DEFNDBINOP_FN (el_or, matrix, complex, array, complex, mx_el_or)
 
 void
 install_m_cs_ops (void)
--- a/src/OPERATORS/op-m-m.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/src/OPERATORS/op-m-m.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -39,8 +39,8 @@
 
 // matrix unary ops.
 
-DEFUNOP_OP (not, matrix, !)
-DEFUNOP_OP (uminus, matrix, -)
+DEFNDUNOP_OP (not, matrix, !)
+DEFNDUNOP_OP (uminus, matrix, -)
 
 DEFUNOP (transpose, matrix)
 {
@@ -54,8 +54,9 @@
 
 // matrix by matrix ops.
 
-DEFBINOP_OP (add, matrix, matrix, +)
-DEFBINOP_OP (sub, matrix, matrix, -)
+DEFNDBINOP_OP (add, matrix, matrix, array, array, +)
+DEFNDBINOP_OP (sub, matrix, matrix, array, array, -)
+
 DEFBINOP_OP (mul, matrix, matrix, *)
 DEFBINOP_FN (div, matrix, matrix, xdiv)
 
@@ -67,40 +68,26 @@
 
 DEFBINOP_FN (ldiv, matrix, matrix, xleftdiv)
 
-DEFBINOP_FN (lt, matrix, matrix, mx_el_lt)
-DEFBINOP_FN (le, matrix, matrix, mx_el_le)
-DEFBINOP_FN (eq, matrix, matrix, mx_el_eq)
-DEFBINOP_FN (ge, matrix, matrix, mx_el_ge)
-DEFBINOP_FN (gt, matrix, matrix, mx_el_gt)
-DEFBINOP_FN (ne, matrix, matrix, mx_el_ne)
+DEFNDBINOP_FN (lt, matrix, matrix, array, array, mx_el_lt)
+DEFNDBINOP_FN (le, matrix, matrix, array, array, mx_el_le)
+DEFNDBINOP_FN (eq, matrix, matrix, array, array, mx_el_eq)
+DEFNDBINOP_FN (ge, matrix, matrix, array, array, mx_el_ge)
+DEFNDBINOP_FN (gt, matrix, matrix, array, array, mx_el_gt)
+DEFNDBINOP_FN (ne, matrix, matrix, array, array, mx_el_ne)
 
-DEFBINOP_FN (el_mul, matrix, matrix, product)
-DEFBINOP_FN (el_div, matrix, matrix, quotient)
-DEFBINOP_FN (el_pow, matrix, matrix, elem_xpow)
+DEFNDBINOP_FN (el_mul, matrix, matrix, array, array, product)
+DEFNDBINOP_FN (el_div, matrix, matrix, array, array, quotient)
+DEFNDBINOP_FN (el_pow, matrix, matrix, array, array, elem_xpow)
 
 DEFBINOP (el_ldiv, matrix, matrix)
 {
   CAST_BINOP_ARGS (const octave_matrix&, const octave_matrix&);
 
-  return octave_value (quotient (v2.matrix_value (), v1.matrix_value ()));
+  return octave_value (quotient (v2.array_value (), v1.array_value ()));
 }
 
-DEFBINOP_FN (el_and, matrix, matrix, mx_el_and)
-DEFBINOP_FN (el_or, matrix, matrix, mx_el_or)
-
-#if 0
-static octave_value
-oct_assignop_assign (octave_value& a1,
-		     const octave_value_list& idx,
-		     const octave_value& a2)
-{
-  CAST_BINOP_ARGS (octave_matrix&, const octave_matrix&);
-
-  v1.assign (idx, v2.double_nd_array_value ());
-
-  return octave_value ();
-}
-#endif
+DEFNDBINOP_FN (el_and, matrix, matrix, array, array, mx_el_and)
+DEFNDBINOP_FN (el_or,  matrix, matrix, array, array, mx_el_or)
 
 DEFASSIGNOP_FN (assign, matrix, matrix, assign)
 
--- a/src/OPERATORS/op-m-nd.cc	Fri Oct 17 04:41:36 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
-
-Copyright (C) 2003 Petter Risholm and John W. Eaton
-
-This file is part of Octave.
-
-Octave is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
-later version.
-
-Octave is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with Octave; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-*/
-
-#if defined (__GNUG__) && defined (USE_PRAGMA_INTERFACE_IMPLEMENTATION)
-#pragma implementation
-#endif
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-//#include "mx-m-nd.h"
-#include "gripes.h"
-#include "oct-obj.h"
-#include "ov.h"
-#include "ov-re-mat.h"
-#include "ov-re-nd-array.h"
-#include "ov-typeinfo.h"
-#include "ops.h"
-#include "xdiv.h"
-#include "xpow.h"
-
-
-
-DEFASSIGNOP_FN (assign, matrix, double_nd_array, assign)
-
-void
-install_m_nd_ops (void)
-{
-  INSTALL_ASSIGNOP (op_asn_eq, octave_matrix, octave_double_nd_array, assign);
-}
--- a/src/OPERATORS/op-m-s.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/src/OPERATORS/op-m-s.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -40,9 +40,9 @@
 
 // matrix by scalar ops.
 
-DEFBINOP_OP (add, matrix, scalar, +)
-DEFBINOP_OP (sub, matrix, scalar, -)
-DEFBINOP_OP (mul, matrix, scalar, *)
+DEFNDBINOP_OP (add, matrix, scalar, array, scalar, +)
+DEFNDBINOP_OP (sub, matrix, scalar, array, scalar, -)
+DEFNDBINOP_OP (mul, matrix, scalar, array, scalar, *)
 
 DEFBINOP (div, matrix, scalar)
 {
@@ -53,7 +53,7 @@
   if (d == 0.0)
     gripe_divide_by_zero ();
 
-  return octave_value (v1.matrix_value () / d);
+  return octave_value (v1.array_value () / d);
 }
 
 DEFBINOP_FN (pow, matrix, scalar, xpow)
@@ -68,14 +68,14 @@
   return octave_value (xleftdiv (m1, m2));
 }
 
-DEFBINOP_FN (lt, matrix, scalar, mx_el_lt)
-DEFBINOP_FN (le, matrix, scalar, mx_el_le)
-DEFBINOP_FN (eq, matrix, scalar, mx_el_eq)
-DEFBINOP_FN (ge, matrix, scalar, mx_el_ge)
-DEFBINOP_FN (gt, matrix, scalar, mx_el_gt)
-DEFBINOP_FN (ne, matrix, scalar, mx_el_ne)
+DEFNDBINOP_FN (lt, matrix, scalar, array, scalar, mx_el_lt)
+DEFNDBINOP_FN (le, matrix, scalar, array, scalar, mx_el_le)
+DEFNDBINOP_FN (eq, matrix, scalar, array, scalar, mx_el_eq)
+DEFNDBINOP_FN (ge, matrix, scalar, array, scalar, mx_el_ge)
+DEFNDBINOP_FN (gt, matrix, scalar, array, scalar, mx_el_gt)
+DEFNDBINOP_FN (ne, matrix, scalar, array, scalar, mx_el_ne)
 
-DEFBINOP_OP (el_mul, matrix, scalar, *)
+DEFNDBINOP_OP (el_mul, matrix, scalar, array, scalar, *)
 
 DEFBINOP (el_div, matrix, scalar)
 {
@@ -86,20 +86,20 @@
   if (d == 0.0)
     gripe_divide_by_zero ();
 
-  return octave_value (v1.matrix_value () / d);
+  return octave_value (v1.array_value () / d);
 }
 
-DEFBINOP_FN (el_pow, matrix, scalar, elem_xpow)
+DEFNDBINOP_FN (el_pow, matrix, scalar, array, scalar, elem_xpow)
 
 DEFBINOP (el_ldiv, matrix, scalar)
 {
   CAST_BINOP_ARGS (const octave_matrix&, const octave_scalar&);
 
-  return x_el_div (v2.double_value (), v1.matrix_value ());
+  return x_el_div (v2.double_value (), v1.array_value ());
 }
 
-DEFBINOP_FN (el_and, matrix, scalar, mx_el_and)
-DEFBINOP_FN (el_or, matrix, scalar, mx_el_or)
+DEFNDBINOP_FN (el_and, matrix, scalar, array, scalar, mx_el_and)
+DEFNDBINOP_FN (el_or, matrix, scalar, array, scalar, mx_el_or)
 
 DEFASSIGNOP_FN (assign, matrix, scalar, assign)
 
@@ -112,7 +112,13 @@
   INSTALL_BINOP (op_div, octave_matrix, octave_scalar, div);
   INSTALL_BINOP (op_pow, octave_matrix, octave_scalar, pow);
   INSTALL_BINOP (op_ldiv, octave_matrix, octave_scalar, ldiv);
-  INSTALL_BINOP (op_lt, octave_matrix, octave_scalar, lt);
+
+  //  INSTALL_BINOP (op_lt, octave_matrix, octave_scalar, lt);
+
+  octave_value_typeinfo::register_binary_op
+    (octave_value::op_lt, octave_matrix::static_type_id (),
+     octave_scalar::static_type_id (), oct_binop_lt);
+
   INSTALL_BINOP (op_le, octave_matrix, octave_scalar, le);
   INSTALL_BINOP (op_eq, octave_matrix, octave_scalar, eq);
   INSTALL_BINOP (op_ge, octave_matrix, octave_scalar, ge);
--- a/src/OPERATORS/op-nd-m.cc	Fri Oct 17 04:41:36 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
-
-Copyright (C) 2003 Petter Risholm and John W. Eaton
-
-This file is part of Octave.
-
-Octave is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
-later version.
-
-Octave is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with Octave; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-*/
-
-#if defined (__GNUG__) && defined (USE_PRAGMA_INTERFACE_IMPLEMENTATION)
-#pragma implementation
-#endif
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#//include "mx-nd-m.h"
-#include "gripes.h"
-#include "oct-obj.h"
-#include "ov.h"
-#include "ov-re-mat.h"
-#include "ov-re-nd-array.h"
-#include "ov-typeinfo.h"
-#include "ops.h"
-#include "xdiv.h"
-#include "xpow.h"
-
-DEFASSIGNOP_FN (assign, double_nd_array, matrix, assign)
-
-void
-install_nd_m_ops (void)
-{
-  INSTALL_ASSIGNOP (op_asn_eq, octave_double_nd_array, octave_matrix, assign);
-}
--- a/src/OPERATORS/op-nd-nd.cc	Fri Oct 17 04:41:36 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/*
-
-Copyright (C) 2003 Petter Risholm and John W. Eaton
-
-This file is part of Octave.
-
-Octave is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
-later version.
-
-Octave is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with Octave; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-*/
-
-#if defined (__GNUG__) && defined (USE_PRAGMA_INTERFACE_IMPLEMENTATION)
-#pragma implementation
-#endif
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "gripes.h"
-#include "oct-obj.h"
-#include "ov.h"
-#include "ov-re-nd-array.h"
-#include "ov-typeinfo.h"
-
-#include "ops.h"
-#include "xdiv.h"
-#include "xpow.h"
- 
-//Using the ! operator causes a segmentation fault
-//DEFUNOP_OP (not, double_nd_array, !)
-/*
-DEFUNOP_OP (uminus, double_nd_array, -)
-
-DEFUNOP (transpose, double_nd_array)
-{
-  error ("Transpose on ND array is not defined.");
-  return octave_value ();
-}
-
-DEFBINOP_OP (add, double_nd_array, double_nd_array, +)
-DEFBINOP_OP (sub, double_nd_array, double_nd_array, -)
-
-DEFBINOP_FN (el_pow, double_nd_array, double_nd_array, elem_xpow)
-
-DEFBINOPX (pow, double_nd_array, double_nd_array)
-{
-  error ("can't do A ^ B for A and B both N-D arrays");
-  return octave_value ();
-}
-*/
-
-DEFASSIGNOP_FN (assign, double_nd_array, double_nd_array, assign)
-
-void
-install_nd_nd_ops (void)
-{
-  //  INSTALL_UNOP (op_not, octave_double_nd_array, not);
-  /*INSTALL_UNOP (op_uminus, octave_double_nd_array, uminus);
-  INSTALL_UNOP (op_transpose, octave_double_nd_array, transpose);
-
-  INSTALL_BINOP (op_add, octave_double_nd_array, octave_double_nd_array, add);
-  INSTALL_BINOP (op_sub, octave_double_nd_array, octave_double_nd_array, sub);
-
-  INSTALL_BINOP (op_el_pow, octave_double_nd_array, octave_double_nd_array, el_pow);
-  */
-  INSTALL_ASSIGNOP (op_asn_eq, octave_double_nd_array, octave_double_nd_array, assign);
-  INSTALL_ASSIGNCONV (octave_double_nd_array, octave_double_nd_array, octave_double_nd_array);
-}
--- a/src/OPERATORS/op-nd-s.cc	Fri Oct 17 04:41:36 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
-
-Copyright (C) 2003 Petter Risholm and John W. Eaton
-
-This file is part of Octave.
-
-Octave is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
-later version.
-
-Octave is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with Octave; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-*/
-
-#if defined (__GNUG__) && defined (USE_PRAGMA_INTERFACE_IMPLEMENTATION)
-#pragma implementation
-#endif
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "gripes.h"
-#include "oct-obj.h"
-#include "ov.h"
-#include "ov-re-nd-array.h"
-#include "ov-scalar.h"
-#include "ov-typeinfo.h"
-//Kluge
-
-#include "ops.h"
-#include "xdiv.h"
-#include "xpow.h"
-
-// ndArray by scalar ops.
-
-/*
-DEFBINOP_OP (add, double_nd_array, scalar, +)
-DEFBINOP_OP (sub, double_nd_array, scalar, -)
-DEFBINOP_OP (mul, double_nd_array, scalar, *)
-
-DEFBINOP (div, double_nd_array, scalar)
-{
-  CAST_BINOP_ARGS (const octave_double_nd_array&, const octave_scalar&);
-  double d = v2.double_value ();
-
-  if (d == 0.0)
-    gripe_divide_by_zero ();
-
-  return octave_value (v1.double_nd_array_value () / d);
-}
-
-DEFBINOP_OP (el_mul, double_nd_array, scalar, *)
-
-DEFBINOP (el_div, double_nd_array, scalar)
-{
-  CAST_BINOP_ARGS (const octave_double_nd_array&, const octave_scalar&);
-
-  double d = v2.double_value ();
-
-  if (d == 0.0)
-    gripe_divide_by_zero ();
-
-  return octave_value (v1.double_nd_array_value () / d);
-}
-
-DEFBINOP_FN (el_pow, double_nd_array, scalar, elem_xpow)
-*/
-DEFASSIGNOP_FN (assign, double_nd_array, scalar, assign)
-
-void
-install_nd_s_ops (void)
-{
-  /*  INSTALL_BINOP (op_add, octave_double_nd_array, octave_scalar, add);
-  INSTALL_BINOP (op_sub, octave_double_nd_array, octave_scalar, sub);
-  INSTALL_BINOP (op_mul, octave_double_nd_array, octave_scalar, mul);
-  INSTALL_BINOP (op_div, octave_double_nd_array, octave_scalar, div);
-  INSTALL_BINOP (op_el_pow, octave_double_nd_array, octave_scalar, el_pow);
-  INSTALL_BINOP (op_el_mul, octave_double_nd_array, octave_scalar, el_mul);
-  INSTALL_BINOP (op_el_div, octave_double_nd_array, octave_scalar, el_div);
-  */
-  INSTALL_ASSIGNOP (op_asn_eq, octave_double_nd_array, octave_scalar, assign);
-}
-
-/*
-;;; Local Variables: ***
-;;; mode: C++ ***
-;;; End: ***
-*/
--- a/src/OPERATORS/op-s-cm.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/src/OPERATORS/op-s-cm.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -44,9 +44,9 @@
 
 // scalar by complex matrix ops.
 
-DEFBINOP_OP (add, scalar, complex_matrix, +)
-DEFBINOP_OP (sub, scalar, complex_matrix, -)
-DEFBINOP_OP (mul, scalar, complex_matrix, *)
+DEFNDBINOP_OP (add, scalar, complex_matrix, scalar, array, +)
+DEFNDBINOP_OP (sub, scalar, complex_matrix, scalar, array, -)
+DEFNDBINOP_OP (mul, scalar, complex_matrix, scalar, array, *)
 
 DEFBINOP (div, scalar, complex_matrix)
 {
@@ -69,19 +69,19 @@
   if (d == 0.0)
     gripe_divide_by_zero ();
 
-  return octave_value (v2.complex_matrix_value () / d);
+  return octave_value (v2.array_value () / d);
 }
 
-DEFBINOP_FN (lt, scalar, complex_matrix, mx_el_lt)
-DEFBINOP_FN (le, scalar, complex_matrix, mx_el_le)
-DEFBINOP_FN (eq, scalar, complex_matrix, mx_el_eq)
-DEFBINOP_FN (ge, scalar, complex_matrix, mx_el_ge)
-DEFBINOP_FN (gt, scalar, complex_matrix, mx_el_gt)
-DEFBINOP_FN (ne, scalar, complex_matrix, mx_el_ne)
+DEFNDBINOP_FN (lt, scalar, complex_matrix, scalar, array, mx_el_lt)
+DEFNDBINOP_FN (le, scalar, complex_matrix, scalar, array, mx_el_le)
+DEFNDBINOP_FN (eq, scalar, complex_matrix, scalar, array, mx_el_eq)
+DEFNDBINOP_FN (ge, scalar, complex_matrix, scalar, array, mx_el_ge)
+DEFNDBINOP_FN (gt, scalar, complex_matrix, scalar, array, mx_el_gt)
+DEFNDBINOP_FN (ne, scalar, complex_matrix, scalar, array, mx_el_ne)
 
-DEFBINOP_OP (el_mul, scalar, complex_matrix, *)
-DEFBINOP_FN (el_div, scalar, complex_matrix, x_el_div)
-DEFBINOP_FN (el_pow, scalar, complex_matrix, elem_xpow)
+DEFNDBINOP_OP (el_mul, scalar, complex_matrix, scalar, array, *)
+DEFNDBINOP_FN (el_div, scalar, complex_matrix, scalar, array, x_el_div)
+DEFNDBINOP_FN (el_pow, scalar, complex_matrix, scalar, array, elem_xpow)
 
 DEFBINOP (el_ldiv, scalar, complex_matrix)
 {
@@ -92,21 +92,21 @@
   if (d == 0.0)
     gripe_divide_by_zero ();
 
-  return octave_value (v2.complex_matrix_value () / d);
+  return octave_value (v2.array_value () / d);
 }
 
 DEFBINOP (el_and, scalar, complex_matrix)
 {
   CAST_BINOP_ARGS (const octave_scalar&, const octave_complex_matrix&);
 
-  return mx_el_and (v1.double_value (), v2.complex_matrix_value ());
+  return mx_el_and (v1.double_value (), v2.array_value ());
 }
 
 DEFBINOP (el_or, scalar, complex_matrix)
 {
   CAST_BINOP_ARGS (const octave_scalar&, const octave_complex_matrix&);
 
-  return mx_el_or (v1.double_value (), v2.complex_matrix_value ());
+  return mx_el_or (v1.double_value (), v2.array_value ());
 }
 
 DEFCONV (complex_matrix_conv, scalar, complex_matrix)
--- a/src/OPERATORS/op-s-m.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/src/OPERATORS/op-s-m.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -40,9 +40,9 @@
 
 // scalar by matrix ops.
 
-DEFBINOP_OP (add, scalar, matrix, +)
-DEFBINOP_OP (sub, scalar, matrix, -)
-DEFBINOP_OP (mul, scalar, matrix, *)
+DEFNDBINOP_OP (add, scalar, matrix, scalar, array, +)
+DEFNDBINOP_OP (sub, scalar, matrix, scalar, array, -)
+DEFNDBINOP_OP (mul, scalar, matrix, scalar, array, *)
 
 DEFBINOP (div, scalar, matrix)
 {
@@ -65,19 +65,19 @@
   if (d == 0.0)
     gripe_divide_by_zero ();
 
-  return octave_value (v2.matrix_value () / d);
+  return octave_value (v2.array_value () / d);
 }
 
-DEFBINOP_FN (lt, scalar, matrix, mx_el_lt)
-DEFBINOP_FN (le, scalar, matrix, mx_el_le)
-DEFBINOP_FN (eq, scalar, matrix, mx_el_eq)
-DEFBINOP_FN (ge, scalar, matrix, mx_el_ge)
-DEFBINOP_FN (gt, scalar, matrix, mx_el_gt)
-DEFBINOP_FN (ne, scalar, matrix, mx_el_ne)
+DEFNDBINOP_FN (lt, scalar, matrix, scalar, array, mx_el_lt)
+DEFNDBINOP_FN (le, scalar, matrix, scalar, array, mx_el_le)
+DEFNDBINOP_FN (eq, scalar, matrix, scalar, array, mx_el_eq)
+DEFNDBINOP_FN (ge, scalar, matrix, scalar, array, mx_el_ge)
+DEFNDBINOP_FN (gt, scalar, matrix, scalar, array, mx_el_gt)
+DEFNDBINOP_FN (ne, scalar, matrix, scalar, array, mx_el_ne)
 
-DEFBINOP_OP (el_mul, scalar, matrix, *)
-DEFBINOP_FN (el_div, scalar, matrix, x_el_div)
-DEFBINOP_FN (el_pow, scalar, matrix, elem_xpow)
+DEFNDBINOP_OP (el_mul, scalar, matrix, scalar, array, *)
+DEFNDBINOP_FN (el_div, scalar, matrix, scalar, array, x_el_div)
+DEFNDBINOP_FN (el_pow, scalar, matrix, scalar, array, elem_xpow)
 
 DEFBINOP (el_ldiv, scalar, matrix)
 {
@@ -88,11 +88,11 @@
   if (d == 0.0)
     gripe_divide_by_zero ();
 
-  return octave_value (v2.matrix_value () / d);
+  return octave_value (v2.array_value () / d);
 }
 
-DEFBINOP_FN (el_and, scalar, matrix, mx_el_and)
-DEFBINOP_FN (el_or, scalar, matrix, mx_el_or)
+DEFNDBINOP_FN (el_and, scalar, matrix, scalar, array, mx_el_and)
+DEFNDBINOP_FN (el_or,  scalar, matrix, scalar, array, mx_el_or)
 
 DEFCONV (matrix_conv, scalar, matrix)
 {
--- a/src/OPERATORS/op-s-nd.cc	Fri Oct 17 04:41:36 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-/*
-
-Copyright (C) 2003 Petter Risholm and John W. Eaton
-
-This file is part of Octave.
-
-Octave is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
-later version.
-
-Octave is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with Octave; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-*/
-
-#if defined (__GNUG__) && defined (USE_PRAGMA_INTERFACE_IMPLEMENTATION)
-#pragma implementation
-#endif
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "gripes.h"
-#include "oct-obj.h"
-#include "ov.h"
-#include "ov-scalar.h"
-#include "ov-re-nd-array.h"
-//Kluge
-//#include "MArrayN.cc"
-#include "ov-typeinfo.h"
-#include "ops.h"
-#include "xdiv.h"
-#include "xpow.h"
-
-// scalar by matrix ops.
-
-/*
-DEFBINOP_OP (add, scalar, double_nd_array, +)
-DEFBINOP_OP (sub, scalar, double_nd_array, -)
-DEFBINOP_OP (mul, scalar, double_nd_array, *)
-
-  DEFBINOP_OP(el_mul, scalar, double_nd_array, *)
-*/
-DEFCONV (array_conv, scalar, double_nd_array)
-{
-  CAST_CONV_ARG (const octave_scalar&);
-
-  return new octave_double_nd_array (v.double_nd_array_value ());
-}
-
-void
-install_s_nd_ops (void)
-{
-  /* 
- INSTALL_BINOP (op_add, octave_scalar, octave_double_nd_array, add);
-  INSTALL_BINOP (op_sub, octave_scalar, octave_double_nd_array, sub);
-  INSTALL_BINOP (op_mul, octave_scalar, octave_double_nd_array, mul);
-  INSTALL_BINOP (op_el_mul, octave_scalar, octave_double_nd_array, el_mul);
-  */  
-  INSTALL_ASSIGNCONV (octave_scalar, octave_double_nd_array, octave_double_nd_array);
-
-  INSTALL_WIDENOP (octave_scalar, octave_double_nd_array, array_conv);
-}
-
-/*
-;;; Local Variables: ***
-;;; mode: C++ ***
-;;; End: ***
-*/
--- a/src/ops.h	Fri Oct 17 04:41:36 2003 +0000
+++ b/src/ops.h	Sat Oct 18 03:53:53 2003 +0000
@@ -190,6 +190,13 @@
     return octave_value (op v.t ## _value ()); \
   }
 
+#define DEFNDUNOP_OP(name, t, op) \
+  UNOPDECL (name, a) \
+  { \
+    CAST_UNOP_ARG (const octave_ ## t&); \
+    return octave_value (op v.array_value ()); \
+  }
+
 // XXX FIXME XXX -- in some cases, the constructor isn't necessary.
 
 #define DEFUNOP_FN(name, t, f) \
@@ -199,6 +206,13 @@
     return octave_value (f (v.t ## _value ())); \
   }
 
+#define DEFNDUNOP_FN(name, t, f) \
+  UNOPDECL (name, a) \
+  { \
+    CAST_UNOP_ARG (const octave_ ## t&); \
+    return octave_value (f (v.array_value ())); \
+  }
+
 #define DEFNCUNOP_METHOD(name, t, method) \
   static void \
   oct_unop_ ## name (octave_value& a) \
@@ -225,6 +239,14 @@
       (v1.t1 ## _value () op v2.t2 ## _value ()); \
   }
 
+#define DEFNDBINOP_OP(name, t1, t2, e1, e2, op) \
+  BINOPDECL (name, a1, a2) \
+  { \
+    CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \
+    return octave_value \
+      (v1.e1 ## _value () op v2.e2 ## _value ()); \
+  }
+
 // XXX FIXME XXX -- in some cases, the constructor isn't necessary.
 
 #define DEFBINOP_FN(name, t1, t2, f) \
@@ -234,6 +256,13 @@
     return octave_value (f (v1.t1 ## _value (), v2.t2 ## _value ())); \
   }
 
+#define DEFNDBINOP_FN(name, t1, t2, e1, e2, f) \
+  BINOPDECL (name, a1, a2) \
+  { \
+    CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \
+    return octave_value (f (v1.e1 ## _value (), v2.e2 ## _value ())); \
+  }
+
 #define BINOP_NONCONFORMANT(msg) \
   gripe_nonconformant (msg, \
 		       a1.rows (), a1.columns (), \
--- a/src/ov-bool-mat.h	Fri Oct 17 04:41:36 2003 +0000
+++ b/src/ov-bool-mat.h	Sat Oct 18 03:53:53 2003 +0000
@@ -104,6 +104,9 @@
   boolMatrix bool_matrix_value (void) const
     { return matrix.matrix_value (); }
 
+  boolNDArray array_value (bool = false) const
+    { return matrix; }
+
   octave_value convert_to_str_internal (bool pad, bool force) const;
 
 protected:
--- a/src/ov-ch-mat.h	Fri Oct 17 04:41:36 2003 +0000
+++ b/src/ov-ch-mat.h	Sat Oct 18 03:53:53 2003 +0000
@@ -106,6 +106,9 @@
   charMatrix char_matrix_value (bool = false) const
     { return matrix.matrix_value (); }
 
+  charNDArray array_value (bool = false) const
+    { return matrix; }
+
   octave_value convert_to_str_internal (bool, bool) const
     { return octave_value (matrix.matrix_value (), true); }
 
--- a/src/ov-cx-mat.h	Fri Oct 17 04:41:36 2003 +0000
+++ b/src/ov-cx-mat.h	Sat Oct 18 03:53:53 2003 +0000
@@ -102,6 +102,8 @@
 
   ComplexMatrix complex_matrix_value (bool = false) const;
 
+  ComplexNDArray array_value (void) const { return matrix; }
+
   void increment (void) { matrix += Complex (1.0); }
 
   void decrement (void) { matrix -= Complex (1.0); }
--- a/src/ov-re-mat.h	Fri Oct 17 04:41:36 2003 +0000
+++ b/src/ov-re-mat.h	Sat Oct 18 03:53:53 2003 +0000
@@ -101,7 +101,7 @@
 
   ComplexMatrix complex_matrix_value (bool = false) const;
 
-  NDArray double_nd_array_value (bool = false) const
+  NDArray array_value (bool = false) const
     { return matrix; }
 
   void increment (void) { matrix += 1.0; }
--- a/src/xdiv.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/src/xdiv.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -28,6 +28,8 @@
 
 #include "CMatrix.h"
 #include "dMatrix.h"
+#include "CNDArray.h"
+#include "dNDArray.h"
 #include "oct-cmplx.h"
 #include "quit.h"
 
@@ -305,6 +307,71 @@
   return result;
 }
 
+// Funny element by element division operations.
+//
+//          op2 \ op1:   s   cs
+//               +--   +---+----+
+//   N-d array         | 1 |  3 |
+//                     +---+----+
+//   complex N-d array | 2 |  4 |
+//                     +---+----+
+
+NDArray
+x_el_div (double a, const NDArray& b)
+{
+  NDArray result (b.dims ());
+
+  for (int i = 0; i < b.length (); i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = a / b (i);
+    }
+
+  return result;
+}
+
+ComplexNDArray
+x_el_div (double a, const ComplexNDArray& b)
+{
+  ComplexNDArray result (b.dims ());
+
+  for (int i = 0; i < b.length (); i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = a / b (i);
+    }
+
+  return result;
+}
+
+ComplexNDArray
+x_el_div (const Complex a, const NDArray& b)
+{
+  ComplexNDArray result (b.dims ());
+
+  for (int i = 0; i < b.length (); i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = a / b (i);
+    }
+
+  return result;
+}
+
+ComplexNDArray
+x_el_div (const Complex a, const ComplexNDArray& b)
+{
+  ComplexNDArray result (b.dims ());
+
+  for (int i = 0; i < b.length (); i++)
+    {
+      OCTAVE_QUIT;
+      result (i) = a / b (i);
+    }
+
+  return result;
+}
+
 // Left division functions.
 //
 //       op2 \ op1:   m   cm
--- a/src/xdiv.h	Fri Oct 17 04:41:36 2003 +0000
+++ b/src/xdiv.h	Sat Oct 18 03:53:53 2003 +0000
@@ -28,6 +28,9 @@
 class Matrix;
 class ComplexMatrix;
 
+class NDArray;
+class ComplexNDArray;
+
 extern Matrix xdiv (const Matrix& a, const Matrix& b);
 extern ComplexMatrix xdiv (const Matrix& a, const ComplexMatrix& b);
 extern ComplexMatrix xdiv (const ComplexMatrix& a, const Matrix& b);
@@ -38,6 +41,11 @@
 extern ComplexMatrix x_el_div (const Complex a, const Matrix& b);
 extern ComplexMatrix x_el_div (const Complex a, const ComplexMatrix& b);
 
+extern NDArray x_el_div (double a, const NDArray& b);
+extern ComplexNDArray x_el_div (double a, const ComplexNDArray& b);
+extern ComplexNDArray x_el_div (const Complex a, const NDArray& b);
+extern ComplexNDArray x_el_div (const Complex a, const ComplexNDArray& b);
+
 extern Matrix xleftdiv (const Matrix& a, const Matrix& b);
 extern ComplexMatrix xleftdiv (const Matrix& a, const ComplexMatrix& b);
 extern ComplexMatrix xleftdiv (const ComplexMatrix& a, const Matrix& b);
--- a/src/xpow.cc	Fri Oct 17 04:41:36 2003 +0000
+++ b/src/xpow.cc	Sat Oct 18 03:53:53 2003 +0000
@@ -839,6 +839,343 @@
   return result;
 }
 
+// Safer pow functions that work elementwise for N-d arrays.
+//
+//       op2 \ op1:   s   nd  cs   cnd
+//            +--   +---+---+----+----+
+//   scalar   |     | * | 3 |  * |  9 |
+//                  +---+---+----+----+
+//   N_d            | 1 | 4 |  7 | 10 |
+//                  +---+---+----+----+
+//   complex_scalar | * | 5 |  * | 11 |
+//                  +---+---+----+----+
+//   complex_N_d    | 2 | 6 |  8 | 12 |
+//                  +---+---+----+----+
+//
+//   * -> not needed.
+
+// XXX FIXME XXX -- these functions need to be fixed so that things
+// like
+//
+//   a = -1; b = [ 0, 0.5, 1 ]; r = a .^ b
+//
+// and
+//
+//   a = -1; b = [ 0, 0.5, 1 ]; for i = 1:3, r(i) = a .^ b(i), end
+//
+// produce identical results.  Also, it would be nice if -1^0.5
+// produced a pure imaginary result instead of a complex number with a
+// small real part.  But perhaps that's really a problem with the math
+// library...
+
+// -*- 1 -*-
+octave_value
+elem_xpow (double a, const NDArray& b)
+{
+  octave_value retval;
+
+  double d1, d2;
+
+  if (a < 0.0 && ! b.all_integers (d1, d2))
+    {
+      Complex atmp (a);
+      ComplexNDArray result (b.dims ());
+      for (int i = 0; i < b.length (); i++)
+	{
+	  OCTAVE_QUIT;
+	  result(i) = pow (atmp, b(i));
+	}
+
+      retval = result;
+    }
+  else
+    {
+      NDArray result (b.dims ());
+      for (int i = 0; i < b.length (); i++)
+	{
+	  OCTAVE_QUIT;
+	  result (i) = pow (a, b(i));
+	}
+
+      retval = result;
+    }
+
+  return retval;
+}
+
+// -*- 2 -*-
+octave_value
+elem_xpow (double a, const ComplexNDArray& b)
+{
+  ComplexNDArray result (b.dims ());
+  Complex atmp (a);
+  for (int i = 0; i < b.length (); i++)
+    {
+      OCTAVE_QUIT;
+      result(i) = pow (atmp, b(i));
+    }
+
+  return result;
+}
+
+// -*- 3 -*-
+octave_value
+elem_xpow (const NDArray& a, double b)
+{
+  octave_value retval;
+
+  if (static_cast<int> (b) != b && a.any_element_is_negative ())
+    {
+      ComplexNDArray result (a.dims ());
+
+      for (int i = 0; i < a.length (); i++)
+	{
+	  OCTAVE_QUIT;
+	  Complex atmp (a(i));
+	  result(i) = pow (atmp, b);
+	}
+
+      retval = result;
+    }
+  else
+    {
+      NDArray result (a.dims ());
+
+      for (int i = 0; i < a.length (); i++)
+	{
+	  OCTAVE_QUIT;
+	  result(i) = pow (a(i), b);
+	}
+
+      retval = result;
+    }
+
+  return retval;
+}
+
+// -*- 4 -*-
+octave_value
+elem_xpow (const NDArray& a, const NDArray& b)
+{
+  octave_value retval;
+
+  dim_vector a_dims = a.dims ();
+  dim_vector b_dims = b.dims ();
+
+  if (a_dims != b_dims)
+    {
+      gripe_nonconformant ("operator .^", a_dims, b_dims);
+      return octave_value ();
+    }
+
+  int len = a.length ();
+
+  bool convert_to_complex = false;
+
+  for (int i = 0; i < len; i++)
+    {
+      OCTAVE_QUIT;
+      double atmp = a(i);
+      double btmp = b(i);
+      if (atmp < 0.0 && static_cast<int> (btmp) != btmp)
+	{
+	  convert_to_complex = true;
+	  goto done;
+	}
+    }
+
+done:
+
+  if (convert_to_complex)
+    {
+      ComplexNDArray complex_result (a_dims);
+
+      for (int i = 0; i < len; i++)
+	{
+	  OCTAVE_QUIT;
+	  Complex atmp (a(i));
+	  Complex btmp (b(i));
+	  complex_result(i) = pow (atmp, btmp);
+	}
+
+      retval = complex_result;
+    }
+  else
+    {
+      NDArray result (a_dims);
+
+      for (int i = 0; i < len; i++)
+	{
+	  OCTAVE_QUIT;
+	  result(i) = pow (a(i), b(i));
+	}
+
+      retval = result;
+    }
+
+  return retval;
+}
+
+// -*- 5 -*-
+octave_value
+elem_xpow (const NDArray& a, const Complex& b)
+{
+  ComplexNDArray result (a.dims ());
+
+  for (int i = 0; i < a.length (); i++)
+    {
+      OCTAVE_QUIT;
+      result(i) = pow (Complex (a(i)), b);
+    }
+
+  return result;
+}
+
+// -*- 6 -*-
+octave_value
+elem_xpow (const NDArray& a, const ComplexNDArray& b)
+{
+  dim_vector a_dims = a.dims ();
+  dim_vector b_dims = b.dims ();
+
+  if (a_dims != b_dims)
+    {
+      gripe_nonconformant ("operator .^", a_dims, b_dims);
+      return octave_value ();
+    }
+
+  ComplexNDArray result (a_dims);
+  for (int i = 0; i < a.length (); i++)
+    {
+      OCTAVE_QUIT;
+      result(i) = pow (Complex (a(i)), b(i));
+    }
+
+  return result;
+}
+
+// -*- 7 -*-
+octave_value
+elem_xpow (const Complex& a, const NDArray& b)
+{
+  ComplexNDArray result (b.dims ());
+  for (int i = 0; i < b.length (); i++)
+    {
+      OCTAVE_QUIT;
+      double btmp = b(i);
+      if (xisint (btmp))
+	result(i) = pow (a, static_cast<int> (btmp));
+      else
+	result(i) = pow (a, btmp);
+    }
+
+  return result;
+}
+
+// -*- 8 -*-
+octave_value
+elem_xpow (const Complex& a, const ComplexNDArray& b)
+{
+  ComplexNDArray result (b.dims ());
+  for (int i = 0; i < b.length (); i++)
+    {
+      OCTAVE_QUIT;
+      result(i) = pow (a, b(i));
+    }
+
+  return result;
+}
+
+// -*- 9 -*-
+octave_value
+elem_xpow (const ComplexNDArray& a, double b)
+{
+  ComplexNDArray result (a.dims ());
+
+  if (xisint (b))
+    {
+      for (int i = 0; i < a.length (); i++)
+	{
+	  OCTAVE_QUIT;
+	  result(i) = pow (a(i), static_cast<int> (b));
+	}
+    }
+  else
+    {
+      for (int i = 0; i < a.length (); i++)
+	{
+	  OCTAVE_QUIT;
+	  result(i) = pow (a(i), b);
+	}
+    }
+
+  return result;
+}
+
+// -*- 10 -*-
+octave_value
+elem_xpow (const ComplexNDArray& a, const NDArray& b)
+{
+  dim_vector a_dims = a.dims ();
+  dim_vector b_dims = b.dims ();
+
+  if (a_dims != b_dims)
+    {
+      gripe_nonconformant ("operator .^", a_dims, b_dims);
+      return octave_value ();
+    }
+
+  ComplexNDArray result (a_dims);
+  for (int i = 0; i < a.length (); i++)
+    {
+      OCTAVE_QUIT;
+      double btmp = b(i);
+      if (xisint (btmp))
+	result(i) = pow (a(i), static_cast<int> (btmp));
+      else
+	result(i) = pow (a(i), btmp);
+    }
+
+  return result;
+}
+
+// -*- 11 -*-
+octave_value
+elem_xpow (const ComplexNDArray& a, const Complex& b)
+{
+  ComplexNDArray result (a.dims ());
+  for (int i = 0; i < a.length (); i++)
+    {
+      OCTAVE_QUIT;
+      result(i) = pow (a(i), b);
+    }
+
+  return result;
+}
+
+// -*- 12 -*-
+octave_value
+elem_xpow (const ComplexNDArray& a, const ComplexNDArray& b)
+{
+  dim_vector a_dims = a.dims ();
+  dim_vector b_dims = b.dims ();
+
+  if (a_dims != b_dims)
+    {
+      gripe_nonconformant ("operator .^", a_dims, b_dims);
+      return octave_value ();
+    }
+
+  ComplexNDArray result (a_dims);
+  for (int i = 0; i < a.length (); i++)
+    {
+      OCTAVE_QUIT;
+      result(i) = pow (a(i), b(i));
+    }
+
+  return result;
+}
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/src/xpow.h	Fri Oct 17 04:41:36 2003 +0000
+++ b/src/xpow.h	Sat Oct 18 03:53:53 2003 +0000
@@ -61,6 +61,23 @@
 extern octave_value elem_xpow (const ComplexMatrix& a, const Complex& b);
 extern octave_value elem_xpow (const ComplexMatrix& a, const ComplexMatrix& b);
 
+
+extern octave_value elem_xpow (double a, const NDArray& b);
+extern octave_value elem_xpow (double a, const ComplexNDArray& b);
+
+extern octave_value elem_xpow (const NDArray& a, double b);
+extern octave_value elem_xpow (const NDArray& a, const NDArray& b);
+extern octave_value elem_xpow (const NDArray& a, const Complex& b);
+extern octave_value elem_xpow (const NDArray& a, const ComplexNDArray& b);
+
+extern octave_value elem_xpow (const Complex& a, const NDArray& b);
+extern octave_value elem_xpow (const Complex& a, const ComplexNDArray& b);
+
+extern octave_value elem_xpow (const ComplexNDArray& a, double b);
+extern octave_value elem_xpow (const ComplexNDArray& a, const NDArray& b);
+extern octave_value elem_xpow (const ComplexNDArray& a, const Complex& b);
+extern octave_value elem_xpow (const ComplexNDArray& a, const ComplexNDArray& b);
+
 #endif
 
 /*
--- a/test/octave.test/matrix/matrix.exp	Fri Oct 17 04:41:36 2003 +0000
+++ b/test/octave.test/matrix/matrix.exp	Sat Oct 18 03:53:53 2003 +0000
@@ -211,7 +211,7 @@
 do_test rand-1.m
 
 set test rand-2
-set prog_output "\n... rand:.*"
+set prog_output "^ans = 1"
 do_test rand-2.m
 
 set test randn-1
@@ -219,7 +219,7 @@
 do_test randn-1.m
 
 set test randn-2
-set prog_output "\n... randn:.*"
+set prog_output "^ans = 1"
 do_test randn-2.m
 
 set test diag-1
--- a/test/octave.test/matrix/rand-2.m	Fri Oct 17 04:41:36 2003 +0000
+++ b/test/octave.test/matrix/rand-2.m	Sat Oct 18 03:53:53 2003 +0000
@@ -1,1 +1,1 @@
-rand (1, 2, 3)
+all (size (rand (1, 2, 3)) == [1, 2, 3])
--- a/test/octave.test/matrix/randn-2.m	Fri Oct 17 04:41:36 2003 +0000
+++ b/test/octave.test/matrix/randn-2.m	Sat Oct 18 03:53:53 2003 +0000
@@ -1,1 +1,1 @@
-randn (1, 2, 3)
+all (size (randn (1, 2, 3)) == [1, 2, 3])