changeset 1560:27a03373de41

[project @ 1995-10-12 07:22:26 by jwe]
author jwe
date Thu, 12 Oct 1995 07:24:52 +0000
parents 1adb4798e5c1
children ffee86c37931
files liboctave/Array-C.cc liboctave/Array-d.cc liboctave/Array.cc liboctave/Array.h liboctave/Makefile.in liboctave/idx-vector.cc liboctave/idx-vector.h
diffstat 7 files changed, 725 insertions(+), 291 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/Array-C.cc	Thu Oct 12 07:22:26 1995 +0000
+++ b/liboctave/Array-C.cc	Thu Oct 12 07:24:52 1995 +0000
@@ -33,6 +33,12 @@
 template class Array2<Complex>;
 template class DiagArray<Complex>;
 
+template void assign (Array<Complex>&, const Array<Complex>&);
+template void assign (Array<Complex>&, const Array<double>&);
+
+template void assign (Array2<Complex>&, const Array2<Complex>&);
+template void assign (Array2<Complex>&, const Array2<double>&);
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/liboctave/Array-d.cc	Thu Oct 12 07:22:26 1995 +0000
+++ b/liboctave/Array-d.cc	Thu Oct 12 07:24:52 1995 +0000
@@ -31,6 +31,10 @@
 template class Array2<double>;
 template class DiagArray<double>;
 
+template void assign (Array<double>&, const Array<double>&);
+
+template void assign (Array2<double>&, const Array2<double>&);
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/liboctave/Array.cc	Thu Oct 12 07:22:26 1995 +0000
+++ b/liboctave/Array.cc	Thu Oct 12 07:24:52 1995 +0000
@@ -31,8 +31,17 @@
 
 #include <cassert>
 
+#include <iostream.h>
+
 #include "Array.h"
 
+#if defined (HEAVYWEIGHT_INDEXING)
+#include "idx-vector.h"
+#include "Array-idx.h"
+#endif
+
+#include "lo-error.h"
+
 // The real representation of all arrays.
 
 template <class T>
@@ -40,6 +49,12 @@
 {
   len = n;
   data = new T [len];
+
+#ifdef HEAVYWEIGHT_INDEXING
+  idx = 0;
+  max_indices = 0;
+  idx_count = 0;
+#endif
 }
 
 template <class T>
@@ -47,16 +62,30 @@
 {
   len = a.len;
   count = a.count;
+
   data = new T [len];
   for (int i = 0; i < len; i++)
     data[i] = a.data[i];
+
+#ifdef HEAVYWEIGHT_INDEXING
+  max_indices = a.max_indices;
+  idx_count = a.idx_count;
+  if (a.idx)
+    {
+      idx_vector *idx = new idx_vector [max_indices];
+      for (int i = 0; i < max_indices; i++)
+	idx[i] = a.idx[i];
+    }
+  else
+    idx = 0;
+#endif
 }
 
 template <class T>
 ArrayRep<T>::~ArrayRep (void)
 {
   delete [] data;
-  data = (T *) 0;
+  delete [] idx;
 }
 
 template <class T>
@@ -97,7 +126,6 @@
       rep = a.rep;
       rep->count++;
     }
-
   return *this;
 }
 
@@ -148,8 +176,7 @@
 {
   if (n < 0)
     {
-      (*current_liboctave_error_handler)
-	("can't resize to negative dimension");
+      (*current_liboctave_error_handler) ("can't resize to negative dimension");
       return;
     }
 
@@ -163,6 +190,8 @@
   rep = new ArrayRep<T> (n);
   rep->count = 1;
 
+  SET_MAX_INDICES (1);
+
   if (old_data && old_len > 0)
     {
       int min_len = old_len < n ? old_len : n;
@@ -181,8 +210,7 @@
 {
   if (n < 0)
     {
-      (*current_liboctave_error_handler)
-	("can't resize to negative dimension");
+      (*current_liboctave_error_handler) ("can't resize to negative dimension");
       return;
     }
 
@@ -196,6 +224,8 @@
   rep = new ArrayRep<T> (n);
   rep->count = 1;
 
+  SET_MAX_INDICES (1);
+
   int min_len = old_len < n ? old_len : n;
 
   if (old_data && old_len > 0)
@@ -280,8 +310,7 @@
 {
   if (r < 0 || c < 0)
     {
-      (*current_liboctave_error_handler)
-	("can't resize to negative dimension");
+      (*current_liboctave_error_handler) ("can't resize to negative dimension");
       return;
     }
 
@@ -290,6 +319,7 @@
 
   ArrayRep<T> *old_rep = rep;
   const T *old_data = data ();
+
   int old_d1 = dim1 ();
   int old_d2 = dim2 ();
   int old_len = length ();
@@ -297,6 +327,8 @@
   rep = new ArrayRep<T> (r*c);
   rep->count = 1;
 
+  SET_MAX_INDICES (2);
+
   d1 = r;
   d2 = c;
 
@@ -320,8 +352,7 @@
 {
   if (r < 0 || c < 0)
     {
-      (*current_liboctave_error_handler)
-	("can't resize to negative dimension");
+      (*current_liboctave_error_handler) ("can't resize to negative dimension");
       return;
     }
 
@@ -337,6 +368,8 @@
   rep = new ArrayRep<T> (r*c);
   rep->count = 1;
 
+  SET_MAX_INDICES (2);
+
   d1 = r;
   d2 = c;
 
@@ -513,8 +546,7 @@
 {
   if (r < 0 || c < 0)
     {
-      (*current_liboctave_error_handler)
-	("can't resize to negative dimensions");
+      (*current_liboctave_error_handler) ("can't resize to negative dimensions");
       return;
     }
 
@@ -530,6 +562,8 @@
   rep = new ArrayRep<T> (new_len);
   rep->count = 1;
 
+  SET_MAX_INDICES (2);
+
   nr = r;
   nc = c;
 
@@ -551,8 +585,7 @@
 {
   if (r < 0 || c < 0)
     {
-      (*current_liboctave_error_handler)
-	("can't resize to negative dimensions");
+      (*current_liboctave_error_handler) ("can't resize to negative dimensions");
       return;
     }
 
@@ -568,6 +601,8 @@
   rep = new ArrayRep<T> (new_len);
   rep->count = 1;
 
+  SET_MAX_INDICES (2);
+
   nr = r;
   nc = c;
 
--- a/liboctave/Array.h	Thu Oct 12 07:22:26 1995 +0000
+++ b/liboctave/Array.h	Thu Oct 12 07:24:52 1995 +0000
@@ -28,10 +28,14 @@
 #pragma interface
 #endif
 
+#define HEAVYWEIGHT_INDEXING 1
+
 #include <cassert>
 
 #include "lo-error.h"
 
+class idx_vector;
+
 // Classes we declare.
 
 template <class T> class ArrayRep;
@@ -40,6 +44,12 @@
 template <class T> class Array3;
 template <class T> class DiagArray;
 
+#ifdef HEAVYWEIGHT_INDEXING
+#define SET_MAX_INDICES(n) set_max_indices (n)
+#else
+#define SET_MAX_INDICES(n)
+#endif
+
 // The real representation of all arrays.
 
 template <class T>
@@ -54,24 +64,42 @@
 
 private:
 
+  T *data;
   int count;
   int len;
-  T *data;
+
+#ifdef HEAVYWEIGHT_INDEXING
+  idx_vector *idx;
+  int max_indices;
+  int idx_count;
+#endif
 
 protected:
 
   ArrayRep (T *d, int l)
     {
+      data = d;
       len = l;
-      data = d;
+
+#ifdef HEAVYWEIGHT_INDEXING
+      idx = 0;
+      max_indices = 0;
+      idx_count = 0;
+#endif
     }
 
 public:
 
   ArrayRep (void)
     {
+      data = 0;
       len = 0;
-      data = 0;
+
+#ifdef HEAVYWEIGHT_INDEXING
+      idx = 0;
+      max_indices = 0;
+      idx_count = 0;
+#endif
     }
 
   ArrayRep (int n);
@@ -86,7 +114,17 @@
 
   T elem (int n) const;
 
-  void resize (int n);
+#ifdef HEAVYWEIGHT_INDEXING
+  void set_max_indices (int mi) { max_indices = mi; }
+
+  void clear_index (void);
+
+  void set_index (const idx_vector& i);
+
+  int index_count (void) const { return idx_count; }
+
+  idx_vector *get_idx (void) const { return idx; }
+#endif
 };
 
 // One dimensional array class.  Handles the reference counting for
@@ -103,20 +141,23 @@
     {
       rep = new ArrayRep<T> (d, l);
       rep->count = 1;
+      set_max_indices (1);
     }
 
 public:
 
   Array (void)
     {
-      rep = new ArrayRep<T>;
+      rep = new ArrayRep<T> ();
       rep->count = 1;
+      set_max_indices (1);
     }
 
   Array (int n)
     {
       rep = new ArrayRep<T> (n);
       rep->count = 1;
+      set_max_indices (1);
     }
 
   Array (int n, const T& val);
@@ -166,8 +207,27 @@
   const T *data (void) const { return rep->data; }
 
   T *fortran_vec (void);
+
+#ifdef HEAVYWEIGHT_INDEXING
+  void set_max_indices (int mi) { rep->set_max_indices (mi); }
+
+  void clear_index (void) { rep->clear_index (); }
+
+  void set_index (const idx_vector& i) { rep->set_index (i); }
+
+  int index_count (void) const { return rep->index_count (); }
+
+  idx_vector *get_idx (void) const { return rep->get_idx (); }
+
+  void maybe_delete_elements (idx_vector& i);
+
+  Array<T> value (void);
+#endif
 };
 
+template <class LT, class RT>
+int assign (Array<LT>& lhs, const Array<RT>& rhs);
+
 // Two dimensional array class.
 
 template <class T>
@@ -175,45 +235,63 @@
 {
 protected:
 
-  int d1;
-  int d2;
-
   Array2 (T *d, int n, int m) : Array<T> (d, n*m)
     {
       d1 = n;
       d2 = m;
+      set_max_indices (2);
     }
 
 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> ()
     {
       d1 = 0;
       d2 = 0;
+      set_max_indices (2);
     }
 
   Array2 (int n, int m) : Array<T> (n*m)
     {
       d1 = n;
       d2 = m;
+      set_max_indices (2);
     }
 
   Array2 (int n, int m, const T& val) : Array<T> (n*m, val)
     {
       d1 = n;
       d2 = m;
+      set_max_indices (2);
     }
 
   Array2 (const Array2<T>& a) : Array<T> (a)
     {
       d1 = a.d1;
       d2 = a.d2;
+      set_max_indices (2);
     }
 
-  Array2 (const DiagArray<T>& a)  : Array<T> (a.rows () * a.cols (), T (0))
+  Array2 (const Array<T>& a, int n, int m) : Array<T> (a)
+    {
+      d1 = n;
+      d2 = m;
+      set_max_indices (2);
+    }
+
+  Array2 (const DiagArray<T>& a) : Array<T> (a.rows () * a.cols (), T (0))
     {
       for (int i = 0; i < a.length (); i++)
 	elem (i, i) = a.elem (i, i);
+
+      set_max_indices (2);
     }
 
   ~Array2 (void) { }
@@ -251,8 +329,17 @@
 
   void resize (int n, int m);
   void resize (int n, int m, const T& val);
+
+#ifdef HEAVYWEIGHT_INDEXING
+  void maybe_delete_elements (idx_vector& i, idx_vector& j);
+
+  Array2<T> value (void);
+#endif
 };
 
+template <class LT, class RT>
+int assign (Array2<LT>& lhs, const Array2<RT>& rhs);
+
 // Three dimensional array class.
 
 template <class T>
@@ -266,6 +353,7 @@
     {
       d2 = m;
       d3 = k;
+      set_max_indices (3);
     }
 
 public:
@@ -274,24 +362,28 @@
     {
       d2 = 0;
       d3 = 0;
+      set_max_indices (3);
     }
 
   Array3 (int n, int m, int k) : Array2<T> (n, m*k)
     {
       d2 = m;
       d3 = k;
+      set_max_indices (3);
     }
 
   Array3 (int n, int m, int k, const T& val) : Array2<T> (n, m*k, val)
     {
       d2 = m;
       d3 = k;
+      set_max_indices (3);
     }
 
   Array3 (const Array3<T>& a) : Array2<T> (a)
     {
       d2 = a.d2;
       d3 = a.d3;
+      set_max_indices (3);
     }
 
   ~Array3 (void) { }
@@ -325,8 +417,17 @@
 
   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
 };
 
+template <class LT, class RT>
+int assign (Array3<LT>& lhs, const Array3<RT>& rhs);
+
 // A two-dimensional array with diagonal elements only.
 //
 // Idea and example code for Proxy class and functions from:
@@ -344,8 +445,8 @@
 class DiagArray : public Array<T>
 {
 private:
-  inline T get (int i) { return Array<T>::elem (i); }
-  inline void set (const T& val, int i) { Array<T>::elem (i) = val; }
+  T get (int i) { return Array<T>::elem (i); }
+  void set (const T& val, int i) { Array<T>::elem (i) = val; }
 
 #if 0
 #if ! (defined (_AIX) && defined (__GNUG__) && __GNUC__ > 1 && __GNUC_MINOR__ < 6)
@@ -353,33 +454,32 @@
   {
   public:
 
-    inline Proxy (DiagArray<T> *ref, int r, int c)
+    Proxy (DiagArray<T> *ref, int r, int c)
       : i (r), j (c), object (ref) { } 
 
-    inline const Proxy& operator = (const T& val) const
-    {
-      if (i == j)
-	{
-	  if (object)
-	    object->set (val, i);
-	}
-      else
-	(*current_liboctave_error_handler)
-	  ("assignment to off-diagonal element attempted for diagonal array");
+    const Proxy& operator = (const T& val) const
+      {
+	if (i == j)
+	  {
+	    if (object)
+	      object->set (val, i);
+	  }
+	else
+	  (*current_liboctave_error_handler) ("invalid assignment to off-diagonal in diagonal array");
 
-      return *this;
-    }
+	return *this;
+      }
 
-    inline operator T () const
-    {
-      if (object && i == j)
-	return object->get (i);
-      else
-	{
-	  static T foo (0);
-	  return foo;
-	}
-    }
+    operator T () const
+      {
+	if (object && i == j)
+	  return object->get (i);
+	else
+	  {
+	    static T foo (0);
+	    return foo;
+	  }
+      }
 
   private:
 
@@ -387,7 +487,7 @@
     // taking the address of a Proxy.  Maybe it should be implemented
     // by means of a companion function in the DiagArray class.
 
-    inline T *operator& () const { assert (0); return (T *) 0; }
+    T *operator& () const { assert (0); return (T *) 0; }
 
     int i;
     int j;
@@ -409,6 +509,7 @@
     {
       nr = r;
       nc = c;
+      set_max_indices (2);
     }
 
 public:
@@ -417,57 +518,64 @@
     {
       nr = 0;
       nc = 0;
+      set_max_indices (2);
     }
 
   DiagArray (int n) : Array<T> (n)
-{
-  nr = n;
-  nc = n;
-}
+    {
+      nr = n;
+      nc = n;
+      set_max_indices (2);
+    }
 
   DiagArray (int n, const T& val) : Array<T> (n, val)
-{
-  nr = n;
-  nc = n;
-}
+    {
+      nr = n;
+      nc = n;
+      set_max_indices (2);
+    }
 
   DiagArray (int r, int c) : Array<T> (r < c ? r : c)
-{
-  nr = r;
-  nc = c;
-}
+    {
+      nr = r;
+      nc = c;
+      set_max_indices (2);
+    }
 
   DiagArray (int r, int c, const T& val) : Array<T> (r < c ? r : c, val)
-{
-  nr = r;
-  nc = c;
-}
+    {
+      nr = r;
+      nc = c;
+      set_max_indices (2);
+    }
 
   DiagArray (const Array<T>& a) : Array<T> (a)
-{
-  nr = nc = a.length ();
-}
+    {
+      nr = nc = a.length ();
+      set_max_indices (2);
+    }
 
   DiagArray (const DiagArray<T>& a) : Array<T> (a)
-{
-  nr = a.nr;
-  nc = a.nc;
-}
+    {
+      nr = a.nr;
+      nc = a.nc;
+      set_max_indices (2);
+    }
 
   ~DiagArray (void) { }
 
   DiagArray<T>& operator = (const DiagArray<T>& a)
-{
-  if (this != &a)
     {
-      Array<T>::operator = (a);
-      nr = a.nr;
-      nc = a.nc;
+      if (this != &a)
+	{
+	  Array<T>::operator = (a);
+	  nr = a.nr;
+	  nc = a.nc;
+	}
+
+      return *this;
     }
 
-  return *this;
-}
-
   int dim1 (void) const { return nr; }
   int dim2 (void) const { return nc; }
 
@@ -476,31 +584,31 @@
   int columns (void) const { return nc; }
 
 #if 0
-  inline Proxy elem (int r, int c)
-  {
-    return Proxy (this, r, c);
-  }
+  Proxy elem (int r, int c)
+    {
+      return Proxy (this, r, c);
+    }
 
-  inline Proxy checkelem (int r, int c)
-  {
-    if (r < 0 || c < 0 || r >= nr || c >= nc)
-      {
-	(*current_liboctave_error_handler) ("range error");
-	return Proxy (0, r, c);
-      }
-    else
-      return Proxy (this, r, c);
-  }
+  Proxy checkelem (int r, int c)
+    {
+      if (r < 0 || c < 0 || r >= nr || c >= nc)
+	{
+	  (*current_liboctave_error_handler) ("range error");
+	  return Proxy (0, r, c);
+	}
+      else
+	return Proxy (this, r, c);
+    }
 
-  inline Proxy operator () (int r, int c)
-  {
-    if (r < 0 || c < 0 || r >= nr || c >= nc)
-      {
-	(*current_liboctave_error_handler) ("range error");
-	return Proxy (0, r, c);
-      }
-    else
-      return Proxy (this, r, c);
+  Proxy operator () (int r, int c)
+    {
+      if (r < 0 || c < 0 || r >= nr || c >= nc)
+	{
+	  (*current_liboctave_error_handler) ("range error");
+	  return Proxy (0, r, c);
+	}
+      else
+	return Proxy (this, r, c);
   }
 #else
   T& elem (int r, int c);
@@ -518,6 +626,8 @@
 
   void resize (int n, int m);
   void resize (int n, int m, const T& val);
+
+  void maybe_delete_elements (idx_vector& i, idx_vector& j);
 };
 
 #endif
--- a/liboctave/Makefile.in	Thu Oct 12 07:22:26 1995 +0000
+++ b/liboctave/Makefile.in	Thu Oct 12 07:24:52 1995 +0000
@@ -18,10 +18,10 @@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_DATA = @INSTALL_DATA@
 
-MATRIX_INC = Array.h MArray.h Matrix.h mx-base.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 \
+MATRIX_INC = Array.h Array-idx.h MArray.h Matrix.h mx-base.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 \
 	dColVector.h dDiagMatrix.h dMatrix.h dRowVector.h dbleAEPBAL.h \
 	dbleCHOL.h dbleDET.h dbleGEPBAL.h dbleHESS.h dbleLU.h dbleQR.h \
 	dbleQRP.h dbleSCHUR.h dbleSVD.h
@@ -37,7 +37,8 @@
 
 TI_SRC = Array-C.cc Array-i.cc Array-d.cc MArray-C.cc MArray-d.cc
 
-MATRIX_SRC = CColVector.cc CDiagMatrix.cc CMatrix.cc CRowVector.cc \
+MATRIX_SRC = Array-ext.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 \
 	dColVector.cc dDiagMatrix.cc dMatrix.cc dRowVector.cc \
--- a/liboctave/idx-vector.cc	Thu Oct 12 07:22:26 1995 +0000
+++ b/liboctave/idx-vector.cc	Thu Oct 12 07:24:52 1995 +0000
@@ -34,17 +34,26 @@
 #include <iostream.h>
 
 #include "Range.h"
+#include "dColVector.h"
 #include "dMatrix.h"
 
-#include "error.h"
 #include "idx-vector.h"
-#include "user-prefs.h"
-#include "utils.h"
+#include "lo-error.h"
 
-idx_vector::idx_vector (const idx_vector& a)
+#define IDX_VEC_REP idx_vector::idx_vector_rep
+
+IDX_VEC_REP::idx_vector_rep (const IDX_VEC_REP& a)
 {
   data = 0;
   initialized = a.initialized;
+  frozen = a.frozen;
+  colon_equiv_checked = a.colon_equiv_checked;
+  colon_equiv = a.colon_equiv;
+
+  colon = a.colon;
+
+  orig_nr = a.orig_nr;
+  orig_nc = a.orig_nc;
 
   len = a.len;
   if (len > 0)
@@ -71,65 +80,93 @@
     return ((int) (x - 0.5) - 1);
 }
 
-idx_vector::idx_vector (const Matrix& m, int do_ftn_idx,
-			const char *rc, int z_len)
+IDX_VEC_REP::idx_vector_rep (const ColumnVector& v)
 {
   data = 0;
   initialized = 0;
-
-  int nr = m.rows ();
-  int nc = m.columns ();
+  frozen = 0;
+  colon_equiv_checked = 0;
+  colon_equiv = 0;
+  colon = 0;
 
-  if (nr == 0 || nc == 0)
+  int len = v.length ();
+
+  orig_nr = len;
+  orig_nc = 1;
+
+  if (len == 0)
     {
-      len = 0;
       num_zeros = 0;
       num_ones = 0;
       one_zero = 0;
+      max_val = 0;
+      min_val = 0;
       initialized = 1;
       return;
     }
-  else if (nr > 1 && nc > 1 && do_ftn_idx)
+  else
     {
-      const double *cop_out = m.data ();
-      len = nr * nc;
       data = new int [len];
       for (int i = 0; i < len; i++)
-	data[i] = tree_to_mat_idx (*cop_out++);
+	data[i] = tree_to_mat_idx (v.elem (i));
     }
-  else if (nr == 1 && nc > 0)
+
+  init_state ();
+}
+
+IDX_VEC_REP::idx_vector_rep (const Matrix& m)
+{
+  data = 0;
+  initialized = 0;
+  frozen = 0;
+  colon_equiv_checked = 0;
+  colon_equiv = 0;
+  colon = 0;
+
+  orig_nr = m.rows ();
+  orig_nc = m.columns ();
+
+  len = orig_nr * orig_nc;
+
+  if (len == 0)
     {
-      len = nc;
-      data = new int [len];
-      for (int i = 0; i < len; i++)
-	data[i] = tree_to_mat_idx (m.elem (0, i)); 
-    }  
-  else if (nc == 1 && nr > 0)
-    {
-      len = nr;
-      data = new int [len];
-      for (int i = 0; i < len; i++)
-	data[i] = tree_to_mat_idx (m.elem (i, 0));
+      num_zeros = 0;
+      num_ones = 0;
+      one_zero = 0;
+      max_val = 0;
+      min_val = 0;
+      initialized = 1;
+      return;
     }
   else
     {
-      ::error ("invalid matrix used as index");
-      return;
+      int k = 0;
+      data = new int [len];
+      for (int j = 0; j < orig_nc; j++)
+	for (int i = 0; i < orig_nr; i++)
+	  data[k++] = tree_to_mat_idx (m.elem (i, j));
     }
 
-  init_state (rc, z_len);
+  init_state ();
 }
 
-idx_vector::idx_vector (const Range& r)
+IDX_VEC_REP::idx_vector_rep (const Range& r)
 {
   data = 0;
   initialized = 0;
+  frozen = 0;
+  colon_equiv_checked = 0;
+  colon_equiv = 0;
+  colon = 0;
 
   len = r.nelem ();
 
+  orig_nr = 1;
+  orig_nc = len;
+
   if (len < 0)
     {
-      ::error ("invalid range used as index");
+      (*current_liboctave_error_handler) ("invalid range used as index");
       return;
     }
   else if (len == 0)
@@ -137,6 +174,8 @@
       num_zeros = 0;
       num_ones = 0;
       one_zero = 0;
+      max_val = 0;
+      min_val = 0;
       initialized = 1;
       return;
     }
@@ -155,12 +194,38 @@
   init_state ();
 }
 
-idx_vector&
-idx_vector::operator = (const idx_vector& a)
+IDX_VEC_REP::idx_vector_rep (char c)
+{
+  assert (c == ':');
+
+  colon = 1;
+  len = 0;
+  num_zeros = 0;
+  num_ones = 0;
+  one_zero = 0;
+  initialized = 0;
+  frozen = 0;
+  colon_equiv_checked = 0;
+  colon_equiv = 0;
+  data = 0;
+
+  init_state ();
+}
+
+IDX_VEC_REP&
+IDX_VEC_REP::operator = (const IDX_VEC_REP& a)
 {
   if (this != &a)
     {
       initialized = a.initialized;
+      frozen = a.frozen;
+      colon_equiv_checked = a.colon_equiv_checked;
+      colon_equiv = a.colon_equiv;
+
+      colon = a.colon;
+
+      orig_nr = a.orig_nr;
+      orig_nc = a.orig_nc;
 
       delete [] data;
       len = a.len;
@@ -179,90 +244,33 @@
 }
 
 void
-idx_vector::init_state (const char *rc, int z_len)
+IDX_VEC_REP::init_state (void)
 {
-  one_zero = 1;
   num_zeros = 0;
   num_ones = 0;
 
-  min_val = max_val = data[0];
-
-  int i = 0;
-  do
-    {
-      if (data[i] == -1)
-	num_zeros++;
-      else if (data[i] == 0)
-	num_ones++;
-
-      if (one_zero && data[i] != -1 && data[i] != 0)
-	one_zero = 0;
-
-      if (data[i] > max_val)
-	max_val = data[i];
-
-      if (data[i] < min_val)
-	min_val = data[i];
-    }
-  while (++i < len);
-
-  if (one_zero && z_len == len)
-    {
-      if (num_ones != len || user_pref.prefer_zero_one_indexing)
-	convert_one_zero_to_idx ();
-    }
-  else if (min_val < 0)
+  if (colon)
     {
-      ::error ("%s index %d out of range", rc, min_val+1);
-      initialized = 0;
-      return;
-    }
-#if 0
-  // Checking max index against size won't work right here unless we
-  // also look at resize on range error, and we have to do that later
-  // on anyway.
-
-  else if (max_val >= z_len)
-    {
-      ::error ("%s index %d out of range", rc, max_val+1);
-      initialized = 0;
-      return;
-    }
-#endif
-
-  initialized = 1;
-}
-
-void
-idx_vector::convert_one_zero_to_idx (void)
-{
-  if (num_ones == 0)
-    {
-      len = 0;
-      max_val = 0;
-      min_val = 0;
-      delete [] data;
-      data = 0;
+      one_zero = 0;
+      min_val = max_val = 0;
     }
   else
     {
-      assert (num_ones + num_zeros == len);
-
-      int *new_data = new int [num_ones];
-      int count = 0;
-      for (int i = 0; i < len; i++)
-	if (data[i] == 0)
-	  new_data[count++] = i;
-
-      delete [] data;
-      len = num_ones;
-      data = new_data;
+      one_zero = 1;
 
       min_val = max_val = data[0];
 
       int i = 0;
       do
 	{
+	  if (data[i] == -1)
+	    num_zeros++;
+	  else if (data[i] == 0)
+	    num_ones++;
+
+	  if (one_zero && data[i] != -1 && data[i] != 0)
+	    one_zero = 0;
+
 	  if (data[i] > max_val)
 	    max_val = data[i];
 
@@ -271,14 +279,60 @@
 	}
       while (++i < len);
     }
+
+  initialized = 1;
+}
+
+void
+IDX_VEC_REP::maybe_convert_one_zero_to_idx (int z_len, int prefer_zero_one)
+{
+  if (one_zero && z_len == len
+      && (num_ones != len || prefer_zero_one))
+    {
+      if (num_ones == 0)
+	{
+	  len = 0;
+	  max_val = 0;
+	  min_val = 0;
+	  delete [] data;
+	  data = 0;
+	}
+      else
+	{
+	  assert (num_ones + num_zeros == len);
+
+	  int *new_data = new int [num_ones];
+	  int count = 0;
+	  for (int i = 0; i < len; i++)
+	    if (data[i] == 0)
+	      new_data[count++] = i;
+
+	  delete [] data;
+	  len = num_ones;
+	  data = new_data;
+
+	  min_val = max_val = data[0];
+
+	  int i = 0;
+	  do
+	    {
+	      if (data[i] > max_val)
+		max_val = data[i];
+
+	      if (data[i] < min_val)
+		min_val = data[i];
+	    }
+	  while (++i < len);
+	}
+    }
 }
 
 int
-idx_vector::checkelem (int n) const
+IDX_VEC_REP::checkelem (int n) const
 {
   if (n < 0 || n >= len)
     {
-      ::error ("idx-vector: index out of range");
+      (*current_liboctave_error_handler) ("idx-vector: index out of range");
       return 0;
     }
 
@@ -291,52 +345,147 @@
   return (*i - *j);
 }
 
-void
-idx_vector::sort (void)
+static inline void
+sort_data (int *d, int len)
+{
+  qsort ((void *) d, len, sizeof (int),
+	 (int (*)(const void*, const void*)) intcmp);
+}
+
+static inline int
+make_uniq (int *d, int len)
+{
+  int k = 0;
+  for (int i = 1; i < len; i++)
+    {
+      if (d[i] != d[k])
+	{
+	  k++;
+	  d[k] = d[i];
+	}
+    }
+  return k+1;
+}
+
+static inline int *
+copy_data (const int *d, int len)
 {
-  qsort ((void *) data, len, sizeof (int),
-	 (int (*)(const void*, const void*)) intcmp); 
+  int *new_data = new int [len];
+
+  for (int i = 0; i < len; i++)
+    new_data[i] = d[i];
+
+  return new_data;
+}
+
+int
+IDX_VEC_REP::is_colon_equiv (int n, int sort)
+{
+  if (! colon_equiv_checked)
+    {
+      if (colon)
+	{
+	  colon_equiv = 1;
+	}
+      else if (len > 0)
+	{
+	  int *tmp_data = copy_data (data, len);
+
+	  if (sort)
+	    sort_data (tmp_data, len);
+
+	  int tmp_len = make_uniq (tmp_data, len);
+
+	  colon_equiv = ((tmp_len == 0 && n == 0)
+			 || (tmp_len == n
+			     && tmp_data[0] == 0
+			     && tmp_data[tmp_len-1] == tmp_len - 1));
+
+	  delete [] tmp_data;
+	}
+      else
+	colon_equiv = 0;
+
+      colon_equiv_checked = 1;
+    }
+
+  return colon_equiv;
 }
 
 void
-idx_vector::sort_uniq (void)
-{
-  if (len > 0)
-    {
-      sort ();
-
-      int *new_data = new int [len];
-      new_data[0] = data[0];
-      int k = 0;
-      for (int i = 1; i < len; i++)
-	{
-	  if (data[i] != new_data[k])
-	    {
-	      k++;
-	      new_data[k] = data[i];
-	    }
-	}
-      delete [] data;
-      len = k+1;
-      data = new_data;
-    }
-}
-
-void
-idx_vector::shorten (int n)
+IDX_VEC_REP::shorten (int n)
 {
   if (n > 0 && n <= len)
     len = n;
   else
-    panic_impossible ();
+    (*current_liboctave_error_handler)
+      ("idx_vector::shorten: internal error!");
 }
 
 ostream&
-operator << (ostream& os, const idx_vector& a)
+IDX_VEC_REP::print (ostream& os) const
+{
+  for (int i = 0; i < len; i++)
+    os << data[i] << "\n";
+  return os;
+}
+
+int
+IDX_VEC_REP::freeze (int z_len, const char *tag,
+		     int prefer_zero_one, int resize_ok)
 {
-  for (int i = 0; i < a.len; i++)
-    os << a.data[i] << "\n";
-  return os;
+  if (frozen)
+    {
+      assert (frozen_at_z_len == z_len);
+      return frozen_len;
+    }
+
+  frozen_len = -1;
+
+  if (colon)
+    frozen_len = z_len;
+  else
+    {
+      if (len == 0)
+	frozen_len = 0;
+      else
+	{
+	  maybe_convert_one_zero_to_idx (z_len, prefer_zero_one);
+
+	  int max_val = max ();
+	  int min_val = min ();
+
+	  if (min_val < 0)
+	    {
+	      if (tag)
+		(*current_liboctave_error_handler)
+		  ("invalid %s index = %d", tag, min_val+1);
+	      else
+		(*current_liboctave_error_handler)
+		  ("invalid index = %d", min_val+1);
+
+	      initialized = 0;
+	    }
+	  else if (! resize_ok && max_val >= z_len)
+	    {
+	      if (tag)
+		(*current_liboctave_error_handler)
+		  ("invalid %s index = %d", tag, max_val+1);
+	      else
+		(*current_liboctave_error_handler)
+		  ("invalid index = %d", max_val+1);
+
+	      initialized = 0;
+	    }
+	  else
+	    frozen_len = length (z_len);
+	}
+    }
+
+  frozen = 1;
+  frozen_at_z_len = z_len;
+
+  return frozen_len;
 }
 
 /*
--- a/liboctave/idx-vector.h	Thu Oct 12 07:22:26 1995 +0000
+++ b/liboctave/idx-vector.h	Thu Oct 12 07:24:52 1995 +0000
@@ -29,78 +29,207 @@
 #endif
 
 class ostream;
+class ColumnVector;
 class Matrix;
 class Range;
 
 class
 idx_vector
 {
+private:
+
+  struct
+  idx_vector_rep
+    {
+      idx_vector_rep::idx_vector_rep (void)
+	{
+	  colon = 0;
+	  len = 0;
+	  num_zeros = 0;
+	  num_ones = 0;
+	  one_zero = 0;
+	  orig_nr = 0;
+	  orig_nc = 0;
+	  initialized = 0;
+	  frozen = 0;
+	  colon_equiv_checked = 0;
+	  colon_equiv = 0;
+	  data = 0;
+	}
+
+      idx_vector_rep (const ColumnVector& v);
+
+      idx_vector_rep (const Matrix& m);
+
+      idx_vector_rep (const Range& r);
+
+      idx_vector_rep (char c);
+
+      idx_vector_rep (const idx_vector_rep& a);
+
+      idx_vector_rep::~idx_vector_rep (void) { delete [] data; }
+
+      idx_vector_rep& operator = (const idx_vector_rep& a);
+
+      int ok (void) { return initialized; }
+
+      int capacity (void) const { return len; }
+      int length (int colon_len) const { return colon ? colon_len : len; }
+
+      int elem (int n) const { return colon ? n : data[n]; }
+
+      int checkelem (int n) const;
+      int operator () (int n) const { return checkelem (n); }
+	  
+      int max (void) const { return max_val; }
+      int min (void) const { return min_val; }
+	  
+      int one_zero_only (void) const { return one_zero; }
+      int zeros_count (void) const { return num_zeros; }
+      int ones_count (void) const { return num_ones; }
+
+      int is_colon (void) const { return colon; }
+      int is_colon_equiv (int n, int sort);
+
+      int orig_rows (void) const { return orig_nr; }
+      int orig_columns (void) const { return orig_nc; }
+
+      // other stuff
+
+      void shorten (int n); // Unsafe.  Avoid at all cost.
+
+      int freeze (int z_len, const char *tag, int prefer_zero_one,
+		  int resize_ok);
+
+      // i/o
+
+      ostream& print (ostream& os) const;
+
+      int *data;
+      int len;
+      int num_zeros;
+      int num_ones;
+      int max_val;
+      int min_val;
+      int orig_nr;
+      int orig_nc;
+      int count;
+      int frozen_at_z_len;
+      int frozen_len;
+      unsigned int colon : 1;
+      unsigned int one_zero : 1;
+      unsigned int initialized : 1;
+      unsigned int frozen : 1;
+      unsigned int colon_equiv_checked : 1;
+      unsigned int colon_equiv : 1;
+
+      void init_state (void);
+
+      void maybe_convert_one_zero_to_idx (int z_len, int prefer_zero_one);
+    };
+
 public:
 
   idx_vector::idx_vector (void)
     {
-      len = 0;
-      num_zeros = 0;
-      num_ones = 0;
-      one_zero = 0;
-      initialized = 0;
-      data = 0;
+      rep = new idx_vector_rep ();
+      rep->count = 1;
+    }
+
+  idx_vector (const ColumnVector& v)
+    {
+      rep = new idx_vector_rep (v);
+      rep->count = 1;
+    }
+
+  idx_vector (const Matrix& m)
+    {
+      rep = new idx_vector_rep (m);
+      rep->count = 1;
+    }
+
+  idx_vector (const Range& r)
+    {
+      rep = new idx_vector_rep (r);
+      rep->count = 1;
+    }
+
+  idx_vector (char c)
+    {
+      rep = new idx_vector_rep (c);
+      rep->count = 1;
+    }
+
+  idx_vector (const idx_vector& a)
+    {
+      rep = a.rep;
+      rep->count++;
     }
 
-  idx_vector (const idx_vector& a);
-
-  idx_vector (const Matrix& m, int do_ftn_idx,
-	      const char *rc = 0, int z_len = 0);
-
-  idx_vector (const Range& r);
+  idx_vector::~idx_vector (void)
+    {
+      if (--rep->count <= 0)
+	delete rep;
+    }
 
-  idx_vector::~idx_vector (void) { delete [] data; }
-
-  idx_vector& operator = (const idx_vector& a);
+  idx_vector& operator = (const idx_vector& a)
+    {
+      if (this != &a)
+	{
+	  if (--rep->count <= 0)
+	    delete rep;
 
-  idx_vector::operator void * () const
-    {
-      return initialized ? (void *) 1 : (void *) 0;
+	  rep = a.rep;
+	  rep->count++;
+	}
+      return *this;
     }
 
-  int idx_vector::capacity (void) const { return len; }
-  int idx_vector::length (void) const { return len; }
+  idx_vector::operator void * () const { return (void *) rep->ok (); }
+
+  int idx_vector::capacity (void) const { return rep->capacity (); }
+  int idx_vector::length (int cl) const { return rep->length (cl); }
 
-  int idx_vector::elem (int n) const { return data[n]; }
-  int idx_vector::checkelem (int n) const;
-  int idx_vector::operator () (int n) const { return checkelem (n); }
+  int idx_vector::elem (int n) const { return rep->elem (n); }
+  int idx_vector::checkelem (int n) const { return rep->checkelem (n); }
+  int idx_vector::operator () (int n) const { return rep->operator () (n); }
 
-  int idx_vector::max (void) const { return max_val; }
-  int idx_vector::min (void) const { return min_val; }
+  int idx_vector::max (void) const { return rep->max (); }
+  int idx_vector::min (void) const { return rep->min (); }
 
-  int idx_vector::one_zero_only (void) const { return one_zero; }
-  int idx_vector::zeros_count (void) const { return num_zeros; }
-  int idx_vector::ones_count (void) const { return num_ones; }
+  int idx_vector::one_zero_only (void) const { return rep->one_zero_only (); }
+  int idx_vector::zeros_count (void) const { return rep->zeros_count (); }
+  int idx_vector::ones_count (void) const { return rep->ones_count (); }
 
-// other stuff
+  int is_colon (void) const { return rep->is_colon (); }
+  int is_colon_equiv (int n, int sort = 0) const
+    { return rep->is_colon_equiv (n, sort); }
 
-  void sort (void);
-  void sort_uniq (void);
+  int orig_rows (void) const { return rep->orig_rows (); }
+  int orig_columns (void) const { return rep->orig_columns (); }
 
-  void shorten (int n); // Unsafe.  Avoid at all cost.
+// Unsafe.  Avoid at all cost.
+  void shorten (int n) { rep->shorten (n); }
 
 // i/o
 
-  friend ostream& operator << (ostream& os, const idx_vector& a);
+  int freeze (int z_len, const char *tag, int prefer_zero_one = 0,
+	      int resize_ok = 0)
+    { return rep->freeze (z_len, tag, prefer_zero_one, resize_ok); }
+
+  ostream& print (ostream& os) const { return rep->print (os); }
+
+  friend ostream& operator << (ostream& os, const idx_vector& a)
+    { return a.print (os); }
+
+  void maybe_convert_one_zero_to_idx (int z_len, int prefer_zero_one = 0)
+    { rep->maybe_convert_one_zero_to_idx (z_len, prefer_zero_one); }
 
 private:
 
-  int *data;
-  int len;
-  int num_zeros;
-  int num_ones;
-  int max_val;
-  int min_val;
-  unsigned int one_zero : 1;
-  unsigned int initialized : 1;
+  idx_vector_rep *rep;
 
-  void init_state (const char *rc = 0, int z_len = 0);
-  void convert_one_zero_to_idx (void);
+  void init_state (void) { rep->init_state (); }
 };
 
 #endif