changeset 4517:b4449b1193ac

[project @ 2003-09-20 02:06:06 by jwe]
author jwe
date Sat, 20 Sep 2003 02:06:07 +0000
parents 34c934a1b08f
children 382cb0ed8c14
files liboctave/Array-idx.h liboctave/Array.cc liboctave/Array.h liboctave/ChangeLog liboctave/Makefile.in
diffstat 5 files changed, 1748 insertions(+), 1798 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/Array-idx.h	Fri Sep 19 22:04:54 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1724 +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 "Range.h"
-#include "idx-vector.h"
-#include "lo-error.h"
-
-template <class T>
-void
-Array<T>::clear_index (void)
-{
-  delete [] idx;
-  idx = 0;
-  idx_count = 0;
-}
-
-template <class T>
-void
-Array<T>::set_index (const idx_vector& idx_arg)
-{
-  int nd = ndims ();
-
-  if (! idx && nd > 0)
-    idx = new idx_vector [nd];
-
-  if (idx_count < nd)
-    {
-      idx[idx_count++] = idx_arg;
-    }
-  else
-    {
-      idx_vector *new_idx = new idx_vector [idx_count+1];
-
-      for (int i = 0; i < idx_count; i++)
-	new_idx[i] = idx[i];
-
-      new_idx[idx_count++] = idx_arg;
-
-      delete [] idx;
-
-      idx = new_idx;
-    }
-}
-
-template <class T>
-Array<T>
-Array<T>::value (void)
-{
-  Array<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];
-
-      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 ();
-
-  return retval;
-}
-
-template <class T>
-Array<T>
-Array<T>::index (idx_vector& idx_arg, int resize_ok, const T& rfv) const
-{
-  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);
-
-  if (idx_arg)
-    {
-      if (idx_arg.is_colon_equiv (len))
-	{
-	  retval = *this;
-	}
-      else if (n == 0)
-	{
-	  retval.resize_no_fill (0);
-	}
-      else if (len == 1 && n > 1
-	       && idx_arg.one_zero_only ()
-	       && idx_arg.ones_count () == n)
-	{
-	  retval.resize (n, elem (0));
-	}
-      else
-	{
-	  retval.resize_no_fill (n);
-
-	  for (int i = 0; i < n; i++)
-	    {
-	      int ii = idx_arg.elem (i);
-	      if (ii >= len)
-		retval.elem (i) = rfv;
-	      else
-		retval.elem (i) = elem (ii);
-	    }
-	}
-    }
-
-  // idx_vector::freeze() printed an error message for us.
-
-  return retval;
-}
-
-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_no_fill (0);
-  else
-    {
-      int num_to_delete = idx_arg.length (len);
-
-      if (num_to_delete != 0)
-	{
-	  int new_len = len;
-
-	  int iidx = 0;
-
-	  for (int i = 0; i < len; i++)
-	    if (i == idx_arg.elem (iidx))
-	      {
-		iidx++;
-		new_len--;
-
-		if (iidx == num_to_delete)
-		  break;
-	      }
-
-	  if (new_len > 0)
-	    {
-	      T *new_data = new T [new_len];
-
-	      int ii = 0;
-	      iidx = 0;
-	      for (int i = 0; i < len; i++)
-		{
-		  if (iidx < num_to_delete && i == idx_arg.elem (iidx))
-		    iidx++;
-		  else
-		    {
-		      new_data[ii] = elem (i);
-		      ii++;
-		    }
-		}
-
-	      if (--rep->count <= 0)
-		delete rep;
-
-	      rep = new typename Array<T>::ArrayRep (new_data, new_len);
-
-	      dimensions.resize (1);
-	      dimensions(0) = new_len;
-	    }
-	  else
-	    (*current_liboctave_error_handler)
-	      ("A(idx) = []: index out of range");
-	}
-    }
-}
-
-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 ();
-
-  idx_vector lhs_idx = tmp[0];
-
-  int lhs_len = lhs.length ();
-  int rhs_len = rhs.length ();
-
-  int n = lhs_idx.freeze (lhs_len, "vector", true, liboctave_wrore_flag);
-
-  if (n != 0)
-    {
-      if (rhs_len == n || rhs_len == 1)
-	{
-	  int max_idx = lhs_idx.max () + 1;
-	  if (max_idx > lhs_len)
-	    lhs.resize (max_idx, rfv);
-	}
-
-      if (rhs_len == n)
-	{
-	  for (int i = 0; i < n; i++)
-	    {
-	      int ii = lhs_idx.elem (i);
-	      lhs.elem (ii) = rhs.elem (i);
-	    }
-	}
-      else if (rhs_len == 1)
-	{
-	  RT scalar = rhs.elem (0);
-
-	  for (int i = 0; i < n; i++)
-	    {
-	      int ii = lhs_idx.elem (i);
-	      lhs.elem (ii) = scalar;
-	    }
-	}
-      else
-	{
-	  (*current_liboctave_error_handler)
-	    ("A(I) = X: X must be a scalar or a vector with same length as I");
-
-	  retval = 0;
-	}
-    }
-  else if (lhs_idx.is_colon ())
-    {
-      if (lhs_len == 0)
-	{
-	  lhs.resize_no_fill (rhs_len);
-
-	  for (int i = 0; i < rhs_len; i++)
-	    lhs.elem (i) = rhs.elem (i);
-	}
-      else
-	(*current_liboctave_error_handler)
-	  ("A(:) = X: A must be the same size as X");
-    }
-  else if (! (rhs_len == 1 || rhs_len == 0))
-    {
-      (*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;
-    }
-
-  lhs.clear_index ();
-
-  return retval;
-}
-
-/*
-;;; Local Variables: ***
-;;; mode: C++ ***
-;;; End: ***
-*/
--- a/liboctave/Array.cc	Fri Sep 19 22:04:54 2003 +0000
+++ b/liboctave/Array.cc	Sat Sep 20 02:06:07 2003 +0000
@@ -34,7 +34,8 @@
 #include <iostream>
 
 #include "Array.h"
-#include "Array-idx.h"
+#include "Array-flags.h"
+#include "Range.h"
 #include "idx-vector.h"
 #include "lo-error.h"
 
@@ -225,29 +226,6 @@
   return retval;
 }
 
-#if 0
-
-template <class T>
-int
-Array<T>::compute_index (int i, int j) const
-{
-  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
@@ -767,35 +745,6 @@
 }
 
 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
 {
@@ -833,6 +782,1726 @@
 
 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>
+void
+Array<T>::clear_index (void)
+{
+  delete [] idx;
+  idx = 0;
+  idx_count = 0;
+}
+
+template <class T>
+void
+Array<T>::set_index (const idx_vector& idx_arg)
+{
+  int nd = ndims ();
+
+  if (! idx && nd > 0)
+    idx = new idx_vector [nd];
+
+  if (idx_count < nd)
+    {
+      idx[idx_count++] = idx_arg;
+    }
+  else
+    {
+      idx_vector *new_idx = new idx_vector [idx_count+1];
+
+      for (int i = 0; i < idx_count; i++)
+	new_idx[i] = idx[i];
+
+      new_idx[idx_count++] = idx_arg;
+
+      delete [] idx;
+
+      idx = new_idx;
+    }
+}
+
+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_no_fill (0);
+  else
+    {
+      int num_to_delete = idx_arg.length (len);
+
+      if (num_to_delete != 0)
+	{
+	  int new_len = len;
+
+	  int iidx = 0;
+
+	  for (int i = 0; i < len; i++)
+	    if (i == idx_arg.elem (iidx))
+	      {
+		iidx++;
+		new_len--;
+
+		if (iidx == num_to_delete)
+		  break;
+	      }
+
+	  if (new_len > 0)
+	    {
+	      T *new_data = new T [new_len];
+
+	      int ii = 0;
+	      iidx = 0;
+	      for (int i = 0; i < len; i++)
+		{
+		  if (iidx < num_to_delete && i == idx_arg.elem (iidx))
+		    iidx++;
+		  else
+		    {
+		      new_data[ii] = elem (i);
+		      ii++;
+		    }
+		}
+
+	      if (--rep->count <= 0)
+		delete rep;
+
+	      rep = new typename Array<T>::ArrayRep (new_data, new_len);
+
+	      dimensions.resize (1);
+	      dimensions(0) = new_len;
+	    }
+	  else
+	    (*current_liboctave_error_handler)
+	      ("A(idx) = []: index out of range");
+	}
+    }
+}
+
+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.");
+    }
+}
+
+template <class T>
+Array<T>
+Array<T>::value (void)
+{
+  Array<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];
+
+      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 ();
+
+  return retval;
+}
+
+template <class T>
+Array<T>
+Array<T>::index (idx_vector& idx_arg, int resize_ok, const T& rfv) const
+{
+  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);
+
+  if (idx_arg)
+    {
+      if (idx_arg.is_colon_equiv (len))
+	{
+	  retval = *this;
+	}
+      else if (n == 0)
+	{
+	  retval.resize_no_fill (0);
+	}
+      else if (len == 1 && n > 1
+	       && idx_arg.one_zero_only ()
+	       && idx_arg.ones_count () == n)
+	{
+	  retval.resize (n, elem (0));
+	}
+      else
+	{
+	  retval.resize_no_fill (n);
+
+	  for (int i = 0; i < n; i++)
+	    {
+	      int ii = idx_arg.elem (i);
+	      if (ii >= len)
+		retval.elem (i) = rfv;
+	      else
+		retval.elem (i) = elem (ii);
+	    }
+	}
+    }
+
+  // idx_vector::freeze() printed an error message for us.
+
+  return retval;
+}
+
+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;
+}
+
+// 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 ();
+
+  idx_vector lhs_idx = tmp[0];
+
+  int lhs_len = lhs.length ();
+  int rhs_len = rhs.length ();
+
+  int n = lhs_idx.freeze (lhs_len, "vector", true, liboctave_wrore_flag);
+
+  if (n != 0)
+    {
+      if (rhs_len == n || rhs_len == 1)
+	{
+	  int max_idx = lhs_idx.max () + 1;
+	  if (max_idx > lhs_len)
+	    lhs.resize (max_idx, rfv);
+	}
+
+      if (rhs_len == n)
+	{
+	  for (int i = 0; i < n; i++)
+	    {
+	      int ii = lhs_idx.elem (i);
+	      lhs.elem (ii) = rhs.elem (i);
+	    }
+	}
+      else if (rhs_len == 1)
+	{
+	  RT scalar = rhs.elem (0);
+
+	  for (int i = 0; i < n; i++)
+	    {
+	      int ii = lhs_idx.elem (i);
+	      lhs.elem (ii) = scalar;
+	    }
+	}
+      else
+	{
+	  (*current_liboctave_error_handler)
+	    ("A(I) = X: X must be a scalar or a vector with same length as I");
+
+	  retval = 0;
+	}
+    }
+  else if (lhs_idx.is_colon ())
+    {
+      if (lhs_len == 0)
+	{
+	  lhs.resize_no_fill (rhs_len);
+
+	  for (int i = 0; i < rhs_len; i++)
+	    lhs.elem (i) = rhs.elem (i);
+	}
+      else
+	(*current_liboctave_error_handler)
+	  ("A(:) = X: A must be the same size as X");
+    }
+  else if (! (rhs_len == 1 || rhs_len == 0))
+    {
+      (*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;
+    }
+
+  lhs.clear_index ();
+
+  return retval;
+}
+
+template <class T>
+void
 Array<T>::print_info (std::ostream& os, const std::string& prefix) const
 {
   os << prefix << "rep address: " << rep << "\n"
--- a/liboctave/Array.h	Fri Sep 19 22:04:54 2003 +0000
+++ b/liboctave/Array.h	Sat Sep 20 02:06:07 2003 +0000
@@ -66,8 +66,6 @@
     int len;
     int count;
 
-    ArrayRep& operator = (const ArrayRep& a);
-
     ArrayRep (T *d, int l) : data (d), len (l), count (1) { }
 
     ArrayRep (void) : data (0), len (0), count (1) { }
@@ -86,7 +84,7 @@
         for (int i = 0; i < len; i++)
 	  data[i] = a.data[i];
       }
-
+ 
     ~ArrayRep (void) { delete [] data; }
 
     int length (void) const { return len; }
@@ -105,6 +103,12 @@
       {
 	octave_qsort (data, static_cast<size_t> (len), sizeof (T), compare);
       }
+
+  private:
+
+    // No assignment!
+
+    ArrayRep& operator = (const ArrayRep& a);
   };
 
   //--------------------------------------------------------------------
@@ -238,6 +242,8 @@
   static int get_size (int r, int c, int p);
   static int get_size (const dim_vector& dims);
 
+  int compute_index (const Array<int>& ra_idx) const;
+
   T range_error (const char *fcn, int n) const;
   T& range_error (const char *fcn, int n);
 
@@ -388,8 +394,6 @@
   T operator () (const Array<int>& ra_idx) const { return elem (ra_idx); }
 #endif
 
-  int compute_index (const Array<int>& ra_idx) const;
-
 protected:
 
   void resize_no_fill (int n);
@@ -444,6 +448,8 @@
 
   int ndims (void) const { return dimensions.length (); }
 
+  void maybe_delete_dims (void);
+
   void clear_index (void);
 
   void set_index (const idx_vector& i);
@@ -464,8 +470,6 @@
 
   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,
@@ -485,8 +489,6 @@
 
   //  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);
@@ -502,6 +504,8 @@
   template <class LT, class RT>
   friend int
   assignN (Array<LT>& lhs, const Array<RT>& rhs, const LT& rfv);
+
+  void print_info (std::ostream& os, const std::string& prefix) const;
 };
 
 template <class LT, class RT>
--- a/liboctave/ChangeLog	Fri Sep 19 22:04:54 2003 +0000
+++ b/liboctave/ChangeLog	Sat Sep 20 02:06:07 2003 +0000
@@ -1,5 +1,8 @@
 2003-09-19  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
+	* Array.cc: Merge Array-idx.h.
+	* Array-idx.h: Delete.
+
 	* chNDArray.h, chNDArray.cc, boolNDArray.h, boolNDArray.cc: New files.
 
 	* Array.h, Array-idx.h, Array.cc: Fold all N-d functionality here.
--- a/liboctave/Makefile.in	Fri Sep 19 22:04:54 2003 +0000
+++ b/liboctave/Makefile.in	Sat Sep 20 02:06:07 2003 +0000
@@ -26,18 +26,16 @@
 endif
 
 MATRIX_INC := Array.h Array2.h Array3.h ArrayN.h DiagArray2.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 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
+	Array-flags.h ArrayN-idx.h ArrayN-inlines.h MArray-defs.h \
+	MArray.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 \
 	mx-cdm-s.h mx-cm-cdm.h mx-cm-dm.h mx-cm-m.h mx-cm-s.h \