]> Creatis software - CreaPhase.git/blob - octave_packages/m/general/rotdim.m
update packages
[CreaPhase.git] / octave_packages / m / general / rotdim.m
1 ## Copyright (C) 2004-2012 David Bateman
2 ##
3 ## This file is part of Octave.
4 ##
5 ## Octave is free software; you can redistribute it and/or modify it
6 ## under the terms of the GNU General Public License as published by
7 ## the Free Software Foundation; either version 3 of the License, or (at
8 ## your option) any later version.
9 ##
10 ## Octave is distributed in the hope that it will be useful, but
11 ## WITHOUT ANY WARRANTY; without even the implied warranty of
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 ## General Public License for more details.
14 ##
15 ## You should have received a copy of the GNU General Public License
16 ## along with Octave; see the file COPYING.  If not, see
17 ## <http://www.gnu.org/licenses/>.
18
19 ## -*- texinfo -*-
20 ## @deftypefn  {Function File} {} rotdim (@var{x})
21 ## @deftypefnx {Function File} {} rotdim (@var{x}, @var{n})
22 ## @deftypefnx {Function File} {} rotdim (@var{x}, @var{n}, @var{plane})
23 ## Return a copy of @var{x} with the elements rotated counterclockwise in
24 ## 90-degree increments.
25 ## The second argument @var{n} is optional, and specifies how many 90-degree
26 ## rotations are to be applied (the default value is 1).
27 ## The third argument is also optional and defines the plane of the
28 ## rotation.  If present, @var{plane} is a two element vector containing two
29 ## different valid dimensions of the matrix.  When @var{plane} is not given
30 ## the first two non-singleton dimensions are used.
31 ##
32 ## Negative values of @var{n} rotate the matrix in a clockwise direction.
33 ## For example,
34 ##
35 ## @example
36 ## @group
37 ## rotdim ([1, 2; 3, 4], -1, [1, 2])
38 ##      @result{}  3  1
39 ##          4  2
40 ## @end group
41 ## @end example
42 ##
43 ## @noindent
44 ## rotates the given matrix clockwise by 90 degrees.  The following are all
45 ## equivalent statements:
46 ##
47 ## @example
48 ## @group
49 ## rotdim ([1, 2; 3, 4], -1, [1, 2])
50 ## rotdim ([1, 2; 3, 4], 3, [1, 2])
51 ## rotdim ([1, 2; 3, 4], 7, [1, 2])
52 ## @end group
53 ## @end example
54 ## @seealso{rot90, flipud, fliplr, flipdim}
55 ## @end deftypefn
56
57 function y = rotdim (x, n, plane)
58
59   if (nargin < 1 || nargin > 3)
60     print_usage ();
61   endif
62
63   if (nargin > 1 && ! isempty(n))
64     if (!isscalar (n) || !isreal(n) || fix (n) != n)
65       error ("rotdim: N must be a scalar integer");
66     endif
67   else
68     n = 1;
69   endif
70
71   nd = ndims (x);
72   sz = size (x);
73   if (nargin < 3)
74     if (nd > 2)
75       ## Find the first two non-singleton dimension.
76       plane = [];
77       dim = 0;
78       while (dim < nd)
79         dim = dim + 1;
80         if (sz (dim) != 1)
81           plane = [plane, dim];
82           if (length (plane) == 2)
83             break;
84           endif
85         endif
86       endwhile
87       if (length (plane) < 1)
88         plane = [1, 2];
89       elseif (length (plane) < 2)
90         plane = [1, plane];
91       endif
92     else
93       plane = [1, 2];
94     endif
95   else
96     if (! (isvector (plane) && length (plane) == 2
97            && all (plane == fix (plane)) && all (plane > 0)
98            && all (plane < (nd + 1)) && plane(1) != plane(2)))
99       error ("rotdim: PLANE must be a 2 element integer vector defining a valid PLANE");
100     endif
101   endif
102
103   n = rem (n, 4);
104   if (n < 0)
105     n = n + 4;
106   endif
107   if (n == 0)
108     y = x;
109   elseif (n == 2)
110     y = flipdim (flipdim (x, plane(1)), plane(2));
111   elseif (n == 1 || n == 3)
112     perm = 1:nd;
113     perm(plane(1)) = plane(2);
114     perm(plane(2)) = plane(1);
115     y = permute (x, perm);
116     if (n == 1)
117       y = flipdim (y, min (plane));
118     else
119       y = flipdim (y, max (plane));
120     endif
121   else
122     error ("rotdim: internal error!");
123   endif
124
125 endfunction
126
127 %!error rotdim ();
128 %!error rotdim (1, 2, 3, 4);
129
130 %!shared r, rr
131 %! r = [1,2,3]; rr = [3,2,1];
132 %!assert (rotdim (r, 0), r);
133 %!assert (rotdim (r, 1), rr');
134 %!assert (rotdim (r, 2), rr);
135 %!assert (rotdim (r, 3), r');
136 %!assert (rotdim (r, 3), rotdim (r, -1));
137 %!assert (rotdim (r, 1), rotdim (r));
138
139 %!shared c, cr
140 %! c = [1;2;3]; cr = [3;2;1];
141 %!assert (rotdim (c, 0), c);
142 %!assert (rotdim (c, 1), c');
143 %!assert (rotdim (c, 2), cr);
144 %!assert (rotdim (c, 3), cr');
145 %!assert (rotdim (c, 3), rotdim (c, -1));
146 %!assert (rotdim (c, 1), rotdim (c));
147
148 %!shared m
149 %! m = [1,2;3,4];
150 %!assert (rotdim (m, 0), m);
151 %!assert (rotdim (m, 1), [2,4;1,3]);
152 %!assert (rotdim (m, 2), [4,3;2,1]);
153 %!assert (rotdim (m, 3), [3,1;4,2]);
154 %!assert (rotdim (m, 3), rotdim (m, -1));
155 %!assert (rotdim (m, 1), rotdim (m));
156
157 ## FIXME -- we need tests for multidimensional arrays and different
158 ## values of PLANE.