From help-request at octave dot org Fri Feb 18 13:06:07 2005 Subject: Re: permute three dimensional Array From: "John W. Eaton" To: "Hugo Neto" Cc: "Quentin Spencer" , Date: Fri, 18 Feb 2005 14:10:57 -0500 On 18-Feb-2005, Hugo Neto wrote: | Thanks a lot for your help, you are right, "Example" is in fact a | 2-dimensional array. I have used the Transpose option. I didn't think in | that chance.... but it is right, i reach the same goal. Still, I think permutations like the one you attempted should be allowed. Please try the following patch. With it, you should be able to do things like this: octave:6> x = [1,2;3,4] x = 1 2 3 4 octave:7> permute (x, [4,3,2,1]) ans = ans(:,:,1,1) = 1 ans(:,:,2,1) = 2 ans(:,:,1,2) = 3 ans(:,:,2,2) = 4 The patch is relative to the current main cvs branch, but should also apply to the "testing" snapshots. Thanks, jwe liboctave/ChangeLog: 2005-02-18 John W. Eaton * Array.cc (Array::permute): Allow permutation vector longer than number of dimenensions of permuted matrix. * Array.cc (Array::permute): Use zero-based indexing for perm_vec. * Array-util.cc (calc_permutated_idx): Likewise. src/ChangeLog: 2005-02-18 John W. Eaton * data.cc (do_permute): Use zero-based indexing for permutation vector that is passed to octave_value::permute method. Allow permutation vector longer than number of dimenensions of permuted matrix. Index: liboctave/Array-util.cc =================================================================== RCS file: /usr/local/cvsroot/octave/liboctave/Array-util.cc,v retrieving revision 1.10 diff -u -r1.10 Array-util.cc --- liboctave/Array-util.cc 9 Feb 2005 08:02:58 -0000 1.10 +++ liboctave/Array-util.cc 18 Feb 2005 18:58:28 -0000 at @ -461,9 +461,9 @@ for (int i = 0; i < n_el; i++) { if (inv) - retval(perm_vec(i)-1) = old_idx(i); + retval(perm_vec(i)) = old_idx(i); else - retval(i) = old_idx(perm_vec(i)-1); + retval(i) = old_idx(perm_vec(i)); } return retval; Index: liboctave/Array.cc =================================================================== RCS file: /usr/local/cvsroot/octave/liboctave/Array.cc,v retrieving revision 1.127 diff -u -r1.127 Array.cc --- liboctave/Array.cc 26 Jan 2005 22:08:37 -0000 1.127 +++ liboctave/Array.cc 18 Feb 2005 18:58:28 -0000 at @ -430,43 +430,54 @@ dim_vector dv = dims (); dim_vector dv_new; - int nd = dv.length (); + int perm_vec_len = perm_vec.length (); - dv_new.resize (nd); + if (perm_vec_len < dv.length ()) + (*current_liboctave_error_handler) + ("%s: invalid permutation vector", inv ? "ipermute" : "permute"); + + dv_new.resize (perm_vec_len); + + // Append singleton dimensions as needed. + dv.resize (perm_vec_len, 1); + + const Array tmp = reshape (dv); // Need this array to check for identical elements in permutation array. - Array checked (nd, false); + Array checked (perm_vec_len, false); // Find dimension vector of permuted array. - for (int i = 0; i < nd; i++) + for (int i = 0; i < perm_vec_len; i++) { - int perm_el = perm_vec.elem (i); + int perm_elt = perm_vec.elem (i); - if (perm_el > dv.length () || perm_el < 1) + if (perm_elt >= perm_vec_len || perm_elt < 0) { (*current_liboctave_error_handler) - ("permutation vector contains an invalid element"); + ("%s: permutation vector contains an invalid element", + inv ? "ipermute" : "permute"); return retval; } - if (checked.elem(perm_el - 1)) + if (checked.elem(perm_elt)) { (*current_liboctave_error_handler) - ("PERM cannot contain identical elements"); + ("%s: permutation vector cannot contain identical elements", + inv ? "ipermute" : "permute"); return retval; } else - checked.elem(perm_el - 1) = true; + checked.elem(perm_elt) = true; - dv_new (i) = dv (perm_el - 1); + dv_new(i) = dv(perm_elt); } retval.resize (dv_new); // Index array to the original array. - Array old_idx (nd, 0); + Array old_idx (perm_vec_len, 0); // Number of elements in Array (should be the same for // both the permuted array and original array). at @ -478,7 +489,7 @@ // Get the idx of permuted array. Array new_idx = calc_permutated_idx (old_idx, perm_vec, inv); - retval.elem (new_idx) = elem (old_idx); + retval.elem (new_idx) = tmp.elem (old_idx); increment_index (old_idx, dv); } Index: src/data.cc =================================================================== RCS file: /usr/local/cvsroot/octave/src/data.cc,v retrieving revision 1.138 diff -u -r1.138 data.cc --- src/data.cc 3 Nov 2004 21:23:43 -0000 1.138 +++ src/data.cc 18 Feb 2005 18:58:35 -0000 at @ -863,10 +863,18 @@ { octave_value retval; - if (args.length () == 2 && args(1).length () == args(0).dims ().length ()) + if (args.length () == 2 && args(1).length () >= args(1).ndims ()) { Array vec = args(1).int_vector_value (); + // XXX FIXME XXX -- maybe we shoudl create an idx_vector object + // here and pass that to permute? + + int n = vec.length (); + + for (int i = 0; i < n; i++) + vec(i)--; + octave_value ret = args(0).permute (vec, inv); if (! error_state) ------------------------------------------------------------- Octave is freely available under the terms of the GNU GPL. Octave's home on the web: http://www.octave.org How to fund new projects: http://www.octave.org/funding.html Subscription information: http://www.octave.org/archive.html -------------------------------------------------------------