changeset 19147:8b2a919d24bc

rot90.m: add support for N-dimensional arrays. * rot90.m: implement rotation for N-dimensional arrays (in part gained from its implementation on flipud and fliplr). Replace consecutive call to flipud and fliplr when k = 2 into single indexing problem. Add tests. * NEWS: note support for ND arrays in rot90.
author Carnë Draug <carandraug@octave.org>
date Sun, 21 Sep 2014 23:27:27 +0100
parents a84f0182f912
children e278c939a419
files NEWS scripts/general/rot90.m
diffstat 2 files changed, 47 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Sun Sep 21 22:22:46 2014 +0100
+++ b/NEWS	Sun Sep 21 23:27:27 2014 +0100
@@ -140,7 +140,7 @@
 
       fliplr
       flipud
-
+      rot90
 
 Summary of important user-visible changes for version 4.0:
 ---------------------------------------------------------
--- a/scripts/general/rot90.m	Sun Sep 21 22:22:46 2014 +0100
+++ b/scripts/general/rot90.m	Sun Sep 21 23:27:27 2014 +0100
@@ -19,6 +19,8 @@
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {} rot90 (@var{A})
 ## @deftypefnx {Function File} {} rot90 (@var{A}, @var{k})
+## Rotate array by 90 degree increments.
+##
 ## Return a copy of @var{A} with the elements rotated counterclockwise in
 ## 90-degree increments.  The second argument is optional, and specifies
 ## how many 90-degree rotations are to be applied (the default value is 1).
@@ -45,8 +47,10 @@
 ## @end group
 ## @end example
 ##
-## Note that @code{rot90} only works with 2-D arrays.  To rotate N-D arrays
-## use @code{rotdim} instead.
+## The rotation is always performed on the plane of the first two dimensions,
+## i.e., rows and columns.  To perform a rotation on any other plane, use
+## @code{rotdim}.
+##
 ## @seealso{rotdim, flipud, fliplr, flip}
 ## @end deftypefn
 
@@ -58,22 +62,24 @@
     print_usage ();
   endif
 
-  if (ndims (A) > 2)
-    error ("rot90: A must be a 2-D array");
-  elseif (! (isscalar (k) && isreal (k) && k == fix (k)))
+  if (! (isscalar (k) && isreal (k) && k == fix (k)))
     error ("rot90: K must be a single real integer");
   endif
 
   k = mod (k, 4);
+  nd = ndims (A);
 
   if (k == 0)
     B = A;
   elseif (k == 1)
-    B = flipud (A.');
+    B = flipud (permute (A, [2 1 3:1:nd]));
   elseif (k == 2)
-    B = flipud (fliplr (A));
+    idx(1:nd) = {':'};
+    idx{1} = rows (A):-1:1;
+    idx{2} = columns (A):-1:1;
+    B = A(idx{:});
   elseif (k == 3)
-    B = (flipud (A)).';
+    B = permute (flipud (A), [2 1 3:1:nd]);
   else
     error ("rot90: internal error!");
   endif
@@ -94,6 +100,38 @@
 %! assert (rot90 (x1, 5), x2);
 %! assert (rot90 (x1, -1), x4);
 
+## Test NDArrays
+%!test
+%! a(1:2,1:2,1) = [1 2; 3 4];
+%! a(1:2,1:2,2) = [5 6; 7 8];
+%! b(1:2,1:2,1) = [2 4; 1 3];
+%! b(1:2,1:2,2) = [6 8; 5 7];
+%! assert (rot90 (a, 1), b)
+%! assert (rot90 (a, 2), rot90 (b, 1))
+%! assert (rot90 (a, 3), rot90 (b, 2))
+
+%!test
+%! a = b = zeros (2, 2, 1, 2);
+%! a(1:2,1:2,:,1) = [1 2; 3 4];
+%! a(1:2,1:2,:,2) = [5 6; 7 8];
+%! b(1:2,1:2,:,1) = [2 4; 1 3];
+%! b(1:2,1:2,:,2) = [6 8; 5 7];
+%! assert (rot90 (a, 1), b)
+%! assert (rot90 (a, 2), rot90 (b, 1))
+%! assert (rot90 (a, 3), rot90 (b, 2))
+
+## With non-square matrices
+%!test
+%! a = zeros (3, 2, 1, 2);
+%! b = zeros (2, 3, 1, 2);
+%! a(1:2,1:3,:,1) = [ 1  2  3;  4  5  6];
+%! a(1:2,1:3,:,2) = [ 7  8  9; 10 11 12];
+%! b(1:3,1:2,:,1) = [ 3  6;  2  5;  1  4];
+%! b(1:3,1:2,:,2) = [ 9 12;  8 11;  7 10];
+%! assert (rot90 (a, 1), b)
+%! assert (rot90 (a, 2), rot90 (b, 1))
+%! assert (rot90 (a, 3), rot90 (b, 2))
+
 %% Test input validation
 %!error rot90 ()
 %!error rot90 (1, 2, 3)