changeset 4593:77566be8b9e9

[project @ 2003-11-11 17:25:42 by jwe]
author jwe
date Tue, 11 Nov 2003 17:25:42 +0000
parents a97b498e1b32
children 3a284f89aa41
files liboctave/Array-util.cc liboctave/Array-util.h liboctave/Array.cc liboctave/Array.h liboctave/CMatrix.cc liboctave/ChangeLog liboctave/dMatrix.cc src/ChangeLog src/data.cc src/ov-base-mat.h src/ov-base.cc src/ov-base.h src/ov.h
diffstat 13 files changed, 203 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/Array-util.cc	Tue Nov 11 01:13:10 2003 +0000
+++ b/liboctave/Array-util.cc	Tue Nov 11 17:25:42 2003 +0000
@@ -510,6 +510,25 @@
   return retval;
 }
 
+Array<int>
+calc_permutated_idx (const Array<int>& old_idx, 
+		     const Array<int>& perm_vec, bool inv)
+{
+  int n_el = old_idx.length ();
+
+  Array<int> retval (n_el);
+
+  for (int i = 0; i < n_el; i++)
+    {
+      if (inv)
+	retval(perm_vec(i)-1) = old_idx(i);
+      else
+	retval(i) = old_idx(perm_vec(i)-1);
+    }
+
+  return retval;
+}
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/liboctave/Array-util.h	Tue Nov 11 01:13:10 2003 +0000
+++ b/liboctave/Array-util.h	Tue Nov 11 17:25:42 2003 +0000
@@ -87,6 +87,8 @@
 				const dim_vector& dimensions,
 				int resize_ok);
 
+extern Array<int> calc_permutated_idx (const Array<int>& old_idx, 
+				       const Array<int>& perm_vec, bool inv);
 #endif
 
 /*
--- a/liboctave/Array.cc	Tue Nov 11 01:13:10 2003 +0000
+++ b/liboctave/Array.cc	Tue Nov 11 17:25:42 2003 +0000
@@ -356,6 +356,71 @@
 }
 
 template <class T>
+Array<T>
+Array<T>::permute (const Array<int>& perm_vec, bool inv) const
+{
+  Array<T> retval;
+
+  dim_vector dv = dims ();
+  dim_vector dv_new;
+
+  int nd = dv.length ();
+
+  dv_new.resize (nd);
+
+  // Need this array to check for identical elements in permutation array.
+  Array<bool> checked (nd, false);
+
+  // Find dimension vector of permuted array.
+  for (int i = 0; i < nd; i++)
+    {
+      int perm_el = perm_vec.elem (i);
+
+      if (perm_el > dv.length () || perm_el < 1)
+	{
+	  (*current_liboctave_error_handler)
+	    ("permutation vector contains an invalid element");
+
+	  return retval;
+	}
+
+      if (checked.elem(perm_el - 1))
+	{
+	  (*current_liboctave_error_handler)
+	    ("PERM cannot contain identical elements");
+
+	  return retval;
+	}
+      else
+	checked.elem(perm_el - 1) = true;
+
+      dv_new (i) = dv (perm_el - 1);
+    }
+
+  retval.resize (dv_new);
+
+  // Index array to the original array.
+  Array<int> old_idx (nd, 0);
+
+  // Number of elements in Array (should be the same for
+  // both the permuted array and original array).
+  int n = retval.length ();
+
+  // Permute array.
+  for (int i = 0; i < n; i++)
+    {
+      // Get the idx of permuted array.
+      Array<int> new_idx = calc_permutated_idx (old_idx, perm_vec, inv);
+
+      retval.elem (new_idx) = elem (old_idx);
+
+      increment_index (old_idx, dv);
+    }
+
+  return retval;
+}
+
+template <class T>
 void
 Array<T>::resize_no_fill (int n)
 {
--- a/liboctave/Array.h	Tue Nov 11 01:13:10 2003 +0000
+++ b/liboctave/Array.h	Tue Nov 11 17:25:42 2003 +0000
@@ -407,6 +407,10 @@
 
   Array<T> reshape (const dim_vector& new_dims) const;
 
+  Array<T> permute (const Array<int>& vec, bool inv = false) const;
+  Array<T> ipermute (const Array<int>& vec) const
+    { return permute (vec, true); }
+
   void resize_no_fill (int n);
   void resize_and_fill (int n, const T& val);
 
--- a/liboctave/CMatrix.cc	Tue Nov 11 01:13:10 2003 +0000
+++ b/liboctave/CMatrix.cc	Tue Nov 11 17:25:42 2003 +0000
@@ -2220,32 +2220,32 @@
   OCTAVE_QUIT;
 
   // construct balancing permutation vector
-  Array<int> ipermute (nc);
+  Array<int> iperm (nc);
   for (int i = 0; i < nc; i++)
-    ipermute(i) = i;  // initialize to identity permutation
+    iperm(i) = i;  // initialize to identity permutation
 
   // leading permutations in forward order
   for (int i = 0; i < (ilo-1); i++)
     {
       int swapidx = static_cast<int> (dpermute(i)) - 1;
-      int tmp = ipermute(i);
-      ipermute(i) = ipermute(swapidx);
-      ipermute(swapidx) = tmp;
+      int tmp = iperm(i);
+      iperm(i) = iperm(swapidx);
+      iperm(swapidx) = tmp;
     }
 
   // trailing permutations must be done in reverse order
   for (int i = nc - 1; i >= ihi; i--)
     {
       int swapidx = static_cast<int> (dpermute(i)) - 1;
-      int tmp = ipermute(i);
-      ipermute(i) = ipermute(swapidx);
-      ipermute(swapidx) = tmp;
+      int tmp = iperm(i);
+      iperm(i) = iperm(swapidx);
+      iperm(swapidx) = tmp;
     }
 
   // construct inverse balancing permutation vector
   Array<int> invpvec (nc);
   for (int i = 0; i < nc; i++)
-    invpvec(ipermute(i)) = i;     // Thanks to R. A. Lippert for this method
+    invpvec(iperm(i)) = i;     // Thanks to R. A. Lippert for this method
 
   OCTAVE_QUIT;
 
--- a/liboctave/ChangeLog	Tue Nov 11 01:13:10 2003 +0000
+++ b/liboctave/ChangeLog	Tue Nov 11 17:25:42 2003 +0000
@@ -1,3 +1,15 @@
+2003-11-11  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* Array.h (Array<T>::ipermute): New function.
+
+2003-11-11  Petter Risholm  <risholm@stud.ntnu.no>
+
+	* Array.cc (Array<T>::permute): New function.
+	* Array.h: Provide decl.
+
+	* Array-util.cc (calc_permutated_idx): New function.
+	* Array-util.h: Provide decl.
+
 2003-11-10  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
 	* Array.cc (Array<T>::index2): Return value has orientation of
--- a/liboctave/dMatrix.cc	Tue Nov 11 01:13:10 2003 +0000
+++ b/liboctave/dMatrix.cc	Tue Nov 11 17:25:42 2003 +0000
@@ -1863,32 +1863,32 @@
   OCTAVE_QUIT;
 
   // construct balancing permutation vector
-  Array<int> ipermute (nc);
+  Array<int> iperm (nc);
   for (int i = 0; i < nc; i++)
-    ipermute(i) = i;  // identity permutation
+    iperm(i) = i;  // identity permutation
 
   // leading permutations in forward order
   for (int i = 0; i < (ilo-1); i++)
     {
       int swapidx = static_cast<int> (dpermute(i)) - 1;
-      int tmp = ipermute(i);
-      ipermute(i) = ipermute (swapidx);
-      ipermute(swapidx) = tmp;
+      int tmp = iperm(i);
+      iperm(i) = iperm (swapidx);
+      iperm(swapidx) = tmp;
     }
 
   // trailing permutations must be done in reverse order
   for (int i = nc - 1; i >= ihi; i--)
     {
       int swapidx = static_cast<int> (dpermute(i)) - 1;
-      int tmp = ipermute(i);
-      ipermute(i) = ipermute(swapidx);
-      ipermute(swapidx) = tmp;
+      int tmp = iperm(i);
+      iperm(i) = iperm(swapidx);
+      iperm(swapidx) = tmp;
     }
 
   // construct inverse balancing permutation vector
   Array<int> invpvec (nc);
   for (int i = 0; i < nc; i++)
-    invpvec(ipermute(i)) = i;     // Thanks to R. A. Lippert for this method
+    invpvec(iperm(i)) = i;     // Thanks to R. A. Lippert for this method
 
   OCTAVE_QUIT;
  
--- a/src/ChangeLog	Tue Nov 11 01:13:10 2003 +0000
+++ b/src/ChangeLog	Tue Nov 11 17:25:42 2003 +0000
@@ -1,3 +1,19 @@
+2003-11-11  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* data.cc (do_permute): New function.
+	(Fpermute, Fipermute): Use it.
+
+	* ov-base.cc (octave_base_value::permute): New function.
+	* ov-base.h: Provide decl.
+
+	* ov.h (octave_value::ipermute): New function.
+
+2003-11-11  Petter Risholm  <risholm@stud.ntnu.no>
+
+	* data.cc (Fpermute, Fipermute): New functions.
+	* ov.h (octave_value::permute): New function.
+	* ov-base-mat.h (octave_base_matrix::permute): New function.
+
 2003-11-10  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
 	* oct-obj.h (octave_value_list): Internal representation is now
--- a/src/data.cc	Tue Nov 11 01:13:10 2003 +0000
+++ b/src/data.cc	Tue Nov 11 17:25:42 2003 +0000
@@ -665,6 +665,55 @@
   DATA_REDUCTION (prod);
 }
 
+static octave_value
+do_permute (const octave_value_list& args, bool inv, const std::string& fname)
+{
+  octave_value retval;
+
+  if (args.length () == 2 && args(1).length () == args(0).dims ().length ())
+    {
+      Array<int> vec = args(1).int_vector_value ();
+
+      octave_value ret = args(0).permute (vec, inv);
+
+      if (! error_state)
+	retval = ret;
+    }
+  else
+    print_usage (fname);
+
+  return retval;
+}
+
+DEFUN (permute, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {} permute (@var{a}, @var{perm})\n\
+Return the generalized transpose for an N-d array object @var{a}.\n\
+The permutation vector @var{perm} must contain the elements\n\
+@code{1:ndims(a)} (in any order, but each element must appear just once).\n\
+\n\
+@end deftypefn\n\
+@seealso{ipermute}")
+{
+  return do_permute (args, false, "permute");
+}
+
+DEFUN (ipermute, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {} ipermute (@var{a}, @var{iperm})\n\
+The inverse of the @code{permute} function.  The expression\n\
+\n\
+@example\n\
+ipermute (permute (a, perm), perm)\n\
+@end example\n\
+returns the original array @var{a}.\n\
+\n\
+@end deftypefn\n\
+@seealso{permute}")
+{
+  return do_permute (args, true, "ipermute");
+}
+
 DEFUN (length, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} length (@var{a})\n\
--- a/src/ov-base-mat.h	Tue Nov 11 01:13:10 2003 +0000
+++ b/src/ov-base-mat.h	Tue Nov 11 17:25:42 2003 +0000
@@ -95,6 +95,9 @@
   octave_value reshape (const dim_vector& new_dims) const
     { return MT (matrix.reshape (new_dims)); }
 
+  octave_value permute (const Array<int>& vec, bool inv = false) const
+    { return MT (matrix.permute (vec, inv)); }
+
   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	Tue Nov 11 01:13:10 2003 +0000
+++ b/src/ov-base.cc	Tue Nov 11 17:25:42 2003 +0000
@@ -181,6 +181,13 @@
 }
 
 octave_value
+octave_base_value::permute (const Array<int>&, bool) const
+{
+  gripe_wrong_type_arg ("octave_base_value::permute ()", 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	Tue Nov 11 01:13:10 2003 +0000
+++ b/src/ov-base.h	Tue Nov 11 17:25:42 2003 +0000
@@ -98,6 +98,8 @@
 
   octave_value reshape (const dim_vector&) const;
 
+  octave_value permute (const Array<int>& vec, bool = false) const;
+
   bool is_defined (void) const { return false; }
 
   bool is_cell (void) const { return false; }
--- a/src/ov.h	Tue Nov 11 01:13:10 2003 +0000
+++ b/src/ov.h	Tue Nov 11 17:25:42 2003 +0000
@@ -332,6 +332,12 @@
   virtual octave_value reshape (const dim_vector& dv) const
     { return rep->reshape (dv); }
 
+  virtual octave_value permute (const Array<int>& vec, bool inv = false) const
+    { return rep->permute (vec, inv); }
+
+  octave_value ipermute (const Array<int>& vec) const
+    { return rep->permute (vec, true); }
+
   // 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().