changeset 4567:fc30061d01da

[project @ 2003-10-29 20:11:15 by jwe]
author jwe
date Wed, 29 Oct 2003 20:11:16 +0000
parents 30ba814d6700
children 03c053808a7c
files liboctave/Array.cc liboctave/Array.h liboctave/ChangeLog liboctave/dim-vector.h scripts/ChangeLog scripts/general/reshape.m src/Cell.h src/ChangeLog src/data.cc src/oct-map.cc src/oct-map.h src/ov-base-mat.h src/ov-base.cc src/ov-base.h src/ov-struct.h src/ov.cc src/ov.h
diffstat 17 files changed, 183 insertions(+), 91 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/Array.cc	Wed Oct 29 15:06:29 2003 +0000
+++ b/liboctave/Array.cc	Wed Oct 29 20:11:16 2003 +0000
@@ -338,6 +338,23 @@
 }
 
 template <class T>
+Array<T>
+Array<T>::reshape (const dim_vector& new_dims) const
+{
+  Array<T> retval;
+
+  if (dimensions != new_dims)
+    {
+      if (dimensions.numel () == new_dims.numel ())
+	retval = Array<T> (*this, new_dims);
+      else
+	(*current_liboctave_error_handler) ("reshape: size mismatch");
+    }
+
+  return retval;
+}
+
+template <class T>
 void
 Array<T>::resize_no_fill (int n)
 {
--- a/liboctave/Array.h	Wed Oct 29 15:06:29 2003 +0000
+++ b/liboctave/Array.h	Wed Oct 29 20:11:16 2003 +0000
@@ -405,6 +405,8 @@
   T operator () (const Array<int>& ra_idx) const { return elem (ra_idx); }
 #endif
 
+  Array<T> reshape (const dim_vector& new_dims) const;
+
   void resize_no_fill (int n);
   void resize_and_fill (int n, const T& val);
 
--- a/liboctave/ChangeLog	Wed Oct 29 15:06:29 2003 +0000
+++ b/liboctave/ChangeLog	Wed Oct 29 20:11:16 2003 +0000
@@ -1,5 +1,10 @@
 2003-10-29  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
+	* Array.cc (Array<T>::reshape): New function.
+	* Array.h: Provide decl.
+
+	* dim-vector.h (dim_vector::numel): New function.
+
 	* dim-vector.h (dim_vector_rep::dim_vector_rep (int, const
 	dim_vector&)): Correctly handle case of n < dv->ndims.
 
--- a/liboctave/dim-vector.h	Wed Oct 29 15:06:29 2003 +0000
+++ b/liboctave/dim-vector.h	Wed Oct 29 20:11:16 2003 +0000
@@ -253,6 +253,22 @@
 
     return retval;
   }
+
+  // This is the number of elements that a matrix with this dimension
+  // vector would have, NOT the number of dimensions (elements in the
+  // dimension vector).
+
+  int numel (void) const
+  {
+    int n_dims = length ();
+
+    int retval = n_dims > 0 ? elem (0) : 0;
+
+    for (int i = 1; i < n_dims; i++)
+      retval *= elem (i);
+
+    return retval;
+  }
 };
 
 static inline bool
--- a/scripts/ChangeLog	Wed Oct 29 15:06:29 2003 +0000
+++ b/scripts/ChangeLog	Wed Oct 29 20:11:16 2003 +0000
@@ -1,3 +1,7 @@
+2003-10-29  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* general/reshape: Delete.
+
 2003-10-28  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
 	* general/numel.m: Delete.
--- a/scripts/general/reshape.m	Wed Oct 29 15:06:29 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-## 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.
-
-## -*- texinfo -*-
-## @deftypefn {Function File} {} reshape (@var{a}, @var{m}, @var{n})
-## Return a matrix with @var{m} rows and @var{n} columns whose elements are
-## taken from the matrix @var{a}.  To decide how to order the elements,
-## Octave pretends that the elements of a matrix are stored in column-major
-## order (like Fortran arrays are stored).
-##
-## For example,
-##
-## @example
-## @group
-## reshape ([1, 2, 3, 4], 2, 2)
-##      @result{}  1  3
-##          2  4
-## @end group
-## @end example
-##
-## The @code{reshape} function is equivalent to
-##
-## @example
-## @group
-## retval = zeros (m, n);
-## retval (:) = a;
-## @end group
-## @end example
-##
-## @noindent
-## but it is somewhat less cryptic to use @code{reshape} instead of the
-## colon operator.  Note that the total number of elements in the original
-## matrix must match the total number of elements in the new matrix.
-## @end deftypefn
-## @seealso{`:'}
-
-## Author: jwe
-
-function retval = reshape (a, m, n)
-
-  if (nargin == 2 && prod (size (m)) == 2)
-    n = m(2);
-    m = m(1);
-    nargin = 3;
-  endif
-
-  if (nargin == 3)
-    [nr, nc] = size (a);
-    if (nr * nc == m * n)
-      retval = zeros (m, n);
-      if (isstr (a))
-	retval = setstr (retval);
-      endif
-      retval(:) = a;
-    else
-      error ("reshape: sizes must match");
-    endif
-  else
-    usage ("reshape (a, m, n) or reshape (a, size (b))");
-  endif
-
-endfunction
--- a/src/Cell.h	Wed Oct 29 15:06:29 2003 +0000
+++ b/src/Cell.h	Wed Oct 29 20:11:16 2003 +0000
@@ -56,12 +56,16 @@
   Cell (int n, int m, const octave_value& val = resize_fill_value ())
     : ArrayN<octave_value> (dim_vector (n, m), val) { }
 
-  Cell (const dim_vector& dims, const octave_value& val = resize_fill_value ())
+  Cell (const dim_vector& dims,
+		 const octave_value& val = resize_fill_value ())
     : ArrayN<octave_value> (dims, val) { }
 
   Cell (const ArrayN<octave_value>& c)
     : ArrayN<octave_value> (c) { }
 
+  Cell (const Array<octave_value>& c)
+    : ArrayN<octave_value> (c) { }
+
   Cell (const Array<octave_value>& c, int nr, int nc)
     : ArrayN<octave_value> (c, dim_vector (nr, nc)) { }
 
@@ -74,15 +78,15 @@
 
   Cell index (idx_vector& i, int resize_ok = 0,
 	      const octave_value& rfv = resize_fill_value ()) const
-    { return ArrayN<octave_value>::index (i, resize_ok, rfv); }
+    { return Cell (ArrayN<octave_value>::index (i, resize_ok, rfv)); }
 
   Cell index (idx_vector& i, idx_vector& j, int resize_ok = 0,
 	      const octave_value& rfv = resize_fill_value ()) const
-    { return ArrayN<octave_value>::index (i, j, resize_ok, rfv); }
+    { return Cell (ArrayN<octave_value>::index (i, j, resize_ok, rfv)); }
 
   Cell index (Array<idx_vector>& ra_idx, int resize_ok = 0,
 	      const octave_value& rfv = resize_fill_value ()) const
-    { return ArrayN<octave_value>::index (ra_idx, resize_ok, rfv); }
+    { return Cell (ArrayN<octave_value>::index (ra_idx, resize_ok, rfv)); }
 
   Cell& assign (const octave_value_list& idx, const Cell& rhs,
 		const octave_value& fill_val = octave_value ());
--- a/src/ChangeLog	Wed Oct 29 15:06:29 2003 +0000
+++ b/src/ChangeLog	Wed Oct 29 20:11:16 2003 +0000
@@ -1,5 +1,18 @@
 2003-10-29  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
+	* oct-map.cc (Octave_map::reshape): New function.
+	* oct-map.h: Provide decl.
+
+	* ov-struct.h (octave_struct::reshape): New function.
+
+	* Cell.h (Cell:Cell (const Array<octave_value>&): New constructor.
+
+	* data.cc (Freshape): New function.
+	* ov.h (octave_value::reshape): New function.
+	* ov-base-mat.h (octave_base_matrix::reshape): New function.
+	* ov-base.cc (octave_base_value::reshape): New function.
+	* ov-base.h: Provide decl.
+
 	* DLD-FUNCTIONS/balance.cc: lscale and rscale args for dggbak are
 	const.  Use data() instead of fortran_vec where possible.
 	* DLD-FUNCTIONS/qz.cc: Likewise.
--- a/src/data.cc	Wed Oct 29 15:06:29 2003 +0000
+++ b/src/data.cc	Wed Oct 29 20:11:16 2003 +0000
@@ -1236,6 +1236,86 @@
   return retval;
 }
 
+DEFUN (reshape, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Function File} {} reshape (@var{a}, @var{m}, @var{n}, @dots{})\n\
+@deftypefnx {Function File} {} reshape (@var{a}, @var{siz})\n\
+Return a matrix with the given dimensions whose elements are taken\n\
+from the matrix @var{a}.  The elements of the matrix are access in\n\
+column-major order (like Fortran arrays are stored).\n\
+\n\
+For example,\n\
+\n\
+@example\n\
+@group\n\
+reshape ([1, 2, 3, 4], 2, 2)\n\
+     @result{}  1  3\n\
+         2  4\n\
+@end group\n\
+@end example\n\
+\n\
+@noindent\n\
+Note that the total number of elements in the original\n\
+matrix must match the total number of elements in the new matrix.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  Array<int> new_size;
+
+  if (nargin == 2)
+    new_size = args(1).int_vector_value ();
+  else if (nargin > 2)
+    {
+      new_size.resize (nargin-1);
+
+      for (int i = 1; i < nargin; i++)
+	{
+	  new_size(i-1) = args(i).int_value ();
+
+	  if (error_state)
+	    break;
+	}
+    }
+  else
+    {
+      print_usage ("reshape");
+      return retval;
+    }
+
+  if (error_state)
+    {
+      error ("reshape: invalid arguments");
+      return retval;
+    }
+
+  int n = new_size.length ();
+
+  if (n < 2)
+    {
+      error ("reshape: expecting size to be vector with at least 2 elements");
+      return retval;
+    }
+
+  dim_vector new_dims;
+
+  new_dims.resize (n);
+
+  for (int i = 0; i < n; i++)
+    new_dims(i) = new_size(i);
+
+  octave_value arg = args(0);
+
+  if (new_dims.numel () == arg.numel ())
+    retval = (new_dims == arg.dims ()) ? arg : arg.reshape (new_dims);
+  else
+    error ("reshape: size mismatch");
+
+  return retval;
+}
+
 DEFUN (squeeze, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} squeeze (@var{x})\n\
--- a/src/oct-map.cc	Wed Oct 29 15:06:29 2003 +0000
+++ b/src/oct-map.cc	Wed Oct 29 20:11:16 2003 +0000
@@ -56,6 +56,22 @@
   return names;
 }
 
+Octave_map
+Octave_map::reshape (const dim_vector& new_dims) const
+{
+  Octave_map retval;
+
+  if (new_dims != dims ())
+    {
+      for (const_iterator p = begin (); p != end (); p++)
+	retval[key(p)] = contents(p).reshape (new_dims);
+
+      dimensions = new_dims;
+    }
+
+  return retval;
+}
+
 int
 Octave_map::numel (void) const
 {
--- a/src/oct-map.h	Wed Oct 29 15:06:29 2003 +0000
+++ b/src/oct-map.h	Wed Oct 29 20:11:16 2003 +0000
@@ -46,7 +46,7 @@
 
   Octave_map (const std::string& key, const octave_value& value)
     : map (), dimensions (1, 1)
-    { map[key] = Cell (value); }
+    { map[key] = value; }
 
   Octave_map (const std::string& key, const Cell& vals)
     : map (), dimensions (vals.dims ())
@@ -116,6 +116,8 @@
 
   dim_vector dims (void) const { return dimensions; }
 
+  Octave_map reshape (const dim_vector& new_dims) const;
+
   int numel (void) const;
 
   Octave_map& assign (const octave_value_list& idx, const Octave_map& rhs);
--- a/src/ov-base-mat.h	Wed Oct 29 15:06:29 2003 +0000
+++ b/src/ov-base-mat.h	Wed Oct 29 20:11:16 2003 +0000
@@ -92,6 +92,9 @@
 
   dim_vector dims (void) const { return matrix.dims (); }
 
+  octave_value reshape (const dim_vector& new_dims) const
+    { return MT (matrix.reshape (new_dims)); }
+
   octave_value all (int dim = 0) const { return matrix.all (dim); }
   octave_value any (int dim = 0) const { return matrix.any (dim); }
 
--- a/src/ov-base.cc	Wed Oct 29 15:06:29 2003 +0000
+++ b/src/ov-base.cc	Wed Oct 29 20:11:16 2003 +0000
@@ -174,6 +174,13 @@
 }
 
 octave_value
+octave_base_value::reshape (const dim_vector&) const
+{
+  gripe_wrong_type_arg ("octave_base_value::reshape ()", type_name ());
+  return octave_value ();
+}
+
+octave_value
 octave_base_value::convert_to_str_internal (bool, bool) const
 {
   gripe_wrong_type_arg ("octave_base_value::convert_to_str_internal ()",
--- a/src/ov-base.h	Wed Oct 29 15:06:29 2003 +0000
+++ b/src/ov-base.h	Wed Oct 29 20:11:16 2003 +0000
@@ -96,6 +96,8 @@
 
   dim_vector dims (void) const { return dim_vector (-1, -1); }
 
+  octave_value reshape (const dim_vector&) const;
+
   bool is_defined (void) const { return false; }
 
   bool is_cell (void) const { return false; }
--- a/src/ov-struct.h	Wed Oct 29 15:06:29 2003 +0000
+++ b/src/ov-struct.h	Wed Oct 29 20:11:16 2003 +0000
@@ -89,6 +89,9 @@
 
   dim_vector dims (void) const { return map.dims (); }
 
+  octave_value reshape (const dim_vector& new_dims) const
+    { return map.reshape (new_dims); }
+
   bool is_defined (void) const { return true; }
 
   bool is_constant (void) const { return true; }
--- a/src/ov.cc	Wed Oct 29 15:06:29 2003 +0000
+++ b/src/ov.cc	Wed Oct 29 20:11:16 2003 +0000
@@ -885,14 +885,7 @@
 {
   dim_vector dv = dims ();
 
-  int n_dims = dv.length ();
-
-  int retval = n_dims > 0 ? dv(0) : 0;
-
-  for (int i = 1; i < n_dims; i++)
-    retval *= dv(i);
-
-  return retval;    
+  return dv.numel ();
 }
 
 Cell
--- a/src/ov.h	Wed Oct 29 15:06:29 2003 +0000
+++ b/src/ov.h	Wed Oct 29 20:11:16 2003 +0000
@@ -329,6 +329,9 @@
 
   int numel (void) const;
 
+  virtual octave_value reshape (const dim_vector& dims) const
+    { return rep->reshape (dims); }
+
   // Does this constant have a type?  Both of these are provided since
   // it is sometimes more natural to write is_undefined() instead of
   // ! is_defined().