changeset 4513:508238e65af7

[project @ 2003-09-19 21:40:57 by jwe]
author jwe
date Fri, 19 Sep 2003 21:41:21 +0000
parents b55eaa010770
children 8373b9b41eee
files ChangeLog configure.in liboctave/Array-C.cc liboctave/Array-b.cc liboctave/Array-ch.cc liboctave/Array-d.cc liboctave/Array-flags.cc liboctave/Array-i.cc liboctave/Array-idx.h liboctave/Array-s.cc liboctave/Array.cc liboctave/Array.h liboctave/Array2-idx.h liboctave/Array2.cc liboctave/Array2.h liboctave/Array3-idx.h liboctave/Array3.cc liboctave/Array3.h liboctave/ArrayN-idx.h liboctave/ArrayN-inline.h liboctave/ArrayN.cc liboctave/ArrayN.h liboctave/CDiagMatrix.cc liboctave/CMatrix.cc liboctave/ChangeLog liboctave/DiagArray2.cc liboctave/DiagArray2.h liboctave/MArray-C.cc liboctave/MArray-d.cc liboctave/MArray-defs.h liboctave/MArrayN.cc liboctave/MArrayN.h liboctave/MDiagArray2.h liboctave/Makefile.in liboctave/dDiagMatrix.cc liboctave/dMatrix.cc liboctave/dNDArray.cc liboctave/dNDArray.h liboctave/dim-vector.h liboctave/mx-base.h src/Cell.cc src/Cell.h src/ChangeLog src/Makefile.in src/TEMPLATE-INST/Array-tc.cc src/data.cc src/load-save.cc src/oct-map.cc src/oct-map.h src/ov-base-mat.cc src/ov-base-mat.h src/ov-base.h src/ov-bool-mat.cc src/ov-bool-mat.h src/ov-cell.cc src/ov-ch-mat.cc src/ov-ch-mat.h src/ov-cs-list.h src/ov-cx-mat.cc src/ov-cx-mat.h src/ov-list.cc src/ov-list.h src/ov-re-mat.cc src/ov-re-mat.h src/ov-re-nd-array.cc src/ov-re-nd-array.h src/ov-scalar.h src/ov-str-mat.cc src/ov-str-mat.h src/ov-struct.cc src/ov-struct.h src/ov.cc src/ov.h src/pr-output.cc src/pr-output.h src/pt-loop.cc src/utils.cc src/utils.h test/octave.test/matrix/matrix.exp
diffstat 79 files changed, 4042 insertions(+), 3824 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sat Sep 13 07:53:55 2003 +0000
+++ b/ChangeLog	Fri Sep 19 21:41:21 2003 +0000
@@ -1,3 +1,7 @@
+2003-09-19  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* configure.in (AH_BOTTOM): Don't define HEAVYWEIGHT_INDEXING here.
+
 2003-07-30  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
 	* emacs/octave-mod.el (octave-variables): Delete
--- a/configure.in	Sat Sep 13 07:53:55 2003 +0000
+++ b/configure.in	Fri Sep 19 21:41:21 2003 +0000
@@ -22,7 +22,7 @@
 ### 02111-1307, USA. 
 
 AC_INIT
-AC_REVISION($Revision: 1.431 $)
+AC_REVISION($Revision: 1.432 $)
 AC_PREREQ(2.52)
 AC_CONFIG_SRCDIR([src/octave.cc])
 AC_CONFIG_HEADER(config.h)
@@ -1350,8 +1350,6 @@
 
 #define X_CAST(T, E) (T) (E)
 
-#define HEAVYWEIGHT_INDEXING 1
-
 #if defined(HAVE_F2C) && !defined(F77_FUNC)
 #  define F77_FUNC(x,X) x ## _
 #  define F77_FUNC_(x,X) x ## __
--- a/liboctave/Array-C.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/Array-C.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -50,6 +50,8 @@
 
 template class Array2<Complex>;
 
+#if 0
+
 template int assign (Array2<Complex>&, const Array2<Complex>&);
 template int assign (Array2<Complex>&, const Array2<double>&);
 template int assign (Array2<Complex>&, const Array2<int>&);
@@ -62,6 +64,15 @@
 template int assign (Array2<Complex>&, const Array2<short>&, const Complex&);
 template int assign (Array2<Complex>&, const Array2<char>&, const Complex&);
 
+#endif
+
+#include "ArrayN.h"
+#include "ArrayN.cc"
+
+template class ArrayN<Complex>;
+
+template std::ostream& operator << (std::ostream&, const ArrayN<Complex>&);
+
 #include "DiagArray2.h"
 #include "DiagArray2.cc"
 
--- a/liboctave/Array-b.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/Array-b.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -40,10 +40,21 @@
 
 template class Array2<bool>;
 
+#if 0
+
 template int assign (Array2<bool>&, const Array2<bool>&);
 
 template int assign (Array2<bool>&, const Array2<bool>&, const bool&);
 
+#endif
+
+#include "ArrayN.h"
+#include "ArrayN.cc"
+
+template class ArrayN<bool>;
+
+template std::ostream& operator << (std::ostream&, const ArrayN<bool>&);
+
 #include "DiagArray2.h"
 #include "DiagArray2.cc"
 
--- a/liboctave/Array-ch.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/Array-ch.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -40,10 +40,21 @@
 
 template class Array2<char>;
 
+#if 0
+
 template int assign (Array2<char>&, const Array2<char>&);
 
 template int assign (Array2<char>&, const Array2<char>&, const char&);
 
+#endif
+
+#include "ArrayN.h"
+#include "ArrayN.cc"
+
+template class ArrayN<char>;
+
+template std::ostream& operator << (std::ostream&, const ArrayN<char>&);
+
 #include "DiagArray2.h"
 #include "DiagArray2.cc"
 
--- a/liboctave/Array-d.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/Array-d.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -46,6 +46,8 @@
 
 template class Array2<double>;
 
+#if 0
+
 template int assign (Array2<double>&, const Array2<double>&);
 template int assign (Array2<double>&, const Array2<int>&);
 template int assign (Array2<double>&, const Array2<short>&);
@@ -56,11 +58,15 @@
 template int assign (Array2<double>&, const Array2<short>&, const double&);
 template int assign (Array2<double>&, const Array2<char>&, const double&);
 
+#endif
+
 #include "ArrayN.h"
 #include "ArrayN.cc"
 
 template class ArrayN<double>;
 
+#if 0
+
 template int assign (ArrayN<double>&, const ArrayN<double>&);
 template int assign (ArrayN<double>&, const ArrayN<int>&);
 template int assign (ArrayN<double>&, const ArrayN<short>&);
@@ -71,6 +77,8 @@
 template int assign (ArrayN<double>&, const ArrayN<short>&, const double&);
 template int assign (ArrayN<double>&, const ArrayN<char>&, const double&);
 
+#endif
+
 template std::ostream& operator << (std::ostream&, const ArrayN<double>&);
 
 #include "DiagArray2.h"
--- a/liboctave/Array-flags.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/Array-flags.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -28,13 +28,9 @@
 
 // These have to be defined somewhere, but only once.
 
-#if defined (HEAVYWEIGHT_INDEXING)
-
 bool liboctave_wfi_flag = false;
 bool liboctave_wrore_flag = false;
 
-#endif
-
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/liboctave/Array-i.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/Array-i.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -44,6 +44,8 @@
 
 template class Array2<int>;
 
+#if 0
+
 template int assign (Array2<int>&, const Array2<int>&);
 template int assign (Array2<int>&, const Array2<short>&);
 template int assign (Array2<int>&, const Array2<char>&);
@@ -52,6 +54,8 @@
 template int assign (Array2<int>&, const Array2<short>&, const int&);
 template int assign (Array2<int>&, const Array2<char>&, const int&);
 
+#endif
+
 #include "DiagArray2.h"
 #include "DiagArray2.cc"
 
--- a/liboctave/Array-idx.h	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/Array-idx.h	Fri Sep 19 21:41:21 2003 +0000
@@ -22,6 +22,7 @@
 */
 
 #include "Array-flags.h"
+#include "Range.h"
 #include "idx-vector.h"
 #include "lo-error.h"
 
@@ -38,19 +39,27 @@
 void
 Array<T>::set_index (const idx_vector& idx_arg)
 {
-  if (! idx)
-    idx = new idx_vector [max_indices];
+  int nd = ndims ();
 
-  if (idx_count < max_indices)
+  if (! idx && nd > 0)
+    idx = new idx_vector [nd];
+
+  if (idx_count < nd)
     {
       idx[idx_count++] = idx_arg;
     }
   else
     {
-      (*current_liboctave_error_handler)
-	("invalid number of indices specified");
+      idx_vector *new_idx = new idx_vector [idx_count+1];
+
+      for (int i = 0; i < idx_count; i++)
+	new_idx[i] = idx[i];
 
-      clear_index ();
+      new_idx[idx_count++] = idx_arg;
+
+      delete [] idx;
+
+      idx = new_idx;
     }
 }
 
@@ -60,7 +69,24 @@
 {
   Array<T> retval;
 
-  retval = index (idx[0]);
+  int n_idx = index_count ();
+
+  if (n_idx == 2)
+    {
+      idx_vector *tmp = get_idx ();
+
+      idx_vector idx_i = tmp[0];
+      idx_vector idx_j = tmp[1];
+
+      retval = index (idx_i, idx_j);
+    }
+  else if (n_idx == 1)
+    {
+      retval = index (idx[0]);
+    }
+  else
+    (*current_liboctave_error_handler)
+      ("Array<T>::value: invalid number of indices specified");
 
   clear_index ();
 
@@ -73,6 +99,34 @@
 {
   Array<T> retval;
 
+  switch (ndims ())
+    {
+    case 1:
+      retval = index1 (idx_arg, resize_ok, rfv);
+      break;
+
+    case 2:
+      retval = index2 (idx_arg, resize_ok, rfv);
+      break;
+
+    default:
+      {
+	Array<idx_vector> tmp (1, idx_arg);
+
+	retval = index (tmp, resize_ok, rfv);
+      }
+      break;
+    }
+
+  return retval;
+}
+
+template <class T>
+Array<T>
+Array<T>::index1 (idx_vector& idx_arg, int resize_ok, const T& rfv) const
+{
+  Array<T> retval;
+
   int len = length ();
 
   int n = idx_arg.freeze (len, "vector", resize_ok);
@@ -85,7 +139,7 @@
 	}
       else if (n == 0)
 	{
-	  retval.resize (0);
+	  retval.resize_no_fill (0);
 	}
       else if (len == 1 && n > 1
 	       && idx_arg.one_zero_only ()
@@ -95,7 +149,7 @@
 	}
       else
 	{
-	  retval.resize (n);
+	  retval.resize_no_fill (n);
 
 	  for (int i = 0; i < n; i++)
 	    {
@@ -114,16 +168,280 @@
 }
 
 template <class T>
+Array<T>
+Array<T>::index2 (idx_vector& idx_arg, int resize_ok, const T& rfv) const
+{
+  Array<T> retval;
+
+  int nr = dim1 ();
+  int nc = dim2 ();
+
+  int orig_len = nr * nc;
+
+  int idx_orig_rows = idx_arg.orig_rows ();
+  int idx_orig_columns = idx_arg.orig_columns ();
+
+  if (idx_arg.is_colon ())
+    {
+      // Fast magic colon processing.
+
+      int result_nr = nr * nc;
+      int result_nc = 1;
+
+      retval = Array<T> (*this, dim_vector (result_nr, result_nc));
+    }
+  else if (nr == 1 && nc == 1)
+    {
+      Array<T> tmp = Array<T>::index1 (idx_arg, resize_ok);
+
+      if (tmp.length () != 0)
+	retval = Array<T> (tmp, dim_vector (idx_orig_rows, idx_orig_columns));
+      else
+	retval = Array<T> (tmp, dim_vector (0, 0));
+    }
+  else if (nr == 1 || nc == 1)
+    {
+      // If indexing a vector with a matrix, return value has same
+      // shape as the index.  Otherwise, it has same orientation as
+      // indexed object.
+
+      Array<T> tmp = index1 (idx_arg, resize_ok);
+
+      int len = tmp.length ();
+
+      if (len == 0)
+	{
+	  if (idx_orig_rows == 0 || idx_orig_columns == 0)
+	    retval = Array<T> (dim_vector (idx_orig_rows, idx_orig_columns));
+	  else if (nr == 1)
+	    retval = Array<T> (dim_vector (1, 0));
+	  else
+	    retval = Array<T> (dim_vector (0, 1));
+	}
+      else
+	{
+	  if (idx_orig_rows == 1 || idx_orig_columns == 1)
+	    {
+	      if (nr == 1)
+		retval = Array<T> (tmp, dim_vector (1, len));
+	      else
+		retval = Array<T> (tmp, dim_vector (len, 1));
+	    }
+	  else
+	    retval = Array<T> (tmp, dim_vector (idx_orig_rows, idx_orig_columns));
+	}
+    }
+  else
+    {
+      if (liboctave_wfi_flag
+	  && ! (idx_arg.one_zero_only ()
+		&& idx_orig_rows == nr
+		&& idx_orig_columns == nc))
+	(*current_liboctave_warning_handler) ("single index used for matrix");
+
+      // This code is only for indexing matrices.  The vector
+      // cases are handled above.
+
+      idx_arg.freeze (nr * nc, "matrix", resize_ok);
+
+      if (idx_arg)
+	{
+	  int result_nr = idx_orig_rows;
+	  int result_nc = idx_orig_columns;
+
+	  if (idx_arg.one_zero_only ())
+	    {
+	      result_nr = idx_arg.ones_count ();
+	      result_nc = (result_nr > 0 ? 1 : 0);
+	    }
+
+	  retval.resize_no_fill (result_nr, result_nc);
+
+	  int k = 0;
+	  for (int j = 0; j < result_nc; j++)
+	    {
+	      for (int i = 0; i < result_nr; i++)
+		{
+		  int ii = idx_arg.elem (k++);
+		  if (ii >= orig_len)
+		    retval.elem (i, j) = rfv;
+		  else
+		    {
+		      int fr = ii % nr;
+		      int fc = (ii - fr) / nr;
+		      retval.elem (i, j) = elem (fr, fc);
+		    }
+		}
+	    }
+	}
+      // idx_vector::freeze() printed an error message for us.
+    }
+
+  return retval;
+}
+
+template <class T>
+Array<T>
+Array<T>::index (idx_vector& idx_i, idx_vector& idx_j, int resize_ok,
+		 const T& rfv) const
+{
+  Array<T> retval;
+
+  int nr = dim1 ();
+  int nc = dim2 ();
+
+  int n = idx_i.freeze (nr, "row", resize_ok);
+  int m = idx_j.freeze (nc, "column", resize_ok);
+
+  if (idx_i && idx_j)
+    {
+      if (idx_i.orig_empty () || idx_j.orig_empty () || n == 0 || m == 0)
+	{
+	  retval.resize_no_fill (n, m);
+	}
+      else if (idx_i.is_colon_equiv (nr) && idx_j.is_colon_equiv (nc))
+	{
+	  retval = *this;
+	}
+      else
+	{
+	  retval.resize_no_fill (n, m);
+
+	  for (int j = 0; j < m; j++)
+	    {
+	      int jj = idx_j.elem (j);
+	      for (int i = 0; i < n; i++)
+		{
+		  int ii = idx_i.elem (i);
+		  if (ii >= nr || jj >= nc)
+		    retval.elem (i, j) = rfv;
+		  else
+		    retval.elem (i, j) = elem (ii, jj);
+		}
+	    }
+	}
+    }
+
+  // idx_vector::freeze() printed an error message for us.
+
+  return retval;
+}
+
+#include "ArrayN-inline.h"
+
+template <class T>
+Array<T>
+Array<T>::index (Array<idx_vector>& ra_idx, int resize_ok, const T& rfv) const
+{
+  Array<T> retval;
+
+  int n_idx = ra_idx.length ();
+
+  int n_dims = dimensions.length ();
+
+  if (n_idx == n_dims)
+    {
+      dim_vector frozen_lengths = freeze (ra_idx, dimensions, resize_ok);
+
+      if (frozen_lengths.length () == n_dims)
+	{
+	  if (all_ok (ra_idx))
+	    {
+	      if (any_orig_empty (ra_idx))
+		{
+		  retval.resize (frozen_lengths);
+		}
+	      else if (any_zero_len (frozen_lengths))
+		{
+		  dim_vector new_size = get_zero_len_size (frozen_lengths,
+							   dimensions);
+
+		  retval.resize (new_size);
+		}
+	      else if (all_colon_equiv (ra_idx, frozen_lengths))
+		{
+		  retval = *this;
+		}
+	      else
+		{
+		  (*current_liboctave_error_handler) ("not implemented");
+#if 0
+		  retval.resize (frozen_lengths);
+
+		  int n = Array<T>::get_size (frozen_lengths);
+
+		  dim_vector result_idx (n_dims, 0);
+
+		  for (int i = 0; i < n; i++)
+		    {
+		      dim_vector elt_idx = get_elt_idx (result_idx);
+
+		      if (elt_idx > orig_len)
+			retval.elem (result_idx) = rfv;
+		      else
+			retval.elem (result_idx) = elem (elt_idx);
+
+		      increment_index (result_idx, frozen_lengths);
+		    }
+#endif
+		}
+	    }
+	  // idx_vector::freeze() printed an error message for us.
+	}
+    }
+  else if (n_idx == 1)
+    {
+      if (ra_idx(0).is_colon ())
+	{
+	  // Fast magic colon processing.
+
+	  int result_nr = Array<int>::get_size (dimensions);
+	  int result_nc = 1;
+
+	  retval = Array<T> (*this, dim_vector (result_nr, result_nc));
+	}
+      else
+	(*current_liboctave_error_handler) ("not implemented");
+    }
+  else
+    (*current_liboctave_error_handler)
+      ("invalid number of dimensions for N-dimensional array index");
+
+  return retval;
+}
+
+template <class T>
 void
 Array<T>::maybe_delete_elements (idx_vector& idx_arg)
 {
+  switch (ndims ())
+    {
+    case 1:
+      maybe_delete_elements_1 (idx_arg);
+      break;
+
+    case 2:
+      maybe_delete_elements_2 (idx_arg);
+      break;
+
+    default:
+      (*current_liboctave_error_handler)
+	("Array<T>::maybe_delete_elements: invalid operation");
+      break;
+    }
+}
+
+template <class T>
+void
+Array<T>::maybe_delete_elements_1 (idx_vector& idx_arg)
+{
   int len = length ();
 
   if (len == 0)
     return;
 
   if (idx_arg.is_colon_equiv (len, 1))
-    resize (0);
+    resize_no_fill (0);
   else
     {
       int num_to_delete = idx_arg.length (len);
@@ -166,7 +484,8 @@
 
 	      rep = new typename Array<T>::ArrayRep (new_data, new_len);
 
-	      set_max_indices (1);
+	      dimensions.resize (1);
+	      dimensions(0) = new_len;
 	    }
 	  else
 	    (*current_liboctave_error_handler)
@@ -175,13 +494,539 @@
     }
 }
 
-// ??? FIXME ??? -- this does not handle assignment of empty vectors
-// to delete elements.  Should it?
+template <class T>
+void
+Array<T>::maybe_delete_elements_2 (idx_vector& idx_arg)
+{
+  int nr = dim1 ();
+  int nc = dim2 ();
+
+  if (nr == 0 && nc == 0)
+    return;
+
+  int n;
+  if (nr == 1)
+    n = nc;
+  else if (nc == 1)
+    n = nr;
+  else
+    {
+      (*current_liboctave_error_handler)
+	("A(idx) = []: expecting A to be row or column vector or scalar");
+
+      return;
+    }
+
+  if (idx_arg.is_colon_equiv (n, 1))
+    {
+      // Either A(:) = [] or A(idx) = [] with idx enumerating all
+      // elements, so we delete all elements and return [](0x0).  To
+      // preserve the orientation of the vector, you have to use
+      // A(idx,:) = [] (delete rows) or A(:,idx) (delete columns).
+
+      resize_no_fill (0, 0);
+      return;
+    }
+
+  idx_arg.sort (true);
+
+  int num_to_delete = idx_arg.length (n);
+
+  if (num_to_delete != 0)
+    {
+      int new_n = n;
+
+      int iidx = 0;
+
+      for (int i = 0; i < n; i++)
+	if (i == idx_arg.elem (iidx))
+	  {
+	    iidx++;
+	    new_n--;
+
+	    if (iidx == num_to_delete)
+	      break;
+	  }
+
+      if (new_n > 0)
+	{
+	  T *new_data = new T [new_n];
+
+	  int ii = 0;
+	  iidx = 0;
+	  for (int i = 0; i < n; i++)
+	    {
+	      if (iidx < num_to_delete && i == idx_arg.elem (iidx))
+		iidx++;
+	      else
+		{
+		  if (nr == 1)
+		    new_data[ii] = elem (0, i);
+		  else
+		    new_data[ii] = elem (i, 0);
+
+		  ii++;
+		}
+	    }
+
+	  if (--(Array<T>::rep)->count <= 0)
+	    delete Array<T>::rep;
+
+	  Array<T>::rep = new typename Array<T>::ArrayRep (new_data, new_n);
+
+	  dimensions.resize (2);
+
+	  if (nr == 1)
+	    {
+	      dimensions(0) = 1;
+	      dimensions(1) = new_n;
+	    }
+	  else
+	    {
+	      dimensions(0) = new_n;
+	      dimensions(1) = 1;
+	    }
+	}
+      else
+	(*current_liboctave_error_handler)
+	  ("A(idx) = []: index out of range");
+    }
+}
+
+template <class T>
+void
+Array<T>::maybe_delete_elements (idx_vector& idx_i, idx_vector& idx_j)
+{
+  int nr = dim1 ();
+  int nc = dim2 ();
+
+  if (nr == 0 && nc == 0)
+    return;
+
+  if (idx_i.is_colon ())
+    {
+      if (idx_j.is_colon ())
+	{
+	  // A(:,:) -- We are deleting columns and rows, so the result
+	  // is [](0x0).
+
+	  resize_no_fill (0, 0);
+	  return;
+	}
+
+      if (idx_j.is_colon_equiv (nc, 1))
+	{
+	  // A(:,j) -- We are deleting columns by enumerating them,
+	  // If we enumerate all of them, we should have zero columns
+	  // with the same number of rows that we started with.
+
+	  resize_no_fill (nr, 0);
+	  return;
+	}
+    }
+
+  if (idx_j.is_colon () && idx_i.is_colon_equiv (nr, 1))
+    {
+      // A(i,:) -- We are deleting rows by enumerating them.  If we
+      // enumerate all of them, we should have zero rows with the
+      // same number of columns that we started with.
+
+      resize_no_fill (0, nc);
+      return;
+    }
+
+  if (idx_i.is_colon_equiv (nr, 1))
+    {
+      if (idx_j.is_colon_equiv (nc, 1))
+	resize_no_fill (0, 0);
+      else
+	{
+	  idx_j.sort (true);
+
+	  int num_to_delete = idx_j.length (nc);
+
+	  if (num_to_delete != 0)
+	    {
+	      if (nr == 1 && num_to_delete == nc)
+		resize_no_fill (0, 0);
+	      else
+		{
+		  int new_nc = nc;
+
+		  int iidx = 0;
+
+		  for (int j = 0; j < nc; j++)
+		    if (j == idx_j.elem (iidx))
+		      {
+			iidx++;
+			new_nc--;
+
+			if (iidx == num_to_delete)
+			  break;
+		      }
+
+		  if (new_nc > 0)
+		    {
+		      T *new_data = new T [nr * new_nc];
+
+		      int jj = 0;
+		      iidx = 0;
+		      for (int j = 0; j < nc; j++)
+			{
+			  if (iidx < num_to_delete && j == idx_j.elem (iidx))
+			    iidx++;
+			  else
+			    {
+			      for (int i = 0; i < nr; i++)
+				new_data[nr*jj+i] = elem (i, j);
+			      jj++;
+			    }
+			}
+
+		      if (--(Array<T>::rep)->count <= 0)
+			delete Array<T>::rep;
+
+		      Array<T>::rep = new typename Array<T>::ArrayRep (new_data, nr * new_nc);
+
+		      dimensions.resize (2);
+		      dimensions(1) = new_nc;
+		    }
+		  else
+		    (*current_liboctave_error_handler)
+		      ("A(idx) = []: index out of range");
+		}
+	    }
+	}
+    }
+  else if (idx_j.is_colon_equiv (nc, 1))
+    {
+      if (idx_i.is_colon_equiv (nr, 1))
+	resize_no_fill (0, 0);
+      else
+	{
+	  idx_i.sort (true);
+
+	  int num_to_delete = idx_i.length (nr);
+
+	  if (num_to_delete != 0)
+	    {
+	      if (nc == 1 && num_to_delete == nr)
+		resize_no_fill (0, 0);
+	      else
+		{
+		  int new_nr = nr;
+
+		  int iidx = 0;
+
+		  for (int i = 0; i < nr; i++)
+		    if (i == idx_i.elem (iidx))
+		      {
+			iidx++;
+			new_nr--;
+
+			if (iidx == num_to_delete)
+			  break;
+		      }
+
+		  if (new_nr > 0)
+		    {
+		      T *new_data = new T [new_nr * nc];
+
+		      int ii = 0;
+		      iidx = 0;
+		      for (int i = 0; i < nr; i++)
+			{
+			  if (iidx < num_to_delete && i == idx_i.elem (iidx))
+			    iidx++;
+			  else
+			    {
+			      for (int j = 0; j < nc; j++)
+				new_data[new_nr*j+ii] = elem (i, j);
+			      ii++;
+			    }
+			}
+
+		      if (--(Array<T>::rep)->count <= 0)
+			delete Array<T>::rep;
+
+		      Array<T>::rep = new typename Array<T>::ArrayRep (new_data, new_nr * nc);
+
+		      dimensions.resize (2);
+		      dimensions(0) = new_nr;
+		    }
+		  else
+		    (*current_liboctave_error_handler)
+		      ("A(idx) = []: index out of range");
+		}
+	    }
+	}
+    }
+}
+
+template <class T>
+void
+Array<T>::maybe_delete_elements (idx_vector&, idx_vector&, idx_vector&)
+{
+  assert (0);
+}
+
+template <class T>
+void
+Array<T>::maybe_delete_elements (Array<idx_vector>& idx, const T& rfv)
+{
+  int n_idx = idx.length ();
+
+  dim_vector lhs_dims = dims ();
+
+  dim_vector idx_is_colon;
+  idx_is_colon.resize (n_idx);
+
+  dim_vector idx_is_colon_equiv;
+  idx_is_colon_equiv.resize (n_idx);
+
+  // Initialization of colon arrays.
+
+  for (int i = 0; i < n_idx; i++)
+    {
+      idx_is_colon_equiv(i) = idx(i).is_colon_equiv (lhs_dims(i), 1);
+
+      idx_is_colon(i) = idx(i).is_colon ();
+    }
+
+  if (all_ones (idx_is_colon) || all_ones (idx_is_colon_equiv))
+    {
+      // A(:,:,:) -- we are deleting elements in all dimensions, so
+      // the result is [](0x0x0).
+
+      dim_vector zeros;
+      zeros.resize (n_idx);
+
+      for (int i = 0; i < n_idx; i++)
+	zeros(i) = 0;
+
+      resize (zeros, rfv);
+    }
+
+  else if (num_ones (idx_is_colon) == n_idx - 1
+	   && num_ones (idx_is_colon_equiv) == n_idx)
+    {
+      // A(:,:,j) -- we are deleting elements in one dimension by
+      // enumerating them.
+      //
+      // If we enumerate all of the elements, we should have zero
+      // elements in that dimension with the same number of elements
+      // in the other dimensions that we started with.
+
+      dim_vector temp_dims;
+      temp_dims.resize (n_idx);
+
+      for (int i = 0; i < n_idx; i++)
+	{
+	  if (idx_is_colon (i))
+	    temp_dims (i) =  lhs_dims (i);
+	  else
+	    temp_dims (i) = 0;
+	}
+
+      resize (temp_dims);
+    }
+  else if (num_ones (idx_is_colon) == n_idx - 1)
+    {
+      // We have colons in all indices except for one.
+      // This index tells us which slice to delete
+
+      int non_col = 0;
+
+      // Find the non-colon column.
+
+      for (int i = 0; i < n_idx; i++)
+	{
+	  if (! idx_is_colon (i))
+	    non_col = i;
+	}
+
+      // The length of the non-colon dimension.
+
+      int non_col_dim = lhs_dims (non_col);
+
+      idx(non_col).sort (true);
+
+      int num_to_delete = idx(non_col).length (lhs_dims (non_col));
+
+      if (num_to_delete > 0)
+	{
+	  int temp = num_ones(lhs_dims);
+
+	  if (non_col_dim == 1)
+	    temp--;
+
+	  if (temp == n_idx - 1 && num_to_delete == non_col_dim)
+	    {
+	      // We have A with (1x1x4), where A(1,:,1:4)
+	      // Delete all (0x0x0)
+
+	      dim_vector zero_dims (n_idx, 0);
+
+	      resize (zero_dims, rfv);
+	    }
+	  else
+	    {
+	      // New length of non-colon dimension
+	      // (calculated in the next for loop)
+
+	      int new_dim = non_col_dim;
+
+	      int iidx = 0;
+
+	      for (int j = 0; j < non_col_dim; j++)
+		if (j == idx(non_col).elem (iidx))
+		  {
+		    iidx++;
+
+		    new_dim--;
+
+		    if (iidx == num_to_delete)
+		      break;
+		  }
+
+	      // Creating the new nd array after deletions.
+
+	      if (new_dim > 0)
+		{
+		  // Calculate number of elements in new array.
+
+		  int num_new_elem=1;
+
+		  for (int i = 0; i < n_idx; i++)
+		    {
+		      if (i == non_col)
+			num_new_elem *= new_dim;
+
+		      else
+			num_new_elem *= lhs_dims(i);
+		    }
+
+		  T *new_data = new T [num_new_elem];
+		  
+		  Array<int> result_idx (lhs_dims.length (), 0);
+
+		  dim_vector lhs_inc;
+		  lhs_inc.resize (lhs_dims.length ());
+
+		  for (int i = 0; i < lhs_dims.length (); i++)
+		    lhs_inc(i) = lhs_dims(i) + 1;
+
+		  dim_vector new_lhs_dim = lhs_dims;
+
+		  new_lhs_dim(non_col) = new_dim;
+
+		  int num_elem = 1;
+
+		  int numidx = 0;
+
+		  int n = length ();
+
+		  for (int i =0; i < lhs_dims.length (); i++)
+		    if (i != non_col)
+		      num_elem *= lhs_dims (i);
+
+		  num_elem *= idx(non_col).capacity ();
+
+		  for (int i = 0; i < n; i++)
+		    {
+		      if (numidx < num_elem
+			  && is_in (result_idx(non_col), idx(non_col)))
+			numidx++;
+
+		      else
+			{
+			  Array<int> temp_result_idx = result_idx;
+
+			  int num_lgt
+			    = how_many_lgt (result_idx(non_col), idx(non_col));
+
+			  temp_result_idx(non_col) -= num_lgt;
+
+			  int kidx
+			    = ::compute_index (temp_result_idx, new_lhs_dim);
+
+			  new_data[kidx] = elem (result_idx);
+			}
+
+		      increment_index (result_idx, lhs_dims);
+		    }
+
+		  if (--rep->count <= 0)
+		    delete rep;
+
+		  rep = new typename Array<T>::ArrayRep (new_data,
+							 num_new_elem);
+
+		  dimensions = new_lhs_dim;
+	    	}
+	    }
+	}
+    }
+  else if (num_ones(idx_is_colon) < n_idx)
+    {
+      (*current_liboctave_error_handler)
+	("A null assignment can have only one non-colon index.");
+    }
+}
+
+// XXX FIXME XXX -- this is a mess.
 
 template <class LT, class RT>
 int
 assign (Array<LT>& lhs, const Array<RT>& rhs, const LT& rfv)
 {
+  int retval = 0;
+
+  switch (lhs.ndims ())
+    {
+    case 0:
+      {
+	if (lhs.index_count () < 3)
+	  {
+	    // kluge...
+	    lhs.resize_no_fill (0, 0);
+	    retval = assign2 (lhs, rhs, rfv);
+	  }
+	else
+	  retval = assignN (lhs, rhs, rfv);
+      }
+      break;
+
+    case 1:
+      {
+	if (lhs.index_count () > 1)
+	  retval = assignN (lhs, rhs, rfv);
+	else
+	  retval = assign1 (lhs, rhs, rfv);
+      }
+      break;
+
+    case 2:
+      {
+	if (lhs.index_count () > 2)
+	  retval = assignN (lhs, rhs, rfv);
+	else
+	  retval = assign2 (lhs, rhs, rfv);
+      }
+      break;
+
+    default:
+      retval = assignN (lhs, rhs, rfv);
+      break;
+    }
+
+  return retval;
+}
+
+template <class LT, class RT>
+int
+assign1 (Array<LT>& lhs, const Array<RT>& rhs, const LT& rfv)
+{
   int retval = 1;
 
   idx_vector *tmp = lhs.get_idx ();
@@ -232,7 +1077,7 @@
     {
       if (lhs_len == 0)
 	{
-	  lhs.resize (rhs_len);
+	  lhs.resize_no_fill (rhs_len);
 
 	  for (int i = 0; i < rhs_len; i++)
 	    lhs.elem (i) = rhs.elem (i);
@@ -245,7 +1090,625 @@
     {
       (*current_liboctave_error_handler)
 	("A([]) = X: X must also be an empty matrix or a scalar");
-  
+
+      retval = 0;
+    }
+
+  lhs.clear_index ();
+
+  return retval;
+}
+
+#define MAYBE_RESIZE_LHS \
+  do \
+    { \
+      int max_row_idx = idx_i_is_colon ? rhs_nr : idx_i.max () + 1; \
+      int max_col_idx = idx_j_is_colon ? rhs_nc : idx_j.max () + 1; \
+ \
+      int new_nr = max_row_idx > lhs_nr ? max_row_idx : lhs_nr; \
+      int new_nc = max_col_idx > lhs_nc ? max_col_idx : lhs_nc; \
+ \
+      lhs.resize_and_fill (new_nr, new_nc, rfv); \
+    } \
+  while (0)
+
+template <class LT, class RT>
+int
+assign2 (Array<LT>& lhs, const Array<RT>& rhs, const LT& rfv)
+{
+  int retval = 1;
+
+  int n_idx = lhs.index_count ();
+
+  int lhs_nr = lhs.rows ();
+  int lhs_nc = lhs.cols ();
+
+  int rhs_nr = rhs.rows ();
+  int rhs_nc = rhs.cols ();
+
+  idx_vector *tmp = lhs.get_idx ();
+
+  idx_vector idx_i;
+  idx_vector idx_j;
+
+  if (n_idx > 1)
+    idx_j = tmp[1];
+
+  if (n_idx > 0)
+    idx_i = tmp[0];
+
+  if (n_idx == 2)
+    {
+      int n = idx_i.freeze (lhs_nr, "row", true, liboctave_wrore_flag);
+
+      int m = idx_j.freeze (lhs_nc, "column", true, liboctave_wrore_flag);
+
+      int idx_i_is_colon = idx_i.is_colon ();
+      int idx_j_is_colon = idx_j.is_colon ();
+
+      if (idx_i_is_colon)
+	n = lhs_nr > 0 ? lhs_nr : rhs_nr;
+
+      if (idx_j_is_colon)
+	m = lhs_nc > 0 ? lhs_nc : rhs_nc;
+
+      if (idx_i && idx_j)
+	{
+	  if (rhs_nr == 0 && rhs_nc == 0)
+	    {
+	      lhs.maybe_delete_elements (idx_i, idx_j);
+	    }
+	  else
+	    {
+	      if (rhs_nr == 1 && rhs_nc == 1 && n > 0 && m > 0)
+		{
+		  MAYBE_RESIZE_LHS;
+
+		  RT scalar = rhs.elem (0, 0);
+
+		  for (int j = 0; j < m; j++)
+		    {
+		      int jj = idx_j.elem (j);
+		      for (int i = 0; i < n; i++)
+			{
+			  int ii = idx_i.elem (i);
+			  lhs.elem (ii, jj) = scalar;
+			}
+		    }
+		}
+	      else if (n == rhs_nr && m == rhs_nc)
+		{
+		  if (n > 0 && m > 0)
+		    {
+		      MAYBE_RESIZE_LHS;
+
+		      for (int j = 0; j < m; j++)
+			{
+			  int jj = idx_j.elem (j);
+			  for (int i = 0; i < n; i++)
+			    {
+			      int ii = idx_i.elem (i);
+			      lhs.elem (ii, jj) = rhs.elem (i, j);
+			    }
+			}
+		    }
+		}
+	      else if (n == 0 && m == 0)
+		{
+		  if (! ((rhs_nr == 1 && rhs_nc == 1)
+			 || (rhs_nr == 0 && rhs_nc == 0)))
+		    {
+		      (*current_liboctave_error_handler)
+		("A([], []) = X: X must be an empty matrix or a scalar");
+
+		      retval = 0;
+		    }
+		}
+	      else
+		{
+		  (*current_liboctave_error_handler)
+    ("A(I, J) = X: X must be a scalar or the number of elements in I must");
+		  (*current_liboctave_error_handler)
+    ("match the number of rows in X and the number of elements in J must");
+		  (*current_liboctave_error_handler)
+    ("match the number of columns in X");
+
+		  retval = 0;
+		}
+	    }
+	}
+      // idx_vector::freeze() printed an error message for us.
+    }
+  else if (n_idx == 1)
+    {
+      int lhs_is_empty = lhs_nr == 0 || lhs_nc == 0;
+
+      if (lhs_is_empty || (lhs_nr == 1 && lhs_nc == 1))
+	{
+	  int lhs_len = lhs.length ();
+
+	  int n = idx_i.freeze (lhs_len, 0, true, liboctave_wrore_flag);
+
+	  if (idx_i)
+	    {
+	      if (rhs_nr == 0 && rhs_nc == 0)
+		{
+		  if (n != 0 && (lhs_nr != 0 || lhs_nc != 0))
+		    lhs.maybe_delete_elements (idx_i);
+		}
+	      else
+		{
+		  if (liboctave_wfi_flag)
+		    {
+		      if (lhs_is_empty
+			  && idx_i.is_colon ()
+			  && ! (rhs_nr == 1 || rhs_nc == 1))
+			{
+			  (*current_liboctave_warning_handler)
+			    ("A(:) = X: X is not a vector or scalar");
+			}
+		      else
+			{
+			  int idx_nr = idx_i.orig_rows ();
+			  int idx_nc = idx_i.orig_columns ();
+
+			  if (! (rhs_nr == idx_nr && rhs_nc == idx_nc))
+			    (*current_liboctave_warning_handler)
+			      ("A(I) = X: X does not have same shape as I");
+			}
+		    }
+
+		  if (assign1 ((Array<LT>&) lhs, (Array<RT>&) rhs, rfv))
+		    {
+		      int len = lhs.length ();
+
+		      if (len > 0)
+			{
+			  // The following behavior is much simplified
+			  // over previous versions of Octave.  It
+			  // seems to be compatible with Matlab.
+
+			  lhs.dimensions = dim_vector (1, lhs.length ());
+			}
+		      else
+			lhs.dimensions = dim_vector (0, 0);
+		    }
+		  else
+		    retval = 0;
+		}
+	    }
+	  // idx_vector::freeze() printed an error message for us.
+	}
+      else if (lhs_nr == 1)
+	{
+	  idx_i.freeze (lhs_nc, "vector", true, liboctave_wrore_flag);
+
+	  if (idx_i)
+	    {
+	      if (rhs_nr == 0 && rhs_nc == 0)
+		lhs.maybe_delete_elements (idx_i);
+	      else
+		{
+		  if (assign1 ((Array<LT>&) lhs, (Array<RT>&) rhs, rfv))
+		    lhs.dimensions = dim_vector (1, lhs.length ());
+		  else
+		    retval = 0;
+		}
+	    }
+	  // idx_vector::freeze() printed an error message for us.
+	}
+      else if (lhs_nc == 1)
+	{
+	  idx_i.freeze (lhs_nr, "vector", true, liboctave_wrore_flag);
+
+	  if (idx_i)
+	    {
+	      if (rhs_nr == 0 && rhs_nc == 0)
+		lhs.maybe_delete_elements (idx_i);
+	      else
+		{
+		  if (assign1 ((Array<LT>&) lhs, (Array<RT>&) rhs, rfv))
+		    lhs.dimensions = dim_vector (lhs.length (), 1);
+		  else
+		    retval = 0;
+		}
+	    }
+	  // idx_vector::freeze() printed an error message for us.
+	}
+      else
+	{
+	  if (liboctave_wfi_flag
+	      && ! (idx_i.is_colon ()
+		    || (idx_i.one_zero_only ()
+			&& idx_i.orig_rows () == lhs_nr
+			&& idx_i.orig_columns () == lhs_nc)))
+	    (*current_liboctave_warning_handler)
+	      ("single index used for matrix");
+
+	  int len = idx_i.freeze (lhs_nr * lhs_nc, "matrix");
+
+	  if (idx_i)
+	    {
+	      if (len == 0)
+		{
+		  if (! ((rhs_nr == 1 && rhs_nc == 1)
+			 || (rhs_nr == 0 && rhs_nc == 0)))
+		    (*current_liboctave_error_handler)
+		      ("A([]) = X: X must be an empty matrix or scalar");
+		}
+	      else if (len == rhs_nr * rhs_nc)
+		{
+		  int k = 0;
+		  for (int j = 0; j < rhs_nc; j++)
+		    {
+		      for (int i = 0; i < rhs_nr; i++)
+			{
+			  int ii = idx_i.elem (k++);
+			  int fr = ii % lhs_nr;
+			  int fc = (ii - fr) / lhs_nr;
+			  lhs.elem (fr, fc) = rhs.elem (i, j);
+			}
+		    }
+		}
+	      else if (rhs_nr == 1 && rhs_nc == 1 && len <= lhs_nr * lhs_nc)
+		{
+		  RT scalar = rhs.elem (0, 0);
+
+		  for (int i = 0; i < len; i++)
+		    {
+		      int ii = idx_i.elem (i);
+		      int fr = ii % lhs_nr;
+		      int fc = (ii - fr) / lhs_nr;
+		      lhs.elem (fr, fc) = scalar;
+		    }
+		}
+	      else
+		{
+		  (*current_liboctave_error_handler)
+      ("A(I) = X: X must be a scalar or a matrix with the same size as I");
+
+		  retval = 0;
+		}
+	    }
+	  // idx_vector::freeze() printed an error message for us.
+	}
+    }
+  else
+    {
+      (*current_liboctave_error_handler)
+	("invalid number of indices for matrix expression");
+
+      retval = 0;
+    }
+
+  lhs.clear_index ();
+
+  return retval;
+}
+
+#define MAYBE_RESIZE_ND_DIMS \
+  do \
+    { \
+      if (n_idx >= lhs_dims.length () && ! rhs_is_empty) \
+	{ \
+	  Array<int> max_idx (n_idx); \
+	  dim_vector new_idx; \
+          new_idx.resize (n_idx); \
+ \
+	  for (int i = 0; i < n_idx; i++) \
+	    { \
+	      if (lhs_dims.length () == 0 || i >= lhs_dims.length ()) \
+		new_idx(i) = idx(i).max () + 1; \
+	      else \
+		{ \
+		  if (i < rhs_dims.length ()) \
+		    max_idx(i) = idx(i).is_colon () ? rhs_dims(i) : idx(i).max () + 1; \
+		  else \
+		    max_idx(i) = idx(i).max () + 1; \
+ \
+		  new_idx(i) = max_idx(i) > lhs_dims(i) ? max_idx(i) : lhs_dims(i); \
+		} \
+            } \
+ \
+	  lhs.resize (new_idx, rfv); \
+	  lhs_dims = lhs.dims ();  \
+        } \
+    } \
+  while (0)
+
+template <class LT, class RT>
+int
+assignN (Array<LT>& lhs, const Array<RT>& rhs, const LT& rfv)
+{
+  int retval = 1;
+
+  int n_idx = lhs.index_count ();
+
+  dim_vector lhs_dims = lhs.dims ();
+  dim_vector rhs_dims = rhs.dims ();
+
+  idx_vector *tmp = lhs.get_idx ();
+
+  Array<idx_vector> idx = conv_to_array (tmp, n_idx);
+
+  // This needs to be defined before MAYBE_RESIZE_ND_DIMS.
+
+  bool rhs_is_empty = rhs_dims.length () == 0 ? true : any_zero_len (rhs_dims);
+
+  // Maybe expand to more dimensions.
+
+  MAYBE_RESIZE_ND_DIMS;
+
+  Array<int> idx_is_colon (n_idx, 0);
+  Array<int> idx_is_colon_equiv (n_idx, 0);
+
+  for (int i = 0; i < n_idx; i++)
+    {
+      idx_is_colon_equiv(i) = idx(i).is_colon_equiv (lhs_dims(i), 1);
+
+      idx_is_colon(i) = idx(i).is_colon ();
+    }
+
+  int resize_ok = 1;
+
+  dim_vector frozen_len;
+
+  if (n_idx == lhs_dims.length ())
+    frozen_len = freeze (idx, lhs_dims, resize_ok);
+
+  bool rhs_is_scalar = is_scalar (rhs_dims);
+
+  bool idx_is_empty = any_zero_len (frozen_len);
+
+  if (rhs_is_empty)
+    {
+      lhs.maybe_delete_elements (idx, rfv);
+    }
+  else if (rhs_is_scalar)
+    {
+      if (n_idx == 0)
+	(*current_liboctave_error_handler)
+	  ("number of indices is zero.");
+
+      else if (n_idx < lhs_dims.length ())
+	{
+	  // Number of indices is less than dimensions.
+
+	  if (any_ones (idx_is_colon)|| any_ones (idx_is_colon_equiv))
+	    {
+	      (*current_liboctave_error_handler)
+		("number of indices is less than number of dimensions, one or more indices are colons.");
+	    }
+	  else
+	    {
+	      // Fewer indices than dimensions, no colons.
+
+	      bool resize = false;
+
+	      // Subtract one since the last idx do not tell us
+	      // anything about dimensionality.
+
+	      for (int i = 0; i < idx.length () - 1; i++)
+		{
+		  // Subtract one since idx counts from 0 while dims
+		  // count from 1.
+
+		  if (idx(i).elem (0) + 1 > lhs_dims(i))
+		    resize = true;
+		}
+
+	      if (resize)
+		{
+		  dim_vector new_dims;
+		  new_dims.resize (lhs_dims.length ());
+
+		  for (int i = 0; i < lhs_dims.length (); i++)
+		    {
+		      if (i < idx.length () - 1
+			  && idx(i).elem (0) + 1 > lhs_dims(i))
+			new_dims(i) = idx(i).elem (0)+1;
+		      else
+			new_dims(i) = lhs_dims(i);
+		    }
+
+		  lhs.resize (new_dims, rfv);
+
+		  lhs_dims = lhs.dims ();
+		}
+
+	      Array<int> one_arg_temp (1, 0);
+
+	      RT scalar = rhs.elem (one_arg_temp);
+
+	      Array<int> int_arr = conv_to_int_array (idx);
+
+	      int numelem = get_scalar_idx (int_arr, lhs_dims);
+
+	      if (numelem > lhs.length () || numelem < 0)
+		(*current_liboctave_error_handler)
+		  ("attempt to grow array along ambiguous dimension.");
+	      else
+		lhs.Array<LT>::checkelem (numelem) = scalar;
+	    }
+	}
+      else
+	{
+	  // Scalar to matrix assignment with as many indices as lhs
+	  // dimensions.
+
+	  int n = Array<LT>::get_size (frozen_len);
+
+	  Array<int> result_idx (lhs_dims.length (), 0);
+
+	  Array<int> elt_idx;
+
+	  RT scalar = rhs.elem (0);
+
+	  for (int i = 0; i < n; i++)
+	    {
+	      elt_idx = get_elt_idx (idx, result_idx);
+
+	      dim_vector lhs_inc;
+	      lhs_inc.resize (lhs_dims.length ());
+
+	      for (int i = 0; i < lhs_dims.length (); i++)
+		lhs_inc(i) = lhs_dims(i) + 1;
+
+	      if (index_in_bounds(elt_idx, lhs_inc))
+		lhs.checkelem (elt_idx) = scalar;
+	      else
+		lhs.checkelem (elt_idx) = rfv;
+
+	      increment_index (result_idx, frozen_len);
+	    }
+	}
+    }
+  else if (rhs_dims.length () >= 2)
+    {
+      // RHS is matrix or higher dimension.
+
+      // Subtracting number of dimensions of length 1 will catch
+      // cases where: A(2,1,2)=3  A(:,1,:)=[2,3;4,5]
+
+      if (rhs_dims.length () != num_ones(idx_is_colon_equiv) - num_ones(lhs_dims))
+	{
+	  (*current_liboctave_error_handler)
+	    ("dimensions do not match in matrix assignment.");
+	}
+      else
+	{
+	  bool dim_ok(true);
+
+	  int jj = 0;
+
+	  // Check that RHS dimensions are the same length as the
+	  // corresponding LHS dimensions.
+
+	  for (int j = 0; j < idx_is_colon.length (); j++)
+	    {
+	      if (idx_is_colon(j) || idx_is_colon_equiv(j))
+		{
+		  if (rhs_dims(jj) < lhs_dims(j))
+		    {
+		      dim_ok = false;
+
+		      break;
+		    }
+
+		  jj++;
+		}
+	    }
+
+	  if (! dim_ok)
+	    (*current_liboctave_error_handler)
+	      ("subscripted assignment dimension mismatch.");
+	  else
+	    {
+	      dim_vector new_dims;
+	      new_dims.resize (n_idx);
+
+	      bool resize = false;
+
+	      int ii = 0;
+
+	      // Update idx vectors.
+
+	      for (int i = 0; i < n_idx; i++)
+		{
+		  if (idx(i).is_colon ())
+		    {
+		      // Add appropriate idx_vector to idx(i) since
+		      // index with : contains no indexes.
+
+		      frozen_len(i) = lhs_dims(i) > rhs_dims(ii) ? lhs_dims(i) : rhs_dims(ii);
+
+		      new_dims(i) = lhs_dims(i) > rhs_dims(ii) ? lhs_dims(i) : rhs_dims(ii);
+
+		      ii++;
+
+		      Range idxrange (1, frozen_len(i), 1);
+
+		      idx_vector idxv (idxrange);
+
+		      idx(i) = idxv;
+		    }
+		  else
+		    {
+		      new_dims(i) = lhs_dims(i) > idx(i).max () + 1 ? lhs_dims(i) : idx(i).max () + 1;
+
+		      if (frozen_len(i) > 1)
+			ii++;
+		    }
+		  if (new_dims(i) != lhs_dims(i))
+		    resize = true;
+		}
+
+	      // Resize LHS if dimensions have changed.
+
+	      if (resize)
+		{
+		  lhs.resize (new_dims, rfv);
+
+		  lhs_dims = lhs.dims ();
+		}
+
+	      // Number of elements which need to be set.
+
+	      int n = Array<LT>::get_size (frozen_len);
+
+	      Array<int> result_idx (lhs_dims.length (), 0);
+	      Array<int> elt_idx;
+
+	      Array<int> result_rhs_idx (rhs_dims.length (), 0);
+
+	      dim_vector frozen_rhs;
+	      frozen_rhs.resize (rhs_dims.length());
+
+	      for (int i = 0; i < rhs_dims.length (); i++)
+		frozen_rhs(i) = rhs_dims(i);
+
+	      dim_vector lhs_inc;
+	      lhs_inc.resize (lhs_dims.length ());
+
+	      for (int i = 0; i < lhs_dims.length (); i++)
+		lhs_inc(i) = lhs_dims(i) + 1;
+
+	      for (int i = 0; i < n; i++)
+		{
+		  elt_idx = get_elt_idx (idx, result_idx);
+
+		  if (index_in_bounds (elt_idx, lhs_inc))
+		    {
+		      int s = compute_index (result_rhs_idx,rhs_dims);
+
+		      lhs.checkelem (elt_idx) = rhs.elem (s);
+
+		      increment_index (result_rhs_idx, frozen_rhs);
+		    }
+		  else
+		    lhs.checkelem (elt_idx) = rfv;
+
+		  increment_index (result_idx, frozen_len);
+		}
+	    }
+	}
+    }
+  else if (idx_is_empty)
+    {
+      // Assignment to matrix with at least one empty index.
+
+      if (! rhs_is_empty || ! rhs_is_scalar)
+	{
+	  (*current_liboctave_error_handler)
+	    ("A([], []) = X: X must be an empty matrix or a scalar");
+
+	  retval = 0;
+	}
+    }
+  else if (lhs_dims.length () != rhs_dims.length ())
+    {
+      (*current_liboctave_error_handler)
+	("A(I) = X: X must be a scalar or a matrix with the same size as I");
       retval = 0;
     }
 
--- a/liboctave/Array-s.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/Array-s.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -42,12 +42,16 @@
 
 template class Array2<short>;
 
+#if 0
+
 template int assign (Array2<short>&, const Array2<short>&);
 template int assign (Array2<short>&, const Array2<char>&);
 
 template int assign (Array2<short>&, const Array2<short>&, const short&);
 template int assign (Array2<short>&, const Array2<char>&, const short&);
 
+#endif
+
 #include "DiagArray2.h"
 #include "DiagArray2.cc"
 
--- a/liboctave/Array.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/Array.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -34,140 +34,220 @@
 #include <iostream>
 
 #include "Array.h"
-
-#if defined (HEAVYWEIGHT_INDEXING)
+#include "Array-idx.h"
 #include "idx-vector.h"
-#include "Array-idx.h"
-#endif
-
 #include "lo-error.h"
 
 // One dimensional array class.  Handles the reference counting for
 // all the derived classes.
 
 template <class T>
-Array<T>::Array (int n, const T& val)
-{
-  rep = new typename Array<T>::ArrayRep (n);
-
-  for (int i = 0; i < n; i++)
-    rep->data[i] = val;
-
-#ifdef HEAVYWEIGHT_INDEXING
-  max_indices = 1;
-  idx_count = 0;
-  idx = 0;
-#endif
-}
-
-template <class T>
 Array<T>::~Array (void)
 {
   if (--rep->count <= 0)
     delete rep;
 
-#ifdef HEAVYWEIGHT_INDEXING
   delete [] idx;
-#endif
+}
+
+// A guess (should be quite conservative).
+#define MALLOC_OVERHEAD 1024
+
+template <class T>
+int
+Array<T>::get_size (int r, int c)
+{
+  // XXX KLUGE XXX
+
+  // If an allocation of an array with r * c elements of type T
+  // would cause an overflow in the allocator when computing the
+  // size of the allocation, then return a value which, although
+  // not equivalent to the actual request, should be too large for
+  // most current hardware, but not so large to cause the
+  // allocator to barf on computing retval * sizeof (T).
+
+  static int nl;
+  static double dl
+    = frexp (static_cast<double>
+	     (INT_MAX - MALLOC_OVERHEAD) / sizeof (T), &nl);
+
+  // This value should be an integer.  If we return this value and
+  // things work the way we expect, we should be paying a visit to
+  // new_handler in no time flat.
+  static int max_items = static_cast<int> (ldexp (dl, nl));
+
+  int nr, nc;
+  double dr = frexp (static_cast<double> (r), &nr);
+  double dc = frexp (static_cast<double> (c), &nc);
+
+  int nt = nr + nc;
+  double dt = dr * dc;
+
+  if (dt <= 0.5)
+    {
+      nt--;
+      dt *= 2;
+
+      if (dt <= 0.5)
+	nt--;
+    }
+
+  return (nt < nl || (nt == nl && dt < dl)) ? r * c : max_items;
 }
 
 template <class T>
-Array<T>&
-Array<T>::operator = (const Array<T>& a)
+int
+Array<T>::get_size (int r, int c, int p)
 {
-  if (this != &a && rep != a.rep)
+  // XXX KLUGE XXX
+
+  // If an allocation of an array with r * c * p elements of type T
+  // would cause an overflow in the allocator when computing the
+  // size of the allocation, then return a value which, although
+  // not equivalent to the actual request, should be too large for
+  // most current hardware, but not so large to cause the
+  // allocator to barf on computing retval * sizeof (T).
+
+  static int nl;
+  static double dl
+    = frexp (static_cast<double>
+	     (INT_MAX - MALLOC_OVERHEAD) / sizeof (T), &nl);
+
+  // This value should be an integer.  If we return this value and
+  // things work the way we expect, we should be paying a visit to
+  // new_handler in no time flat.
+  static int max_items = static_cast<int> (ldexp (dl, nl));
+
+  int nr, nc, np;
+  double dr = frexp (static_cast<double> (r), &nr);
+  double dc = frexp (static_cast<double> (c), &nc);
+  double dp = frexp (static_cast<double> (p), &np);
+
+  int nt = nr + nc + np;
+  double dt = dr * dc * dp;
+
+  if (dt <= 0.5)
     {
-      if (--rep->count <= 0)
-	delete rep;
+      nt--;
+      dt *= 2;
 
-      rep = a.rep;
-      rep->count++;
+      if (dt <= 0.5)
+	nt--;
     }
 
-#ifdef HEAVYWEIGHT_INDEXING
-  idx_count = 0;
-  idx = 0;
-#endif
-
-  return *this;
+  return (nt < nl || (nt == nl && dt < dl)) ? r * c * p : max_items;
 }
 
 template <class T>
-void
-Array<T>::resize (int n)
+int
+Array<T>::get_size (const dim_vector& ra_idx)
 {
-  if (n < 0)
+  // XXX KLUGE XXX
+
+  // If an allocation of an array with r * c elements of type T
+  // would cause an overflow in the allocator when computing the
+  // size of the allocation, then return a value which, although
+  // not equivalent to the actual request, should be too large for
+  // most current hardware, but not so large to cause the
+  // allocator to barf on computing retval * sizeof (T).
+
+  static int nl;
+  static double dl
+    = frexp (static_cast<double>
+	     (INT_MAX - MALLOC_OVERHEAD) / sizeof (T), &nl);
+
+  // This value should be an integer.  If we return this value and
+  // things work the way we expect, we should be paying a visit to
+  // new_handler in no time flat.
+
+  static int max_items = static_cast<int> (ldexp (dl, nl));
+
+  int retval = max_items;
+
+  int n = ra_idx.length ();
+
+  int nt = 0;
+  double dt = 1;
+
+  for (int i = 0; i < n; i++)
     {
-      (*current_liboctave_error_handler) ("can't resize to negative dimension");
-      return;
+      int nra_idx;
+      double dra_idx = frexp (static_cast<double> (ra_idx(i)), &nra_idx);
+
+      nt += nra_idx;
+      dt *= dra_idx;
     }
 
-  if (n == length ())
-    return;
-
-  typename Array<T>::ArrayRep *old_rep = rep;
-  const T *old_data = data ();
-  int old_len = length ();
+  if (dt <= 0.5)
+    {
+      nt--;
+      dt *= 2;
 
-  rep = new typename Array<T>::ArrayRep (n);
-
-  if (old_data && old_len > 0)
-    {
-      int min_len = old_len < n ? old_len : n;
-
-      for (int i = 0; i < min_len; i++)
-	xelem (i) = old_data[i];
+      if (dt <= 0.5)
+	nt--;
     }
 
-  if (--old_rep->count <= 0)
-    delete old_rep;
+  if (nt < nl || (nt == nl && dt < dl))
+    {
+      retval = 1;
+
+      for (int i = 0; i < n; i++)
+	retval *= ra_idx(i);
+    }
+
+  return retval;
 }
 
+#undef MALLOC_OVERHEAD
+
 template <class T>
-void
-Array<T>::resize (int n, const T& val)
+int
+Array<T>::compute_index (const Array<int>& ra_idx) const
 {
-  if (n < 0)
+  int retval = -1;
+
+  int n = dimensions.length ();
+
+  if (n > 0 && n == ra_idx.length ())
     {
-      (*current_liboctave_error_handler) ("can't resize to negative dimension");
-      return;
-    }
-
-  if (n == length ())
-    return;
-
-  typename Array<T>::ArrayRep *old_rep = rep;
-  const T *old_data = data ();
-  int old_len = length ();
+      retval = ra_idx(--n);
 
-  rep = new typename Array<T>::ArrayRep (n);
-
-  int min_len = old_len < n ? old_len : n;
+      while (--n >= 0)
+	{
+	  retval *= dimensions(n);
+	  retval += ra_idx(n);
+	}
+    }
+  else
+    (*current_liboctave_error_handler)
+      ("Array<T>::compute_index: invalid ra_idxing operation");
 
-  if (old_data && old_len > 0)
-    {
-      for (int i = 0; i < min_len; i++)
-	xelem (i) = old_data[i];
-    }
-
-  for (int i = old_len; i < n; i++)
-    xelem (i) = val;
-
-  if (--old_rep->count <= 0)
-    delete old_rep;
+  return retval;
 }
 
+#if 0
+
 template <class T>
-T *
-Array<T>::fortran_vec (void)
+int
+Array<T>::compute_index (int i, int j) const
 {
-  if (rep->count > 1)
-    {
-      --rep->count;
-      rep = new typename Array<T>::ArrayRep (*rep);
-    }
-  return rep->data;
+  int retval = -1;
+
+  int n = dimensions.length ();
+
+  if (n == 2)
+    retval = j*dimensions(0)+i;
+  else if (n == 1 && j == 0)
+    retval = i;
+  else
+    (*current_liboctave_error_handler)
+      ("Array<T>::compute_index: invalid ra_idxing operation");
+
+  return retval;
 }
+
+#endif
+
 template <class T>
 T
 Array<T>::range_error (const char *fcn, int n) const
@@ -186,6 +266,572 @@
 }
 
 template <class T>
+T
+Array<T>::range_error (const char *fcn, int i, int j) const
+{
+  (*current_liboctave_error_handler)
+    ("%s (%d, %d): range error", fcn, i, j);
+  return T ();
+}
+
+template <class T>
+T&
+Array<T>::range_error (const char *fcn, int i, int j)
+{
+  (*current_liboctave_error_handler)
+    ("%s (%d, %d): range error", fcn, i, j);
+  static T foo;
+  return foo;
+}
+
+template <class T>
+T
+Array<T>::range_error (const char *fcn, int i, int j, int k) const
+{
+  (*current_liboctave_error_handler)
+    ("%s (%d, %d, %d): range error", fcn, i, j, k);
+  return T ();
+}
+
+template <class T>
+T&
+Array<T>::range_error (const char *fcn, int i, int j, int k)
+{
+  (*current_liboctave_error_handler)
+    ("%s (%d, %d, %d): range error", fcn, i, j, k);
+  static T foo;
+  return foo;
+}
+
+template <class T>
+T
+Array<T>::range_error (const char *fcn, const Array<int>& ra_idx) const
+{
+  // XXX FIXME XXX -- report index values too!
+
+  (*current_liboctave_error_handler) ("range error in Array");
+
+  return T ();
+}
+
+template <class T>
+T&
+Array<T>::range_error (const char *fcn, const Array<int>& ra_idx)
+{
+  // XXX FIXME XXX -- report index values too!
+
+  (*current_liboctave_error_handler) ("range error in Array");
+
+  static T foo;
+  return foo;
+}
+
+template <class T>
+void
+Array<T>::resize_no_fill (int n)
+{
+  if (n < 0)
+    {
+      (*current_liboctave_error_handler)
+	("can't resize to negative dimension");
+      return;
+    }
+
+  if (n == length ())
+    return;
+
+  typename Array<T>::ArrayRep *old_rep = rep;
+  const T *old_data = data ();
+  int old_len = length ();
+
+  rep = new typename Array<T>::ArrayRep (n);
+
+  dimensions = dim_vector (n);
+
+  if (old_data && old_len > 0)
+    {
+      int min_len = old_len < n ? old_len : n;
+
+      for (int i = 0; i < min_len; i++)
+	xelem (i) = old_data[i];
+    }
+
+  if (--old_rep->count <= 0)
+    delete old_rep;
+}
+
+template <class T>
+void
+Array<T>::resize_no_fill (const dim_vector& dims)
+{
+  int n = dims.length ();
+
+  for (int i = 0; i < n; i++)
+    {
+      if (dims(i) < 0)
+	{
+	  (*current_liboctave_error_handler)
+	    ("can't resize to negative dimension");
+	  return;
+	}
+    }
+
+  bool no_change = true;
+
+  for (int i = 0; i < n; i++)
+    {
+      if (dims(i) != dimensions(i))
+	{
+	  no_change = false;
+	  break;
+	}
+    }
+
+  if (no_change)
+    return;
+
+  int old_len = length ();
+
+  typename Array<T>::ArrayRep *old_rep = rep;
+  const T *old_data = data ();
+
+  rep = new typename Array<T>::ArrayRep (get_size (dims));
+
+  dim_vector old_dimensions = dimensions;
+
+  dimensions = dims;
+
+  Array<int> ra_idx (dimensions.length (), 0);
+
+  for (int i = 0; i < old_len; i++)
+    {
+      if (index_in_bounds (ra_idx, dimensions))
+	xelem (ra_idx) = old_data[i];
+
+      increment_index (ra_idx, dimensions);
+    }
+
+  if (--old_rep->count <= 0)
+    delete old_rep;
+}
+
+template <class T>
+void
+Array<T>::resize_no_fill (int r, int c)
+{
+  if (r < 0 || c < 0)
+    {
+      (*current_liboctave_error_handler)
+	("can't resize to negative dimension");
+      return;
+    }
+
+  if (r == dim1 () && c == dim2 ())
+    return;
+
+  typename Array<T>::ArrayRep *old_rep = Array<T>::rep;
+  const T *old_data = data ();
+
+  int old_d1 = dim1 ();
+  int old_d2 = dim2 ();
+  int old_len = length ();
+
+  rep = new typename Array<T>::ArrayRep (get_size (r, c));
+
+  dimensions = dim_vector (r, c);
+
+  if (old_data && old_len > 0)
+    {
+      int min_r = old_d1 < r ? old_d1 : r;
+      int min_c = old_d2 < c ? old_d2 : c;
+
+      for (int j = 0; j < min_c; j++)
+	for (int i = 0; i < min_r; i++)
+	  xelem (i, j) = old_data[old_d1*j+i];
+    }
+
+  if (--old_rep->count <= 0)
+    delete old_rep;
+}
+
+template <class T>
+void
+Array<T>::resize_no_fill (int r, int c, int p)
+{
+  if (r < 0 || c < 0 || p < 0)
+    {
+      (*current_liboctave_error_handler)
+	("can't resize to negative dimension");
+      return;
+    }
+
+  if (r == dim1 () && c == dim2 () && p == dim3 ())
+    return;
+
+  typename Array<T>::ArrayRep *old_rep = rep;
+  const T *old_data = data ();
+
+  int old_d1 = dim1 ();
+  int old_d2 = dim2 ();
+  int old_d3 = dim3 ();
+  int old_len = length ();
+
+  int ts = get_size (get_size (r, c), p);
+
+  rep = new typename Array<T>::ArrayRep (ts);
+
+  dimensions = dim_vector (r, c, p);
+
+  if (old_data && old_len > 0)
+    {
+      int min_r = old_d1 < r ? old_d1 : r;
+      int min_c = old_d2 < c ? old_d2 : c;
+      int min_p = old_d3 < p ? old_d3 : p;
+
+      for (int k = 0; k < min_p; k++)
+	for (int j = 0; j < min_c; j++)
+	  for (int i = 0; i < min_r; i++)
+	    xelem (i, j, k) = old_data[old_d1*(old_d2*k+j)+i];
+    }
+
+  if (--old_rep->count <= 0)
+    delete old_rep;
+}
+
+template <class T>
+void
+Array<T>::resize_and_fill (int n, const T& val)
+{
+  if (n < 0)
+    {
+      (*current_liboctave_error_handler)
+	("can't resize to negative dimension");
+      return;
+    }
+
+  if (n == length ())
+    return;
+
+  typename Array<T>::ArrayRep *old_rep = rep;
+  const T *old_data = data ();
+  int old_len = length ();
+
+  rep = new typename Array<T>::ArrayRep (n);
+
+  dimensions = dim_vector (n);
+
+  int min_len = old_len < n ? old_len : n;
+
+  if (old_data && old_len > 0)
+    {
+      for (int i = 0; i < min_len; i++)
+	xelem (i) = old_data[i];
+    }
+
+  for (int i = old_len; i < n; i++)
+    xelem (i) = val;
+
+  if (--old_rep->count <= 0)
+    delete old_rep;
+}
+
+template <class T>
+void
+Array<T>::resize_and_fill (int r, int c, const T& val)
+{
+  if (r < 0 || c < 0)
+    {
+      (*current_liboctave_error_handler)
+	("can't resize to negative dimension");
+      return;
+    }
+
+  if (r == dim1 () && c == dim2 ())
+    return;
+
+  typename Array<T>::ArrayRep *old_rep = Array<T>::rep;
+  const T *old_data = data ();
+
+  int old_d1 = dim1 ();
+  int old_d2 = dim2 ();
+  int old_len = length ();
+
+  rep = new typename Array<T>::ArrayRep (get_size (r, c));
+
+  dimensions = dim_vector (r, c);
+
+  int min_r = old_d1 < r ? old_d1 : r;
+  int min_c = old_d2 < c ? old_d2 : c;
+
+  if (old_data && old_len > 0)
+    {
+      for (int j = 0; j < min_c; j++)
+	for (int i = 0; i < min_r; i++)
+	  xelem (i, j) = old_data[old_d1*j+i];
+    }
+
+  for (int j = 0; j < min_c; j++)
+    for (int i = min_r; i < r; i++)
+      xelem (i, j) = val;
+
+  for (int j = min_c; j < c; j++)
+    for (int i = 0; i < r; i++)
+      xelem (i, j) = val;
+
+  if (--old_rep->count <= 0)
+    delete old_rep;
+}
+
+template <class T>
+void
+Array<T>::resize_and_fill (int r, int c, int p, const T& val)
+{
+  if (r < 0 || c < 0 || p < 0)
+    {
+      (*current_liboctave_error_handler)
+	("can't resize to negative dimension");
+      return;
+    }
+
+  if (r == dim1 () && c == dim2 () && p == dim3 ())
+    return;
+
+  typename Array<T>::ArrayRep *old_rep = rep;
+  const T *old_data = data ();
+
+  int old_d1 = dim1 ();
+  int old_d2 = dim2 ();
+  int old_d3 = dim3 ();
+
+  int old_len = length ();
+
+  int ts = get_size (get_size (r, c), p);
+
+  rep = new typename Array<T>::ArrayRep (ts);
+
+  dimensions = dim_vector (r, c, p);
+
+  int min_r = old_d1 < r ? old_d1 : r;
+  int min_c = old_d2 < c ? old_d2 : c;
+  int min_p = old_d3 < p ? old_d3 : p;
+
+  if (old_data && old_len > 0)
+    for (int k = 0; k < min_p; k++)
+      for (int j = 0; j < min_c; j++)
+	for (int i = 0; i < min_r; i++)
+	  xelem (i, j, k) = old_data[old_d1*(old_d2*k+j)+i];
+
+  // XXX FIXME XXX -- if the copy constructor is expensive, this may
+  // win.  Otherwise, it may make more sense to just copy the value
+  // everywhere when making the new ArrayRep.
+
+  for (int k = 0; k < min_p; k++)
+    for (int j = min_c; j < c; j++)
+      for (int i = 0; i < min_r; i++)
+	xelem (i, j, k) = val;
+
+  for (int k = 0; k < min_p; k++)
+    for (int j = 0; j < c; j++)
+      for (int i = min_r; i < r; i++)
+	xelem (i, j, k) = val;
+
+  for (int k = min_p; k < p; k++)
+    for (int j = 0; j < c; j++)
+      for (int i = 0; i < r; i++)
+	xelem (i, j, k) = val;
+
+  if (--old_rep->count <= 0)
+    delete old_rep;
+}
+
+template <class T>
+void
+Array<T>::resize_and_fill (const dim_vector& dims, const T& val)
+{
+  int n = dims.length ();
+
+  for (int i = 0; i < n; i++)
+    {
+      if (dims(i) < 0)
+	{
+	  (*current_liboctave_error_handler)
+	    ("can't resize to negative dimension");
+	  return;
+	}
+    }
+
+  bool no_change = true;
+
+  for (int i = 0; i < n; i++)
+    {
+      if (dims(i) != dimensions(i))
+	{
+	  no_change = false;
+	  break;
+	}
+    }
+
+  if (no_change)
+    return;
+
+  typename Array<T>::ArrayRep *old_rep = rep;
+  const T *old_data = data ();
+
+  int old_len = length ();
+
+  int len = get_size (dims);
+
+  rep = new typename Array<T>::ArrayRep (len);
+
+  dim_vector old_dimensions = dimensions;
+
+  dimensions = dims;
+
+  Array<int> ra_idx (dimensions.length (), 0);
+
+  // XXX FIXME XXX -- it is much simpler to fill the whole array
+  // first, but probably slower for large arrays, or if the assignment
+  // operator for the type T is expensive.  OTOH, the logic for
+  // deciding whether an element needs the copied value or the filled
+  // value might be more expensive.
+
+  for (int i = 0; i < len; i++)
+    rep->elem (i) = val;
+
+  for (int i = 0; i < old_len; i++)
+    {
+      if (index_in_bounds (ra_idx, dimensions))
+	xelem (ra_idx) = old_data[i];
+
+      increment_index (ra_idx, dimensions);
+    }
+
+  if (--old_rep->count <= 0)
+    delete old_rep;
+}
+
+template <class T>
+Array<T>&
+Array<T>::insert (const Array<T>& a, int r, int c)
+{
+  int a_rows = a.rows ();
+  int a_cols = a.cols ();
+
+  if (r < 0 || r + a_rows > rows () || c < 0 || c + a_cols > cols ())
+    {
+      (*current_liboctave_error_handler) ("range error for insert");
+      return *this;
+    }
+
+  for (int j = 0; j < a_cols; j++)
+    for (int i = 0; i < a_rows; i++)
+      elem (r+i, c+j) = a.elem (i, j);
+
+  return *this;
+}
+
+template <class T>
+Array<T>&
+Array<T>::insert (const Array<T>& a, const Array<int>& ra_idx)
+{
+  int n = ra_idx.length ();
+
+  if (n == dimensions.length ())
+    {
+      dim_vector a_dims = a.dims ();
+
+      for (int i = 0; i < n; i++)
+	{
+	  if (ra_idx(i) < 0 || ra_idx(i) + a_dims(i) > dimensions(i))
+	    {
+	      (*current_liboctave_error_handler)
+		("Array<T>::insert: range error for insert");
+	      return *this;
+	    }
+	}
+
+#if 0
+      // XXX FIXME XXX -- need to copy elements
+
+      for (int j = 0; j < a_cols; j++)
+	for (int i = 0; i < a_rows; i++)
+	  elem (r+i, c+j) = a.elem (i, j);
+#endif
+
+    }
+  else
+    (*current_liboctave_error_handler)
+      ("Array<T>::insert: invalid indexing operation");
+
+  return *this;
+}
+
+template <class T>
+void
+Array<T>::maybe_delete_dims (void)
+{
+  int ndims = dimensions.length ();
+
+  dim_vector new_dims (1, 1);
+
+  bool delete_dims = true;
+
+  for (int i = ndims - 1; i >= 0; i--)
+    {
+      if (delete_dims)
+        {
+          if (dimensions(i) != 1)
+	    {
+	      delete_dims = false;
+
+	      new_dims = dim_vector (i + 1, dimensions(i));
+	    }
+        }
+      else
+	new_dims(i) = dimensions(i);
+    }
+    
+  if (ndims != new_dims.length ())
+    dimensions = new_dims;
+}
+
+template <class T>
+Array<T>
+Array<T>::transpose (void) const
+{
+  int nr = dim1 ();
+  int nc = dim2 ();
+
+  if (nr > 1 && nc > 1)
+    {
+      Array<T> result (dim_vector (nc, nr));
+
+      for (int j = 0; j < nc; j++)
+	for (int i = 0; i < nr; i++)
+	  result.xelem (j, i) = xelem (i, j);
+
+      return result;
+    }
+  else
+    {
+      // Fast transpose for vectors and empty matrices
+      return Array<T> (*this, dim_vector (nc, nr));
+    }
+}
+
+template <class T>
+T *
+Array<T>::fortran_vec (void)
+{
+  if (rep->count > 1)
+    {
+      --rep->count;
+      rep = new typename Array<T>::ArrayRep (*rep);
+    }
+  return rep->data;
+}
+
+template <class T>
 void
 Array<T>::print_info (std::ostream& os, const std::string& prefix) const
 {
@@ -193,6 +839,11 @@
      << prefix << "rep->len:    " << rep->len << "\n"
      << prefix << "rep->data:   " << static_cast<void *> (rep->data) << "\n"
      << prefix << "rep->count:  " << rep->count << "\n";
+
+  // 2D info:
+  //
+  //     << prefix << "rows: " << rows () << "\n"
+  //     << prefix << "cols: " << cols () << "\n";
 }
 
 /*
--- a/liboctave/Array.h	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/Array.h	Fri Sep 19 21:41:21 2003 +0000
@@ -33,17 +33,11 @@
 
 #include <iostream>
 
+#include "dim-vector.h"
 #include "lo-utils.h"
 
 class idx_vector;
 
-// For now, define this here if it is not already defined.  Not doing
-// this can result in bugs that are very hard to find.
-
-#ifndef HEAVYWEIGHT_INDEXING
-#define HEAVYWEIGHT_INDEXING 1
-#endif
-
 // One dimensional array class.  Handles the reference counting for
 // all the derived classes.
 
@@ -60,7 +54,9 @@
 {
 protected:
 
-// The real representation of all arrays.
+  //--------------------------------------------------------------------
+  // The real representation of all arrays.
+  //--------------------------------------------------------------------
 
   class ArrayRep
   {
@@ -78,17 +74,29 @@
 
     explicit ArrayRep (int n) : data (new T [n]), len (n), count (1) { }
 
+    explicit ArrayRep (int n, const T& val)
+      : data (new T [n]), len (n), count (1)
+      {
+	fill (val);
+      }
+
     ArrayRep (const ArrayRep& a)
       : data (new T [a.len]), len (a.len), count (1)
-	{
-	  for (int i = 0; i < len; i++)
-	    data[i] = a.data[i];
-	}
+      {
+        for (int i = 0; i < len; i++)
+	  data[i] = a.data[i];
+      }
 
     ~ArrayRep (void) { delete [] data; }
 
     int length (void) const { return len; }
 
+    void fill (const T& val)
+      {
+	for (int i = 0; i < len; i++)
+	  data[i] = val;
+      }
+
     T& elem (int n) { return data[n]; }
 
     T elem (int n) const { return data[n]; }
@@ -99,6 +107,8 @@
       }
   };
 
+  //--------------------------------------------------------------------
+
   void make_unique (void)
     {
       if (rep->count > 1)
@@ -108,80 +118,155 @@
 	}
     }
 
-#ifdef HEAVYWEIGHT_INDEXING
-  idx_vector *idx;
-  int max_indices;
-  int idx_count;
-#endif
-
-protected:
+  void make_unique (const T& val)
+    {
+      if (rep->count > 1)
+	{
+	  --rep->count;
+	  rep = new ArrayRep (rep->length (), val);
+	}
+      else
+	rep->fill (val);
+    }
 
   typename Array<T>::ArrayRep *rep;
 
-  Array (T *d, int l)
-    {
-      rep = new typename Array<T>::ArrayRep (d, l);
+  dim_vector dimensions;
+
+  idx_vector *idx;
+  int idx_count;
+
+  Array (T *d, int n)
+    : rep (new typename Array<T>::ArrayRep (d, n)), dimensions (n),
+      idx (0), idx_count (0) { }
 
-#ifdef HEAVYWEIGHT_INDEXING
-      idx = 0;
-      max_indices = 1;
-      idx_count = 0;
-#endif
+  Array (T *d, const dim_vector& dims)
+    : rep (new typename Array<T>::ArrayRep (d, get_size (dims))),
+      dimensions (dims), idx (0), idx_count (0) { }
+
+private:
+
+  Array<T>::ArrayRep *nil_rep (void) const
+    {
+      static typename Array<T>::ArrayRep *nr
+	= new typename Array<T>::ArrayRep ();
+
+      return nr;
     }
 
 public:
 
   Array (void)
-    {
-      rep = new typename Array<T>::ArrayRep ();
-
-#ifdef HEAVYWEIGHT_INDEXING
-      idx = 0;
-      max_indices = 1;
-      idx_count = 0;
-#endif
-    }
+    : rep (nil_rep ()), dimensions (),
+      idx (0), idx_count (0) { rep->count++; }
 
   explicit Array (int n)
-    {
-      rep = new typename Array<T>::ArrayRep (n);
+    : rep (new typename Array<T>::ArrayRep (n)), dimensions (n),
+      idx (0), idx_count (0) { }
 
-#ifdef HEAVYWEIGHT_INDEXING
-      idx = 0;
-      max_indices = 1;
-      idx_count = 0;
-#endif
+  explicit Array (int n, const T& val)
+    : rep (new typename Array<T>::ArrayRep (n)), dimensions (n),
+      idx (0), idx_count (0)
+    {
+      fill (val);
+    }
+
+  Array (const Array<T>& a)
+    : rep (a.rep), dimensions (a.dimensions), idx (0), idx_count (0)
+    {
+      rep->count++;
     }
 
-  Array (int n, const T& val);
+public:
+
+  Array (const dim_vector& dims)
+    : rep (new typename Array<T>::ArrayRep (get_size (dims))),
+      dimensions (dims), idx (0), idx_count (0) { }
 
-  Array (const Array<T>& a)
+  Array (const dim_vector& dims, const T& val)
+    : rep (new typename Array<T>::ArrayRep (get_size (dims))),
+      dimensions (dims), idx (0), idx_count (0)
     {
-      rep = a.rep;
+      fill (val);
+    }
+
+  Array (const Array<T>& a, const dim_vector& dims)
+    : rep (a.rep), dimensions (dims), idx (0), idx_count (0)
+    {
       rep->count++;
-
-#ifdef HEAVYWEIGHT_INDEXING
-      max_indices = a.max_indices;
-      idx_count = 0;
-      idx = 0;
-#endif
     }
 
   ~Array (void);
 
-  Array<T>& operator = (const Array<T>& a);
+  Array<T>& operator = (const Array<T>& a)
+    {
+      if (this != &a)
+	{
+	  if (--rep->count <= 0)
+	    delete rep;
+
+	  rep = a.rep;
+	  rep->count++;
+
+	  dimensions = a.dimensions;
+	}
+
+      idx_count = 0;
+      idx = 0;
+
+      return *this;
+    }
+
+  void fill (const T& val) { make_unique (val); }
 
   int capacity (void) const { return rep->length (); }
-  int length (void) const { return rep->length (); }
+  int length (void) const { return capacity (); }
+  int nelem (void) const { return capacity (); }
+
+  int dim1 (void) const { return dimensions(0); }
+  int dim2 (void) const { return dimensions(1); }
+  int dim3 (void) const { return dimensions(2); }
+
+  int rows (void) const { return dim1 (); }
+  int cols (void) const { return dim2 (); }
+  int columns (void) const { return dim2 (); }
+  int pages (void) const { return dim3 (); }
+
+  dim_vector dims (void) const { return dimensions; }
+
+  static int get_size (int r, int c);
+  static int get_size (int r, int c, int p);
+  static int get_size (const dim_vector& dims);
 
   T range_error (const char *fcn, int n) const;
   T& range_error (const char *fcn, int n);
 
+  T range_error (const char *fcn, int i, int j) const;
+  T& range_error (const char *fcn, int i, int j);
+
+  T range_error (const char *fcn, int i, int j, int k) const;
+  T& range_error (const char *fcn, int i, int j, int k);
+
+  T range_error (const char *fcn, const Array<int>& ra_idx) const;
+  T& range_error (const char *fcn, const Array<int>& ra_idx);
+
   // No checking, even for multiple references, ever.
 
   T& xelem (int n) { return rep->elem (n); }
   T xelem (int n) const { return rep->elem (n); }
 
+  T& xelem (int i, int j) { return xelem (dim1()*j+i); }
+  T xelem (int i, int j) const { return xelem (dim1()*j+i); }
+
+  T& xelem (int i, int j, int k) { return xelem (i, dim2()*k+j); }
+  T xelem (int i, int j, int k) const { return xelem (i, dim2()*k+j); }
+
+  T& xelem (const Array<int>& ra_idx)
+    { return xelem (compute_index (ra_idx)); }
+
+  T xelem (const Array<int>& ra_idx) const
+    { return xelem (compute_index (ra_idx)); }
+
   // XXX FIXME XXX -- would be nice to fix this so that we don't
   // unnecessarily force a copy, but that is not so easy, and I see no
   // clean way to do it.
@@ -197,16 +282,55 @@
 	}
     }
 
+  T& checkelem (int i, int j)
+    {
+      if (i < 0 || j < 0 || i >= dim1 () || j >= dim2 ())
+	return range_error ("T& Array<T>::checkelem", i, j);
+      else
+	return elem (dim1()*j+i);
+    }
+
+  T& checkelem (int i, int j, int k)
+    {
+      if (i < 0 || j < 0 || k < 0 || i >= dim1 () || j >= dim2 () || k >= dim3 ())
+	return range_error ("T& Array<T>::checkelem", i, j, k);
+      else
+	return elem (i, dim2()*k+j);
+    }
+
+  T& checkelem (const Array<int>& ra_idx)
+    {
+      int i = compute_index (ra_idx);
+
+      if (i < 0)
+	return range_error ("T& Array<T>::checkelem", ra_idx);
+      else
+	return elem (i);
+    }
+
   T& elem (int n)
     {
       make_unique ();
       return xelem (n);
     }
 
+  T& elem (int i, int j) { return elem (dim1()*j+i); }
+
+  T& elem (int i, int j, int k) { return elem (i, dim2()*k+j); }
+
+  T& elem (const Array<int>& ra_idx)
+    { return Array<T>::elem (compute_index (ra_idx)); }
+
 #if defined (BOUNDS_CHECKING)
   T& operator () (int n) { return checkelem (n); }
+  T& operator () (int i, int j) { return checkelem (i, j); }
+  T& operator () (int i, int j, int k) { return checkelem (i, j, k); }
+  T& operator () (const Array<int>& ra_idx) { return checkelem (ra_idx); }
 #else
   T& operator () (int n) { return elem (n); }
+  T& operator () (int i, int j) { return elem (i, j); }
+  T& operator () (int i, int j, int k) { return elem (i, j, k); }
+  T& operator () (const Array<int>& ra_idx) { return elem (ra_idx); }
 #endif
 
   T checkelem (int n) const
@@ -217,16 +341,91 @@
 	return xelem (n);
     }
 
+  T checkelem (int i, int j) const
+    {
+      if (i < 0 || j < 0 || i >= dim1 () || j >= dim2 ())
+	return range_error ("T Array<T>::checkelem", i, j);
+      else
+	return elem (dim1()*j+i);
+    }
+
+  T checkelem (int i, int j, int k) const
+    {
+      if (i < 0 || j < 0 || k < 0 || i >= dim1 () || j >= dim2 () || k >= dim3 ())
+	return range_error ("T Array<T>::checkelem", i, j, k);
+      else
+	return Array<T>::elem (i, Array<T>::dim1()*k+j);
+    }
+
+  T checkelem (const Array<int>& ra_idx) const
+    {
+      int i = compute_index (ra_idx);
+
+      if (i < 0)
+	return range_error ("T Array<T>::checkelem", ra_idx);
+      else
+	return Array<T>::elem (i);
+    }
+
   T elem (int n) const { return xelem (n); }
 
+  T elem (int i, int j) const { return elem (dim1()*j+i); }
+
+  T elem (int i, int j, int k) const { return elem (i, dim2()*k+j); }
+
+  T elem (const Array<int>& ra_idx) const
+    { return Array<T>::elem (compute_index (ra_idx)); }
+
 #if defined (BOUNDS_CHECKING)
   T operator () (int n) const { return checkelem (n); }
+  T operator () (int i, int j) const { return checkelem (i, j); }
+  T operator () (int i, int j, int k) const { return checkelem (i, j, k); }
+  T operator () (const Array<int>& ra_idx) const { return checkelem (ra_idx); }
 #else
   T operator () (int n) const { return elem (n); }
+  T operator () (int i, int j) const { return elem (i, j); }
+  T operator () (int i, int j, int k) const { return elem (i, j, k); }
+  T operator () (const Array<int>& ra_idx) const { return elem (ra_idx); }
 #endif
 
-  void resize (int n);
-  void resize (int n, const T& val);
+  int compute_index (const Array<int>& ra_idx) const;
+
+protected:
+
+  void resize_no_fill (int n);
+
+  void resize_no_fill (int r, int c);
+
+  void resize_no_fill (int r, int c, int p);
+
+  void resize_no_fill (const dim_vector& dims);
+
+  void resize_and_fill (int n, const T& val);
+
+  void resize_and_fill (int r, int c, const T& val);
+
+  void resize_and_fill (int r, int c, int p, const T& val);
+
+  void resize_and_fill (const dim_vector& dims, const T& val);
+
+public:
+
+  void resize (int n) { resize_no_fill (n); }
+
+  //  void resize (int n, const T& val) { resize_and_fill (n, val); }
+
+  void resize (const dim_vector& dims) { resize_no_fill (dims); }
+
+  void resize (const dim_vector& dims, const T& val)
+    { resize_and_fill (dims, val); }
+
+  Array<T>& insert (const Array<T>& a, int r, int c);
+
+  Array<T>& insert (const Array<T>& a, const Array<int>& dims);
+
+  bool is_square (void) const { return (dim1 () == dim2 ()); }
+
+  Array<T> transpose (void) const;
 
   const T *data (void) const { return rep->data; }
 
@@ -243,9 +442,7 @@
       return *this;
     }
 
-#ifdef HEAVYWEIGHT_INDEXING
-
-  void set_max_indices (int mi) { max_indices = mi; }
+  int ndims (void) const { return dimensions.length (); }
 
   void clear_index (void);
 
@@ -257,28 +454,60 @@
 
   void maybe_delete_elements (idx_vector& i);
 
+  void maybe_delete_elements_1 (idx_vector& i);
+
+  void maybe_delete_elements_2 (idx_vector& i);
+
+  void maybe_delete_elements (idx_vector& i, idx_vector& j);
+
+  void maybe_delete_elements (idx_vector& i, idx_vector& j, idx_vector& k);
+
+  void maybe_delete_elements (Array<idx_vector>& ra_idx, const T& rfv);
+
+  void maybe_delete_dims (void);
+
   Array<T> value (void);
 
   Array<T> index (idx_vector& i, int resize_ok = 0,
 		  const T& rfv = resize_fill_value (T ())) const;
 
-#endif
+  Array<T> index1 (idx_vector& i, int resize_ok = 0,
+		   const T& rfv = resize_fill_value (T ())) const;
+
+  Array<T> index2 (idx_vector& i, int resize_ok = 0,
+		   const T& rfv = resize_fill_value (T ())) const;
+
+  Array<T> index (idx_vector& i, idx_vector& j, int resize_ok = 0,
+		  const T& rfv = resize_fill_value (T ())) const;
+
+  Array<T> index (Array<idx_vector>& ra_idx, int resize_ok = 0,
+		  const T& rfv = resize_fill_value (T ())) const;
 
   //  static T resize_fill_value (void) { return T (); }
 
   void print_info (std::ostream& os, const std::string& prefix) const;
-};
+
+  template <class LT, class RT>
+  friend int
+  assign (Array<LT>& lhs, const Array<RT>& rhs, const LT& rfv);
+
+  template <class LT, class RT>
+  friend int
+  assign1 (Array<LT>& lhs, const Array<RT>& rhs, const LT& rfv);
 
-template <class LT, class RT>
-int
-assign (Array<LT>& lhs, const Array<RT>& rhs, const LT& rfv);
+  template <class LT, class RT>
+  friend int
+  assign2 (Array<LT>& lhs, const Array<RT>& rhs, const LT& rfv);
 
+  template <class LT, class RT>
+  friend int
+  assignN (Array<LT>& lhs, const Array<RT>& rhs, const LT& rfv);
+};
 
 template <class LT, class RT>
 int
 assign (Array<LT>& lhs, const Array<RT>& rhs)
 {
-  //  return assign (lhs, rhs, Array<LT>::resize_fill_value ());
   return assign (lhs, rhs, resize_fill_value (LT ()));
 }
 
--- a/liboctave/Array2-idx.h	Sat Sep 13 07:53:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,783 +0,0 @@
-// Template array classes
-/*
-
-Copyright (C) 1996, 1997 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.
-
-*/
-
-#include "Array-flags.h"
-#include "idx-vector.h"
-#include "lo-error.h"
-
-template <class T>
-Array2<T>
-Array2<T>::value (void)
-{
-  Array2<T> retval;
-
-  int n_idx = index_count ();
-
-  if (n_idx == 2)
-    {
-      idx_vector *tmp = get_idx ();
-      idx_vector idx_i = tmp[0];
-      idx_vector idx_j = tmp[1];
-
-      return index (idx_i, idx_j);
-    }
-  else if (n_idx == 1)
-    {
-      return index (Array<T>::idx[0]);
-    }
-  else
-    (*current_liboctave_error_handler)
-      ("invalid number of indices for matrix expression");
-
-  clear_index ();
-
-  return retval;
-}
-
-template <class T>
-Array2<T>
-Array2<T>::index (idx_vector& idx_arg, int resize_ok, const T& rfv) const
-{
-  Array2<T> retval;
-
-  int nr = d1;
-  int nc = d2;
-
-  int orig_len = nr * nc;
-
-  int idx_orig_rows = idx_arg.orig_rows ();
-  int idx_orig_columns = idx_arg.orig_columns ();
-
-  if (idx_arg.is_colon ())
-    {
-      // Fast magic colon processing.
-
-      int result_nr = nr * nc;
-      int result_nc = 1;
-
-      retval = Array2<T> (*this, result_nr, result_nc);
-    }
-  else if (nr == 1 && nc == 1)
-    {
-      Array<T> tmp = Array<T>::index (idx_arg, resize_ok);
-
-      if (tmp.length () != 0)
-	retval = Array2<T> (tmp, idx_orig_rows, idx_orig_columns);
-      else
-	retval = Array2<T> (tmp, 0, 0);
-    }
-  else if (nr == 1 || nc == 1)
-    {
-      // If indexing a vector with a matrix, return value has same
-      // shape as the index.  Otherwise, it has same orientation as
-      // indexed object.
-
-      Array<T> tmp = Array<T>::index (idx_arg, resize_ok);
-
-      int len = tmp.length ();
-
-      if (len == 0)
-	{
-	  if (idx_orig_rows == 0 || idx_orig_columns == 0)
-	    retval = Array2<T> (idx_orig_rows, idx_orig_columns);
-	  else if (nr == 1)
-	    retval = Array2<T> (1, 0);
-	  else
-	    retval = Array2<T> (0, 1);
-	}
-      else
-	{
-	  if (idx_orig_rows == 1 || idx_orig_columns == 1)
-	    {
-	      if (nr == 1)
-		retval = Array2<T> (tmp, 1, len);
-	      else
-		retval = Array2<T> (tmp, len, 1);
-	    }
-	  else
-	    retval = Array2<T> (tmp, idx_orig_rows, idx_orig_columns);
-	}
-    }
-  else
-    {
-      if (liboctave_wfi_flag
-	  && ! (idx_arg.one_zero_only ()
-		&& idx_orig_rows == nr
-		&& idx_orig_columns == nc))
-	(*current_liboctave_warning_handler) ("single index used for matrix");
-
-      // This code is only for indexing matrices.  The vector
-      // cases are handled above.
-
-      idx_arg.freeze (nr * nc, "matrix", resize_ok);
-
-      if (idx_arg)
-	{
-	  int result_nr = idx_orig_rows;
-	  int result_nc = idx_orig_columns;
-
-	  if (idx_arg.one_zero_only ())
-	    {
-	      result_nr = idx_arg.ones_count ();
-	      result_nc = (result_nr > 0 ? 1 : 0);
-	    }
-
-	  retval.resize (result_nr, result_nc);
-
-	  int k = 0;
-	  for (int j = 0; j < result_nc; j++)
-	    {
-	      for (int i = 0; i < result_nr; i++)
-		{
-		  int ii = idx_arg.elem (k++);
-		  if (ii >= orig_len)
-		    retval.elem (i, j) = rfv;
-		  else
-		    {
-		      int fr = ii % nr;
-		      int fc = (ii - fr) / nr;
-		      retval.elem (i, j) = elem (fr, fc);
-		    }
-		}
-	    }
-	}
-      // idx_vector::freeze() printed an error message for us.
-    }
-
-  return retval;
-}
-
-template <class T>
-Array2<T>
-Array2<T>::index (idx_vector& idx_i, idx_vector& idx_j, int resize_ok,
-		  const T& rfv) const
-{
-  Array2<T> retval;
-
-  int nr = d1;
-  int nc = d2;
-
-  int n = idx_i.freeze (nr, "row", resize_ok);
-  int m = idx_j.freeze (nc, "column", resize_ok);
-
-  if (idx_i && idx_j)
-    {
-      if (idx_i.orig_empty () || idx_j.orig_empty () || n == 0 || m == 0)
-	{
-	  retval.resize (n, m);
-	}
-      else if (idx_i.is_colon_equiv (nr) && idx_j.is_colon_equiv (nc))
-	{
-	  retval = *this;
-	}
-      else
-	{
-	  retval.resize (n, m);
-
-	  for (int j = 0; j < m; j++)
-	    {
-	      int jj = idx_j.elem (j);
-	      for (int i = 0; i < n; i++)
-		{
-		  int ii = idx_i.elem (i);
-		  if (ii >= nr || jj >= nc)
-		    retval.elem (i, j) = rfv;
-		  else
-		    retval.elem (i, j) = elem (ii, jj);
-		}
-	    }
-	}
-    }
-
-  // idx_vector::freeze() printed an error message for us.
-
-  return retval;
-}
-
-template <class T>
-void
-Array2<T>::maybe_delete_elements (idx_vector& idx_arg)
-{
-  int nr = d1;
-  int nc = d2;
-
-  if (nr == 0 && nc == 0)
-    return;
-
-  int n;
-  if (nr == 1)
-    n = nc;
-  else if (nc == 1)
-    n = nr;
-  else
-    {
-      (*current_liboctave_error_handler)
-	("A(idx) = []: expecting A to be row or column vector or scalar");
-
-      return;
-    }
-
-  if (idx_arg.is_colon_equiv (n, 1))
-    {
-      // Either A(:) = [] or A(idx) = [] with idx enumerating all
-      // elements, so we delete all elements and return [](0x0).  To
-      // preserve the orientation of the vector, you have to use
-      // A(idx,:) = [] (delete rows) or A(:,idx) (delete columns).
-
-      resize (0, 0);
-      return;
-    }
-
-  idx_arg.sort (true);
-
-  int num_to_delete = idx_arg.length (n);
-
-  if (num_to_delete != 0)
-    {
-      int new_n = n;
-
-      int iidx = 0;
-
-      for (int i = 0; i < n; i++)
-	if (i == idx_arg.elem (iidx))
-	  {
-	    iidx++;
-	    new_n--;
-
-	    if (iidx == num_to_delete)
-	      break;
-	  }
-
-      if (new_n > 0)
-	{
-	  T *new_data = new T [new_n];
-
-	  int ii = 0;
-	  iidx = 0;
-	  for (int i = 0; i < n; i++)
-	    {
-	      if (iidx < num_to_delete && i == idx_arg.elem (iidx))
-		iidx++;
-	      else
-		{
-		  if (nr == 1)
-		    new_data[ii] = elem (0, i);
-		  else
-		    new_data[ii] = elem (i, 0);
-
-		  ii++;
-		}
-	    }
-
-	  if (--(Array<T>::rep)->count <= 0)
-	    delete Array<T>::rep;
-
-	  Array<T>::rep = new typename Array<T>::ArrayRep (new_data, new_n);
-
-	  if (nr == 1)
-	    {
-	      d1 = 1;
-	      d2 = new_n;
-	    }
-	  else
-	    {
-	      d1 = new_n;
-	      d2 = 1;
-	    }
-
-	  set_max_indices (2);
-	}
-      else
-	(*current_liboctave_error_handler)
-	  ("A(idx) = []: index out of range");
-    }
-}
-
-template <class T>
-void
-Array2<T>::maybe_delete_elements (idx_vector& idx_i, idx_vector& idx_j)
-{
-  int nr = d1;
-  int nc = d2;
-
-  if (nr == 0 && nc == 0)
-    return;
-
-  if (idx_i.is_colon ())
-    {
-      if (idx_j.is_colon ())
-	{
-	  // A(:,:) -- We are deleting columns and rows, so the result
-	  // is [](0x0).
-
-	  resize (0, 0);
-	  return;
-	}
-
-      if (idx_j.is_colon_equiv (nc, 1))
-	{
-	  // A(:,j) -- We are deleting columns by enumerating them,
-	  // If we enumerate all of them, we should have zero columns
-	  // with the same number of rows that we started with.
-
-	  resize (nr, 0);
-	  return;
-	}
-    }
-
-  if (idx_j.is_colon () && idx_i.is_colon_equiv (nr, 1))
-    {
-      // A(i,:) -- We are deleting rows by enumerating them.  If we
-      // enumerate all of them, we should have zero rows with the
-      // same number of columns that we started with.
-
-      resize (0, nc);
-      return;
-    }
-
-  if (idx_i.is_colon_equiv (nr, 1))
-    {
-      if (idx_j.is_colon_equiv (nc, 1))
-	resize (0, 0);
-      else
-	{
-	  idx_j.sort (true);
-
-	  int num_to_delete = idx_j.length (nc);
-
-	  if (num_to_delete != 0)
-	    {
-	      if (nr == 1 && num_to_delete == nc)
-		resize (0, 0);
-	      else
-		{
-		  int new_nc = nc;
-
-		  int iidx = 0;
-
-		  for (int j = 0; j < nc; j++)
-		    if (j == idx_j.elem (iidx))
-		      {
-			iidx++;
-			new_nc--;
-
-			if (iidx == num_to_delete)
-			  break;
-		      }
-
-		  if (new_nc > 0)
-		    {
-		      T *new_data = new T [nr * new_nc];
-
-		      int jj = 0;
-		      iidx = 0;
-		      for (int j = 0; j < nc; j++)
-			{
-			  if (iidx < num_to_delete && j == idx_j.elem (iidx))
-			    iidx++;
-			  else
-			    {
-			      for (int i = 0; i < nr; i++)
-				new_data[nr*jj+i] = elem (i, j);
-			      jj++;
-			    }
-			}
-
-		      if (--(Array<T>::rep)->count <= 0)
-			delete Array<T>::rep;
-
-		      Array<T>::rep = new typename Array<T>::ArrayRep (new_data, nr * new_nc);
-
-		      d2 = new_nc;
-
-		      set_max_indices (2);
-		    }
-		  else
-		    (*current_liboctave_error_handler)
-		      ("A(idx) = []: index out of range");
-		}
-	    }
-	}
-    }
-  else if (idx_j.is_colon_equiv (nc, 1))
-    {
-      if (idx_i.is_colon_equiv (nr, 1))
-	resize (0, 0);
-      else
-	{
-	  idx_i.sort (true);
-
-	  int num_to_delete = idx_i.length (nr);
-
-	  if (num_to_delete != 0)
-	    {
-	      if (nc == 1 && num_to_delete == nr)
-		resize (0, 0);
-	      else 
-		{
-		  int new_nr = nr;
-
-		  int iidx = 0;
-
-		  for (int i = 0; i < nr; i++)
-		    if (i == idx_i.elem (iidx))
-		      {
-			iidx++;
-			new_nr--;
-
-			if (iidx == num_to_delete)
-			  break;
-		      }
-
-		  if (new_nr > 0)
-		    {
-		      T *new_data = new T [new_nr * nc];
-
-		      int ii = 0;
-		      iidx = 0;
-		      for (int i = 0; i < nr; i++)
-			{
-			  if (iidx < num_to_delete && i == idx_i.elem (iidx))
-			    iidx++;
-			  else
-			    {
-			      for (int j = 0; j < nc; j++)
-				new_data[new_nr*j+ii] = elem (i, j);
-			      ii++;
-			    }
-			}
-
-		      if (--(Array<T>::rep)->count <= 0)
-			delete Array<T>::rep;
-
-		      Array<T>::rep = new typename Array<T>::ArrayRep (new_data, new_nr * nc);
-
-		      d1 = new_nr;
-
-		      set_max_indices (2);
-		    }
-		  else
-		    (*current_liboctave_error_handler)
-		      ("A(idx) = []: index out of range");
-		}
-	    }
-	}
-    }
-}
-
-#define MAYBE_RESIZE_LHS \
-  do \
-    { \
-      int max_row_idx = idx_i_is_colon ? rhs_nr : idx_i.max () + 1; \
-      int max_col_idx = idx_j_is_colon ? rhs_nc : idx_j.max () + 1; \
- \
-      int new_nr = max_row_idx > lhs_nr ? max_row_idx : lhs_nr; \
-      int new_nc = max_col_idx > lhs_nc ? max_col_idx : lhs_nc; \
- \
-      lhs.resize (new_nr, new_nc, rfv); \
-    } \
-  while (0)
-
-template <class LT, class RT>
-int
-assign (Array2<LT>& lhs, const Array2<RT>& rhs, const LT& rfv)
-{
-  int retval = 1;
-
-  int n_idx = lhs.index_count ();
-
-  int lhs_nr = lhs.rows ();
-  int lhs_nc = lhs.cols ();
-
-  int rhs_nr = rhs.rows ();
-  int rhs_nc = rhs.cols ();
-
-  idx_vector *tmp = lhs.get_idx ();
-
-  idx_vector idx_i;
-  idx_vector idx_j;
-
-  if (n_idx > 1)
-    idx_j = tmp[1];
-
-  if (n_idx > 0)
-    idx_i = tmp[0];
-
-  if (n_idx == 2)
-    {
-      int n = idx_i.freeze (lhs_nr, "row", true, liboctave_wrore_flag);
-
-      int m = idx_j.freeze (lhs_nc, "column", true, liboctave_wrore_flag);
-
-      int idx_i_is_colon = idx_i.is_colon ();
-      int idx_j_is_colon = idx_j.is_colon ();
-
-      if (idx_i_is_colon)
-	n = lhs_nr > 0 ? lhs_nr : rhs_nr;
-
-      if (idx_j_is_colon)
-	m = lhs_nc > 0 ? lhs_nc : rhs_nc;
-
-      if (idx_i && idx_j)
-	{
-	  if (rhs_nr == 0 && rhs_nc == 0)
-	    {
-	      lhs.maybe_delete_elements (idx_i, idx_j);
-	    }
-	  else
-	    {
-	      if (rhs_nr == 1 && rhs_nc == 1 && n > 0 && m > 0)
-		{
-		  MAYBE_RESIZE_LHS;
-
-		  RT scalar = rhs.elem (0, 0);
-
-		  for (int j = 0; j < m; j++)
-		    {
-		      int jj = idx_j.elem (j);
-		      for (int i = 0; i < n; i++)
-			{
-			  int ii = idx_i.elem (i);
-			  lhs.elem (ii, jj) = scalar;
-			}
-		    }
-		}
-	      else if (n == rhs_nr && m == rhs_nc)
-		{
-		  if (n > 0 && m > 0)
-		    {
-		      MAYBE_RESIZE_LHS;
-
-		      for (int j = 0; j < m; j++)
-			{
-			  int jj = idx_j.elem (j);
-			  for (int i = 0; i < n; i++)
-			    {
-			      int ii = idx_i.elem (i);
-			      lhs.elem (ii, jj) = rhs.elem (i, j);
-			    }
-			}
-		    }
-		}
-	      else if (n == 0 && m == 0)
-		{
-		  if (! ((rhs_nr == 1 && rhs_nc == 1)
-			 || (rhs_nr == 0 && rhs_nc == 0)))
-		    {
-		      (*current_liboctave_error_handler)
-		("A([], []) = X: X must be an empty matrix or a scalar");
-
-		      retval = 0;
-		    }
-		}
-	      else
-		{
-		  (*current_liboctave_error_handler)
-    ("A(I, J) = X: X must be a scalar or the number of elements in I must");
-		  (*current_liboctave_error_handler)
-    ("match the number of rows in X and the number of elements in J must");
-		  (*current_liboctave_error_handler)
-    ("match the number of columns in X");
-
-		  retval = 0;
-		}
-	    }
-	}
-      // idx_vector::freeze() printed an error message for us.
-    }
-  else if (n_idx == 1)
-    {
-      int lhs_is_empty = lhs_nr == 0 || lhs_nc == 0;
-
-      if (lhs_is_empty || (lhs_nr == 1 && lhs_nc == 1))
-	{
-	  int lhs_len = lhs.length ();
-
-	  int n = idx_i.freeze (lhs_len, 0, true, liboctave_wrore_flag);
-
-	  if (idx_i)
-	    {
-	      if (rhs_nr == 0 && rhs_nc == 0)
-		{
-		  if (n != 0 && (lhs_nr != 0 || lhs_nc != 0))
-		    lhs.maybe_delete_elements (idx_i);
-		}
-	      else
-		{
-		  if (liboctave_wfi_flag)
-		    {
-		      if (lhs_is_empty
-			  && idx_i.is_colon ()
-			  && ! (rhs_nr == 1 || rhs_nc == 1))
-			{
-			  (*current_liboctave_warning_handler)
-			    ("A(:) = X: X is not a vector or scalar");
-			}
-		      else
-			{
-			  int idx_nr = idx_i.orig_rows ();
-			  int idx_nc = idx_i.orig_columns ();
-
-			  if (! (rhs_nr == idx_nr && rhs_nc == idx_nc))
-			    (*current_liboctave_warning_handler)
-			      ("A(I) = X: X does not have same shape as I");
-			}
-		    }
-
-		  if (assign ((Array<LT>&) lhs, (Array<RT>&) rhs))
-		    {
-		      int len = lhs.length ();
-
-		      if (len > 0)
-			{
-			  // The following behavior is much simplified
-			  // over previous versions of Octave.  It
-			  // seems to be compatible with Matlab.
-
-			  lhs.d1 = 1;
-			  lhs.d2 = lhs.length ();
-			}
-		      else
-			{
-			  lhs.d1 = 0;
-			  lhs.d2 = 0;
-			}
-		    }
-		  else
-		    retval = 0;
-		}
-	    }
-	  // idx_vector::freeze() printed an error message for us.
-	}
-      else if (lhs_nr == 1)
-	{
-	  idx_i.freeze (lhs_nc, "vector", true, liboctave_wrore_flag);
-
-	  if (idx_i)
-	    {
-	      if (rhs_nr == 0 && rhs_nc == 0)
-		lhs.maybe_delete_elements (idx_i);
-	      else
-		{
-		  if (assign ((Array<LT>&) lhs, (Array<RT>&) rhs))
-		    lhs.d2 = lhs.length ();
-		  else
-		    retval = 0;
-		}
-	    }
-	  // idx_vector::freeze() printed an error message for us.
-	}
-      else if (lhs_nc == 1)
-	{
-	  idx_i.freeze (lhs_nr, "vector", true, liboctave_wrore_flag);
-
-	  if (idx_i)
-	    {
-	      if (rhs_nr == 0 && rhs_nc == 0)
-		lhs.maybe_delete_elements (idx_i);
-	      else
-		{
-		  if (assign ((Array<LT>&) lhs, (Array<RT>&) rhs))
-		    lhs.d1 = lhs.length ();
-		  else
-		    retval = 0;
-		}
-	    }
-	  // idx_vector::freeze() printed an error message for us.
-	}
-      else
-	{
-	  if (liboctave_wfi_flag
-	      && ! (idx_i.is_colon ()
-		    || (idx_i.one_zero_only ()
-			&& idx_i.orig_rows () == lhs_nr
-			&& idx_i.orig_columns () == lhs_nc)))
-	    (*current_liboctave_warning_handler)
-	      ("single index used for matrix");
-
-	  int len = idx_i.freeze (lhs_nr * lhs_nc, "matrix");
-
-	  if (idx_i)
-	    {
-	      if (len == 0)
-		{
-		  if (! ((rhs_nr == 1 && rhs_nc == 1)
-			 || (rhs_nr == 0 && rhs_nc == 0)))
-		    (*current_liboctave_error_handler)
-		      ("A([]) = X: X must be an empty matrix or scalar");
-		}
-	      else if (len == rhs_nr * rhs_nc)
-		{
-		  int k = 0;
-		  for (int j = 0; j < rhs_nc; j++)
-		    {
-		      for (int i = 0; i < rhs_nr; i++)
-			{
-			  int ii = idx_i.elem (k++);
-			  int fr = ii % lhs_nr;
-			  int fc = (ii - fr) / lhs_nr;
-			  lhs.elem (fr, fc) = rhs.elem (i, j);
-			}
-		    }
-		}
-	      else if (rhs_nr == 1 && rhs_nc == 1 && len <= lhs_nr * lhs_nc)
-		{
-		  RT scalar = rhs.elem (0, 0);
-
-		  for (int i = 0; i < len; i++)
-		    {
-		      int ii = idx_i.elem (i);
-		      int fr = ii % lhs_nr;
-		      int fc = (ii - fr) / lhs_nr;
-		      lhs.elem (fr, fc) = scalar;
-		    }
-		}
-	      else
-		{
-		  (*current_liboctave_error_handler)
-      ("A(I) = X: X must be a scalar or a matrix with the same size as I");
-
-		  retval = 0;
-		}
-	    }
-	  // idx_vector::freeze() printed an error message for us.
-	}
-    }
-  else
-    {
-      (*current_liboctave_error_handler)
-	("invalid number of indices for matrix expression");
-
-      retval = 0;
-    }
-
-  lhs.clear_index ();
-
-  return retval;
-}
-
-/*
-;;; Local Variables: ***
-;;; mode: C++ ***
-;;; End: ***
-*/
--- a/liboctave/Array2.cc	Sat Sep 13 07:53:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,257 +0,0 @@
-// Template array classes
-/*
-
-Copyright (C) 1996, 1997 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 <cassert>
-
-#include <iostream>
-
-#include "Array2.h"
-
-#if defined (HEAVYWEIGHT_INDEXING)
-#include "idx-vector.h"
-#include "Array2-idx.h"
-#endif
-
-#include "lo-error.h"
-
-// Two dimensional array class.
-
-// A guess (should be quite conservative).
-#define MALLOC_OVERHEAD 1024
-
-template <class T>
-int
-Array2<T>::get_size (int r, int c) const
-{
-  // XXX KLUGE XXX
-
-  // If an allocation of an array with r * c elements of type T
-  // would cause an overflow in the allocator when computing the
-  // size of the allocation, then return a value which, although
-  // not equivalent to the actual request, should be too large for
-  // most current hardware, but not so large to cause the
-  // allocator to barf on computing retval * sizeof (T).
-
-  static int nl;
-  static double dl
-    = frexp (static_cast<double>
-	     (INT_MAX - MALLOC_OVERHEAD) / sizeof (T), &nl);
-
-  // This value should be an integer.  If we return this value and
-  // things work the way we expect, we should be paying a visit to
-  // new_handler in no time flat.
-  static int max_items = static_cast<int> (ldexp (dl, nl));
-
-  int nr, nc;
-  double dr = frexp (static_cast<double> (r), &nr);
-  double dc = frexp (static_cast<double> (c), &nc);
-
-  int nt = nr + nc;
-  double dt = dr * dc;
-
-  if (dt <= 0.5)
-    {
-      nt--;
-      dt *= 2;
-
-      if (dt <= 0.5)
-	nt--;
-    }
-
-  return (nt < nl || (nt == nl && dt < dl)) ? r * c : max_items;
-}
-
-#undef MALLOC_OVERHEAD
-
-template <class T>
-T
-Array2<T>::range_error (const char *fcn, int i, int j) const
-{
-  (*current_liboctave_error_handler)
-    ("%s (%d, %d): range error", fcn, i, j);
-  return T ();
-}
-
-template <class T>
-T&
-Array2<T>::range_error (const char *fcn, int i, int j)
-{
-  (*current_liboctave_error_handler)
-    ("%s (%d, %d): range error", fcn, i, j);
-  static T foo;
-  return foo;
-}
-
-template <class T>
-void
-Array2<T>::resize (int r, int c)
-{
-  if (r < 0 || c < 0)
-    {
-      (*current_liboctave_error_handler)
-	("can't resize to negative dimension");
-      return;
-    }
-
-  if (r == dim1 () && c == dim2 ())
-    return;
-
-  typename Array<T>::ArrayRep *old_rep = Array<T>::rep;
-  const T *old_data = data ();
-
-  int old_d1 = dim1 ();
-  int old_d2 = dim2 ();
-  int old_len = length ();
-
-  Array<T>::rep = new typename Array<T>::ArrayRep (get_size (r, c));
-
-  d1 = r;
-  d2 = c;
-
-  if (old_data && old_len > 0)
-    {
-      int min_r = old_d1 < r ? old_d1 : r;
-      int min_c = old_d2 < c ? old_d2 : c;
-
-      for (int j = 0; j < min_c; j++)
-	for (int i = 0; i < min_r; i++)
-	  xelem (i, j) = old_data[old_d1*j+i];
-    }
-
-  if (--old_rep->count <= 0)
-    delete old_rep;
-}
-
-template <class T>
-void
-Array2<T>::resize (int r, int c, const T& val)
-{
-  if (r < 0 || c < 0)
-    {
-      (*current_liboctave_error_handler)
-	("can't resize to negative dimension");
-      return;
-    }
-
-  if (r == dim1 () && c == dim2 ())
-    return;
-
-  typename Array<T>::ArrayRep *old_rep = Array<T>::rep;
-  const T *old_data = data ();
-
-  int old_d1 = dim1 ();
-  int old_d2 = dim2 ();
-  int old_len = length ();
-
-  Array<T>::rep = new typename Array<T>::ArrayRep (get_size (r, c));
-
-  d1 = r;
-  d2 = c;
-
-  int min_r = old_d1 < r ? old_d1 : r;
-  int min_c = old_d2 < c ? old_d2 : c;
-
-  if (old_data && old_len > 0)
-    {
-      for (int j = 0; j < min_c; j++)
-	for (int i = 0; i < min_r; i++)
-	  xelem (i, j) = old_data[old_d1*j+i];
-    }
-
-  for (int j = 0; j < min_c; j++)
-    for (int i = min_r; i < r; i++)
-      xelem (i, j) = val;
-
-  for (int j = min_c; j < c; j++)
-    for (int i = 0; i < r; i++)
-      xelem (i, j) = val;
-
-  if (--old_rep->count <= 0)
-    delete old_rep;
-}
-
-template <class T>
-Array2<T>&
-Array2<T>::insert (const Array2<T>& a, int r, int c)
-{
-  int a_rows = a.rows ();
-  int a_cols = a.cols ();
-
-  if (r < 0 || r + a_rows > rows () || c < 0 || c + a_cols > cols ())
-    {
-      (*current_liboctave_error_handler) ("range error for insert");
-      return *this;
-    }
-
-  for (int j = 0; j < a_cols; j++)
-    for (int i = 0; i < a_rows; i++)
-      elem (r+i, c+j) = a.elem (i, j);
-
-  return *this;
-}
-
-template <class T>
-Array2<T>
-Array2<T>::transpose (void) const
-{
-  if (d1 > 1 && d2 > 1)
-    {
-      Array2<T> result (d2, d1);
-
-      for (int j = 0; j < d2; j++)
-	for (int i = 0; i < d1; i++)
-	  result.xelem (j, i) = xelem (i, j);
-
-      return result;
-    }
-  else
-    {
-      // Fast transpose for vectors and empty matrices
-      return Array2<T> (*this, d2, d1);
-    }
-}
-
-template <class T>
-void
-Array2<T>::print_info (std::ostream& os, const std::string& prefix) const
-{
-  os << "\n"
-     << prefix << "rows: " << rows () << "\n"
-     << prefix << "cols: " << cols () << "\n";
-
-  Array<T>::print_info (os, prefix + "  ");
-}
-
-/*
-;;; Local Variables: ***
-;;; mode: C++ ***
-;;; End: ***
-*/
--- a/liboctave/Array2.h	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/Array2.h	Fri Sep 19 21:41:21 2003 +0000
@@ -46,58 +46,23 @@
 {
 protected:
 
-  int get_size (int r, int c) const;
+  static int get_size (int r, int c) { return Array<T>::get_size (r, c); }
 
-  Array2 (T *d, int n, int m) : Array<T> (d, get_size (n, m))
-    {
-      d1 = n;
-      d2 = m;
-      set_max_indices (2);
-    }
+  Array2 (T *d, int r, int c) : Array<T> (d, dim_vector (r, c)) { }
 
 public:
 
-  // These really need to be protected (and they will be in the
-  // future, so don't depend on them being here!), but they can't be
-  // until template friends work correctly in g++.
-
-  int d1;
-  int d2;
+  Array2 (void) : Array<T> (dim_vector (0, 0)) { }
 
-  Array2 (void) : Array<T> ()
-    {
-      d1 = 0;
-      d2 = 0;
-      set_max_indices (2);
-    }
-
-  Array2 (int n, int m) : Array<T> (get_size (n, m))
-    {
-      d1 = n;
-      d2 = m;
-      set_max_indices (2);
-    }
+  Array2 (int r, int c) : Array<T> (dim_vector (r, c)) { }
 
-  Array2 (int n, int m, const T& val) : Array<T> (get_size (n, m), val)
-    {
-      d1 = n;
-      d2 = m;
-      set_max_indices (2);
-    }
+  Array2 (int r, int c, const T& val)
+    : Array<T> (dim_vector (r, c), val) { }
 
-  Array2 (const Array2<T>& a) : Array<T> (a)
-    {
-      d1 = a.d1;
-      d2 = a.d2;
-      set_max_indices (2);
-    }
+  Array2 (const Array2<T>& a) : Array<T> (a, a.dims ()) { }
 
-  Array2 (const Array<T>& a, int n, int m) : Array<T> (a)
-    {
-      d1 = n;
-      d2 = m;
-      set_max_indices (2);
-    }
+  Array2 (const Array<T>& a, int r, int c)
+    : Array<T> (a, dim_vector (r, c)) { }
 
   ~Array2 (void) { }
 
@@ -106,103 +71,44 @@
       if (this != &a)
 	{
 	  Array<T>::operator = (a);
-	  d1 = a.d1;
-	  d2 = a.d2;
+
+	  dimensions = a.dimensions;
 	}
 
       return *this;
     }
 
-  int dim1 (void) const { return d1; }
-  int dim2 (void) const { return d2; }
-
-  int rows (void) const { return d1; }
-  int cols (void) const { return d2; }
-  int columns (void) const { return d2; }
-
-  T range_error (const char *fcn, int i, int j) const;
-  T& range_error (const char *fcn, int i, int j);
+  void resize (int r, int c) { resize_no_fill (r, c); }
 
-  // No checking of any kind, ever.
-
-  T& xelem (int i, int j) { return Array<T>::xelem (d1*j+i); }
-  T xelem (int i, int j) const { return Array<T>::xelem (d1*j+i); }
+  void resize (int r, int c, const T& val) { resize_and_fill (r, c, val); }
 
-  // Note that the following element selection methods don't use
-  // xelem() because they need to make use of the code in
-  // Array<T>::elem() that checks the reference count.
-
-  T& checkelem (int i, int j)
+  Array2<T>& insert (const Array2<T>& a, int r, int c)
     {
-      if (i < 0 || j < 0 || i >= d1 || j >= d2)
-	return range_error ("T& Array2<T>::checkelem", i, j);
-      else
-	return Array<T>::elem (d1*j+i);
-    }
-
-  T& elem (int i, int j) { return Array<T>::elem (d1*j+i); }
-
-#if defined (BOUNDS_CHECKING)
-  T& operator () (int i, int j) { return checkelem (i, j); }
-#else
-  T& operator () (int i, int j) { return elem (i, j); }
-#endif
-
-  T checkelem (int i, int j) const
-    {
-      if (i < 0 || j < 0 || i >= d1 || j >= d2)
-	return range_error ("T Array2<T>::checkelem", i, j);
-      else
-	return Array<T>::elem (d1*j+i);
+      Array<T>::insert (a, r, c);
+      return *this;
     }
 
-  T elem (int i, int j) const { return Array<T>::elem (d1*j+i); }
-
-#if defined (BOUNDS_CHECKING)
-  T operator () (int i, int j) const { return checkelem (i, j); }
-#else
-  T operator () (int i, int j) const { return elem (i, j); }
-#endif
-
-  void resize (int n, int m);
-  void resize (int n, int m, const T& val);
-
-  Array2<T>& insert (const Array2<T>& a, int r, int c);
-
-  bool is_square (void) const { return (d1 == d2); }
-
-  Array2<T> transpose (void) const;
-
-#ifdef HEAVYWEIGHT_INDEXING
-
-  void maybe_delete_elements (idx_vector& i);
-
-  void maybe_delete_elements (idx_vector& i, idx_vector& j);
-
-  Array2<T> value (void);
+  Array2<T> transpose (void) const
+    {
+      Array<T> tmp = Array<T>::transpose ();
+      return Array2<T> (tmp, tmp.rows (), tmp.columns ());
+    }
 
   Array2<T> index (idx_vector& i, int resize_ok = 0,
-		   const T& rfv = resize_fill_value (T ())) const;
+		   const T& rfv = resize_fill_value (T ())) const
+    {
+      Array<T> tmp = Array<T>::index (i, resize_ok, rfv);
+      return Array2<T> (tmp, tmp.rows (), tmp.columns ());
+    }
 
   Array2<T> index (idx_vector& i, idx_vector& j, int resize_ok = 0,
-		   const T& rfv = resize_fill_value (T ())) const;
-
-#endif
-
-  void print_info (std::ostream& os, const std::string& prefix) const;
+		   const T& rfv = resize_fill_value (T ())) const
+    {
+      Array<T> tmp = Array<T>::index (i, j, resize_ok, rfv);
+      return Array2<T> (tmp, tmp.rows (), tmp.columns ());
+    }
 };
 
-template <class LT, class RT>
-int
-assign (Array2<LT>& lhs, const Array2<RT>& rhs, const LT& rfv);
-
-template <class LT, class RT>
-int
-assign (Array2<LT>& lhs, const Array2<RT>& rhs)
-{
-  return assign (lhs, rhs, resize_fill_value (LT ()));
-}
-
 #endif
 
 /*
--- a/liboctave/Array3-idx.h	Sat Sep 13 07:53:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-// Template array classes
-/*
-
-Copyright (C) 1996, 1997 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.
-
-*/
-
-#include "Array-flags.h"
-#include "idx-vector.h"
-#include "lo-error.h"
-
-template <class T>
-void
-Array3<T>::maybe_delete_elements (idx_vector&, idx_vector&, idx_vector&)
-{
-  assert (0);
-}
-
-template <class T>
-Array3<T>
-Array3<T>::value (void)
-{
-  Array3<T> retval;
-  assert (0);
-  return retval;
-}
-
-template <class LT, class RT>
-int
-assign (Array3<LT>&, const Array3<RT>&, const LT&)
-{
-  assert (0);
-  return 0;
-}
-
-/*
-;;; Local Variables: ***
-;;; mode: C++ ***
-;;; End: ***
-*/
--- a/liboctave/Array3.cc	Sat Sep 13 07:53:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,161 +0,0 @@
-// Template array classes
-/*
-
-Copyright (C) 1996, 1997 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 <cassert>
-
-#include <iostream>
-
-#include "Array3.h"
-
-#if defined (HEAVYWEIGHT_INDEXING)
-#include "idx-vector.h"
-#include "Array3-idx.h"
-#endif
-
-#include "lo-error.h"
-
-// Three dimensional array class.
-
-template <class T>
-void
-Array3<T>::resize (int r, int c, int p)
-{
-  if (r < 0 || c < 0 || p < 0)
-    {
-      (*current_liboctave_error_handler)
-	("can't resize to negative dimension");
-      return;
-    }
-
-  if (r == dim1 () && c == dim2 () && p == dim3 ())
-    return;
-
-  typename Array<T>::ArrayRep *old_rep = Array<T>::rep;
-  const T *old_data = data ();
-
-  int old_d1 = dim1 ();
-  int old_d2 = dim2 ();
-  int old_d3 = dim3 ();
-  int old_len = length ();
-
-  int ts = get_size (get_size (r, c), p);
-
-  Array<T>::rep = new typename Array<T>::ArrayRep (ts);
-
-  Array2<T>::d1 = r;
-  Array2<T>::d2 = c;
-  d3 = p;
-
-  if (old_data && old_len > 0)
-    {
-      int min_r = old_d1 < r ? old_d1 : r;
-      int min_c = old_d2 < c ? old_d2 : c;
-      int min_p = old_d3 < p ? old_d3 : p;
-
-      for (int k = 0; k < min_p; k++)
-	for (int j = 0; j < min_c; j++)
-	  for (int i = 0; i < min_r; i++)
-	    xelem (i, j, k) = old_data[old_d1*(old_d2*k+j)+i];
-    }
-
-  if (--old_rep->count <= 0)
-    delete old_rep;
-}
-
-template <class T>
-void
-Array3<T>::resize (int r, int c, int p, const T& val)
-{
-  if (r < 0 || c < 0 || p < 0)
-    {
-      (*current_liboctave_error_handler)
-	("can't resize to negative dimension");
-      return;
-    }
-
-  if (r == dim1 () && c == dim2 () && p == dim3 ())
-    return;
-
-  typename Array<T>::ArrayRep *old_rep = Array<T>::rep;
-  const T *old_data = data ();
-
-  int old_d1 = dim1 ();
-  int old_d2 = dim2 ();
-  int old_d3 = dim3 ();
-
-  int old_len = length ();
-
-  int ts = get_size (get_size (r, c), p);
-
-  Array<T>::rep = new typename Array<T>::ArrayRep (ts);
-
-  Array2<T>::d1 = r;
-  Array2<T>::d2 = c;
-  d3 = p;
-
-  int min_r = old_d1 < r ? old_d1 : r;
-  int min_c = old_d2 < c ? old_d2 : c;
-  int min_p = old_d3 < p ? old_d3 : p;
-
-  if (old_data && old_len > 0)
-    for (int k = 0; k < min_p; k++)
-      for (int j = 0; j < min_c; j++)
-	for (int i = 0; i < min_r; i++)
-	  xelem (i, j, k) = old_data[old_d1*(old_d2*k+j)+i];
-
-  // If the copy constructor is expensive, this may win.  Otherwise,
-  // it may make more sense to just copy the value everywhere when
-  // making the new ArrayRep.
-
-  for (int k = 0; k < min_p; k++)
-    for (int j = min_c; j < c; j++)
-      for (int i = 0; i < min_r; i++)
-	xelem (i, j, k) = val;
-
-  for (int k = 0; k < min_p; k++)
-    for (int j = 0; j < c; j++)
-      for (int i = min_r; i < r; i++)
-	xelem (i, j, k) = val;
-
-  for (int k = min_p; k < p; k++)
-    for (int j = 0; j < c; j++)
-      for (int i = 0; i < r; i++)
-	xelem (i, j, k) = val;
-
-  if (--old_rep->count <= 0)
-    delete old_rep;
-}
-
-/*
-;;; Local Variables: ***
-;;; mode: C++ ***
-;;; End: ***
-*/
--- a/liboctave/Array3.h	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/Array3.h	Fri Sep 19 21:41:21 2003 +0000
@@ -31,7 +31,7 @@
 #include <cassert>
 #include <cstdlib>
 
-#include "Array2.h"
+#include "Array.h"
 #include "lo-error.h"
 
 class idx_vector;
@@ -40,133 +40,50 @@
 
 template <class T>
 class
-Array3 : public Array2<T>
+Array3 : public Array<T>
 {
 protected:
 
-  int d3;
+  static int get_size (int r, int c, int p)
+    { return Array<T>::get_size (r, c, p); }
 
-  Array3 (T *d, int n, int m, int k) : Array2<T> (d, n, get_size (m, k))
-    {
-      Array2<T>::d2 = m;
-      d3 = k;
-      set_max_indices (3);
-    }
+  Array3 (T *d, int r, int c, int p) : Array<T> (d, dim_vector (r, c, p)) { }
 
 public:
 
-  Array3 (void) : Array2<T> ()
-    {
-      Array2<T>::d2 = 0;
-      d3 = 0;
-      set_max_indices (3);
-    }
+  Array3 (void) : Array<T> (dim_vector (0, 0, 0)) { }
 
-  Array3 (int n, int m, int k) : Array2<T> (n, get_size (m, k))
-    {
-      Array2<T>::d2 = m;
-      d3 = k;
-      set_max_indices (3);
-    }
+  Array3 (int r, int c, int p) : Array<T> (dim_vector (r, c, p)) { }
 
-  Array3 (int n, int m, int k, const T& val) : Array2<T> (n, m*k, val)
-    {
-      Array2<T>::d2 = m;
-      d3 = k;
-      set_max_indices (3);
-    }
+  Array3 (int r, int c, int p, const T& val)
+    : Array<T> (dim_vector (r, c, p), val) { }
 
-  Array3 (const Array3<T>& a) : Array2<T> (a)
-    {
-      Array2<T>::d2 = a.d2;
-      d3 = a.d3;
-      set_max_indices (3);
-    }
+  Array3 (const Array3<T>& a)
+    : Array<T> (a, a.dims ()) { }
+
+  Array3 (const Array<T>& a, int r, int c, int p)
+    : Array<T> (a, dim_vector (r, c, p)) { }
 
   ~Array3 (void) { }
 
   Array3<T>& operator = (const Array3<T>& a)
     {
-      if (this != &a && Array<T>::rep != a.rep)
+      if (this != &a)
 	{
 	  Array<T>::operator = (a);
-	  Array2<T>::d1 = a.d1;
-	  Array2<T>::d2 = a.d2;
-	  d3 = a.d3;
+
+	  dimensions = a.dimensions;
 	}
 
       return *this;
     }
 
-  int dim3 (void) const { return d3; }
-
-  // No checking of any kind, ever.
-
-  T& xelem (int i, int j, int k) { return Array2<T>::xelem (i, Array2<T>::d2*k+j); }
-  T xelem (int i, int j, int k) const { return Array2<T>::xelem (i, Array2<T>::d2*k+j); }
-
-  // Note that the following element selection methods don't use
-  // xelem() because they need to make use of the code in
-  // Array<T>::elem() that checks the reference count.
-
-  T& checkelem (int i, int j, int k)
-    {
-      if (i < 0 || j < 0 || k < 0 || i >= Array2<T>::d1 || j >= Array2<T>::d2 || k >= d3)
-	{
-	  (*current_liboctave_error_handler) ("range error in Array3");
-	  static T foo;
-	  return foo;
-	}
-      return Array2<T>::elem (i, Array2<T>::d2*k+j);
-    }
-
-  T& elem (int i, int j, int k) { return Array2<T>::elem (i, Array2<T>::d2*k+j); }
-
-#if defined (BOUNDS_CHECKING)
-  T& operator () (int i, int j, int k) { return checkelem (i, j, k); }
-#else
-  T& operator () (int i, int j, int k) { return elem (i, j, k); }
-#endif
+  void resize (int r, int c, int p) { resize_no_fill (r, c, p); }
 
-  T checkelem (int i, int j, int k) const
-    {
-      if (i < 0 || j < 0 || k < 0 || i >= Array2<T>::d1 || j >= Array2<T>::d2 || k >= d3)
-	{
-	  (*current_liboctave_error_handler) ("range error in Array3");
-	  return T ();
-	}
-      return Array2<T>::elem (i, Array2<T>::d1*k+j);
-    }
-
-  T elem (int i, int j, int k) const { return Array2<T>::elem (i, Array2<T>::d2*k+j); }
-
-#if defined (BOUNDS_CHECKING)
-  T operator () (int i, int j, int k) const { return checkelem (i, j, k); }
-#else
-  T operator () (int i, int j, int k) const { return elem (i, j, k); }
-#endif
-
-  void resize (int n, int m, int k);
-  void resize (int n, int m, int k, const T& val);
-
-#ifdef HEAVYWEIGHT_INDEXING
-  void maybe_delete_elements (idx_vector& i, idx_vector& j, idx_vector& k);
-
-  Array3<T> value (void);
-#endif
+  void resize (int r, int c, int p, const T& val)
+    { resize_and_fill (r, c, p, val); }
 };
 
-template <class LT, class RT>
-int
-assign (Array3<LT>& lhs, const Array3<RT>& rhs, const LT& rfv);
-
-template <class LT, class RT>
-int
-assign (Array3<LT>& lhs, const Array3<RT>& rhs)
-{
-  return assign (lhs, rhs, static_cast<LT> (0));
-}
-
 #endif
 
 /*
--- a/liboctave/ArrayN-idx.h	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/ArrayN-idx.h	Fri Sep 19 21:41:21 2003 +0000
@@ -26,203 +26,7 @@
 #include "idx-vector.h"
 #include "lo-error.h"
 
-template <class T>
-void
-ArrayN<T>::maybe_delete_elements (Array<idx_vector>& idx, const T& rfv)
-{
-  int n_idx = idx.length ();
-
-  Array<int> lhs_dims = dims ();
-
-  Array<int> idx_is_colon (n_idx, 0);
-  Array<int> idx_is_colon_equiv (n_idx, 0);
-
-  // Initialization of colon arrays.
-
-  for (int i = 0; i < n_idx; i++)
-    {
-      idx_is_colon_equiv(i) = idx(i).is_colon_equiv (lhs_dims(i), 1);
-
-      idx_is_colon(i) = idx(i).is_colon ();
-    }
-
-  if (all_ones (idx_is_colon) || all_ones (idx_is_colon_equiv))
-    {
-      // A(:,:,:) -- we are deleting elements in all dimensions, so
-      // the result is [](0x0x0).
-
-      Array<int> zeros (n_idx, 0);
-
-      resize (zeros, rfv);
-    }
-
-  else if (num_ones (idx_is_colon) == n_idx - 1
-	   && num_ones (idx_is_colon_equiv) == n_idx)
-    {
-      // A(:,:,j) -- we are deleting elements in one dimension by
-      // enumerating them.
-      //
-      // If we enumerate all of the elements, we should have zero
-      // elements in that dimension with the same number of elements
-      // in the other dimensions that we started with.
-
-      Array<int> temp_dims (n_idx,0);
-
-      for (int i = 0; i < n_idx; i++)
-	{
-	  if (idx_is_colon (i))
-	    temp_dims (i) =  lhs_dims (i);
-	
-	  else
-	    temp_dims (i) = 0;
-	}
-      resize (temp_dims);
-    }
-  else if (num_ones (idx_is_colon) == n_idx - 1)
-    {
-      // We have colons in all indices except for one.
-      // This index tells us which slice to delete
-
-      int non_col = 0;
-
-      // Find the non-colon column.
-
-      for (int i = 0; i < n_idx; i++)
-	{
-	  if (! idx_is_colon (i))
-	    non_col = i;
-	}
-
-      // The length of the non-colon dimension.
-
-      int non_col_dim = lhs_dims (non_col);
-
-      idx(non_col).sort (true);
-
-      int num_to_delete = idx(non_col).length (lhs_dims (non_col));
-
-      if (num_to_delete > 0)
-	{
-	  int temp = num_ones(lhs_dims);
-	
-	  if (non_col_dim == 1)
-	    temp--;
-	
-	  if (temp == n_idx - 1 && num_to_delete == non_col_dim)
-	    {
-	      // We have A with (1x1x4), where A(1,:,1:4)
-	      // Delete all (0x0x0)
-
-	      Array<int> zero_dims (n_idx, 0);
-	
-	      resize (zero_dims, rfv);	
-	    }
-	  else
-	    {
-	      // New length of non-colon dimension
-	      // (calculated in the next for loop)
-
-	      int new_dim = non_col_dim;
-	
-	      int iidx = 0;
-	
-	      for (int j = 0; j < non_col_dim; j++)
-		if (j == idx(non_col).elem (iidx))
-		  {
-		    iidx++;
-		
-		    new_dim--;
-		
-		    if (iidx == num_to_delete)
-		      break;
-		  }	
-
-	      // Creating the new nd array after deletions.
-
-	      if (new_dim > 0)
-		{
-		  // Calculate number of elements in new array.
-
-		  int num_new_elem=1;
-		
-		  for (int i = 0; i < n_idx; i++)
-		    {
-		      if (i == non_col)
-			num_new_elem *= new_dim;
-		
-		      else
-			num_new_elem *= lhs_dims(i);
-		    }
-		
-		  T *new_data = new T [num_new_elem];
-		  	
-		  Array<int> result_idx (lhs_dims.length (), 0);
-		  Array<int> elt_idx;
-		
-		  Array<int> lhs_inc (lhs_dims.length ());
-		
-		  for (int i = 0; i < lhs_dims.length (); i++)
-		    lhs_inc(i) = lhs_dims(i) + 1;
-		
-		  Array<int> new_lhs_dim = lhs_dims;
-		
-		  new_lhs_dim(non_col) = new_dim;	
-		
-		  int num_elem = 1;
-		
-		  int numidx = 0;
-		
-		  int n = length ();
-		
-		  for (int i =0; i < lhs_dims.length (); i++)
-		    if (i != non_col)
-		      num_elem *= lhs_dims (i);
-		
-		  num_elem *= idx(non_col).capacity ();
-		
-		  for (int i = 0; i < n; i++)
-		    {	
-		      if (numidx < num_elem
-			  && is_in (result_idx(non_col), idx(non_col)))
-			numidx++;
-		
-		      else
-			{
-			  Array<int> temp_result_idx = result_idx;
-			
-			  int num_lgt
-			    = how_many_lgt (result_idx(non_col), idx(non_col));
-			
-			  temp_result_idx(non_col) -= num_lgt;
-				
-			  int kidx
-			    = ::compute_index (temp_result_idx, new_lhs_dim);
-			
-			  new_data[kidx] = elem (result_idx);
-			}
-
-		      increment_index (result_idx, lhs_dims);
-		    }
-		
-		  if (--(Array<T>::rep)->count <= 0)
-		    delete Array<T>::rep;
-		
-		  Array<T>::rep =
-		    new typename Array<T>::ArrayRep (new_data, num_new_elem);
-		
-		  dimensions = new_lhs_dim;
-
-		  set_max_indices (new_lhs_dim.length ());
-	    	}
-	    }
-	}
-    }
-  else if (num_ones(idx_is_colon) < n_idx)
-    {
-      (*current_liboctave_error_handler)
-	("A null assignment can have only one non-colon index.");
-    }
-}
+#if 0
 
 template <class T>
 ArrayN<T>
@@ -260,724 +64,8 @@
   return retval;
 }
 
-template <class T>
-ArrayN<T>
-ArrayN<T>::index (idx_vector& ra_idx, int resize_ok, const T& rfv) const
-{
-  ArrayN<T> retval;
-  assert (0);
-  return retval;
-}
-
-static inline Array<int>
-freeze (Array<idx_vector>& ra_idx, const Array<int>& dimensions, int resize_ok)
-{
-  Array<int> retval;
-
-  int n = ra_idx.length ();
-
-  assert (n == dimensions.length ());
-
-  retval.resize (n);
-
-  for (int i = 0; i < n; i++)
-    retval(i) = ra_idx(i).freeze (dimensions(i), "XXX FIXME XXX", resize_ok);
-
-  return retval;
-}
-
-static inline bool
-vector_equivalent (const Array<int>& ra_idx)
-{
-  int n = ra_idx.length ();
-
-  bool found_first = false;
-
-  for (int i = 0; i < n; i++)
-    {
-      if (ra_idx(i) != 1)
-        {
-	  if (! found_first)
-	    found_first = true;
-	  else
-	    return false;
-	}
-    }
-
-  return true;
-}
-
-static inline bool
-equal_arrays (const Array<int> a, const Array<int> b)
-{
-  bool retval = true;
-
-  if (a.length () != b.length ())
-    retval = false;
-  else
-    {
-      for (int i = 0; i < a.length (); i++)
-	{
-	  if (a(i) != b(i))
-	    retval = false;
-	}
-    }
-
-  return retval;
-}
-
-static inline bool
-all_ok (const Array<idx_vector>& ra_idx)
-{
-  bool retval = true;
-
-  int n = ra_idx.length ();
-
-  for (int i = 0; i < n; i++)
-    {
-      if (! ra_idx(i))
-	{
-	  retval = false;
-	  break;
-	}
-    }
-
-  return retval;
-}
-
-static inline bool
-any_orig_empty (const Array<idx_vector>& ra_idx)
-{
-  bool retval = false;
-
-  int n = ra_idx.length ();
-
-  for (int i = 0; i < n; i++)
-    {
-      if (ra_idx(i).orig_empty ())
-	{
-	  retval = true;
-	  break;
-	}
-    }
-
-  return retval;
-}
-
-static inline bool
-any_zero_len (const Array<int>& frozen_lengths)
-{
-  bool retval = false;
-
-  int n = frozen_lengths.length ();
-
-  for (int i = 0; i < n; i++)
-    {
-      if (frozen_lengths(i) == 0)
-	{
-	  retval = true;
-	  break;
-	}
-    }
-
-  return retval;
-}
-
-static inline Array<int>
-get_zero_len_size (const Array<int>& frozen_lengths,
-		   const Array<int>& dimensions)
-{
-  Array<int> retval;
-  assert (0);
-  return retval;
-}
-
-static inline bool
-all_colon_equiv (const Array<idx_vector>& ra_idx,
-		 const Array<int>& frozen_lengths)
-{
-  bool retval = true;
-
-  int idx_n = ra_idx.length ();
-
-  int n = frozen_lengths.length ();
-
-  assert (idx_n == n);
-
-  for (int i = 0; i < n; i++)
-    {
-      if (! ra_idx(i).is_colon_equiv (frozen_lengths(i)))
-	{
-	  retval = false;
-	  break;
-	}
-    }
-
-  return retval;
-}
-
-static inline bool
-is_in (int num, const idx_vector& idx)
-{
-  int n = idx.capacity ();
-
-  for (int i = 0; i < n; i++)
-    if (idx.elem (i) == num)
-      return true;
-
-  return false;
-}
-
-static inline int
-how_many_lgt (const int num, idx_vector& idxv)
-{
-  int retval = 0;
-
-  int n = idxv.capacity ();
-
-  for (int i = 0; i < n; i++)
-    if (num > idxv.elem (i))
-      retval++;
-
-  return retval;
-}
-
-static inline bool
-all_ones (const Array<int> arr)
-{
-  bool retval = true;
-
-  for (int i = 0; i < arr.length (); i++)
-    {
-      if (arr(i) != 1)
-	{
-	  retval = false;
-	  break;
-	}
-    }
-
-  return retval;
-}
-
-static Array<int>
-get_elt_idx (const Array<idx_vector>& ra_idx, const Array<int>& result_idx)
-{
-  int n = ra_idx.length ();
-
-  Array<int> retval (n);
-
-  for (int i = 0; i < n; i++)
-    retval(i) = ra_idx(i).elem (result_idx(i));
-
-  return retval;
-}
-
-template <class T>
-ArrayN<T>
-ArrayN<T>::index (Array<idx_vector>& ra_idx, int resize_ok, const T& rfv) const
-{
-  ArrayN<T> retval;
-
-  int n_dims = dimensions.length ();
-
-  Array<int> frozen_lengths = freeze (ra_idx, dimensions, resize_ok);
-
-  if (frozen_lengths.length () == n_dims)
-    {
-      if (all_ok (ra_idx))
-	{
-	  if (any_orig_empty (ra_idx))
-	    {
-	      retval.resize (frozen_lengths);
-	    }
-	  else if (any_zero_len (frozen_lengths))
-	    {
-	      Array<int> new_size = get_zero_len_size (frozen_lengths,
-						       dimensions);
-
-	      retval.resize (new_size);
-	    }
-	  else if (all_colon_equiv (ra_idx, frozen_lengths))
-	    {
-	      retval = *this;
-	    }
-	  else
-	    {
-#if 0
-	      retval.resize (frozen_lengths);
-
-	      int n = Array<T>::get_size (frozen_lengths);
-
-	      Array<int> result_idx (n_dims, 0);
-
-	      for (int i = 0; i < n; i++)
-		{
-		  Array<int> elt_idx = get_elt_idx (result_idx);
-
-		  if (elt_idx > orig_len)
-		    retval.elem (result_idx) = rfv;
-		  else
-		    retval.elem (result_idx) = elem (elt_idx);
-
-		  increment_index (result_idx, frozen_lengths);
-		}
 #endif
-	    }
-	}
-      // idx_vector::freeze() printed an error message for us.
-    }
-  else
-    (*current_liboctave_error_handler)
-      ("invalid number of dimensions for N-dimensional array index");
-
-  return retval;
-}
-
-#define MAYBE_RESIZE_ND_DIMS \
-  do \
-    { \
-      if (n_idx >= lhs_dims.length () && ! rhs_is_empty) \
-	{ \
-	  Array<int> max_idx (n_idx); \
-	  Array<int> new_idx (n_idx); \
- \
-	  for (int i = 0; i < n_idx; i++) \
-	    { \
-	      if (lhs_dims.length () == 0 || i >= lhs_dims.length ()) \
-		new_idx(i) = idx(i).max () + 1; \
-	      else \
-		{ \
-		  if (i < rhs_dims.length ()) \
-		    max_idx(i) = idx(i).is_colon () ? rhs_dims(i) : idx(i).max () + 1; \
-		  else \
-		    max_idx(i) = idx(i).max () + 1; \
- \
-		  new_idx(i) = max_idx(i) > lhs_dims(i) ? max_idx(i) : lhs_dims(i); \
-		} \
-            } \
- \
-	  lhs.resize (new_idx, rfv); \
-	  lhs_dims = lhs.dims ();  \
-        } \
-    } \
-  while (0)
-
-template <class LT, class RT>
-int
-assign (ArrayN<LT>& lhs, const ArrayN<RT>& rhs, const LT& rfv)
-{
-  int retval = 1;
-
-  int n_idx = lhs.index_count ();
-
-  Array<int> lhs_dims = lhs.dims ();
-  Array<int> rhs_dims = rhs.dims ();
-
-  idx_vector *tmp = lhs.get_idx ();
-
-  Array<idx_vector> idx = conv_to_array (tmp, n_idx);
-
-  // This needs to be defined before MAYBE_RESIZE_ND_DIMS.
-
-  bool rhs_is_empty = rhs_dims.length () == 0 ? true : any_zero_len (rhs_dims);
-
-  // Maybe expand to more dimensions.
-
-  MAYBE_RESIZE_ND_DIMS;
-
-  Array<int> idx_is_colon (n_idx, 0);
-  Array<int> idx_is_colon_equiv (n_idx, 0);
-
-  for (int i = 0; i < n_idx; i++)
-    {
-      idx_is_colon_equiv(i) = idx(i).is_colon_equiv (lhs_dims(i), 1);
-
-      idx_is_colon(i) = idx(i).is_colon ();
-    }
-
-  int resize_ok = 1;
-
-  Array<int> frozen_len;
-
-  if (n_idx == lhs_dims.length ())
-    frozen_len = freeze (idx, lhs_dims, resize_ok);
-
-  bool rhs_is_scalar = is_scalar (rhs_dims);
-
-  bool idx_is_empty = any_zero_len (frozen_len);
 
-  if (rhs_is_empty)
-    {
-      lhs.maybe_delete_elements (idx, rfv);
-    }
-  else if (rhs_is_scalar)
-    {
-      if (n_idx == 0)
-	(*current_liboctave_error_handler)
-	  ("number of indices is zero.");
-		
-      else if (n_idx < lhs_dims.length ())
-	{
-	  // Number of indices is less than dimensions.
-
-	  if (any_ones (idx_is_colon)|| any_ones (idx_is_colon_equiv))
-	    {
-	      (*current_liboctave_error_handler)
-		("number of indices is less than number of dimensions, one or more indices are colons.");
-	    }
-	  else
-	    {
-	      // Fewer indices than dimensions, no colons.
-
-	      bool resize = false;
-
-	      // Subtract one since the last idx do not tell us
-	      // anything about dimensionality.
-
-	      for (int i = 0; i < idx.length () - 1; i++)
-		{
-		  // Subtract one since idx counts from 0 while dims
-		  // count from 1.
-
-		  if (idx(i).elem (0) + 1 > lhs_dims(i))
-		    resize = true;
-		}
-
-	      if (resize)
-		{
-		  Array<int> new_dims (lhs_dims.length ());
-
-		  for (int i = 0; i < lhs_dims.length (); i++)
-		    {
-		      if (i < idx.length () - 1
-			  && idx(i).elem (0) + 1 > lhs_dims(i))
-			new_dims(i) = idx(i).elem (0)+1;
-		      else
-			new_dims(i) = lhs_dims(i);
-		    }
-
-		  lhs.resize (new_dims, rfv);
-
-		  lhs_dims = lhs.dims ();
-		}
-
-	      Array<int> one_arg_temp (1, 0);
-		
-	      RT scalar = rhs.elem (one_arg_temp);
-
-	      Array<int> int_arr = conv_to_int_array (idx);
-
-	      int numelem = get_scalar_idx (int_arr, lhs_dims);
-	
-	      if (numelem > lhs.length () || numelem < 0)
-		(*current_liboctave_error_handler)
-		  ("attempt to grow array along ambiguous dimension.");
-	      else
-		lhs.Array<LT>::checkelem (numelem) = scalar;
-	    }
-	}
-      else
-	{
-	  // Scalar to matrix assignment with as many indices as lhs
-	  // dimensions.
-
-	  int n = ArrayN<LT>::get_size (frozen_len);
-	
-	  Array<int> result_idx (lhs_dims.length (), 0);
-
-	  Array<int> elt_idx;
-	
-	  Array<int> one_arg_temp(1,0);		
-	  RT scalar = rhs.elem (one_arg_temp);
-	
-	  for (int i = 0; i < n; i++)
-	    {
-	      elt_idx = get_elt_idx (idx, result_idx);
-	
-	      Array<int> lhs_inc(lhs_dims.length());
-	
-	      for (int i = 0; i < lhs_dims.length (); i++)
-		lhs_inc(i) = lhs_dims(i) + 1;
-	
-	      if (index_in_bounds(elt_idx, lhs_inc))
-		lhs.checkelem (elt_idx) = scalar;
-	      else
-		lhs.checkelem (elt_idx) = rfv;
-
-	      increment_index (result_idx, frozen_len);
-	    }
-	}
-    }
-  else if (rhs_dims.length () >= 2)
-    {
-      // RHS is matrix or higher dimension.
-
-      // Subtracting number of dimensions of length 1 will catch
-      // cases where: A(2,1,2)=3  A(:,1,:)=[2,3;4,5]
-
-      if (rhs_dims.length () != num_ones(idx_is_colon_equiv) - num_ones(lhs_dims))
-	{
-	  (*current_liboctave_error_handler)
-	    ("dimensions do not match in matrix assignment.");
-	}
-      else
-	{
-	  bool dim_ok(true);
-
-	  int jj = 0;
-
-	  // Check that RHS dimensions are the same length as the
-	  // corresponding LHS dimensions.
-
-	  for (int j = 0; j < idx_is_colon.length (); j++)
-	    {
-	      if (idx_is_colon(j) || idx_is_colon_equiv(j))
-		{
-		  if (rhs_dims(jj) < lhs_dims(j))
-		    {
-		      dim_ok = false;
-
-		      break;
-		    }
-
-		  jj++;
-		}
-	    }
-
-	  if (! dim_ok)
-	    (*current_liboctave_error_handler)
-	      ("subscripted assignment dimension mismatch.");
-	  else
-	    {
-	      Array<int> new_dims (n_idx);
-	
-	      bool resize = false;
-	
-	      int ii = 0;
-
-	      // Update idx vectors.
-
-	      for (int i = 0; i < n_idx; i++)
-		{
-		  if (idx(i).is_colon ())
-		    {
-		      // Add appropriate idx_vector to idx(i) since
-		      // index with : contains no indexes.
-
-		      frozen_len(i) = lhs_dims(i) > rhs_dims(ii) ? lhs_dims(i) : rhs_dims(ii);
-		
-		      new_dims(i) = lhs_dims(i) > rhs_dims(ii) ? lhs_dims(i) : rhs_dims(ii);
-		
-		      ii++;
-		
-		      Range idxrange (1, frozen_len(i), 1);
-		
-		      idx_vector idxv (idxrange);
-		
-		      idx(i) = idxv;
-		    }
-		  else
-		    {
-		      new_dims(i) = lhs_dims(i) > idx(i).max () + 1 ? lhs_dims(i) : idx(i).max () + 1;
-		
-		      if (frozen_len(i) > 1)
-			ii++;
-		    }
-		  if (new_dims(i) != lhs_dims(i))
-		    resize = true;
-		}
-	
-	      // Resize LHS if dimensions have changed.
-
-	      if (resize)
-		{
-		  lhs.resize (new_dims, rfv);
-		
-		  lhs_dims = lhs.dims ();
-		}
-	
-	      // Number of elements which need to be set.
-
-	      int n = ArrayN<LT>::get_size (frozen_len);
-	
-	      Array<int> result_idx (lhs_dims.length (), 0);
-	      Array<int> elt_idx;
-	
-	      Array<int> result_rhs_idx (rhs_dims.length (), 0);
-	      Array<int> frozen_rhs (rhs_dims.length(), 0);
-	
-	      for (int i = 0; i < rhs_dims.length (); i++)
-		frozen_rhs(i) = rhs_dims(i);
-	
-	      Array<int> lhs_inc (lhs_dims.length ());
-	
-	      for (int i = 0; i < lhs_dims.length (); i++)
-		lhs_inc(i) = lhs_dims(i) + 1;
-	
-	      for (int i = 0; i < n; i++)
-		{
-		  elt_idx = get_elt_idx (idx, result_idx);
-		
-		  if (index_in_bounds (elt_idx, lhs_inc))
-		    {
-		      int s = compute_index (result_rhs_idx,rhs_dims);
-		
-		      lhs.checkelem (elt_idx) = rhs.Array<RT>::elem (s);
-		
-		      increment_index (result_rhs_idx, frozen_rhs);
-		    }
-		  else
-		    lhs.checkelem (elt_idx) = rfv;
-		
-		  increment_index (result_idx, frozen_len);
-		}
-	    }
-	}
-    }
-  else if (idx_is_empty)
-    {
-      // Assignment to matrix with at least one empty index.
-
-      if (! rhs_is_empty || ! rhs_is_scalar)
-	{
-	  (*current_liboctave_error_handler)
-	    ("A([], []) = X: X must be an empty matrix or a scalar");
-	
-	  retval = 0;
-	}
-    }
-  else if (lhs_dims.length () != rhs_dims.length ())
-    {
-      (*current_liboctave_error_handler)
-	("A(I) = X: X must be a scalar or a matrix with the same size as I");
-      retval = 0;
-    }
-
-  return retval;
-}
-
-static inline int
-get_scalar_idx (Array<int>& idx, Array<int>& dims)
-{
-  int retval (-1);
-
-  int n = idx.length ();
-
-  if (n > 0)
-    {
-      retval = idx(--n);
-
-      while (--n >= 0)
-	{      		
-	  retval *= dims (n);
-	
-	  retval += idx(n);
-	}
-    }
-  return retval;
-}
-
-static inline int
-num_ones (const Array<int> ra_idx)
-{
-  int retval (0);
-  for (int i = 0; i < ra_idx.length (); i++)
-    {
-      if (ra_idx (i) == 1)
-	retval++;
-    }
-  return retval;
-}
-
-static inline bool
-is_scalar (const Array<int>& dim)
-{
-  bool retval = true;
-
-  int n = dim.length ();
-
-  if (n == 0)
-    {
-      retval = false;
-    }
-  else
-    {
-      for (int i = 0; i < n; i ++)
-	{
-	  if (dim (i) != 1)
-	    {
-	      retval = false;
-	
-	      break;
-	    }
-	}
-    }
-  return retval;
-}
-
-static inline bool
-any_ones (const Array<int> arr)
-{
-  bool retval = false;
-
-  for (int i = 0; i < arr.length (); i++)
-    {
-      if (arr (i) == 1)
-	{
-	  retval = true;
-	
-	  break;
-	}
-    }
-  return retval;
-}
-
-static inline int
-compute_index (const Array<int>& ra_idx, const Array<int>& dims)
-{
-  int retval = -1;
-
-  int n = dims.length ();
-
-  if (n > 0 && n == ra_idx.length ())
-    {
-      retval = ra_idx(--n);
-
-      while (--n >= 0)
-	{
-	  retval *= dims(n);
-	
-	  retval += ra_idx(n);
-	}
-    }
-  else
-    (*current_liboctave_error_handler)
-      ("ArrayN<T>::compute_index: invalid ra_idxing operation");
-
-  return retval;
-}
-
-static inline Array<int>
-conv_to_int_array (const Array<idx_vector>& a)
-{
-  Array<int> retval (a.length ());
-
-  for (int i = 0; i < a.length (); i++)
-    retval (i) = a(i).elem (0);
-
-  return retval;
-}
-
-static inline Array<idx_vector>
-conv_to_array (const idx_vector *tmp, const int len)
-{
-  Array<idx_vector> retval (len);
-
-  for (int i = 0; i < len; i++)
-      retval (i) = tmp[i];
-
-  return retval;
-}
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/liboctave/ArrayN-inline.h	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/ArrayN-inline.h	Fri Sep 19 21:41:21 2003 +0000
@@ -21,8 +21,13 @@
 
 */
 
+#ifndef octave_ArrayN_inline_h
+#define octave_ArrayN_inline_h 1
+
+#include "idx-vector.h"
+
 static inline bool
-index_in_bounds (const Array<int>& ra_idx, const Array<int>& dimensions)
+index_in_bounds (const Array<int>& ra_idx, const dim_vector& dimensions)
 {
   bool retval = true;
 
@@ -46,7 +51,7 @@
 }
 
 static inline void
-increment_index (Array<int>& ra_idx, const Array<int>& dimensions,
+increment_index (Array<int>& ra_idx, const dim_vector& dimensions,
 		 int start_dimension = 0)
 {
   ra_idx(start_dimension)++;
@@ -65,6 +70,334 @@
     }
 }
 
+static inline int
+get_scalar_idx (Array<int>& idx, dim_vector& dims)
+{
+  int retval (-1);
+
+  int n = idx.length ();
+
+  if (n > 0)
+    {
+      retval = idx(--n);
+
+      while (--n >= 0)
+	{      		
+	  retval *= dims (n);
+	
+	  retval += idx(n);
+	}
+    }
+  return retval;
+}
+
+static inline int
+num_ones (const Array<int>& ra_idx)
+{
+  int retval (0);
+  for (int i = 0; i < ra_idx.length (); i++)
+    {
+      if (ra_idx (i) == 1)
+	retval++;
+    }
+  return retval;
+}
+
+static inline bool
+is_scalar (const dim_vector& dim)
+{
+  bool retval = true;
+
+  int n = dim.length ();
+
+  if (n == 0)
+    {
+      retval = false;
+    }
+  else
+    {
+      for (int i = 0; i < n; i ++)
+	{
+	  if (dim (i) != 1)
+	    {
+	      retval = false;
+	
+	      break;
+	    }
+	}
+    }
+  return retval;
+}
+
+static inline bool
+any_ones (const Array<int>& arr)
+{
+  bool retval = false;
+
+  for (int i = 0; i < arr.length (); i++)
+    {
+      if (arr (i) == 1)
+	{
+	  retval = true;
+	
+	  break;
+	}
+    }
+  return retval;
+}
+
+static inline int
+compute_index (const Array<int>& ra_idx, const dim_vector& dims)
+{
+  int retval = -1;
+
+  int n = dims.length ();
+
+  if (n > 0 && n == ra_idx.length ())
+    {
+      retval = ra_idx(--n);
+
+      while (--n >= 0)
+	{
+	  retval *= dims(n);
+	
+	  retval += ra_idx(n);
+	}
+    }
+  else
+    (*current_liboctave_error_handler)
+      ("ArrayN<T>::compute_index: invalid ra_idxing operation");
+
+  return retval;
+}
+
+static inline Array<int>
+conv_to_int_array (const Array<idx_vector>& a)
+{
+  Array<int> retval (a.length ());
+
+  for (int i = 0; i < a.length (); i++)
+    retval (i) = a(i).elem (0);
+
+  return retval;
+}
+
+static inline Array<idx_vector>
+conv_to_array (const idx_vector *tmp, const int len)
+{
+  Array<idx_vector> retval (len);
+
+  for (int i = 0; i < len; i++)
+      retval (i) = tmp[i];
+
+  return retval;
+}
+
+static inline dim_vector
+freeze (Array<idx_vector>& ra_idx, const dim_vector& dimensions, int resize_ok)
+{
+  dim_vector retval;
+
+  int n = ra_idx.length ();
+
+  assert (n == dimensions.length ());
+
+  retval.resize (n);
+
+  for (int i = 0; i < n; i++)
+    retval(i) = ra_idx(i).freeze (dimensions(i), "XXX FIXME XXX", resize_ok);
+
+  return retval;
+}
+
+static inline bool
+vector_equivalent (const Array<int>& ra_idx)
+{
+  int n = ra_idx.length ();
+
+  bool found_first = false;
+
+  for (int i = 0; i < n; i++)
+    {
+      if (ra_idx(i) != 1)
+        {
+	  if (! found_first)
+	    found_first = true;
+	  else
+	    return false;
+	}
+    }
+
+  return true;
+}
+
+static inline bool
+equal_arrays (const dim_vector& a, const dim_vector& b)
+{
+  bool retval = true;
+
+  if (a.length () != b.length ())
+    retval = false;
+  else
+    {
+      for (int i = 0; i < a.length (); i++)
+	{
+	  if (a(i) != b(i))
+	    retval = false;
+	}
+    }
+
+  return retval;
+}
+
+static inline bool
+all_ok (const Array<idx_vector>& ra_idx)
+{
+  bool retval = true;
+
+  int n = ra_idx.length ();
+
+  for (int i = 0; i < n; i++)
+    {
+      if (! ra_idx(i))
+	{
+	  retval = false;
+	  break;
+	}
+    }
+
+  return retval;
+}
+
+static inline bool
+any_orig_empty (const Array<idx_vector>& ra_idx)
+{
+  bool retval = false;
+
+  int n = ra_idx.length ();
+
+  for (int i = 0; i < n; i++)
+    {
+      if (ra_idx(i).orig_empty ())
+	{
+	  retval = true;
+	  break;
+	}
+    }
+
+  return retval;
+}
+
+static inline bool
+any_zero_len (const dim_vector& frozen_lengths)
+{
+  bool retval = false;
+
+  int n = frozen_lengths.length ();
+
+  for (int i = 0; i < n; i++)
+    {
+      if (frozen_lengths(i) == 0)
+	{
+	  retval = true;
+	  break;
+	}
+    }
+
+  return retval;
+}
+
+static inline dim_vector
+get_zero_len_size (const dim_vector& frozen_lengths,
+		   const dim_vector& dimensions)
+{
+  dim_vector retval;
+  assert (0);
+  return retval;
+}
+
+static inline bool
+all_colon_equiv (const Array<idx_vector>& ra_idx,
+		 const dim_vector& frozen_lengths)
+{
+  bool retval = true;
+
+  int idx_n = ra_idx.length ();
+
+  int n = frozen_lengths.length ();
+
+  assert (idx_n == n);
+
+  for (int i = 0; i < n; i++)
+    {
+      if (! ra_idx(i).is_colon_equiv (frozen_lengths(i)))
+	{
+	  retval = false;
+	  break;
+	}
+    }
+
+  return retval;
+}
+
+static inline bool
+is_in (int num, const idx_vector& idx)
+{
+  int n = idx.capacity ();
+
+  for (int i = 0; i < n; i++)
+    if (idx.elem (i) == num)
+      return true;
+
+  return false;
+}
+
+static inline int
+how_many_lgt (const int num, idx_vector& idxv)
+{
+  int retval = 0;
+
+  int n = idxv.capacity ();
+
+  for (int i = 0; i < n; i++)
+    if (num > idxv.elem (i))
+      retval++;
+
+  return retval;
+}
+
+static inline bool
+all_ones (const Array<int>& arr)
+{
+  bool retval = true;
+
+  for (int i = 0; i < arr.length (); i++)
+    {
+      if (arr(i) != 1)
+	{
+	  retval = false;
+	  break;
+	}
+    }
+
+  return retval;
+}
+
+static Array<int>
+get_elt_idx (const Array<idx_vector>& ra_idx, const Array<int>& result_idx)
+{
+  int n = ra_idx.length ();
+
+  Array<int> retval (n);
+
+  for (int i = 0; i < n; i++)
+    retval(i) = ra_idx(i).elem (result_idx(i));
+
+  return retval;
+}
+
+#endif
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/liboctave/ArrayN.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/ArrayN.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -35,313 +35,17 @@
 
 #include "ArrayN.h"
 #include "ArrayN-inline.h"
-
-#if defined (HEAVYWEIGHT_INDEXING)
+#include "ArrayN-idx.h"
 #include "idx-vector.h"
-#include "ArrayN-idx.h"
-#endif
-
 #include "lo-error.h"
 
 // N-dimensional array class.
 
 template <class T>
-int
-ArrayN<T>::compute_index (const Array<int>& ra_idx) const
-{
-  int retval = -1;
-
-  int n = dimensions.length ();
-
-  if (n > 0 && n == ra_idx.length ())
-    {
-      retval = ra_idx(--n);
-
-      while (--n >= 0)
-	{
-	  retval *= dimensions(n);
-	  retval += ra_idx(n);
-	}
-    }
-  else
-    (*current_liboctave_error_handler)
-      ("ArrayN<T>::compute_index: invalid ra_idxing operation");
-
-  return retval;
-}
-
-// A guess (should be quite conservative).
-#define MALLOC_OVERHEAD 1024
-
-template <class T>
-int
-ArrayN<T>::get_size (const Array<int>& ra_idx)
-{
-  // XXX KLUGE XXX
-
-  // If an allocation of an array with r * c elements of type T
-  // would cause an overflow in the allocator when computing the
-  // size of the allocation, then return a value which, although
-  // not equivalent to the actual request, should be too large for
-  // most current hardware, but not so large to cause the
-  // allocator to barf on computing retval * sizeof (T).
-
-  static int nl;
-  static double dl
-    = frexp (static_cast<double>
-	     (INT_MAX - MALLOC_OVERHEAD) / sizeof (T), &nl);
-
-  // This value should be an integer.  If we return this value and
-  // things work the way we expect, we should be paying a visit to
-  // new_handler in no time flat.
-
-  static int max_items = static_cast<int> (ldexp (dl, nl));
-
-  int retval = max_items;
-
-  int n = ra_idx.length ();
-
-  int nt = 0;
-  double dt = 1;
-
-  for (int i = 0; i < n; i++)
-    {
-      int nra_idx;
-      double dra_idx = frexp (static_cast<double> (ra_idx(i)), &nra_idx);
-
-      nt += nra_idx;
-      dt *= dra_idx;
-    }
-
-  if (dt <= 0.5)
-    {
-      nt--;
-      dt *= 2;
-
-      if (dt <= 0.5)
-	nt--;
-    }
-
-  if (nt < nl || (nt == nl && dt < dl))
-    {
-      retval = 1;
-
-      for (int i = 0; i < n; i++)
-	retval *= ra_idx(i);
-    }
-
-  return retval;
-}
-
-#undef MALLOC_OVERHEAD
-
-template <class T>
-T
-ArrayN<T>::range_error (const char *fcn, const Array<int>& ra_idx) const
-{
-  // XXX FIXME XXX -- report index values too!
-
-  (*current_liboctave_error_handler) ("range error in ArrayN");
-
-  return T ();
-}
-
-template <class T>
-T&
-ArrayN<T>::range_error (const char *fcn, const Array<int>& ra_idx)
-{
-  // XXX FIXME XXX -- report index values too!
-
-  (*current_liboctave_error_handler) ("range error in ArrayN");
-
-  static T foo;
-  return foo;
-}
-
-template <class T>
-void
-ArrayN<T>::resize (const Array<int>& dims)
-{
-  int n = dims.length ();
-
-  for (int i = 0; i < n; i++)
-    {
-      if (dims(i) < 0)
-	{
-	  (*current_liboctave_error_handler)
-	    ("can't resize to negative dimension");
-	  return;
-	}
-    }
-
-  bool no_change = true;
-
-  for (int i = 0; i < n; i++)
-    {
-      if (dims(i) != dimensions(i))
-	{
-	  no_change = false;
-	  break;
-	}
-    }
-
-  if (no_change)
-    return;
-
-  int old_len = length ();
-
-  typename Array<T>::ArrayRep *old_rep = Array<T>::rep;
-  const T *old_data = data ();
-
-  Array<T>::rep = new typename Array<T>::ArrayRep (get_size (dims));
-
-  Array<int> old_dimensions = dimensions;
-
-  dimensions = dims;
-
-  Array<int> ra_idx (dimensions.length (), 0);
-
-  for (int i = 0; i < old_len; i++)
-    {
-      if (index_in_bounds (ra_idx, dimensions))
-	xelem (ra_idx) = old_data[i];
-
-      increment_index (ra_idx, dimensions);
-    }
-
-  if (--old_rep->count <= 0)
-    delete old_rep;
-}
-
-template <class T>
-void
-ArrayN<T>::resize (const Array<int>& dims, const T& val)
-{
-  int n = dims.length ();
-
-  for (int i = 0; i < n; i++)
-    {
-      if (dims(i) < 0)
-	{
-	  (*current_liboctave_error_handler)
-	    ("can't resize to negative dimension");
-	  return;
-	}
-    }
-
-  bool no_change = true;
-
-  for (int i = 0; i < n; i++)
-    {
-      if (dims(i) != dimensions(i))
-	{
-	  no_change = false;
-	  break;
-	}
-    }
-
-  if (no_change)
-    return;
-
-  typename Array<T>::ArrayRep *old_rep = Array<T>::rep;
-  const T *old_data = data ();
-
-  int old_len = length ();
-
-  int len = get_size (dims);
-
-  Array<T>::rep = new typename Array<T>::ArrayRep (len);
-
-  Array<int> old_dimensions = dimensions;
-
-  dimensions = dims;
-
-  Array<int> ra_idx (dimensions.length (), 0);
-
-  for (int i = 0; i < len; i++)
-    Array<T>::rep->elem (i) = val;
-
-  for (int i = 0; i < old_len; i++)
-    {
-      if (index_in_bounds (ra_idx, dimensions))
-	xelem (ra_idx) = old_data[i];
-
-      increment_index (ra_idx, dimensions);
-    }
-
-  if (--old_rep->count <= 0)
-    delete old_rep;
-}
-
-template <class T>
-ArrayN<T>&
-ArrayN<T>::insert (const ArrayN<T>& a, const Array<int>& ra_idx)
-{
-  int n = ra_idx.length ();
-
-  if (n == dimensions.length ())
-    {
-      Array<int> a_dims = a.dims ();
-
-      for (int i = 0; i < n; i++)
-	{
-	  if (ra_idx(i) < 0 || ra_idx(i) + a_dims(i) > dimensions(i))
-	    {
-	      (*current_liboctave_error_handler)
-		("ArrayN<T>::insert: range error for insert");
-	      return *this;
-	    }
-	}
-
-#if 0
-      // XXX FIXME XXX -- need to copy elements
-
-      for (int j = 0; j < a_cols; j++)
-	for (int i = 0; i < a_rows; i++)
-	  elem (r+i, c+j) = a.elem (i, j);
-#endif
-
-    }
-  else
-    (*current_liboctave_error_handler)
-      ("ArrayN<T>::insert: invalid indexing operation");
-
-  return *this;
-}
-
-template <class T>
-void
-ArrayN<T>::maybe_delete_dims (void)
-{
-  int ndims = dimensions.length ();
-  Array<int> new_dims (1,1);
-  bool delete_dims = true;
-
-  for (int i = ndims - 1; i >= 0; i--)
-    {
-      if (delete_dims)
-        {
-          if (dimensions(i) != 1)
-	    {
-	      delete_dims = false;
-	      new_dims = Array<int> (i + 1, dimensions(i));
-	    }
-        }
-      else
-        {
-	  new_dims(i) = dimensions(i);
-	}
-    }
-    
-  if (ndims != new_dims.length ())
-    dimensions = new_dims;
-}
-
-template <class T>
 std::ostream&
 operator << (std::ostream& os, const ArrayN<T>& a)
 {
-  Array<int> a_dims = a.dimensions;
+  dim_vector a_dims = a.dims ();
 
   int n_dims = a_dims.length ();
 
@@ -363,7 +67,7 @@
     {
       os << "data:";
 
-      Array<int> ra_idx (n_dims,0);
+      Array<int> ra_idx (n_dims, 0);
 
       // Number of times the first 2d-array is to be displayed.
 
--- a/liboctave/ArrayN.h	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/ArrayN.h	Fri Sep 19 21:41:21 2003 +0000
@@ -36,7 +36,7 @@
 #include <cstdlib>
 
 #include "Array.h"
-#include "dMatrix.h"
+#include "Array2.h"
 #include "lo-error.h"
 
 class idx_vector;
@@ -49,175 +49,74 @@
 {
 protected:
 
+  static int get_size (const dim_vector& dims)
+    { return Array<T>::get_size (dims); }
 
-  ArrayN (T *d, const Array<int>& dims) : Array<T> (d, get_size (dims))
-    {
-      dimensions = dims;
-      set_max_indices (dimensions.length ());
-    }
+  ArrayN (T *d, const dim_vector& dims) : Array<T> (d, dims) { }
 
 public:
 
-  static int get_size (const Array<int>& dims);
-
   // These really need to be protected (and they will be in the
   // future, so don't depend on them being here!), but they can't be
   // until template friends work correctly in g++.
 
-  Array<int> dimensions;
-
   ArrayN (void) : Array<T> () { }
 
-  ArrayN (const Array<int>& dims) : Array<T> (get_size (dims))
-    {
-      dimensions = dims;
-      set_max_indices (dimensions.length ());
-    }
+  ArrayN (const dim_vector& dims) : Array<T> (dims) { }
 
-  ArrayN (const Array<int>& dims, const T& val)
-    : Array<T> (get_size (dims), val)
-    {
-      dimensions = dims;
-      set_max_indices (dimensions.length ());
-    }
-
-  ArrayN (const ArrayN<T>& a) : Array<T> (a)
-    {
-      dimensions = a.dimensions;
-      set_max_indices (dimensions.length ());
-    }
+  ArrayN (const dim_vector& dims, const T& val)
+    : Array<T> (dims) { fill (val); }
 
-  ArrayN (const Array<T>& a, const Array<int>& dims) : Array<T> (a)
-    {
-      dimensions = dims;
-      set_max_indices (dimensions.length ());
-    }
-
-  // New constructor which takes a Matrix as an argument.  This should
-  // be moved to a subclass of ArrayN (NDArray) once we add a double
-  // instantiation of ArrayN.
+  ArrayN (const Array2<T>& a) : Array<T> (a, a.dims ()) { }
 
-  ArrayN (const Matrix& m) : Array<T> (m)
-    {
-      set_max_indices (2);
-
-      Array<int> dim (2);
+  ArrayN (const ArrayN<T>& a) : Array<T> (a, a.dims ()) { }
 
-      dim(0) = m.dim1 ();
-      dim(1) = m.dim2 ();
-
-      dimensions = dim;
-    }
+  ArrayN (const Array<T>& a, const dim_vector& dims) : Array<T> (a, dims) { }
 
   ~ArrayN (void) { }
 
   ArrayN<T>& operator = (const ArrayN<T>& a)
     {
-      if (this != &a && Array<T>::rep != a.rep)
-	{
-	  Array<T>::operator = (a);
-	  dimensions = a.dimensions;
-	}
+      if (this != &a)
+	Array<T>::operator = (a);
 
       return *this;
     }
 
-  int compute_index (const Array<int>& ra_idx) const;
-
-  Array<int> dims (void) const { return dimensions; }
-
-  T range_error (const char *fcn, const Array<int>& ra_idx) const;
-  T& range_error (const char *fcn, const Array<int>& ra_idx);
-
-  // No checking of any kind, ever.
-
-  T& xelem (const Array<int>& ra_idx)
-    { return Array<T>::xelem (compute_index (ra_idx)); }
-
-  T xelem (const Array<int>& ra_idx) const
-    { return Array<T>::xelem (compute_index (ra_idx)); }
+  void resize (const dim_vector& dims)
+    { Array<T>resize_no_fill (dims); }
 
-  // Note that the following element selection methods don't use
-  // xelem() because they need to make use of the code in
-  // Array<T>::elem() that checks the reference count.
-
-  T& checkelem (const Array<int>& ra_idx)
-    {
-      int i = compute_index (ra_idx);
+  void resize (const dim_vector& dims, const T& val)
+    { Array<T>::resize (dims, val); }
 
-      if (i < 0)
-	return range_error ("ArrayN<T>::checkelem", ra_idx);
-      else
-	return Array<T>::elem (i);
-    }
-
-  T& elem (const Array<int>& ra_idx)
+  ArrayN<T>& insert (const ArrayN<T>& a, const dim_vector& dims)
     {
-      int i = compute_index (ra_idx);
-
-      return Array<T>::elem (i);
+      Array<T>::insert (a, dims);
+      return *this;
     }
 
-#if defined (BOUNDS_CHECKING)
-  T& operator () (const Array<int>& ra_idx) { return checkelem (ra_idx); }
-#else
-  T& operator () (const Array<int>& ra_idx) { return elem (ra_idx); }
-#endif
-
-  T checkelem (const Array<int>& ra_idx) const
+  ArrayN<T> index (idx_vector& i, int resize_ok = 0,
+		   const T& rfv = resize_fill_value (T ())) const
     {
-      int i = compute_index (ra_idx);
-
-      if (i < 0)
-	return range_error ("ArrayN<T>::checkelem", ra_idx);
-      else
-	return Array<T>::elem (i);
-    }
-
-  T elem (const Array<int>& ra_idx) const
-    {
-      int i = compute_index (ra_idx);
-
-      return Array<T>::elem (i);
+      Array<T> tmp = Array<T>::index (i, resize_ok, rfv);
+      return ArrayN<T> (tmp, tmp.dims ());
     }
 
-#if defined (BOUNDS_CHECKING)
-  T operator () (const Array<int>& ra_idx) const { return checkelem (ra_idx); }
-#else
-  T operator () (const Array<int>& ra_idx) const { return elem (ra_idx); }
-#endif
-
-  void resize (const Array<int>& dims);
-  void resize (const Array<int>& dims, const T& val);
-
-  ArrayN<T>& insert (const ArrayN<T>& a, const Array<int>& dims);
-
-#ifdef HEAVYWEIGHT_INDEXING
-  void maybe_delete_elements (Array<idx_vector>& ra_idx, const T& rfv);
-
-  ArrayN<T> value (void);
-
-  ArrayN<T> index (idx_vector& ra_idx, int resize_ok = 0,
-		   const T& rfv = resize_fill_value (T ())) const;
+  ArrayN<T> index (idx_vector& i, idx_vector& j, int resize_ok = 0,
+		   const T& rfv = resize_fill_value (T ())) const
+    {
+      Array<T> tmp = Array<T>::index (i, j, resize_ok, rfv);
+      return ArrayN<T> (tmp, tmp.dims ());
+    }
 
   ArrayN<T> index (Array<idx_vector>& ra_idx, int resize_ok = 0,
-		   const T& rfv = resize_fill_value (T ())) const;
-  
-  void maybe_delete_dims (void);
-#endif
+		   const T& rfv = resize_fill_value (T ())) const
+    {
+      Array<T> tmp = Array<T>::index (ra_idx, resize_ok, rfv);
+      return ArrayN<T> (tmp, tmp.dims ());
+    }
 };
 
-template <class LT, class RT>
-int
-assign (ArrayN<LT>& lhs, const ArrayN<RT>& rhs, const LT& rfv);
-
-template <class LT, class RT>
-int
-assign (ArrayN<LT>& lhs, const ArrayN<RT>& rhs)
-{
-  return assign (lhs, rhs, resize_fill_value (LT ()));
-}
-
 template <class T>
 std::ostream&
 operator << (std::ostream&, const ArrayN<T>&);
--- a/liboctave/CDiagMatrix.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/CDiagMatrix.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -545,7 +545,8 @@
 	}
     }
   else
-    std::cerr << "diag: requested diagonal out of range\n";
+    (*current_liboctave_error_handler)
+      ("diag: requested diagonal out of range");
 
   return d;
 }
--- a/liboctave/CMatrix.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/CMatrix.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -2691,7 +2691,8 @@
 	}
     }
   else
-    std::cerr << "diag: requested diagonal out of range\n";
+    (*current_liboctave_error_handler)
+      ("diag: requested diagonal out of range");
 
   return d;
 }
--- a/liboctave/ChangeLog	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/ChangeLog	Fri Sep 19 21:41:21 2003 +0000
@@ -1,3 +1,45 @@
+2003-09-19  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* Array.h, Array-idx.h, Array.cc: Fold all N-d functionality here.
+	Turn inheritance hierarchy upside down (2-d and 3-d arrays are now
+	just special cases of the general purpose N-d Array object).
+
+	* dim-vector.h: New file.  Use dim_vector objects instead of
+	ints or Array<int> objects to represent the size of Array
+	objects.
+
+	* MArray-defs.h (INSTANTIATE_MARRAYN_FRIENDS): New macro.
+
+	* Array2-idx.h, Array3-idx.h, Array2.cc, Array3.cc: Delete.
+
+	* mx-base.h: Include NDArray header files.
+
+	* MArray-C.cc, MArray-d.cc: Also instantiate ArrayN objects.
+
+	* Array-C.cc, Array-b.cc, Array-ch.cc, Array-d.cc, Array-i.cc,
+	Array-s.cc: Also instantiate ArrayN objects.
+	Don't instantiate assign funcitons for Array2 objects.
+
+	* CDiagMatrix.cc (ComplexDiagMatrix::diag): Signal error with
+	liboctave_error_handler, not cerr.
+	* CMatrix.cc (ComplexMatrix::diag): Likewise.
+	* dDiagMatrix.cc (DiagMatrix::diag): Likewise.
+	* dMatrix.cc (Matrix::diag): Likewise.
+
+	* Array-flags.cc, Array.cc, Array.h, Array2.h, Array3.h, ArrayN.h:
+	Omit checks for HEAVYWEIGHT_INDEXING.
+
+2003-09-12  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* mx-base.h: Include CNDarray.h.  Include dNDArray.h, not NDArray.h.
+
+	* CNDARray.h, CNDArray.cc: New files.
+	* Makefile.in: Add them to the appropriate lists.
+
+	* dNDArray.h: Rename from NDArray.h.
+	* dNDArray.cc: Rename from NDArray.cc.
+	* Makefile.in: Rename them here too.
+
 2003-09-10  Petter Risholm  <risholm@stud.ntnu.no>
 
 	* mx-base.h: Include NDArray.h, not ArrayN.h.
--- a/liboctave/DiagArray2.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/DiagArray2.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -53,7 +53,7 @@
 DiagArray2<T>::checkelem (int r, int c)
 {
   static T foo (0);
-  if (r < 0 || c < 0 || r >= nr || c >= nc)
+  if (r < 0 || c < 0 || r >= dim1 () || c >= dim2 ())
     {
       (*current_liboctave_error_handler) ("range error in DiagArray2");
       return foo;
@@ -66,7 +66,7 @@
 DiagArray2<T>::operator () (int r, int c)
 {
   static T foo (0);
-  if (r < 0 || c < 0 || r >= nr || c >= nc)
+  if (r < 0 || c < 0 || r >= dim1 () || c >= dim2 ())
     {
       (*current_liboctave_error_handler) ("range error in DiagArray2");
       return foo;
@@ -86,7 +86,7 @@
 T
 DiagArray2<T>::checkelem (int r, int c) const
 {
-  if (r < 0 || c < 0 || r >= nr || c >= nc)
+  if (r < 0 || c < 0 || r >= dim1 () || c >= dim2 ())
     {
       (*current_liboctave_error_handler) ("range error in DiagArray2");
       return T ();
@@ -98,7 +98,7 @@
 T
 DiagArray2<T>::operator () (int r, int c) const
 {
-  if (r < 0 || c < 0 || r >= nr || c >= nc)
+  if (r < 0 || c < 0 || r >= dim1 () || c >= dim2 ())
     {
       (*current_liboctave_error_handler) ("range error in DiagArray2");
       return T ();
@@ -142,8 +142,7 @@
 
   Array<T>::rep = new typename Array<T>::ArrayRep (new_len);
 
-  nr = r;
-  nc = c;
+  dimensions = dim_vector (r, c);
 
   if (old_data && old_len > 0)
     {
@@ -178,8 +177,7 @@
 
   Array<T>::rep = new typename Array<T>::ArrayRep (new_len);
 
-  nr = r;
-  nc = c;
+  dimensions = dim_vector (r, c);
 
   int min_len = old_len < new_len ? old_len : new_len;
 
--- a/liboctave/DiagArray2.h	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/DiagArray2.h	Fri Sep 19 21:41:21 2003 +0000
@@ -110,51 +110,28 @@
 
 protected:
 
-  int nr;
-  int nc;
-
   DiagArray2 (T *d, int r, int c) : Array<T> (d, r < c ? r : c)
-    {
-      nr = r;
-      nc = c;
-      set_max_indices (2);
-    }
+    { dimensions = dim_vector (r, c); }
 
 public:
 
-  DiagArray2 (void) : Array<T> ()
-    {
-      nr = 0;
-      nc = 0;
-      set_max_indices (2);
-    }
+  DiagArray2 (void) : Array<T> (dim_vector (0, 0)) { }
 
   DiagArray2 (int r, int c) : Array<T> (r < c ? r : c)
-    {
-      nr = r;
-      nc = c;
-      set_max_indices (2);
-    }
+    { dimensions = dim_vector (r, c); }
 
-  DiagArray2 (int r, int c, const T& val) : Array<T> (r < c ? r : c, val)
+  DiagArray2 (int r, int c, const T& val) : Array<T> (r < c ? r : c)
     {
-      nr = r;
-      nc = c;
-      set_max_indices (2);
+      dimensions = dim_vector (r, c);
+
+      fill (val);
     }
 
   DiagArray2 (const Array<T>& a) : Array<T> (a)
-    {
-      nr = nc = a.length ();
-      set_max_indices (2);
-    }
+    { dimensions = dim_vector (a.length (), a.length ()); }
 
   DiagArray2 (const DiagArray2<T>& a) : Array<T> (a)
-    {
-      nr = a.nr;
-      nc = a.nc;
-      set_max_indices (2);
-    }
+    { dimensions = a.dims (); }
 
   ~DiagArray2 (void) { }
 
@@ -163,8 +140,7 @@
       if (this != &a)
 	{
 	  Array<T>::operator = (a);
-	  nr = a.nr;
-	  nc = a.nc;
+	  dimensions = a.dims ();
 	}
 
       return *this;
@@ -173,6 +149,9 @@
 #if 0
   operator Array2<T> () const
     {
+      int nr = dim1 ();
+      int nc = dim2 ();
+
       Array2<T> retval (nr, nc,  T (0));
 
       int len = nr < nc ? nr : nc;
@@ -184,13 +163,6 @@
     }
 #endif
 
-  int dim1 (void) const { return nr; }
-  int dim2 (void) const { return nc; }
-
-  int rows (void) const { return nr; }
-  int cols (void) const { return nc; }
-  int columns (void) const { return nc; }
-
 #if 1
   Proxy elem (int r, int c)
     {
@@ -199,7 +171,7 @@
 
   Proxy checkelem (int r, int c)
     {
-      if (r < 0 || c < 0 || r >= nr || c >= nc)
+      if (r < 0 || c < 0 || r >= dim1 () || c >= dim2 ())
 	{
 	  (*current_liboctave_error_handler) ("range error in DiagArray2");
 	  return Proxy (0, r, c);
@@ -210,7 +182,7 @@
 
   Proxy operator () (int r, int c)
     {
-      if (r < 0 || c < 0 || r >= nr || c >= nc)
+      if (r < 0 || c < 0 || r >= dim1 () || c >= dim2 ())
 	{
 	  (*current_liboctave_error_handler) ("range error in DiagArray2");
 	  return Proxy (0, r, c);
--- a/liboctave/MArray-C.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/MArray-C.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -42,6 +42,13 @@
 
 INSTANTIATE_MARRAY2_FRIENDS (Complex)
 
+#include "MArrayN.h"
+#include "MArrayN.cc"
+
+template class MArrayN<Complex>;
+
+INSTANTIATE_MARRAYN_FRIENDS (Complex)
+
 #include "MDiagArray2.h"
 #include "MDiagArray2.cc"
 
--- a/liboctave/MArray-d.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/MArray-d.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -40,6 +40,13 @@
 
 INSTANTIATE_MARRAY2_FRIENDS (double)
 
+#include "MArrayN.h"
+#include "MArrayN.cc"
+
+template class MArrayN<double>;
+
+INSTANTIATE_MARRAYN_FRIENDS (double)
+
 #include "MDiagArray2.h"
 #include "MDiagArray2.cc"
 
--- a/liboctave/MArray-defs.h	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/MArray-defs.h	Fri Sep 19 21:41:21 2003 +0000
@@ -262,14 +262,21 @@
   MARRAY_UNOP_DEFS (MArray, T) \
   MARRAY_BINOP_DEFS (MArray, T)
 
-// Instantiate all the MArray friends for MArray element type T.
+// Instantiate all the MArray2 friends for MArray2 element type T.
 #define INSTANTIATE_MARRAY2_FRIENDS(T) \
   MARRAY_OP_ASSIGN_DEFS (MArray2, T, T) \
   MARRAY_OP_ASSIGN_DEFS (MArray2, T, MArray2<T>) \
   MARRAY_UNOP_DEFS (MArray2, T) \
   MARRAY_BINOP_DEFS (MArray2, T)
 
-// Instantiate all the MArray friends for MArray element type T.
+// 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)  */
+
+// Instantiate all the MDiagArray2 friends for MDiagArray2 element type T.
 #define INSTANTIATE_MDIAGARRAY2_FRIENDS(T) \
   MARRAY_OP_ASSIGN_DEFS (MDiagArray2, T, MDiagArray2<T>) \
   MARRAY_UNOP_DEFS (MDiagArray2, T) \
--- a/liboctave/MArrayN.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/MArrayN.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -34,12 +34,10 @@
 
 #include "MArray-defs.h"
 
-// Two dimensional array with math ops.
+// N-dimensional array with math ops.
 
 // Element by element MArrayN by scalar ops.
 
-
-#if 0
 template <class T>
 MArrayN<T>&
 operator += (MArrayN<T>& a, const T& s)
@@ -56,7 +54,7 @@
   return a;
 }
 
-
+#if 0
 #define MARRAYN_NDS_OP(OP) \
   template <class T> \
   MArrayN<T> \
@@ -100,8 +98,8 @@
 MArrayN<T> \
 FCN (const MArrayN<T>& a, const MArrayN<T>& b) \
 { \
-Array<int> a_dims = a.dims (); \
-Array<int> b_dims = b.dims (); \
+dim_vector a_dims = a.dims (); \
+dim_vector b_dims = b.dims (); \
 int dims_ok = 1; \
 int any_dims_zero = 0; \
 if (a_dims.length () != b_dims.length ()) \
--- a/liboctave/MArrayN.h	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/MArrayN.h	Fri Sep 19 21:41:21 2003 +0000
@@ -29,43 +29,39 @@
 #define octave_MArrayN_h 1
 
 #include "ArrayN.h"
-// Two dimensional array with math ops.
+#include "MArray2.h"
+#include "dim-vector.h"
+
+// N-dimensional array with math ops.
 
 // But first, some preprocessor abuse...
 
 #include "MArray-defs.h"
 
-class Matrix;
-
 MARRAY_OPS_FORWARD_DECLS (MArrayN)
 
 template <class T>
 class
 MArrayN : public ArrayN<T>
 {
- protected:
+protected:
 
-  MArrayN (T *d, const Array<int>& dims) : ArrayN<T> (d, dims)
-    { }
+  MArrayN (T *d, const dim_vector& dims) : ArrayN<T> (d, dims) { }
 
- public:
+public:
   
   MArrayN (void) : ArrayN<T> () {}
   
-  MArrayN (const Array<int>& dims) : ArrayN<T> (dims)
-    { }
+  MArrayN (const dim_vector& dims) : ArrayN<T> (dims) { }
   
-  MArrayN (const Array<int>& dims, const T& val) 
-    : ArrayN<T> (dims, val) { }
+  MArrayN (const dim_vector& dims, const T& val) : ArrayN<T> (dims, val) { }
+
+  MArrayN (const Array2<T>& a) : ArrayN<T> (a) { }
 
   MArrayN (const ArrayN<T>& a) : ArrayN<T> (a) { }
 
-  //MArrayN (const Array<T>& a) : ArrayN<T> (a) { }
-
   MArrayN (const MArrayN<T>& a) : ArrayN<T> (a) { }
 
-  MArrayN (const Matrix& m) : ArrayN<T> (m) { }
-
   ~MArrayN (void) { }
 
   MArrayN<T>& operator = (const MArrayN<T>& a)
@@ -73,10 +69,15 @@
       ArrayN<T>::operator = (a);
       return *this;
     }
-
 };
 
 extern void
-gripe_nonconformant (const char *op, Array<int>& op1_dims, Array<int>& op2_dims);
+gripe_nonconformant (const char *op, dim_vector& op1_dims, dim_vector& op2_dims);
 
 #endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
--- a/liboctave/MDiagArray2.h	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/MDiagArray2.h	Fri Sep 19 21:41:21 2003 +0000
@@ -71,9 +71,12 @@
 
   operator MArray2<T> () const
     {
-      MArray2<T> retval (DiagArray2<T>::nr, DiagArray2<T>::nc,  T (0));
+      int nr = DiagArray2<T>::dim1 ();
+      int nc = DiagArray2<T>::dim2 ();
 
-      int len = DiagArray2<T>::nr < DiagArray2<T>::nc ? DiagArray2<T>::nr : DiagArray2<T>::nc;
+      MArray2<T> retval (nr, nc,  T (0));
+
+      int len = nr < nc ? nr : nc;
 
       for (int i = 0; i < len; i++)
 	retval.xelem (i, i) = xelem (i, i);
--- a/liboctave/Makefile.in	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/Makefile.in	Fri Sep 19 21:41:21 2003 +0000
@@ -26,15 +26,17 @@
 endif
 
 MATRIX_INC := Array.h Array2.h Array3.h ArrayN.h DiagArray2.h \
-	Array-flags.h Array-idx.h Array2-idx.h Array3-idx.h \
+	Array-flags.h Array-idx.h \
 	ArrayN-idx.h ArrayN-inlines.h MArray-defs.h MArray.h \
-	MArray2.h MDiagArray2.h Matrix.h MArrayN.h NDArray.h \
-	base-lu.h mx-base.h mx-op-defs.h mx-ops.h mx-defs.h mx-ext.h \
-	CColVector.h CDiagMatrix.h CMatrix.h CRowVector.h CmplxAEPBAL.h \
-	CmplxCHOL.h CmplxDET.h CmplxHESS.h CmplxLU.h CmplxQR.h \
-	CmplxQRP.h CmplxSCHUR.h CmplxSVD.h EIG.h boolMatrix.h chMatrix.h \
-	dColVector.h dDiagMatrix.h dMatrix.h dRowVector.h dbleAEPBAL.h \
-	dbleCHOL.h dbleDET.h dbleHESS.h dbleLU.h dbleQR.h \
+	MArray2.h MDiagArray2.h Matrix.h MArrayN.h base-lu.h \
+	dim-vector.h mx-base.h mx-op-defs.h mx-ops.h mx-defs.h \
+	mx-ext.h CColVector.h CDiagMatrix.h CMatrix.h CNDArray.h \
+	CRowVector.h CmplxAEPBAL.h CmplxCHOL.h CmplxDET.h \
+	CmplxHESS.h CmplxLU.h CmplxQR.h CmplxQRP.h CmplxSCHUR.h \
+	CmplxSVD.h EIG.h boolMatrix.h boolNDArray.h chMatrix.h \
+	chNDArray.h dColVector.h \
+	dDiagMatrix.h dMatrix.h dNDArray.h dRowVector.h \
+	dbleAEPBAL.h dbleCHOL.h dbleDET.h dbleHESS.h dbleLU.h dbleQR.h \
 	dbleQRP.h dbleSCHUR.h dbleSVD.h
 
 MX_OP_INC := mx-cdm-cm.h mx-cdm-cs.h mx-cdm-dm.h mx-cdm-m.h \
@@ -72,7 +74,7 @@
 	$(MX_OP_INC) \
 	$(VX_OP_INC)
 
-TEMPLATE_SRC := Array.cc Array2.cc Array3.cc ArrayN.cc DiagArray2.cc \
+TEMPLATE_SRC := Array.cc ArrayN.cc DiagArray2.cc \
 	MArray.cc MArray2.cc MDiagArray2.cc base-lu.cc
 
 TI_SRC := Array-C.cc Array-b.cc Array-ch.cc Array-i.cc Array-d.cc \
@@ -80,12 +82,13 @@
 	MArray-C.cc MArray-ch.cc MArray-i.cc MArray-d.cc MArray-s.cc
 
 MATRIX_SRC := Array-flags.cc CColVector.cc CDiagMatrix.cc CMatrix.cc \
-	CRowVector.cc CmplxAEPBAL.cc CmplxCHOL.cc CmplxDET.cc \
-	CmplxHESS.cc CmplxLU.cc CmplxQR.cc CmplxQRP.cc CmplxSCHUR.cc \
-	CmplxSVD.cc EIG.cc MArray-misc.cc MArrayN.cc NDArray.cc \
-	boolMatrix.cc chMatrix.cc \
-	dColVector.cc dDiagMatrix.cc dMatrix.cc dRowVector.cc \
-	dbleAEPBAL.cc dbleCHOL.cc dbleDET.cc dbleHESS.cc dbleLU.cc \
+	CNDArray.cc CRowVector.cc CmplxAEPBAL.cc CmplxCHOL.cc \
+	CmplxDET.cc CmplxHESS.cc CmplxLU.cc CmplxQR.cc CmplxQRP.cc \
+	CmplxSCHUR.cc CmplxSVD.cc EIG.cc MArray-misc.cc MArrayN.cc \
+	boolMatrix.cc boolNDArray.cc chMatrix.cc chNDArray.cc \
+	dColVector.cc dDiagMatrix.cc \
+	dMatrix.cc dNDArray.cc dRowVector.cc dbleAEPBAL.cc \
+	dbleCHOL.cc dbleDET.cc dbleHESS.cc dbleLU.cc \
 	dbleQR.cc dbleQRP.cc dbleSCHUR.cc dbleSVD.cc
 
 MX_OP_SRC := mx-cdm-cm.cc mx-cdm-cs.cc mx-cdm-dm.cc mx-cdm-m.cc \
--- a/liboctave/dDiagMatrix.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/dDiagMatrix.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -391,7 +391,8 @@
 	}
     }
   else
-    std::cerr << "diag: requested diagonal out of range\n";
+    (*current_liboctave_error_handler)
+      ("diag: requested diagonal out of range");
 
   return d;
 }
--- a/liboctave/dMatrix.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/dMatrix.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -2208,7 +2208,8 @@
 	}
     }
   else
-    std::cerr << "diag: requested diagonal out of range\n";
+    (*current_liboctave_error_handler)
+      ("diag: requested diagonal out of range");
 
   return d;
 }
--- a/liboctave/dNDArray.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/dNDArray.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -1,4 +1,4 @@
-//N-D Array  manipulations.
+// N-D Array  manipulations.
 /*
 
 Copyright (C) 1996, 1997 John W. Eaton
@@ -29,10 +29,47 @@
 #include <config.h>
 #endif
 
-#include "NDArray.h"
+#include "dNDArray.h"
 #include "mx-base.h"
+#include "lo-error.h"
 #include "lo-ieee.h"
 
+// XXX FIXME XXX -- this is not quite the right thing.
+
+boolMatrix
+NDArray::all (int dim) const
+{
+  boolMatrix retval;
+
+  if (dimensions.length () == 2)
+    {
+      Matrix tmp = matrix_value ();
+      retval = tmp.all (dim);
+    }
+  else
+    (*current_liboctave_error_handler)
+      ("all is not yet implemented for N-d Arrays");
+
+  return retval;
+}
+
+boolMatrix
+NDArray::any (int dim) const
+{
+  boolMatrix retval;
+
+  if (dimensions.length () == 2)
+    {
+      Matrix tmp = matrix_value ();
+      retval = tmp.any (dim);
+    }
+  else
+    (*current_liboctave_error_handler)
+      ("any is not yet implemented for N-d Arrays");
+
+  return retval;
+}
+
 bool
 NDArray::any_element_is_negative (bool neg_zero) const
 {
@@ -82,3 +119,35 @@
 
   return true;
 }
+
+Matrix
+NDArray::matrix_value (void) const
+{
+  Matrix retval;
+
+  int nd = ndims ();
+
+  switch (nd)
+    {
+    case 1:
+      retval = Matrix (Array2<double> (*this, dimensions(0), 1));
+      break;
+
+    case 2:
+      retval = Matrix (Array2<double> (*this, dimensions(0), dimensions(1)));
+      break;
+
+    default:
+      (*current_liboctave_error_handler)
+	("invalid converstion of NDArray to Matrix");
+      break;
+    }
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
--- a/liboctave/dNDArray.h	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/dNDArray.h	Fri Sep 19 21:41:21 2003 +0000
@@ -20,15 +20,15 @@
 
 */
 
-#if !defined (octave_NDArray_int_h)
-#define octave_NDArray_int_h 1
+#if !defined (octave_NDArray_h)
+#define octave_NDArray_h 1
 
 #if defined (__GNUG__) && defined (USE_PRAGMA_INTERFACE_IMPLEMENTATION)
 #pragma interface
 #endif
 
 #include "MArrayN.h"
-//#include "mx-base.h"
+#include "dMatrix.h"
 
 #include "mx-defs.h"
 #include "mx-op-defs.h"
@@ -36,32 +36,38 @@
 #include "data-conv.h"
 #include "mach-info.h"
 
-class NDArray : public MArrayN<double>
+class
+NDArray : public MArrayN<double>
 {
- public:
+public:
   
   NDArray (void) : MArrayN<double> () { }
 
-  NDArray (Array<int>& dims) : MArrayN<double> (dims) { }
+  NDArray (dim_vector& dims) : MArrayN<double> (dims) { }
 
-  NDArray (Array<int>& dims, double val) : MArrayN<double> (dims, val) { }
+  NDArray (dim_vector& dims, double val) : MArrayN<double> (dims, val) { }
   
-  NDArray (const NDArray& a): MArrayN<double> (a) { }
+  NDArray (const NDArray& a) : MArrayN<double> (a) { }
+
+  NDArray (const Matrix& a) : MArrayN<double> (a) { }
 
   NDArray (const MArrayN<double>& a) : MArrayN<double> (a) { }
 
-  NDArray (const Matrix& m) : MArrayN<double> (m) { }
-
   NDArray (const ArrayN<double>& a) : MArrayN<double> (a) { }
 
-  //NDArray (const Array<double>& a) : MArrayN<double> (a) { }
-
   NDArray& operator = (const NDArray& a)
     {
       MArrayN<double>::operator = (a);
       return *this;
     }
 
+  // XXX FIXME XXX -- this is not quite the right thing.
+
+  boolMatrix all (int dim = -1) const;
+  boolMatrix any (int dim = -1) const;
+
+  Matrix matrix_value (void) const;
+
   // i/o
 
   // friend std::ostream& operator << (std::ostream& os, const NDArray& a);
@@ -72,11 +78,17 @@
   bool any_element_is_negative (bool = false) const;
   bool all_integers (double& max_val, double& min_val) const;
 
- private:
+private:
 
-  NDArray (double *d, Array<int>& dims) : MArrayN<double> (d, dims) { }
+  NDArray (double *d, dim_vector& dims) : MArrayN<double> (d, dims) { }
 };
 
 MARRAY_FORWARD_DEFS (MArrayN, NDArray, double)
 
 #endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboctave/dim-vector.h	Fri Sep 19 21:41:21 2003 +0000
@@ -0,0 +1,134 @@
+/*
+
+Copyright (C) 2003 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 (octave_dim_vector_h)
+#define octave_dim_vector_h 1
+
+#if defined (__GNUG__) && defined (USE_PRAGMA_INTERFACE_IMPLEMENTATION)
+#pragma interface
+#endif
+
+#include <cassert>
+
+class
+dim_vector
+{
+public:
+
+  dim_vector (void) : ndims (0), dims (0) { }
+
+  dim_vector (int n) : ndims (1), dims (new int [1]) { dims[0] = n; }
+
+  dim_vector (int r, int c)
+    : ndims (2), dims (new int [2]) { dims[0] = r; dims[1] = c; }
+
+  dim_vector (int r, int c, int p)
+    : ndims (3), dims (new int [3]) { dims[0] = r; dims[1] = c; dims[2] = p; }
+
+  dim_vector (const dim_vector& dv)
+    : ndims (dv.ndims)
+    {
+      if (dv.dims)
+	{
+	  dims = new int [ndims];
+
+	  for (int i = 0; i < ndims; i++)
+	    dims[i] = dv.dims[i];
+	}
+      else
+	dims = 0;
+    }
+
+  dim_vector& operator = (const dim_vector& dv)
+    {
+      if (&dv != this)
+	{
+	  ndims = dv.ndims;
+
+	  if (dv.dims)
+	    {
+	      dims = new int [ndims];
+
+	      for (int i = 0; i < ndims; i++)
+		dims[i] = dv.dims[i];
+	    }
+	}
+
+      return *this;
+    }
+
+  ~dim_vector (void) { delete [] dims; }
+
+  int length (void) const { return ndims; }
+
+  int& elem (int i)
+    {
+      if (i >= ndims)
+	resize (i+1);
+
+      return dims[i];
+    }
+
+  int elem (int i) const { return i < ndims ? dims[i] : -1; }
+
+  int& operator () (int i) { return elem (i); }
+
+  int operator () (int i) const { return elem (i); }
+
+  void resize (int n)
+    {
+      if (n > ndims)
+	{
+	  int *new_dims = new int [n];
+
+	  for (int i = 0; i < ndims; i++)
+	    new_dims[i] = dims[i];
+
+	  for (int i = ndims; i < n; i++)
+	    new_dims[i] = 0;
+
+	  delete [] dims;
+
+	  dims = new_dims;
+
+	  ndims = n;
+	}
+      else
+	ndims = n;
+    }
+
+private:
+
+  int rows;
+  int cols;
+  int ndims;
+  int *dims;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
+
--- a/liboctave/mx-base.h	Sat Sep 13 07:53:55 2003 +0000
+++ b/liboctave/mx-base.h	Fri Sep 19 21:41:21 2003 +0000
@@ -45,9 +45,12 @@
 #include "dDiagMatrix.h"
 #include "CDiagMatrix.h"
 
-// N-dimensional Array classes.
+// N-d Array classes.
 
-#include "NDArray.h"
+#include "boolNDArray.h"
+#include "chNDArray.h"
+#include "dNDArray.h"
+#include "CNDArray.h"
 
 #endif
 
--- a/src/Cell.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/Cell.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -28,22 +28,78 @@
 #include <config.h>
 #endif
 
+#include "idx-vector.h"
+
 #include "Cell.h"
 
 Cell::Cell (const string_vector& sv)
-  : Array2<octave_value> ()
+  : ArrayN<octave_value> ()
 {
   int n = sv.length ();
 
   if (n > 0)
     {
-      resize (n, 1);
+      resize_no_fill (n, 1);
 
       for (int i = 0; i < n; i++)
 	elem(i,0) = sv[i];
     }
 }
 
+Cell
+Cell::index (const octave_value_list& idx, bool resize_ok) const
+{
+  Cell retval;
+
+  int n = idx.length ();
+
+  switch (n)
+    {
+    case 1:
+      {
+	idx_vector i = idx(0).index_vector ();
+
+	retval = index (i, resize_ok);
+      }
+      break;
+
+    case 2:
+      {
+	idx_vector i = idx(0).index_vector ();
+	idx_vector j = idx(1).index_vector ();
+
+	retval = index (i, j, resize_ok);
+      }
+      break;
+
+    default:
+      {
+	Array<idx_vector> iv (n);
+
+	for (int i = 0; i < n; i++)
+	  iv(i) = idx(i).index_vector ();
+
+	retval = index (iv, resize_ok);
+      }
+      break;
+    }
+
+  return retval;
+}
+
+Cell&
+Cell::assign (const octave_value_list& idx, const Cell& rhs,
+	      const octave_value& fill_val)
+
+{
+  for (int i = 0; i < idx.length (); i++)
+    set_index (idx(i).index_vector ());
+
+  ::assign (*this, rhs, fill_val);
+
+  return *this;
+}
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/src/Cell.h	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/Cell.h	Fri Sep 19 21:41:21 2003 +0000
@@ -29,36 +29,70 @@
 
 #include <string>
 
-#include "Array2.h"
+#include "ArrayN.h"
 #include "oct-alloc.h"
 #include "str-vec.h"
 
 #include "oct-obj.h"
 
 class
-Cell : public Array2<octave_value>
+Cell : public ArrayN<octave_value>
 {
 public:
 
   Cell (void)
-    : Array2<octave_value> () { }
+    : ArrayN<octave_value> () { }
 
   Cell (const octave_value& val)
-    : Array2<octave_value> (1, 1, val) { }
+    : ArrayN<octave_value> (dim_vector (1, 1), val) { }
+
+  Cell (const octave_value_list& ovl)
+    : ArrayN<octave_value> (dim_vector (ovl.length (), 1))
+    {
+      for (int i = 0; i < ovl.length (); i++)
+	elem (i) = ovl (i);
+    }
 
   Cell (int n, int m, const octave_value& val = resize_fill_value ())
-    : Array2<octave_value> (n, m, val) { }
+    : ArrayN<octave_value> (dim_vector (n, m), val) { }
 
-  Cell (const Array2<octave_value>& c)
-    : Array2<octave_value> (c) { }
+  Cell (const ArrayN<octave_value>& c)
+    : ArrayN<octave_value> (c) { }
 
   Cell (const Array<octave_value>& c, int nr, int nc)
-    : Array2<octave_value> (c, nr, nc) { }
+    : ArrayN<octave_value> (c, dim_vector (nr, nc)) { }
 
   Cell (const string_vector& sv);
 
   Cell (const Cell& c)
-    : Array2<octave_value> (c) { }
+    : ArrayN<octave_value> (c) { }
+
+  Cell index (const octave_value_list& idx, bool resize_ok = false) const;
+
+  Cell index (idx_vector& i, int resize_ok = 0,
+	      const octave_value& rfv = resize_fill_value ()) const
+    { return ArrayN<octave_value>::index (i, resize_ok, rfv); }
+
+  Cell index (idx_vector& i, idx_vector& j, int resize_ok = 0,
+	      const octave_value& rfv = resize_fill_value ()) const
+    { return ArrayN<octave_value>::index (i, j, resize_ok, rfv); }
+
+  Cell index (Array<idx_vector>& ra_idx, int resize_ok = 0,
+	      const octave_value& rfv = resize_fill_value ()) const
+    { return ArrayN<octave_value>::index (ra_idx, resize_ok, rfv); }
+
+  Cell& assign (const octave_value_list& idx, const Cell& rhs,
+		const octave_value& fill_val = octave_value ());
+
+  octave_value& operator () (int i) { return elem_internal (i); }
+
+  octave_value operator () (int i) const { return elem_internal (i); }
+
+  octave_value& operator () (int i, int j)
+    { return ArrayN<octave_value>::operator () (i, j); }
+
+  octave_value operator () (int i, int j) const
+    { return ArrayN<octave_value>::operator () (i, j); }
 
   // XXX FIXME XXX
   boolMatrix all (int dim = 0) const { return boolMatrix (); }
@@ -70,6 +104,28 @@
   bool is_true (void) const { return false; }
 
   static octave_value resize_fill_value (void) { return Matrix (); }
+
+private:
+
+  // XXX FIXME XXX -- we need to do something intelligent if there is
+  // more than one dimension, but for now this is all we need...
+
+  void maybe_resize (int n)
+    {
+      if (n >= rows ())
+	resize (dim_vector (n + 1, 1), octave_value ());
+    }
+
+  octave_value& elem_internal (int n)
+    {
+      maybe_resize (n);
+      return elem (n);
+    }
+
+  octave_value elem_internal (int n) const
+    {
+      return elem (n);
+    }
 };
 
 #endif
--- a/src/ChangeLog	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/ChangeLog	Fri Sep 19 21:41:21 2003 +0000
@@ -1,3 +1,43 @@
+2003-09-19  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* ov.h (octave_value::dim_vector): New function.
+
+	* ov.h, ov.cc (octave_value::octave_value (const Cell&)):
+	New arg, is_cs_list.
+	(octave_value::octave_value (const NDArray&)):
+	Create octave_matrix object, not octave_double_nd_array object.
+	(octave_value::octave_value (const ComplexNDArray&),
+	octave_value::octave_value (const boolNDArray&),
+	octave_value (const charNDArray&, bool)): New constructors.
+
+	* ov.h, ov.cc (octave_value::nil_rep): New function.
+	(octave_value::octave_value (void)): Use it to initialize empty
+	octave_value objects.
+
+	* ov-list.h, ov-list.cc (octave_list::octave_list (const Cell&)):
+	New constructor.
+	* ov-cs-list.h (octave_cs_list::octave_cs_list (const Cell&)):
+	Likewise.
+
+	* data.cc (Fsize): Handle N-d objects.
+
+	* pr-output.cc (octave_print_internal): New versions for NDArray,
+	ComplexNDArray, boolNDArray, and charNDArray objects.
+	* pr-output.h: Provide decls.
+
+	* ov-re-nd-array.h, ov-re-nd-array.cc: Delete.
+
+	* Cell.h, Cell.cc, ov-base-mat.h, ov-base-mat.cc, ov-bool-mat.h,
+	ov-bool-mat.cc, ov-ch-mat.h, ov-ch-mat.cc, ov-cx-mat.h,
+	ov-cx-mat.cc, ov-re-mat.h, ov-re-mat.cc, ov-str-mat.h,
+	ov-str-mat.cc: Now N-dimensional.
+
+	* oct-map.h, oct-map.cc: Now based on Cell ojects instead of
+	octave_value_list objects.  Change all uses.
+
+	* TEMPLATE-INST/Array-tc.cc: Also instantiate ArrayN objects.
+	Don't instantiate assign funcitons for Array2 objects.
+
 2003-09-11  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
 	* pt-plot.cc (symbols_of_pt_plot): Default for automatic replot is
--- a/src/Makefile.in	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/Makefile.in	Fri Sep 19 21:41:21 2003 +0000
@@ -71,7 +71,7 @@
 	ov-colon.h ov-base.h ov-base-mat.h ov-base-scalar.h \
 	ov-str-mat.h ov-bool-mat.h ov-bool.h ov-file.h ov-cell.h ov.h \
 	ov-fcn.h ov-builtin.h ov-dld-fcn.h ov-mapper.h ov-usr-fcn.h \
-	ov-base-nd-array.h ov-re-nd-array.h ov-fcn-handle.h ov-typeinfo.h
+	ov-fcn-handle.h ov-typeinfo.h
 
 PT_INCLUDES := pt.h pt-all.h pt-arg-list.h pt-assign.h pt-binop.h \
         pt-bp.h	pt-cell.h pt-check.h pt-cmd.h pt-colon.h pt-const.h \
@@ -99,9 +99,8 @@
 	op-cs-s.cc op-fil-b.cc op-fil-bm.cc op-fil-cm.cc \
 	op-fil-cs.cc op-fil-m.cc op-fil-s.cc op-fil-lis.cc \
 	op-fil-rec.cc op-fil-str.cc op-list.cc op-m-cm.cc \
-	op-m-cs.cc op-m-m.cc op-m-nd.cc op-m-s.cc op-nd-m.cc \
-	op-nd-nd.cc op-nd-s.cc op-range.cc op-s-cm.cc \
-	op-s-cs.cc op-s-m.cc op-s-nd.cc op-s-s.cc op-str-m.cc \
+	op-m-cs.cc op-m-m.cc op-m-s.cc op-range.cc op-s-cm.cc \
+	op-s-cs.cc op-s-m.cc op-s-s.cc op-str-m.cc \
 	op-str-s.cc op-str-str.cc
 
 OP_SRC := $(addprefix OPERATORS/, $(OP_XSRC))
@@ -112,8 +111,7 @@
 	ov-complex.cc ov-str-mat.cc ov-struct.cc ov-va-args.cc \
 	ov-colon.cc ov-bool-mat.cc ov-bool.cc ov-file.cc ov-cell.cc \
 	ov.cc ov-fcn.cc ov-builtin.cc ov-dld-fcn.cc ov-mapper.cc \
-	ov-usr-fcn.cc ov-base-nd-array.cc ov-re-nd-array.cc \
-	ov-fcn-handle.cc ov-typeinfo.cc
+	ov-usr-fcn.cc ov-fcn-handle.cc ov-typeinfo.cc
 
 PT_SRC := pt.cc pt-arg-list.cc pt-assign.cc pt-bp.cc pt-binop.cc \
 	pt-cell.cc pt-check.cc pt-cmd.cc pt-colon.cc pt-const.cc \
--- a/src/TEMPLATE-INST/Array-tc.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/TEMPLATE-INST/Array-tc.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -34,6 +34,9 @@
 #include "Array2.h"
 #include "Array2.cc"
 
+#include "ArrayN.h"
+#include "ArrayN.cc"
+
 #include "DiagArray2.h"
 #include "DiagArray2.cc"
 
@@ -57,11 +60,17 @@
 
 template class Array2<octave_value>;
 
+#if 0
+
 template int assign (Array2<octave_value>&, const Array2<octave_value>&);
 
 template int assign (Array2<octave_value>&,
 		     const Array2<octave_value>&, const octave_value&);
 
+#endif
+
+template class ArrayN<octave_value>;
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/src/data.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/data.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -726,22 +726,25 @@
 
   int nargin = args.length ();
 
-  if (nargin == 1 && nargout < 3)
+  if (nargin == 1)
     {
-      int nr = args(0).rows ();
-      int nc = args(0).columns ();
+      dim_vector dimensions = args(0).dims ();
+
+      int ndims = dimensions.length ();
 
-      if (nargout == 0 || nargout == 1)
+      Matrix m (1, ndims);
+
+      if (nargout > 1)
 	{
-	  Matrix m (1, 2);
-	  m (0, 0) = nr;
-	  m (0, 1) = nc;
-	  retval(0) = m;
+	  while (ndims--)
+	    retval(ndims) = dimensions(ndims);
 	}
-      else if (nargout == 2)
+      else
 	{
-	  retval(1) = nc;
-	  retval(0) = nr;
+	  for (int i = 0; i < ndims; i++)
+	    m(0, i) = dimensions(i);
+
+	  retval(0) = m;
 	}
     }
   else if (nargin == 2 && nargout < 2)
@@ -931,7 +934,7 @@
   int ndim = 0;
   int type = 0;
 
-  Array<int> dims;
+  dim_vector dims;
   
   // Check for type information.
 
--- a/src/load-save.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/load-save.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -4387,7 +4387,7 @@
 	for (Octave_map::iterator i = m.begin (); i != m.end (); i++)
 	  {
 	    // write the data of each element
-	    octave_value_list elts = m.contents (i);
+	    Cell elts = m.contents (i);
 
 	    for (int j = 0; j < len; j++)
 	      {
--- a/src/oct-map.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/oct-map.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -34,12 +34,12 @@
 #include "oct-map.h"
 #include "utils.h"
 
-octave_value_list
+Cell
 Octave_map::operator [] (const std::string& key) const
 {
   const_iterator p = seek (key);
 
-  return p != end () ? p->second : octave_value_list ();
+  return p != end () ? p->second : Cell ();
 }
 
 string_vector
@@ -94,7 +94,7 @@
 }
 
 Octave_map&
-Octave_map::assign (const idx_vector& idx, const Octave_map& rhs)
+Octave_map::assign (const octave_value_list& idx, const Octave_map& rhs)
 {
   string_vector t_keys = empty () ? rhs.keys () : equiv_keys (*this, rhs);
 
@@ -106,7 +106,7 @@
 	{
 	  std::string key = t_keys[i];
 
-	  octave_value_list t_rhs = rhs[key];
+	  Cell t_rhs = rhs[key];
 
 	  assign (idx, key, t_rhs);
 
@@ -121,10 +121,10 @@
 }
 
 Octave_map&
-Octave_map::assign (const idx_vector& idx, const std::string& key,
-		    const octave_value_list& rhs)
+Octave_map::assign (const octave_value_list& idx, const std::string& key,
+		    const Cell& rhs)
 {
-  octave_value_list tmp = map[key];
+  Cell tmp = map[key];
 
   octave_value fill_value = Matrix ();
 
@@ -155,13 +155,13 @@
 }
 
 Octave_map&
-Octave_map::assign (const std::string& key, const octave_value_list& rhs)
+Octave_map::assign (const std::string& key, const Cell& rhs)
 {
   if (empty ())
     map[key] = rhs;
   else
     {
-      octave_value_list tmp = contents (begin ());
+      Cell tmp = contents (begin ());
 
       if (tmp.length () == rhs.length ())
 	map[key] = rhs;
@@ -173,13 +173,13 @@
 }
 
 Octave_map
-Octave_map::index (idx_vector& idx)
+Octave_map::index (const octave_value_list& idx)
 {
   Octave_map retval;
 
   for (iterator p = begin (); p != end (); p++)
     {
-      octave_value_list tmp = contents(p).index (idx);
+      Cell tmp = contents(p).index (idx);
 
       if (error_state)
 	break;
--- a/src/oct-map.h	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/oct-map.h	Fri Sep 19 21:41:21 2003 +0000
@@ -29,6 +29,7 @@
 
 #include <map>
 
+#include "Cell.h"
 #include "oct-obj.h"
 
 class string_vector;
@@ -38,15 +39,21 @@
 {
  public:
 
-  typedef std::map<std::string, octave_value_list>::iterator iterator;
-  typedef std::map<std::string, octave_value_list>::const_iterator const_iterator;
+  typedef std::map<std::string, Cell>::iterator iterator;
+  typedef std::map<std::string, Cell>::const_iterator const_iterator;
 
   Octave_map (void) : map (), array_len (0) { }
 
   Octave_map (const std::string& key, const octave_value& value)
     : map (), array_len (1)
       {
-	map[key] = octave_value_list (value);
+	map[key] = Cell (value);
+      }
+
+  Octave_map (const std::string& key, const Cell& vals)
+    : map (), array_len (vals.length ())
+      {
+	map[key] = vals;
       }
 
   Octave_map (const std::string& key, const octave_value_list& val_list)
@@ -75,9 +82,9 @@
 
   int empty (void) const { return map.empty (); }
 
-  octave_value_list& operator [] (const std::string& key) { return map[key]; }
+  Cell& operator [] (const std::string& key) { return map[key]; }
 
-  octave_value_list operator [] (const std::string& key) const;
+  Cell operator [] (const std::string& key) const;
 
   void del (const std::string& key)
     {
@@ -94,10 +101,10 @@
 
   std::string key (const_iterator p) const { return p->first; }
 
-  octave_value_list& contents (const_iterator p)
+  Cell& contents (const_iterator p)
     { return operator [] (key(p)); }
 
-  octave_value_list contents (const_iterator p) const
+  Cell contents (const_iterator p) const
     { return operator [] (key(p)); }
 
   const_iterator seek (const std::string& key) const { return map.find (key); }
@@ -115,19 +122,19 @@
 
   int array_length (void) const;
 
-  Octave_map& assign (const idx_vector& idx, const Octave_map& rhs);
+  Octave_map& assign (const octave_value_list& idx, const Octave_map& rhs);
 
-  Octave_map& assign (const idx_vector& idx, const std::string& key,
-		      const octave_value_list& rhs);
+  Octave_map& assign (const octave_value_list& idx, const std::string& key,
+		      const Cell& rhs);
 
-  Octave_map& assign (const std::string& key, const octave_value_list& rhs);
+  Octave_map& assign (const std::string& key, const Cell& rhs);
 
-  Octave_map index (idx_vector& idx);
+  Octave_map index (const octave_value_list& idx);
 
 private:
 
   // The map of names to values.
-  std::map<std::string, octave_value_list> map;
+  std::map<std::string, Cell> map;
 
   // The current size of this struct array;
   mutable int array_len;
--- a/src/ov-base-mat.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/ov-base-mat.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -144,10 +144,13 @@
 
     default:
       {
-	std::string n = type_name ();
+	Array<idx_vector> idx_vec (len);
 
-	error ("invalid number of indices (%d) for %s value",
-	       len, n.c_str ());
+	for (int i = 0; i < len; i++)
+	  idx_vec(i) = idx(i).index_vector ();
+
+	retval = MT (matrix.index (idx_vec, resize_ok,
+				   MT::resize_fill_value ()));
       }
       break;
     }
@@ -161,35 +164,10 @@
 {
   int len = idx.length ();
 
-  switch (len)
-    {
-    case 2:
-      {
-	idx_vector i = idx (0).index_vector ();
-	idx_vector j = idx (1).index_vector ();
-
-	matrix.set_index (i);
-	matrix.set_index (j);
-
-	::assign (matrix, rhs, MT::resize_fill_value ());
-      }
-      break;
+  for (int i = 0; i < len; i++)
+    matrix.set_index (idx(i).index_vector ());
 
-    case 1:
-      {
-	idx_vector i = idx (0).index_vector ();
-
-	matrix.set_index (i);
-
-	::assign (matrix, rhs, MT::resize_fill_value ());
-      }
-      break;
-
-    default:
-      error ("invalid number of indices (%d) for indexed assignment",
-	     len);
-      break;
-    }
+  ::assign (matrix, rhs, MT::resize_fill_value ());
 }
 
 template <class MT>
--- a/src/ov-base-mat.h	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/ov-base-mat.h	Fri Sep 19 21:41:21 2003 +0000
@@ -91,13 +91,16 @@
   int rows (void) const { return matrix.rows (); }
   int columns (void) const { return matrix.columns (); }
 
+  dim_vector dims (void) const { return matrix.dims (); }
+
+  // XXX FIXME XXX 
   int length (void) const
-  {
-    int r = rows ();
-    int c = columns ();
+    {
+      int r = rows ();
+      int c = columns ();
 
-    return (r == 0 || c == 0) ? 0 : ((r > c) ? r : c);
-  }
+      return (r == 0 || c == 0) ? 0 : ((r > c) ? r : c);
+    }
 
   octave_value all (int dim = 0) const { return matrix.all (dim); }
   octave_value any (int dim = 0) const { return matrix.any (dim); }
--- a/src/ov-base.h	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/ov-base.h	Fri Sep 19 21:41:21 2003 +0000
@@ -96,6 +96,8 @@
 
   int columns (void) const { return -1; }
 
+  dim_vector dims (void) const { return dim_vector (rows (), columns ()); }
+
   int length (void) const { return -1; }
 
   bool is_defined (void) const { return false; }
--- a/src/ov-bool-mat.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/ov-bool-mat.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -44,7 +44,7 @@
 #include "ov-re-mat.h"
 #include "pr-output.h"
 
-template class octave_base_matrix<boolMatrix>;
+template class octave_base_matrix<boolNDArray>;
 
 DEFINE_OCTAVE_ALLOCATOR (octave_bool_matrix);
 
@@ -69,11 +69,16 @@
 {
   octave_value *retval = 0;
 
-  int nr = matrix.rows ();
-  int nc = matrix.cols ();
+  if (matrix.ndims () == 2)
+    {
+      boolMatrix bm = matrix.matrix_value ();
 
-  if (nr == 1 && nc == 1)
-    retval = new octave_bool (matrix (0, 0));
+      int nr = bm.rows ();
+      int nc = bm.cols ();
+
+      if (nr == 1 && nc == 1)
+	retval = new octave_bool (bm (0, 0));
+    }
 
   return retval;
 }
--- a/src/ov-bool-mat.h	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/ov-bool-mat.h	Fri Sep 19 21:41:21 2003 +0000
@@ -48,21 +48,24 @@
 // Character matrix values.
 
 class
-octave_bool_matrix : public octave_base_matrix<boolMatrix>
+octave_bool_matrix : public octave_base_matrix<boolNDArray>
 {
 public:
 
   octave_bool_matrix (void)
-    : octave_base_matrix<boolMatrix> () { }
+    : octave_base_matrix<boolNDArray> () { }
+
+  octave_bool_matrix (const boolNDArray& bnda)
+    : octave_base_matrix<boolNDArray> (bnda) { }
 
   octave_bool_matrix (const boolMatrix& bm)
-    : octave_base_matrix<boolMatrix> (bm) { }
+    : octave_base_matrix<boolNDArray> (bm) { }
 
   octave_bool_matrix (const Array2<bool>& a)
-    : octave_base_matrix<boolMatrix> (a) { }
+    : octave_base_matrix<boolNDArray> (a) { }
 
   octave_bool_matrix (const octave_bool_matrix& bm)
-    : octave_base_matrix<boolMatrix> (bm) { }
+    : octave_base_matrix<boolNDArray> (bm) { }
 
   ~octave_bool_matrix (void) { }
 
@@ -73,7 +76,9 @@
 
   octave_value *try_narrowing_conversion (void);
 
-  idx_vector index_vector (void) const { return idx_vector (matrix); }
+  // XXX FIXME XXX
+  idx_vector index_vector (void) const
+    { return idx_vector (matrix.matrix_value ()); }
 
   bool is_bool_matrix (void) const { return true; }
 
@@ -88,15 +93,16 @@
   double scalar_value (bool frc_str_conv = false) const
     { return double_value (frc_str_conv); }
 
-  Matrix matrix_value (bool = false) const { return Matrix (matrix); }
+  Matrix matrix_value (bool = false) const
+    { return Matrix (matrix.matrix_value ()); }
 
   Complex complex_value (bool = false) const;
 
   ComplexMatrix complex_matrix_value (bool = false) const
-    { return ComplexMatrix (matrix); }
+    { return ComplexMatrix (matrix.matrix_value ( )); }
 
   boolMatrix bool_matrix_value (void) const
-    { return matrix; }
+    { return matrix.matrix_value (); }
 
   octave_value convert_to_str_internal (bool pad, bool force) const;
 
--- a/src/ov-cell.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/ov-cell.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -327,47 +327,66 @@
 void
 octave_cell::print_raw (std::ostream& os, bool) const
 {
-  int nr = rows ();
-  int nc = columns ();
+  int ndims = matrix.ndims ();
+
+  if (ndims == 2)
+    {
+      int nr = rows ();
+      int nc = columns ();
+
+      if (nr > 0 && nc > 0)
+	{
+	  indent (os);
+	  os << "{";
+	  newline (os);
+
+	  increment_indent_level ();
+
+	  for (int j = 0; j < nc; j++)
+	    {
+	      for (int i = 0; i < nr; i++)
+		{
+		  OCTAVE_QUIT;
+
+		  OSSTREAM buf;
+		  buf << "[" << i+1 << "," << j+1 << "]" << OSSTREAM_ENDS;
 
-  if (nr > 0 && nc > 0)
+		  octave_value val = matrix(i,j);
+
+		  val.print_with_name (os, OSSTREAM_STR (buf));
+
+		  OSSTREAM_FREEZE (buf);
+		}
+	    }
+
+	  decrement_indent_level ();
+
+	  indent (os);
+	  os << "}";
+	  newline (os);
+	}
+      else
+	{
+	  os << "{}";
+	  if (nr > 0 || nc > 0)
+	    os << "(" << nr << "x" << nc << ")";
+	  os << "\n";
+	}
+    }
+  else
     {
       indent (os);
       os << "{";
-      newline (os);
-
-      increment_indent_level ();
-
-      for (int j = 0; j < nc; j++)
+      dim_vector dv = matrix.dims ();
+      for (int i = 0; i < ndims; i++)
 	{
-	  for (int i = 0; i < nr; i++)
-	    {
-	      OCTAVE_QUIT;
-
-	      OSSTREAM buf;
-	      buf << "[" << i+1 << "," << j+1 << "]" << OSSTREAM_ENDS;
-
-	      octave_value val = matrix(i,j);
-
-	      val.print_with_name (os, OSSTREAM_STR (buf));
-
-	      OSSTREAM_FREEZE (buf);
-	    }
+	  if (i > 0)
+	    os << "x";
+	  os << dv(i);
 	}
-
-      decrement_indent_level ();
-
-      indent (os);
-      os << "}";
+      os << " Cell Array}";
       newline (os);
     }
-  else
-    {
-      os << "{}";
-      if (nr > 0 || nc > 0)
-	os << "(" << nr << "x" << nc << ")";
-      os << "\n";
-    }
 }
 
 bool
--- a/src/ov-ch-mat.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/ov-ch-mat.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -40,7 +40,7 @@
 #include "gripes.h"
 #include "pr-output.h"
 
-template class octave_base_matrix<charMatrix>;
+template class octave_base_matrix<charNDArray>;
 
 DEFINE_OCTAVE_ALLOCATOR (octave_char_matrix);
 
--- a/src/ov-ch-mat.h	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/ov-ch-mat.h	Fri Sep 19 21:41:21 2003 +0000
@@ -38,6 +38,7 @@
 
 #include "error.h"
 #include "ov-base.h"
+
 #include "ov-base-mat.h"
 #include "ov-typeinfo.h"
 
@@ -49,30 +50,33 @@
 // Character matrix values.
 
 class
-octave_char_matrix : public octave_base_matrix<charMatrix>
+octave_char_matrix : public octave_base_matrix<charNDArray>
 {
 public:
 
   octave_char_matrix (void)
-    : octave_base_matrix<charMatrix> () { }
+    : octave_base_matrix<charNDArray> () { }
 
   octave_char_matrix (const charMatrix& chm, bool = false)
-    : octave_base_matrix<charMatrix> (chm) { }
+    : octave_base_matrix<charNDArray> (chm) { }
+
+  octave_char_matrix (const charNDArray& chm, bool = false)
+    : octave_base_matrix<charNDArray> (chm) { }
 
   octave_char_matrix (char c)
-    : octave_base_matrix<charMatrix> (c) { }
+    : octave_base_matrix<charNDArray> (c) { }
 
   octave_char_matrix (const char *s)
-    : octave_base_matrix<charMatrix> (s) { }
+    : octave_base_matrix<charNDArray> (s) { }
 
   octave_char_matrix (const std::string& s)
-    : octave_base_matrix<charMatrix> (s) { }
+    : octave_base_matrix<charNDArray> (s) { }
 
   octave_char_matrix (const string_vector& s)
-    : octave_base_matrix<charMatrix> (s) { }
+    : octave_base_matrix<charNDArray> (s) { }
 
   octave_char_matrix (const octave_char_matrix& chm)
-    : octave_base_matrix<charMatrix> (chm) { }
+    : octave_base_matrix<charNDArray> (chm) { }
 
   ~octave_char_matrix (void) { }
 
@@ -91,18 +95,19 @@
   double scalar_value (bool frc_str_conv = false) const
     { return double_value (frc_str_conv); }
 
-  Matrix matrix_value (bool = false) const { return Matrix (matrix); }
+  Matrix matrix_value (bool = false) const
+    { return Matrix (matrix.matrix_value ()); }
 
   Complex complex_value (bool = false) const;
 
   ComplexMatrix complex_matrix_value (bool = false) const
-    { return ComplexMatrix (matrix); }
+    { return ComplexMatrix (matrix.matrix_value ()); }
 
   charMatrix char_matrix_value (bool = false) const
-    { return matrix; }
+    { return matrix.matrix_value (); }
 
   octave_value convert_to_str_internal (bool, bool) const
-    { return octave_value (matrix, true); }
+    { return octave_value (matrix.matrix_value (), true); }
 
 protected:
 
--- a/src/ov-cs-list.h	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/ov-cs-list.h	Fri Sep 19 21:41:21 2003 +0000
@@ -56,6 +56,9 @@
   octave_cs_list (const octave_value_list& l)
     : octave_list (l) { }
 
+  octave_cs_list (const Cell& c)
+    : octave_list (c) { }
+
   octave_cs_list (const octave_cs_list& l)
     : octave_list (l) { }
 
--- a/src/ov-cx-mat.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/ov-cx-mat.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -45,7 +45,7 @@
 #include "ov-scalar.h"
 #include "pr-output.h"
 
-template class octave_base_matrix<ComplexMatrix>;
+template class octave_base_matrix<ComplexNDArray>;
 
 DEFINE_OCTAVE_ALLOCATOR (octave_complex_matrix);
 
@@ -56,22 +56,27 @@
 {
   octave_value *retval = 0;
 
-  int nr = matrix.rows ();
-  int nc = matrix.cols ();
+  if (matrix.ndims () == 2)
+    {
+      ComplexMatrix cm = matrix.matrix_value ();
 
-  if (nr == 1 && nc == 1)
-    {
-      Complex c = matrix (0, 0);
+      int nr = cm.rows ();
+      int nc = cm.cols ();
+
+      if (nr == 1 && nc == 1)
+	{
+	  Complex c = matrix (0, 0);
 
-      if (imag (c) == 0.0)
-	retval = new octave_scalar (std::real (c));
-      else
-	retval = new octave_complex (c);
+	  if (imag (c) == 0.0)
+	    retval = new octave_scalar (std::real (c));
+	  else
+	    retval = new octave_complex (c);
+	}
+      else if (nr == 0 || nc == 0)
+	retval = new octave_matrix (Matrix (nr, nc));
+      else if (cm.all_elements_are_real ())
+	retval = new octave_matrix (::real (cm));
     }
-  else if (nr == 0 || nc == 0)
-    retval = new octave_matrix (Matrix (nr, nc));
-  else if (matrix.all_elements_are_real ())
-    retval = new octave_matrix (::real (matrix));
 
   return retval;
 }
@@ -80,7 +85,7 @@
 octave_complex_matrix::assign (const octave_value_list& idx,
 			       const ComplexMatrix& rhs)
 {
-  octave_base_matrix<ComplexMatrix>::assign (idx, rhs);
+  octave_base_matrix<ComplexNDArray>::assign (idx, rhs);
 }
 
 void
@@ -89,35 +94,10 @@
 {
   int len = idx.length ();
 
-  switch (len)
-    {
-    case 2:
-      {
-	idx_vector i = idx (0).index_vector ();
-	idx_vector j = idx (1).index_vector ();
-
-	matrix.set_index (i);
-	matrix.set_index (j);
-
-	::assign (matrix, rhs);
-      }
-      break;
+  for (int i = 0; i < len; i++)
+    matrix.set_index (idx(i).index_vector ());
 
-    case 1:
-      {
-	idx_vector i = idx (0).index_vector ();
-
-	matrix.set_index (i);
-
-	::assign (matrix, rhs);
-      }
-      break;
-
-    default:
-      error ("invalid number of indices (%d) for indexed matrix assignment",
-	     len);
-      break;
-    }
+  ::assign (matrix, rhs);
 }
 
 bool
@@ -158,7 +138,7 @@
   if (! force_conversion && Vwarn_imag_to_real)
     gripe_implicit_conversion ("complex matrix", "real matrix");
 
-  retval = ::real (matrix);
+  retval = ::real (matrix.matrix_value ());
 
   return retval;
 }
@@ -188,7 +168,7 @@
 ComplexMatrix
 octave_complex_matrix::complex_matrix_value (bool) const
 {
-  return matrix;
+  return matrix.matrix_value ();
 }
 
 /*
--- a/src/ov-cx-mat.h	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/ov-cx-mat.h	Fri Sep 19 21:41:21 2003 +0000
@@ -49,27 +49,30 @@
 // Complex matrix values.
 
 class
-octave_complex_matrix : public octave_base_matrix<ComplexMatrix>
+octave_complex_matrix : public octave_base_matrix<ComplexNDArray>
 {
 public:
 
   octave_complex_matrix (void)
-    : octave_base_matrix<ComplexMatrix> () { }
+    : octave_base_matrix<ComplexNDArray> () { }
+
+  octave_complex_matrix (const ComplexNDArray& m)
+    : octave_base_matrix<ComplexNDArray> (m) { }
 
   octave_complex_matrix (const ComplexMatrix& m)
-    : octave_base_matrix<ComplexMatrix> (m) { }
+    : octave_base_matrix<ComplexNDArray> (m) { }
 
   octave_complex_matrix (const ComplexDiagMatrix& d)
-    : octave_base_matrix<ComplexMatrix> (ComplexMatrix (d)) { }
+    : octave_base_matrix<ComplexNDArray> (ComplexMatrix (d)) { }
 
   octave_complex_matrix (const ComplexRowVector& v)
-    : octave_base_matrix<ComplexMatrix> (ComplexMatrix (v)) { }
+    : octave_base_matrix<ComplexNDArray> (ComplexMatrix (v)) { }
 
   octave_complex_matrix (const ComplexColumnVector& v)
-    : octave_base_matrix<ComplexMatrix> (ComplexMatrix (v)) { }
+    : octave_base_matrix<ComplexNDArray> (ComplexMatrix (v)) { }
 
   octave_complex_matrix (const octave_complex_matrix& cm)
-    : octave_base_matrix<ComplexMatrix> (cm) { }
+    : octave_base_matrix<ComplexNDArray> (cm) { }
 
   ~octave_complex_matrix (void) { }
 
--- a/src/ov-list.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/ov-list.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -33,6 +33,7 @@
 #include "lo-sstream.h"
 #include "lo-utils.h"
 
+#include "Cell.h"
 #include "defun.h"
 #include "error.h"
 #include "ov-list.h"
@@ -42,6 +43,17 @@
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_list, "list");
 
+octave_list::octave_list (const Cell& c)
+  : octave_base_value (), lst ()
+{
+  int n = c.length ();
+
+  lst.resize (n);
+
+  for (int i = 0; i < n; i++)
+    lst(i) = c(i);
+}
+
 octave_value
 octave_list::subsref (const std::string& type,
 		      const std::list<octave_value_list>& idx)
--- a/src/ov-list.h	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/ov-list.h	Fri Sep 19 21:41:21 2003 +0000
@@ -56,6 +56,8 @@
   octave_list (const octave_value_list& l)
     : octave_base_value (), lst (l) { }
 
+  octave_list (const Cell& c);
+
   octave_list (const octave_list& l)
     : octave_base_value (), lst (l.lst) { }
 
--- a/src/ov-re-mat.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/ov-re-mat.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -53,7 +53,7 @@
 #define UCHAR_MAX 255
 #endif
 
-template class octave_base_matrix<Matrix>;
+template class octave_base_matrix<NDArray>;
 
 DEFINE_OCTAVE_ALLOCATOR (octave_matrix);
 
@@ -64,11 +64,8 @@
 {
   octave_value *retval = 0;
 
-  int nr = matrix.rows ();
-  int nc = matrix.cols ();
-
-  if (nr == 1 && nc == 1)
-    retval = new octave_scalar (matrix (0, 0));
+  if (matrix.nelem () == 1)
+    retval = new octave_scalar (matrix (0));
 
   return retval;
 }
@@ -100,6 +97,14 @@
   return retval;
 }
 
+// XXX FIXME XXX
+
+Matrix
+octave_matrix::matrix_value (bool) const
+{
+  return matrix.matrix_value ();
+}
+
 Complex
 octave_matrix::complex_value (bool) const
 {
@@ -122,6 +127,14 @@
   return retval;
 }
 
+// XXX FIXME XXX
+
+ComplexMatrix
+octave_matrix::complex_matrix_value (bool) const
+{
+  return ComplexMatrix (matrix.matrix_value ());
+}
+
 octave_value
 octave_matrix::convert_to_str_internal (bool, bool) const
 {
--- a/src/ov-re-mat.h	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/ov-re-mat.h	Fri Sep 19 21:41:21 2003 +0000
@@ -49,27 +49,30 @@
 // Real matrix values.
 
 class
-octave_matrix : public octave_base_matrix<Matrix>
+octave_matrix : public octave_base_matrix<NDArray>
 {
 public:
 
   octave_matrix (void)
-    : octave_base_matrix<Matrix> () { }
+    : octave_base_matrix<NDArray> () { }
 
   octave_matrix (const Matrix& m)
-    : octave_base_matrix<Matrix> (m) { }
+    : octave_base_matrix<NDArray> (m) { }
+
+  octave_matrix (const NDArray& nda)
+    : octave_base_matrix<NDArray> (nda) { }
 
   octave_matrix (const DiagMatrix& d)
-    : octave_base_matrix<Matrix> (Matrix (d)) { }
+    : octave_base_matrix<NDArray> (Matrix (d)) { }
 
   octave_matrix (const RowVector& v)
-    : octave_base_matrix<Matrix> (Matrix (v)) { }
+    : octave_base_matrix<NDArray> (Matrix (v)) { }
 
   octave_matrix (const ColumnVector& v)
-    : octave_base_matrix<Matrix> (Matrix (v)) { }
+    : octave_base_matrix<NDArray> (Matrix (v)) { }
 
   octave_matrix (const octave_matrix& m)
-    : octave_base_matrix<Matrix> (m) { }
+    : octave_base_matrix<NDArray> (m) { }
 
   ~octave_matrix (void) { }
 
@@ -78,7 +81,8 @@
 
   octave_value *try_narrowing_conversion (void);
 
-  idx_vector index_vector (void) const { return idx_vector (matrix); }
+  // XXX FIXME XXX
+  idx_vector index_vector (void) const { return idx_vector (matrix_value ()); }
 
   bool is_real_matrix (void) const { return true; }
 
@@ -91,15 +95,14 @@
   double scalar_value (bool frc_str_conv = false) const
     { return double_value (frc_str_conv); }
 
-  Matrix matrix_value (bool = false) const { return matrix; }
+  Matrix matrix_value (bool = false) const;
 
   Complex complex_value (bool = false) const;
 
-  ComplexMatrix complex_matrix_value (bool = false) const
-    { return ComplexMatrix (matrix); }
+  ComplexMatrix complex_matrix_value (bool = false) const;
 
   NDArray double_nd_array_value (bool = false) const
-    { return NDArray (matrix); }
+    { return matrix; }
 
   void increment (void) { matrix += 1.0; }
 
--- a/src/ov-re-nd-array.cc	Sat Sep 13 07:53:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,203 +0,0 @@
-/*
-
-Copyright (C) 2000 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 <iostream>
-
-#include "lo-ieee.h"
-#include "lo-utils.h"
-#include "mx-base.h"
-
-#include "gripes.h"
-#include "oct-obj.h"
-#include "oct-lvalue.h"
-#include "ops.h"
-#include "ov-base.h"
-#include "ov-scalar.h"
-#include "ov-re-mat.h"
-#include "ov-base-nd-array.h"
-#include "ov-base-nd-array.cc"
-#include "ov-re-nd-array.h"
-#include "pr-output.h"
-#include "variables.h"
-
-template class octave_base_nd_array<NDArray>;
-
-DEFINE_OCTAVE_ALLOCATOR (octave_double_nd_array);
-
-DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_double_nd_array,
-				     "double-nd-array");
-
-octave_value *
-octave_double_nd_array::try_narrowing_conversion (void)
-{
-  octave_value *retval = 0;
-
-  array.maybe_delete_dims ();
-
-  int n_dims = array.dims ().length ();
-  Array<int> dims = array.dims();
-
-  // Scalar
-  if (n_dims == 1 && dims(0) == 1)
-    {
-      retval = new octave_scalar (array(Array<int> (1,0)));
-    }
-
-  // Matrix
-  if (n_dims == 2 || n_dims == 1)
-    {
-      retval = new octave_matrix (matrix_value ());
-    }
-
-
-
-  return retval;
-}
-
-void
-octave_double_nd_array::assign (const octave_value_list& idx,
-				const NDArray& rhs)
-{
-  int len = idx.length ();
-
-  if ( len < 0)
-    {
-      error ("invalid number of indices (%d) for indexed matrix assignment",
-	     len);
-      return;
-    }  
-
-  // XXX FIXME XXX -- where should this go?
-  array.set_max_indices (len);
-  
-  array.clear_index ();
-  
-
-  for (int i = 0; i < len; i++) 
-    {
-      idx_vector temp = idx(i).index_vector ();
-      array.set_index(temp);
-    }
-
-  ::assign (array, rhs);
-
-  // When subclasses of ArrayN are constructed, add an extra arguemnt
-  // resize_fill_value ()
-}
-
-bool
-octave_double_nd_array::valid_as_scalar_index (void) const
-{
-  // XXX FIXME XXX
-  return false;
-}
-
-double
-octave_double_nd_array::double_value (bool) const
-{
-  double retval = lo_ieee_nan_value ();
-
-  // XXX FIXME XXX
-
-  gripe_invalid_conversion ("real nd-array", "real scalar");
-
-  return retval;
-}
-
-
-Matrix
-octave_double_nd_array::matrix_value (bool ) const
-{
-  Array<int> ra_idx (array.dimensions.length (), 0);
-
-  return convert_slice_to_matrix (ra_idx);
-}
-
-Matrix
-octave_double_nd_array::convert_slice_to_matrix (const Array<int>& ra_idx) const
-{
-  int n_dims = array.dimensions.length ();
-
-  assert(ra_idx.length () == n_dims);
-
-  Array<int> idx (ra_idx);
-  Matrix retval;
-
-  if (n_dims > 1)
-    {
-      int d1 = array.dimensions(0);
-      int d2 = array.dimensions(1);
-
-      retval = Matrix (d1, d2);
-
-      for (int i = 0; i < d1; i++)
-        {
-          idx(0) = i;
-          for (int j = 0; j < d2; j++)
-            {
-              idx(1) = j;
-              retval(i,j) = array.elem (idx);
-            }
-        }
-    }
-  else if (n_dims == 1)
-    {
-      int d1 = array.dimensions(0);
-      int d2 = 1;
-
-      retval = Matrix (d1, d2);
-
-      for (int i = 0; i < d1; i++)
-        {
-	  idx(0) = i;
-	  retval(i, 0) = array.elem (idx);
-	}
-
-    }
-  return retval;
-}
-
-Complex
-octave_double_nd_array::complex_value (bool) const
-{
-  double tmp = lo_ieee_nan_value ();
-
-  Complex retval (tmp, tmp);
-
-  gripe_invalid_conversion ("real matrix", "complex scalar");
-
-  return retval;
-}
-
-/*
-;;; Local Variables: ***
-;;; mode: C++ ***
-;;; End: ***
-*/
--- a/src/ov-re-nd-array.h	Sat Sep 13 07:53:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-/*
-
-Copyright (C) 2000 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 (octave_re_nd_array_h)
-#define octave_re_nd_array_h 1
-
-#if defined (__GNUG__) && defined (USE_PRAGMA_INTERFACE_IMPLEMENTATION)
-#pragma interface
-#endif
-
-#include <cstdlib>
-
-#include <iostream>
-#include <string>
-
-#include "mx-base.h"
-#include "oct-alloc.h"
-
-#include "error.h"
-#include "ov-base.h"
-#include "ov-base-nd-array.h"
-#include "ov-typeinfo.h"
-
-class octave_value_list;
-
-// Real N-dimensional array values.
-
-class
-octave_double_nd_array : public octave_base_nd_array<NDArray>
-{
-public:
-
-  octave_double_nd_array (void)
-    : octave_base_nd_array<NDArray> () { }
-
-  octave_double_nd_array (const NDArray& a)
-    : octave_base_nd_array<NDArray> (a) { }
-
-  octave_double_nd_array (const octave_double_nd_array& a)
-    : octave_base_nd_array<NDArray> (a) { }
-
-  ~octave_double_nd_array (void) { }
-
-  octave_value *clone (void) const
-    { return new octave_double_nd_array (*this); }
-
-  octave_value *empty_clone (void) const
-    { return new octave_double_nd_array (); }
-
-  octave_value *try_narrowing_conversion (void);
-
-  void assign (const octave_value_list& idx, const NDArray& rhs);
-
-  // Need to implement idx_vector (NDArray) for this one.
-  //
-  // idx_vector index_vector (void) const { return idx_vector (array); }
-
-  bool is_real_nd_array (void) const { return true; }
-
-  bool is_real_matrix (void) const { return false; }
-
-  bool is_real_type (void) const { return true; }
-
-  bool valid_as_scalar_index (void) const;
-
-  double double_value (bool = false) const;
-
-  NDArray double_nd_array_value (bool = false) const { return array; }
-
-  double scalar_value (bool frc_str_conv = false) const
-    { return double_value (frc_str_conv); }
-
-  Matrix matrix_value (bool = false) const;
-
-  Complex complex_value (bool = false) const;
-
-  ComplexMatrix complex_matrix_value (bool = false) const
-    { return ComplexMatrix (matrix_value ()); }
-
-  Matrix convert_slice_to_matrix (const Array<int>& ra_idx) const;
-
-private:
-
-  DECLARE_OCTAVE_ALLOCATOR
-
-  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
-};
-
-#endif
-
-/*
-;;; Local Variables: ***
-;;; mode: C++ ***
-;;; End: ***
-*/
--- a/src/ov-scalar.h	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/ov-scalar.h	Fri Sep 19 21:41:21 2003 +0000
@@ -90,8 +90,10 @@
     { return Matrix (1, 1, scalar); }
 
   NDArray double_nd_array_value (bool = false) const
-  { Array<int> temp (1, 1);
-      return NDArray (temp, double_value ()); }
+    {
+      dim_vector temp (1, 1);
+      return NDArray (temp, double_value ());
+    }
 
   Complex complex_value (bool = false) const { return scalar; }
 
--- a/src/ov-str-mat.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/ov-str-mat.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -76,7 +76,7 @@
 	idx_vector i = idx (0).index_vector ();
 	idx_vector j = idx (1).index_vector ();
 
-	retval = octave_value (charMatrix (matrix.index (i, j, resize_ok)),
+	retval = octave_value (charNDArray (matrix.index (i, j, resize_ok)),
 			       true);
       }
       break;
@@ -85,12 +85,21 @@
       {
 	idx_vector i = idx (0).index_vector ();
 
-	retval = octave_value (charMatrix (matrix.index (i, resize_ok)), true);
+	retval = octave_value (charNDArray (matrix.index (i, resize_ok)),
+			       true);
       }
       break;
 
     default:
-      error ("invalid number of indices (%d) for matrix value", len);
+      {
+	Array<idx_vector> idx_vec (len);
+
+	for (int i = 0; i < len; i++)
+	  idx_vec(i) = idx(i).index_vector ();
+
+	retval = octave_value (charNDArray (matrix.index (idx_vec, resize_ok)),
+			       true);
+      }
       break;
     }
 
@@ -108,35 +117,10 @@
   if (tmp.rows () == 1 && tmp.columns () == 0)
     tmp.resize (0, 0);    
 
-  switch (len)
-    {
-    case 2:
-      {
-	idx_vector i = idx (0).index_vector ();
-	idx_vector j = idx (1).index_vector ();
-
-	matrix.set_index (i);
-	matrix.set_index (j);
-
-	::assign (matrix, tmp, Vstring_fill_char);
-      }
-      break;
+  for (int i = 0; i < len; i++)
+    matrix.set_index (idx(i).index_vector ());
 
-    case 1:
-      {
-	idx_vector i = idx (0).index_vector ();
-
-	matrix.set_index (i);
-
-	::assign (matrix, tmp, Vstring_fill_char);
-      }
-      break;
-
-    default:
-      error ("invalid number of indices (%d) for indexed matrix assignment",
-	     len);
-      break;
-    }
+  ::assign (matrix, tmp, Vstring_fill_char);
 }
 
 bool
@@ -155,7 +139,7 @@
   if (! force_string_conv && Vwarn_str_to_num)
     gripe_implicit_conversion ("string", "real matrix");
 
-  retval = Matrix (matrix);
+  retval = Matrix (matrix.matrix_value ());
 
   return retval;
 }
@@ -163,12 +147,21 @@
 string_vector
 octave_char_matrix_str::all_strings (bool, bool) const
 {
-  int n = matrix.rows ();
+  string_vector retval;
+
+  if (matrix.ndims () == 2)
+    {
+      charMatrix chm = matrix.matrix_value ();
+
+      int n = chm.rows ();
 
-  string_vector retval (n);
+      retval.resize (n);
 
-  for (int i = 0; i < n; i++)
-    retval[i] = matrix.row_as_string (i, true);
+      for (int i = 0; i < n; i++)
+	retval[i] = chm.row_as_string (i, true);
+    }
+  else
+    error ("invalid conversion of charNDArray to string_vector");
 
   return retval;
 }
@@ -176,7 +169,18 @@
 std::string
 octave_char_matrix_str::string_value (bool) const
 {
-  return matrix.row_as_string (0);  // XXX FIXME??? XXX
+  std::string retval;
+
+  if (matrix.ndims () == 2)
+    {
+      charMatrix chm = matrix.matrix_value ();
+
+      retval = chm.row_as_string (0);  // XXX FIXME??? XXX
+    }
+  else
+    error ("invalid conversion of charNDArray to string");
+
+  return retval;
 }
 
 void
--- a/src/ov-str-mat.h	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/ov-str-mat.h	Fri Sep 19 21:41:21 2003 +0000
@@ -59,6 +59,9 @@
   octave_char_matrix_str (const charMatrix& chm)
     : octave_char_matrix (chm) { }
 
+  octave_char_matrix_str (const charNDArray& chm)
+    : octave_char_matrix (chm) { }
+
   octave_char_matrix_str (char c)
     : octave_char_matrix (c) { }
 
--- a/src/ov-struct.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/ov-struct.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -44,10 +44,10 @@
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(octave_struct, "struct");
 
-octave_value_list
+Cell
 octave_struct::dotref (const octave_value_list& idx)
 {
-  octave_value_list retval;
+  Cell retval;
 
   assert (idx.length () == 1);
 
@@ -63,11 +63,13 @@
   return retval;
 }
 
+#if 0
 static void
 gripe_invalid_index (void)
 {
   error ("invalid index for structure array");
 }
+#endif
 
 static void
 gripe_invalid_index_for_assignment (void)
@@ -104,46 +106,28 @@
 	    std::list<octave_value_list>::const_iterator p = idx.begin ();
 	    octave_value_list key_idx = *++p;
 
-	    octave_value_list tmp = dotref (key_idx);
+	    Cell tmp = dotref (key_idx);
 
 	    if (! error_state)
 	      {
-		octave_value_list t_idx = idx.front ();
+		Cell t = tmp.index (idx.front ());
 
-		if (t_idx.length () == 1)
-		  {
-		    idx_vector i = t_idx(0).index_vector ();
-		    octave_value_list t = tmp.index (i);
+		retval = (t.length () == 1) ? t(0) : octave_value (t, true);
 
-		    retval = (t.length () == 1) ? t(0) : octave_value (t, true);
-
-		    // We handled two index elements, so tell
-		    // next_subsref to skip both of them.
+		// We handled two index elements, so tell
+		// next_subsref to skip both of them.
 
-		    skip++;
-		  }
-		else
-		  gripe_invalid_index ();
+		skip++;
 	      }
 	  }
 	else
-	  {
-	    octave_value_list t_idx = idx.front ();
-
-	    if (t_idx.length () == 1)
-	      {
-		idx_vector i = t_idx(0).index_vector ();
-		retval = map.index (i);
-	      }
-	    else
-	      gripe_invalid_index ();
-	  }
+	  retval = map.index (idx.front ());
       }
       break;
 
     case '.':
       {
-	octave_value_list t = dotref (idx.front ());
+	Cell t = dotref (idx.front ());
 
 	retval = (t.length () == 1) ? t(0) : octave_value (t, true);
       }
@@ -164,7 +148,7 @@
 }
 
 octave_value
-octave_struct::numeric_conv (const octave_value_list& val,
+octave_struct::numeric_conv (const Cell& val,
 			     const std::string& type)
 {
   octave_value retval;
@@ -204,48 +188,39 @@
 		std::list<octave_value_list>::const_iterator p = idx.begin ();
 		octave_value_list t_idx = *p;
 
-		if (t_idx.length () == 1)
-		  {
-		    octave_value_list key_idx = *++p;
+		octave_value_list key_idx = *++p;
+
+		assert (key_idx.length () == 1);
 
-		    assert (key_idx.length () == 1);
+		std::string key = key_idx(0).string_value ();
 
-		    std::string key = key_idx(0).string_value ();
-
-		    octave_value u;
+		octave_value u;
 
-		    if (! map.contains (key))
-		      u = octave_value::empty_conv (type.substr (2), rhs);
-		    else
-		      {
-			octave_value_list map_val = map[key];
+		if (! map.contains (key))
+		  u = octave_value::empty_conv (type.substr (2), rhs);
+		else
+		  {
+		    Cell map_val = map[key];
 
-			octave_value_list t_idx = idx.front ();
-
-			idx_vector i = t_idx(0).index_vector ();
+		    Cell map_elt = map_val.index (idx.front (), true);
 
-			octave_value_list map_elt = map_val.index (i, true);
+		    u = numeric_conv (map_elt, type.substr (2));
+		  }
 
-			u = numeric_conv (map_elt, type.substr (2));
-		      }
-
-		    if (! error_state)
-		      {
-			std::list<octave_value_list> next_idx (idx);
+		if (! error_state)
+		  {
+		    std::list<octave_value_list> next_idx (idx);
 
-			// We handled two index elements, so subsasgn to
-			// needs to skip both of them.
-
-			next_idx.erase (next_idx.begin ());
-			next_idx.erase (next_idx.begin ());
+		    // We handled two index elements, so subsasgn to
+		    // needs to skip both of them.
 
-			u.make_unique ();
+		    next_idx.erase (next_idx.begin ());
+		    next_idx.erase (next_idx.begin ());
 
-			t_rhs = u.subsasgn (type.substr (2), next_idx, rhs);
-		      }
+		    u.make_unique ();
+
+		    t_rhs = u.subsasgn (type.substr (2), next_idx, rhs);
 		  }
-		else
-		  gripe_invalid_index_for_assignment ();
 	      }
 	    else
 	      gripe_invalid_index_for_assignment ();
@@ -266,7 +241,7 @@
 	      u = octave_value::empty_conv (type.substr (1), rhs);
 	    else
 	      {
-		octave_value_list map_val = map[key];
+		Cell map_val = map[key];
 
 		u = numeric_conv (map_val, type.substr (1));
 	      }
@@ -310,47 +285,31 @@
 
 		if (! error_state)
 		  {
-		    octave_value_list t_idx = idx.front ();
-
-		    if (t_idx.length () == 1)
-		      {
-			idx_vector i = t_idx(0).index_vector ();
-
-			map.assign (i, key, t_rhs);
+		    map.assign (idx.front (), key, t_rhs);
 
-			if (! error_state)
-			  retval = octave_value (this, count + 1);
-			else
-			  gripe_failed_assignment ();
-		      }
+		    if (! error_state)
+		      retval = octave_value (this, count + 1);
 		    else
-		      gripe_invalid_index_for_assignment ();
+		      gripe_failed_assignment ();
 		  }
 		else
 		  gripe_failed_assignment ();
 	      }
 	    else
 	      {
-		octave_value_list t_idx = idx.front ();
+		Octave_map rhs_map = t_rhs.map_value ();
 
-		if (t_idx.length () == 1)
+		if (! error_state)
 		  {
-		    idx_vector i = t_idx(0).index_vector ();
-
-		    Octave_map rhs_map = t_rhs.map_value ();
+		    map.assign (idx.front (), rhs_map);
 
 		    if (! error_state)
-		      {
-			map.assign (i, rhs_map);
-
-			if (! error_state)
-			  retval = octave_value (this, count + 1);
-			else
-			  gripe_failed_assignment ();
-		      }
+		      retval = octave_value (this, count + 1);
 		    else
-		      error ("invalid structure assignment");
+		      gripe_failed_assignment ();
 		  }
+		else
+		  error ("invalid structure assignment");
 	      }
 	  }
 	  break;
@@ -420,7 +379,7 @@
       for (Octave_map::const_iterator p = map.begin (); p != map.end (); p++)
 	{
 	  std::string key = map.key (p);
-	  octave_value_list val = map.contents (p);
+	  Cell val = map.contents (p);
 
 	  octave_value tmp = (n == 1) ? val(0) : octave_value (val, true);
 
--- a/src/ov-struct.h	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/ov-struct.h	Fri Sep 19 21:41:21 2003 +0000
@@ -67,7 +67,7 @@
   octave_value *clone (void) const { return new octave_struct (*this); }
   octave_value *empty_clone (void) const { return new octave_struct (); }
 
-  octave_value_list dotref (const octave_value_list& idx);
+  Cell dotref (const octave_value_list& idx);
 
   octave_value subsref (const std::string& type,
 			const std::list<octave_value_list>& idx);
@@ -80,7 +80,7 @@
       return octave_value_list ();
     }
 
-  static octave_value numeric_conv (const octave_value_list& val,
+  static octave_value numeric_conv (const Cell& val,
 				    const std::string& type);
 
   octave_value subsasgn (const std::string& type,
--- a/src/ov.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/ov.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -323,10 +323,17 @@
   return retval;
 }
 
+octave_value *
+octave_value::nil_rep (void) const
+{
+  static octave_base_value *nr = new octave_base_value ();
+  return nr;
+}
+
 octave_value::octave_value (void)
-  : rep (new octave_base_value ())
+  : rep (nil_rep ())
 {
-  rep->count = 1;
+  rep->count++;
 }
 
 octave_value::octave_value (short int i)
@@ -393,11 +400,15 @@
   rep->count = 1;
 }
 
-octave_value::octave_value (const Cell& c)
-  : rep (new octave_cell (c))
+octave_value::octave_value (const Cell& c, bool is_cs_list)
+  : rep (0)
 {
+  if (is_cs_list)
+    rep = new octave_cs_list (c);
+  else
+    rep = new octave_cell (c);
+
   rep->count = 1;
-  maybe_mutate ();
 }
 
 octave_value::octave_value (const Matrix& m)
@@ -408,7 +419,7 @@
 }
 
 octave_value::octave_value (const NDArray& a)
-  : rep (new octave_double_nd_array (a))
+  : rep (new octave_matrix (a))
 {
   rep->count = 1;
   maybe_mutate ();
@@ -449,14 +460,12 @@
   maybe_mutate ();
 }
 
-#if 0
-octave_value::octave_value (const ArrayN<Complex>& a)
-  : rep (new octave_complex_nd_array (a))
+octave_value::octave_value (const ComplexNDArray& a)
+  : rep (new octave_complex_matrix (a))
 {
   rep->count = 1;
   maybe_mutate ();
 }
-#endif
 
 octave_value::octave_value (const ComplexDiagMatrix& d)
   : rep (new octave_complex_matrix (d))
@@ -492,6 +501,13 @@
   maybe_mutate ();
 }
 
+octave_value::octave_value (const boolNDArray& bnda)
+  : rep (new octave_bool_matrix (bnda))
+{
+  rep->count = 1;
+  maybe_mutate ();
+}
+
 octave_value::octave_value (char c)
   : rep (new octave_char_matrix_str (c))
 {
@@ -521,13 +537,19 @@
 }
 
 octave_value::octave_value (const charMatrix& chm, bool is_string)
-  : rep (0)
+  : rep (is_string
+	 ? new octave_char_matrix_str (chm)
+	 : new octave_char_matrix (chm))
 {
-  if (is_string)
-    rep = new octave_char_matrix_str (chm);
-  else
-    rep = new octave_char_matrix (chm);
+  rep->count = 1;
+  maybe_mutate ();
+}
 
+octave_value::octave_value (const charNDArray& chm, bool is_string)
+  : rep (is_string
+	 ? new octave_char_matrix_str (chm)
+	 : new octave_char_matrix (chm))
+{
   rep->count = 1;
   maybe_mutate ();
 }
@@ -571,10 +593,8 @@
 }
 
 octave_value::octave_value (const octave_value_list& l, bool is_cs_list)
-  : rep (0)
+  : rep (is_cs_list ? new octave_cs_list (l) : new octave_list (l))
 {
-  rep = is_cs_list ? new octave_cs_list (l) : new octave_list (l);
-
   rep->count = 1;
 }
 
@@ -1751,7 +1771,6 @@
   octave_scalar::register_type ();
   octave_complex::register_type ();
   octave_matrix::register_type ();
-  octave_double_nd_array::register_type ();
   octave_complex_matrix::register_type ();
   octave_range::register_type ();
   octave_bool::register_type ();
--- a/src/ov.h	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/ov.h	Fri Sep 19 21:41:21 2003 +0000
@@ -182,25 +182,28 @@
 
   octave_value (octave_time t);
   octave_value (double d);
-  octave_value (const Cell& m);
+  octave_value (const Cell& m, bool is_cs_list = false);
   octave_value (const Matrix& m);
-  octave_value (const NDArray& m);
+  octave_value (const NDArray& nda);
   octave_value (const DiagMatrix& d);
   octave_value (const RowVector& v);
   octave_value (const ColumnVector& v);
   octave_value (const Complex& C);
   octave_value (const ComplexMatrix& m);
+  octave_value (const ComplexNDArray& cnda);
   octave_value (const ArrayN<Complex>& m);
   octave_value (const ComplexDiagMatrix& d);
   octave_value (const ComplexRowVector& v);
   octave_value (const ComplexColumnVector& v);
   octave_value (bool b);
   octave_value (const boolMatrix& bm);
+  octave_value (const boolNDArray& bnda);
   octave_value (char c);
   octave_value (const char *s);
   octave_value (const std::string& s);
   octave_value (const string_vector& s);
   octave_value (const charMatrix& chm, bool is_string = false);
+  octave_value (const charNDArray& chnda, bool is_string = false);
   octave_value (double base, double limit, double inc);
   octave_value (const Range& r);
   octave_value (const Octave_map& m);
@@ -315,6 +318,9 @@
   virtual int columns (void) const
     { return rep->columns (); }
 
+  virtual dim_vector dims (void) const
+    { return rep->dims (); }
+
   virtual int length (void) const
     { return rep->length (); }
 
@@ -636,6 +642,8 @@
   binary_op op_eq_to_binary_op (assign_op op);
 
   DECLARE_OCTAVE_ALLOCATOR
+
+  octave_value *nil_rep (void) const;
 };
 
 #define OV_UNOP_FN(name) \
--- a/src/pr-output.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/pr-output.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -1485,6 +1485,24 @@
     }
 }
 
+void
+octave_print_internal (std::ostream& os, const NDArray& nda,
+		       bool pr_as_read_syntax, int extra_indent)
+{
+  switch (nda.ndims ())
+    {
+    case 1:
+    case 2:
+      octave_print_internal (os, nda.matrix_value (),
+			     pr_as_read_syntax, extra_indent);
+      break;
+
+    default:
+      os << nda;
+      break;
+    }
+}
+
 static inline void
 pr_plus_format (std::ostream& os, const Complex& c)
 {
@@ -1661,6 +1679,24 @@
 }
 
 void
+octave_print_internal (std::ostream& os, const ComplexNDArray& nda,
+		       bool pr_as_read_syntax, int extra_indent)
+{
+  switch (nda.ndims ())
+    {
+    case 1:
+    case 2:
+      octave_print_internal (os, nda.matrix_value (),
+			     pr_as_read_syntax, extra_indent);
+      break;
+
+    default:
+      os << nda;
+      break;
+    }
+}
+
+void
 octave_print_internal (std::ostream& os, const Range& r,
 		       bool pr_as_read_syntax, int extra_indent)
 {
@@ -1777,6 +1813,25 @@
 }
 
 void
+octave_print_internal (std::ostream& os, const boolNDArray& nda,
+		       bool pr_as_read_syntax,
+		       int extra_indent)
+{
+  switch (nda.ndims ())
+    {
+    case 1:
+    case 2:
+      octave_print_internal (os, nda.matrix_value (),
+			     pr_as_read_syntax, extra_indent);
+      break;
+
+    default:
+      os << nda;
+      break;
+    }
+}
+
+void
 octave_print_internal (std::ostream& os, const charMatrix& chm,
 		       bool pr_as_read_syntax,
 		       int /* extra_indent XXX FIXME XXX */,
@@ -1823,6 +1878,25 @@
     }
 }
 
+void
+octave_print_internal (std::ostream& os, const charNDArray& nda,
+		       bool pr_as_read_syntax, int extra_indent,
+		       bool pr_as_string)
+{
+  switch (nda.ndims ())
+    {
+    case 1:
+    case 2:
+      octave_print_internal (os, nda.matrix_value (),
+			     pr_as_read_syntax, extra_indent, pr_as_string);
+      break;
+
+    default:
+      os << nda;
+      break;
+    }
+}
+
 extern void
 octave_print_internal (std::ostream&, const Cell&, bool, int, bool)
 {
--- a/src/pr-output.h	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/pr-output.h	Fri Sep 19 21:41:21 2003 +0000
@@ -28,10 +28,14 @@
 #include "oct-cmplx.h"
 
 class ComplexMatrix;
+class ComplexNDArray;
 class Matrix;
+class NDArray;
 class Range;
 class boolMatrix;
+class boolNDArray;
 class charMatrix;
+class charNDArray;
 class Cell;
 
 extern void
@@ -44,6 +48,11 @@
 		       int extra_indent = 0);
 
 extern void
+octave_print_internal (std::ostream& os, const NDArray& nda,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0);
+
+extern void
 octave_print_internal (std::ostream& os, const Complex& c,
 		       bool pr_as_read_syntax = false);
 
@@ -53,6 +62,11 @@
 		       int extra_indent = 0);
 
 extern void
+octave_print_internal (std::ostream& os, const ComplexNDArray& nda,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0);
+
+extern void
 octave_print_internal (std::ostream& os, const Range& r,
 		       bool pr_as_read_syntax = false,
 		       int extra_indent = 0);
@@ -63,12 +77,23 @@
 		       int extra_indent = 0);
 
 extern void
+octave_print_internal (std::ostream& os, const boolNDArray& m,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0);
+
+extern void
 octave_print_internal (std::ostream& os, const charMatrix& chm,
 		       bool pr_as_read_syntax = false,
 		       int extra_indent = 0,
 		       bool pr_as_string = false);
 
 extern void
+octave_print_internal (std::ostream& os, const charNDArray& chm,
+		       bool pr_as_read_syntax = false,
+		       int extra_indent = 0,
+		       bool pr_as_string = false);
+
+extern void
 octave_print_internal (std::ostream& os, const Cell& cell,
 		       bool pr_as_read_syntax = false,
 		       int extra_indent = 0,
--- a/src/pt-loop.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/pt-loop.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -379,7 +379,7 @@
 	  {
 	    MAYBE_DO_BREAKPOINT;
 
-	    octave_value_list val_lst = tmp_val.contents (p);
+	    Cell val_lst = tmp_val.contents (p);
 
 	    octave_value val
 	      = (val_lst.length () == 1) ? val_lst(0) : octave_value (val_lst);
@@ -490,7 +490,7 @@
 	{
 	  octave_value key = tmp_val.key (q);
 
-	  octave_value_list val_lst = tmp_val.contents (q);
+	  Cell val_lst = tmp_val.contents (q);
 
 	  int n = tmp_val.array_length ();
 
--- a/src/utils.cc	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/utils.cc	Fri Sep 19 21:41:21 2003 +0000
@@ -766,7 +766,7 @@
 }
 
 void
-check_dimensions (Array<int>& dim, const char *warnfor)
+check_dimensions (dim_vector& dim, const char *warnfor)
 {
   bool neg = false;
 
@@ -788,7 +788,7 @@
 
 void
 get_dimensions (const octave_value& a, const char *warn_for,
-                Array<int>& dim)
+                dim_vector& dim)
 {
   if (a.is_scalar_type ())
     {
--- a/src/utils.h	Sat Sep 13 07:53:55 2003 +0000
+++ b/src/utils.h	Fri Sep 19 21:41:21 2003 +0000
@@ -67,11 +67,11 @@
 extern int check_preference (const std::string& var);
 
 extern void
-check_dimensions (Array<int>& dim, const char *warnfor);
+check_dimensions (dim_vector& dim, const char *warnfor);
 
 extern void
 get_dimensions (const octave_value& a, const char *warn_for,
-                Array<int>& dim);
+                dim_vector& dim);
 
 extern void
 get_dimensions (const octave_value& a, const octave_value& b,
--- a/test/octave.test/matrix/matrix.exp	Sat Sep 13 07:53:55 2003 +0000
+++ b/test/octave.test/matrix/matrix.exp	Fri Sep 19 21:41:21 2003 +0000
@@ -196,7 +196,6 @@
 
 set test ones-2
 set prog_output "^ans = 1";
-setup_xfail *-*-*
 do_test ones-2.m
 
 set test zeros-1
@@ -205,7 +204,6 @@
 
 set test zeros-2
 set prog_output "^ans = 1"
-setup_xfail *-*-*
 do_test zeros-2.m
 
 set test rand-1