changeset 4505:e944fbe3fff2

[project @ 2003-09-09 19:14:06 by jwe]
author jwe
date Tue, 09 Sep 2003 19:14:06 +0000
parents f6a61399bc5c
children 3c82fc8f822c
files liboctave/Array-d.cc liboctave/ArrayN-idx.h liboctave/ChangeLog src/ChangeLog src/Makefile.in src/OPERATORS/op-m-nd.cc src/OPERATORS/op-nd-m.cc src/OPERATORS/op-nd-nd.cc src/OPERATORS/op-nd-s.cc src/OPERATORS/op-s-nd.cc src/ov-base.cc src/ov-base.h src/ov-re-mat.h src/ov-re-nd-array.cc src/ov-re-nd-array.h src/ov-scalar.h src/ov.cc src/ov.h
diffstat 18 files changed, 552 insertions(+), 67 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/Array-d.cc	Tue Sep 09 17:49:13 2003 +0000
+++ b/liboctave/Array-d.cc	Tue Sep 09 19:14:06 2003 +0000
@@ -60,6 +60,17 @@
 #include "ArrayN.cc"
 
 template class ArrayN<double>;
+
+template int assign (ArrayN<double>&, const ArrayN<double>&);
+template int assign (ArrayN<double>&, const ArrayN<int>&);
+template int assign (ArrayN<double>&, const ArrayN<short>&);
+template int assign (ArrayN<double>&, const ArrayN<char>&);
+
+template int assign (ArrayN<double>&, const ArrayN<double>&, const double&);
+template int assign (ArrayN<double>&, const ArrayN<int>&, const double&);
+template int assign (ArrayN<double>&, const ArrayN<short>&, const double&);
+template int assign (ArrayN<double>&, const ArrayN<char>&, const double&);
+
 template std::ostream& operator << (std::ostream&, const ArrayN<double>&);
 
 #include "DiagArray2.h"
--- a/liboctave/ArrayN-idx.h	Tue Sep 09 17:49:13 2003 +0000
+++ b/liboctave/ArrayN-idx.h	Tue Sep 09 19:14:06 2003 +0000
@@ -22,6 +22,7 @@
 */
 
 #include "Array-flags.h"
+#include "Range.h"
 #include "idx-vector.h"
 #include "lo-error.h"
 
--- a/liboctave/ChangeLog	Tue Sep 09 17:49:13 2003 +0000
+++ b/liboctave/ChangeLog	Tue Sep 09 19:14:06 2003 +0000
@@ -1,3 +1,7 @@
+2003-09-09  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* Array-d.cc: Instantiate assign functions.
+
 2003-09-09  Petter Risholm  <risholm@stud.ntnu.no>
 
 	* ArrayN-idx.h (vector_equivalent, equal_arrays): New functions.
--- a/src/ChangeLog	Tue Sep 09 17:49:13 2003 +0000
+++ b/src/ChangeLog	Tue Sep 09 19:14:06 2003 +0000
@@ -1,3 +1,34 @@
+2003-09-09  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* ov.h (octave_value::double_nd_array_value): New function.
+	(octave_value::is_real_nd_array): New function.
+
+	* ov-base.cc (octave_base_value::double_nd_array_value): New function.
+	* ov-base.h: Provide decl.
+	(octave_base_value::is_real_nd_array): New function.
+
+2003-09-09  Petter Risholm  <risholm@stud.ntnu.no>
+
+	* ov-re-mat.h (octave_matrix::double_nd_array_value): New function.
+	* ov-scalar.h (octave_scalar::double_nd_array_value): New function.
+
+	* ov-re-nd-array.cc (octave_double_nd_array::assign): New function.
+	(octave_double_nd_array::try_narrowing_conversion): Likewise.
+	(octave_double_nd_array::valid_as_scalar_index): Likewise.
+	(octave_double_nd_array::double_value): Likewise.
+	(octave_double_nd_array::matrix_value): Likewise.
+	(octave_double_nd_array::complex_value): Likewise.
+	(octave_double_nd_array::convert_slice_to_matrix): Likewise.
+	* ov-re-nd-array.h: Provide decls.
+	(octave_double_nd_array::is_real_nd_array): New function.
+	(octave_double_nd_array::double_nd_array_value): New function.
+	(octave_double_nd_array::double_nd_array_value): New function.
+
+	* OPERATORS/op-m-nd.cc, OPERATORS/op-nd-m.cc,
+	OPERATORS/op-nd-nd.cc, OPERATORS/op-nd-s.cc, OPERATORS/op-s-nd.cc:
+	New files.
+	* Makefile.in (OP_XSRC): Add them to the list.
+
 2003-09-08  D.  <dbateman@free.fr>
 
 	* OPERATORS/op-cs-s.cc (DEFBINOP): First arg is complex, second is
--- a/src/Makefile.in	Tue Sep 09 17:49:13 2003 +0000
+++ b/src/Makefile.in	Tue Sep 09 19:14:06 2003 +0000
@@ -98,9 +98,11 @@
 	op-cm-s.cc op-cs-cm.cc op-cs-cs.cc op-cs-m.cc \
 	op-cs-s.cc op-fil-b.cc op-fil-bm.cc op-fil-cm.cc \
 	op-fil-cs.cc op-fil-m.cc op-fil-s.cc op-fil-lis.cc \
-	op-fil-rec.cc op-fil-str.cc op-list.cc op-m-cm.cc op-m-cs.cc \
-	op-m-m.cc op-m-s.cc op-range.cc op-s-cm.cc op-s-cs.cc op-s-m.cc \
-	op-s-s.cc op-str-m.cc op-str-s.cc op-str-str.cc
+	op-fil-rec.cc op-fil-str.cc op-list.cc op-m-cm.cc \
+	op-m-cs.cc op-m-m.cc op-m-nd.cc op-m-s.cc op-nd-m.cc \
+	op-nd-nd.cc op-nd-s.cc op-range.cc op-s-cm.cc \
+	op-s-cs.cc op-s-m.cc op-s-nd.cc op-s-s.cc op-str-m.cc \
+	op-str-s.cc op-str-str.cc
 
 OP_SRC := $(addprefix OPERATORS/, $(OP_XSRC))
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/OPERATORS/op-m-nd.cc	Tue Sep 09 19:14:06 2003 +0000
@@ -0,0 +1,50 @@
+/*
+
+Copyright (C) 2003 Petter Risholm and John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#if defined (__GNUG__) && defined (USE_PRAGMA_INTERFACE_IMPLEMENTATION)
+#pragma implementation
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+//#include "mx-m-nd.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-re-mat.h"
+#include "ov-re-nd-array.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+
+
+DEFASSIGNOP_FN (assign, matrix, double_nd_array, assign)
+
+void
+install_m_nd_ops (void)
+{
+  INSTALL_ASSIGNOP (op_asn_eq, octave_matrix, octave_double_nd_array, assign);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/OPERATORS/op-nd-m.cc	Tue Sep 09 19:14:06 2003 +0000
@@ -0,0 +1,48 @@
+/*
+
+Copyright (C) 2003 Petter Risholm and John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#if defined (__GNUG__) && defined (USE_PRAGMA_INTERFACE_IMPLEMENTATION)
+#pragma implementation
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#//include "mx-nd-m.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-re-mat.h"
+#include "ov-re-nd-array.h"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+DEFASSIGNOP_FN (assign, double_nd_array, matrix, assign)
+
+void
+install_nd_m_ops (void)
+{
+  INSTALL_ASSIGNOP (op_asn_eq, octave_double_nd_array, octave_matrix, assign);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/OPERATORS/op-nd-nd.cc	Tue Sep 09 19:14:06 2003 +0000
@@ -0,0 +1,80 @@
+/*
+
+Copyright (C) 2003 Petter Risholm and John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#if defined (__GNUG__) && defined (USE_PRAGMA_INTERFACE_IMPLEMENTATION)
+#pragma implementation
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-re-nd-array.h"
+#include "ov-typeinfo.h"
+
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+ 
+//Using the ! operator causes a segmentation fault
+//DEFUNOP_OP (not, double_nd_array, !)
+/*
+DEFUNOP_OP (uminus, double_nd_array, -)
+
+DEFUNOP (transpose, double_nd_array)
+{
+  error ("Transpose on ND array is not defined.");
+  return octave_value ();
+}
+
+DEFBINOP_OP (add, double_nd_array, double_nd_array, +)
+DEFBINOP_OP (sub, double_nd_array, double_nd_array, -)
+
+DEFBINOP_FN (el_pow, double_nd_array, double_nd_array, elem_xpow)
+
+DEFBINOPX (pow, double_nd_array, double_nd_array)
+{
+  error ("can't do A ^ B for A and B both N-D arrays");
+  return octave_value ();
+}
+*/
+
+DEFASSIGNOP_FN (assign, double_nd_array, double_nd_array, assign)
+
+void
+install_nd_nd_ops (void)
+{
+  //  INSTALL_UNOP (op_not, octave_double_nd_array, not);
+  /*INSTALL_UNOP (op_uminus, octave_double_nd_array, uminus);
+  INSTALL_UNOP (op_transpose, octave_double_nd_array, transpose);
+
+  INSTALL_BINOP (op_add, octave_double_nd_array, octave_double_nd_array, add);
+  INSTALL_BINOP (op_sub, octave_double_nd_array, octave_double_nd_array, sub);
+
+  INSTALL_BINOP (op_el_pow, octave_double_nd_array, octave_double_nd_array, el_pow);
+  */
+  INSTALL_ASSIGNOP (op_asn_eq, octave_double_nd_array, octave_double_nd_array, assign);
+  INSTALL_ASSIGNCONV (octave_double_nd_array, octave_double_nd_array, octave_double_nd_array);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/OPERATORS/op-nd-s.cc	Tue Sep 09 19:14:06 2003 +0000
@@ -0,0 +1,97 @@
+/*
+
+Copyright (C) 2003 Petter Risholm and John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#if defined (__GNUG__) && defined (USE_PRAGMA_INTERFACE_IMPLEMENTATION)
+#pragma implementation
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-re-nd-array.h"
+#include "ov-scalar.h"
+#include "ov-typeinfo.h"
+//Kluge
+
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// ndArray by scalar ops.
+
+/*
+DEFBINOP_OP (add, double_nd_array, scalar, +)
+DEFBINOP_OP (sub, double_nd_array, scalar, -)
+DEFBINOP_OP (mul, double_nd_array, scalar, *)
+
+DEFBINOP (div, double_nd_array, scalar)
+{
+  CAST_BINOP_ARGS (const octave_double_nd_array&, const octave_scalar&);
+  double d = v2.double_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.double_nd_array_value () / d);
+}
+
+DEFBINOP_OP (el_mul, double_nd_array, scalar, *)
+
+DEFBINOP (el_div, double_nd_array, scalar)
+{
+  CAST_BINOP_ARGS (const octave_double_nd_array&, const octave_scalar&);
+
+  double d = v2.double_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return octave_value (v1.double_nd_array_value () / d);
+}
+
+DEFBINOP_FN (el_pow, double_nd_array, scalar, elem_xpow)
+*/
+DEFASSIGNOP_FN (assign, double_nd_array, scalar, assign)
+
+void
+install_nd_s_ops (void)
+{
+  /*  INSTALL_BINOP (op_add, octave_double_nd_array, octave_scalar, add);
+  INSTALL_BINOP (op_sub, octave_double_nd_array, octave_scalar, sub);
+  INSTALL_BINOP (op_mul, octave_double_nd_array, octave_scalar, mul);
+  INSTALL_BINOP (op_div, octave_double_nd_array, octave_scalar, div);
+  INSTALL_BINOP (op_el_pow, octave_double_nd_array, octave_scalar, el_pow);
+  INSTALL_BINOP (op_el_mul, octave_double_nd_array, octave_scalar, el_mul);
+  INSTALL_BINOP (op_el_div, octave_double_nd_array, octave_scalar, el_div);
+  */
+  INSTALL_ASSIGNOP (op_asn_eq, octave_double_nd_array, octave_scalar, assign);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/OPERATORS/op-s-nd.cc	Tue Sep 09 19:14:06 2003 +0000
@@ -0,0 +1,77 @@
+/*
+
+Copyright (C) 2003 Petter Risholm and John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#if defined (__GNUG__) && defined (USE_PRAGMA_INTERFACE_IMPLEMENTATION)
+#pragma implementation
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-scalar.h"
+#include "ov-re-nd-array.h"
+//Kluge
+//#include "MArrayN.cc"
+#include "ov-typeinfo.h"
+#include "ops.h"
+#include "xdiv.h"
+#include "xpow.h"
+
+// scalar by matrix ops.
+
+/*
+DEFBINOP_OP (add, scalar, double_nd_array, +)
+DEFBINOP_OP (sub, scalar, double_nd_array, -)
+DEFBINOP_OP (mul, scalar, double_nd_array, *)
+
+  DEFBINOP_OP(el_mul, scalar, double_nd_array, *)
+*/
+DEFCONV (array_conv, scalar, double_nd_array)
+{
+  CAST_CONV_ARG (const octave_scalar&);
+
+  return new octave_double_nd_array (v.double_nd_array_value ());
+}
+
+void
+install_s_nd_ops (void)
+{
+  /* 
+ INSTALL_BINOP (op_add, octave_scalar, octave_double_nd_array, add);
+  INSTALL_BINOP (op_sub, octave_scalar, octave_double_nd_array, sub);
+  INSTALL_BINOP (op_mul, octave_scalar, octave_double_nd_array, mul);
+  INSTALL_BINOP (op_el_mul, octave_scalar, octave_double_nd_array, el_mul);
+  */  
+  INSTALL_ASSIGNCONV (octave_scalar, octave_double_nd_array, octave_double_nd_array);
+
+  INSTALL_WIDENOP (octave_scalar, octave_double_nd_array, array_conv);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
--- a/src/ov-base.cc	Tue Sep 09 17:49:13 2003 +0000
+++ b/src/ov-base.cc	Tue Sep 09 19:14:06 2003 +0000
@@ -291,6 +291,15 @@
   return retval;
 }
 
+ArrayN<double>
+octave_base_value::double_nd_array_value (bool) const
+{
+  ArrayN<double> retval;
+  gripe_wrong_type_arg ("octave_base_value::double_nd_array_value()",
+			type_name ());
+  return retval;
+}
+
 Complex
 octave_base_value::complex_value (bool) const
 {
--- a/src/ov-base.h	Tue Sep 09 17:49:13 2003 +0000
+++ b/src/ov-base.h	Tue Sep 09 19:14:06 2003 +0000
@@ -106,6 +106,8 @@
 
   bool is_real_matrix (void) const { return false; }
 
+  bool is_real_nd_array (void) const { return false; }
+
   bool is_complex_scalar (void) const { return false; }
 
   bool is_complex_matrix (void) const { return false; }
@@ -189,6 +191,8 @@
 
   Matrix matrix_value (bool = false) const;
 
+  ArrayN<double> double_nd_array_value (bool frc_str_conv = false) const;
+
   Complex complex_value (bool = false) const;
 
   ComplexMatrix complex_matrix_value (bool = false) const;
--- a/src/ov-re-mat.h	Tue Sep 09 17:49:13 2003 +0000
+++ b/src/ov-re-mat.h	Tue Sep 09 19:14:06 2003 +0000
@@ -98,6 +98,9 @@
   ComplexMatrix complex_matrix_value (bool = false) const
     { return ComplexMatrix (matrix); }
 
+  ArrayN<double> double_nd_array_value (bool = false) const
+    { return ArrayN<double> (matrix); }
+
   void increment (void) { matrix += 1.0; }
 
   void decrement (void) { matrix -= 1.0; }
--- a/src/ov-re-nd-array.cc	Tue Sep 09 17:49:13 2003 +0000
+++ b/src/ov-re-nd-array.cc	Tue Sep 09 19:14:06 2003 +0000
@@ -39,6 +39,8 @@
 #include "oct-lvalue.h"
 #include "ops.h"
 #include "ov-base.h"
+#include "ov-scalar.h"
+#include "ov-re-mat.h"
 #include "ov-base-nd-array.h"
 #include "ov-base-nd-array.cc"
 #include "ov-re-nd-array.h"
@@ -52,106 +54,147 @@
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_double_nd_array,
 				     "double-nd-array");
 
-#if 0
 octave_value *
-octave_matrix::try_narrowing_conversion (void)
+octave_double_nd_array::try_narrowing_conversion (void)
 {
   octave_value *retval = 0;
 
-  int nr = matrix.rows ();
-  int nc = matrix.cols ();
+  array.maybe_delete_dims ();
+
+  int n_dims = array.dims ().length ();
+  Array<int> dims = array.dims();
 
-  if (nr == 1 && nc == 1)
-    retval = new octave_scalar (matrix (0, 0));
+  // Scalar
+  if (n_dims == 1 && dims(0) == 1)
+    {
+      retval = new octave_scalar (array(Array<int> (1,0)));
+    }
+
+  // Matrix
+  if (n_dims == 2 || n_dims == 1)
+    {
+      retval = new octave_matrix (matrix_value ());
+    }
+
+
 
   return retval;
 }
 
 void
-octave_matrix::assign (const octave_value_list& idx, const Matrix& rhs)
+octave_double_nd_array::assign (const octave_value_list& idx,
+				const ArrayN<double>& rhs)
 {
   int len = idx.length ();
 
-  switch (len)
+  if ( len < 0)
     {
-    case 2:
-      {
-	idx_vector i = idx (0).index_vector ();
-	idx_vector j = idx (1).index_vector ();
-
-	matrix.set_index (i);
-	matrix.set_index (j);
-
-	::assign (matrix, rhs);
-      }
-      break;
-
-    case 1:
-      {
-	idx_vector i = idx (0).index_vector ();
-
-	matrix.set_index (i);
-
-	::assign (matrix, rhs);
-      }
-      break;
-
-    default:
       error ("invalid number of indices (%d) for indexed matrix assignment",
 	     len);
-      break;
+      return;
+    }  
+
+  // XXX FIXME XXX -- where should this go?
+  array.set_max_indices (len);
+  
+  array.clear_index ();
+  
+
+  for (int i = 0; i < len; i++) 
+    {
+      idx_vector temp = idx(i).index_vector ();
+      array.set_index(temp);
     }
+
+  ::assign (array, rhs);
+
+  // When subclasses of ArrayN are constructed, add an extra arguemnt
+  // resize_fill_value ()
 }
 
 bool
-octave_matrix::valid_as_scalar_index (void) const
+octave_double_nd_array::valid_as_scalar_index (void) const
 {
   // XXX FIXME XXX
   return false;
 }
 
 double
-octave_matrix::double_value (bool) const
+octave_double_nd_array::double_value (bool) const
 {
   double retval = lo_ieee_nan_value ();
 
-  // XXX FIXME XXX -- maybe this should be a function, valid_as_scalar()
-  if (rows () > 0 && columns () > 0)
-    {
-      // XXX FIXME XXX -- is warn_fortran_indexing the right variable here?
-      if (Vwarn_fortran_indexing)
-	gripe_implicit_conversion ("real matrix", "real scalar");
+  // XXX FIXME XXX
 
-      retval = matrix (0, 0);
-    }
-  else
-    gripe_invalid_conversion ("real matrix", "real scalar");
+  gripe_invalid_conversion ("real nd-array", "real scalar");
 
   return retval;
 }
 
+
+Matrix
+octave_double_nd_array::matrix_value (bool ) const
+{
+  Array<int> ra_idx (array.dimensions.length (), 0);
+
+  return convert_slice_to_matrix (ra_idx);
+}
+
+Matrix
+octave_double_nd_array::convert_slice_to_matrix (const Array<int>& ra_idx) const
+{
+  int n_dims = array.dimensions.length ();
+
+  assert(ra_idx.length () == n_dims);
+
+  Array<int> idx (ra_idx);
+  Matrix retval;
+
+  if (n_dims > 1)
+    {
+      int d1 = array.dimensions(0);
+      int d2 = array.dimensions(1);
+
+      retval = Matrix (d1, d2);
+
+      for (int i = 0; i < d1; i++)
+        {
+          idx(0) = i;
+          for (int j = 0; j < d2; j++)
+            {
+              idx(1) = j;
+              retval(i,j) = array.elem (idx);
+            }
+        }
+    }
+  else if (n_dims == 1)
+    {
+      int d1 = array.dimensions(0);
+      int d2 = 1;
+
+      retval = Matrix (d1, d2);
+
+      for (int i = 0; i < d1; i++)
+        {
+	  idx(0) = i;
+	  retval(i, 0) = array.elem (idx);
+	}
+
+    }
+  return retval;
+}
+
 Complex
-octave_matrix::complex_value (bool) const
+octave_double_nd_array::complex_value (bool) const
 {
   double tmp = lo_ieee_nan_value ();
 
   Complex retval (tmp, tmp);
 
-  // XXX FIXME XXX -- maybe this should be a function, valid_as_scalar()
-  if (rows () > 0 && columns () > 0)
-    {
-      // XXX FIXME XXX -- is warn_fortran_indexing the right variable here?
-      if (Vwarn_fortran_indexing)
-	gripe_implicit_conversion ("real matrix", "complex scalar");
-
-      retval = matrix (0, 0);
-    }
-  else
-    gripe_invalid_conversion ("real matrix", "complex scalar");
+  gripe_invalid_conversion ("real matrix", "complex scalar");
 
   return retval;
 }
-#endif
 
 /*
 ;;; Local Variables: ***
--- a/src/ov-re-nd-array.h	Tue Sep 09 17:49:13 2003 +0000
+++ b/src/ov-re-nd-array.h	Tue Sep 09 19:14:06 2003 +0000
@@ -32,7 +32,7 @@
 #include <iostream>
 #include <string>
 
-#include "ArrayN.h"
+#include "mx-base.h"
 #include "oct-alloc.h"
 
 #include "error.h"
@@ -60,15 +60,21 @@
 
   ~octave_double_nd_array (void) { }
 
-  octave_value *clone (void) const { return new octave_double_nd_array (*this); }
-  octave_value *empty_clone (void) const { return new octave_double_nd_array (); }
+  octave_value *clone (void) const
+    { return new octave_double_nd_array (*this); }
 
-#if 0
+  octave_value *empty_clone (void) const
+    { return new octave_double_nd_array (); }
+
   octave_value *try_narrowing_conversion (void);
 
-  void assign (const octave_value_list& idx, const Matrix& rhs);
+  void assign (const octave_value_list& idx, const ArrayN<double>& rhs);
 
-  idx_vector index_vector (void) const { return idx_vector (matrix); }
+  // Need to implement idx_vector (ArrayN<double>) for this one.
+  //
+  // idx_vector index_vector (void) const { return idx_vector (array); }
+
+  bool is_real_nd_array (void) const { return true; }
 
   bool is_real_matrix (void) const { return false; }
 
@@ -78,6 +84,8 @@
 
   double double_value (bool = false) const;
 
+  ArrayN<double> double_nd_array_value (bool = false) const { return array; }
+
   double scalar_value (bool frc_str_conv = false) const
     { return double_value (frc_str_conv); }
 
@@ -87,7 +95,8 @@
 
   ComplexMatrix complex_matrix_value (bool = false) const
     { return ComplexMatrix (matrix_value ()); }
-#endif
+
+  Matrix convert_slice_to_matrix (const Array<int>& ra_idx) const;
 
 private:
 
--- a/src/ov-scalar.h	Tue Sep 09 17:49:13 2003 +0000
+++ b/src/ov-scalar.h	Tue Sep 09 19:14:06 2003 +0000
@@ -89,6 +89,9 @@
   Matrix matrix_value (bool = false) const
     { return Matrix (1, 1, scalar); }
 
+  ArrayN<double> double_nd_array_value (bool = false) const
+    { return ArrayN<double> (Array<int> (1, 1), scalar); }
+
   Complex complex_value (bool = false) const { return scalar; }
 
   ComplexMatrix complex_matrix_value (bool = false) const
--- a/src/ov.cc	Tue Sep 09 17:49:13 2003 +0000
+++ b/src/ov.cc	Tue Sep 09 19:14:06 2003 +0000
@@ -1221,6 +1221,11 @@
 		{
 		  retval = tmp->subsasgn (type, idx, rhs);
 
+		  // The assignment may have converted to a type that
+		  // is wider than necessary.
+
+		  retval.maybe_mutate ();
+
 		  done = (! error_state);
 		}
 	      else
@@ -1746,6 +1751,7 @@
   octave_scalar::register_type ();
   octave_complex::register_type ();
   octave_matrix::register_type ();
+  octave_double_nd_array::register_type ();
   octave_complex_matrix::register_type ();
   octave_range::register_type ();
   octave_bool::register_type ();
--- a/src/ov.h	Tue Sep 09 17:49:13 2003 +0000
+++ b/src/ov.h	Tue Sep 09 19:14:06 2003 +0000
@@ -33,6 +33,7 @@
 #include <string>
 #include <list>
 
+#include "ArrayN.h"
 #include "Range.h"
 #include "idx-vector.h"
 #include "mx-base.h"
@@ -336,6 +337,9 @@
   virtual bool is_real_matrix (void) const
     { return rep->is_real_matrix (); }
 
+  virtual bool is_real_nd_array (void) const
+    { return rep->is_real_nd_array (); }
+
   virtual bool is_complex_scalar (void) const
     { return rep->is_complex_scalar (); }
 
@@ -471,6 +475,9 @@
   virtual Matrix matrix_value (bool frc_str_conv = false) const
     { return rep->matrix_value (frc_str_conv); }
 
+  virtual ArrayN<double> double_nd_array_value (bool frc_str_conv = false) const
+    { return rep->double_nd_array_value (frc_str_conv); }
+
   virtual Complex complex_value (bool frc_str_conv = false) const
     { return rep->complex_value (frc_str_conv); }