1######################################################################## 2## 3## Copyright (C) 2004-2021 The Octave Project Developers 4## 5## See the file COPYRIGHT.md in the top-level directory of this 6## distribution or <https://octave.org/copyright/>. 7## 8## This file is part of Octave. 9## 10## Octave is free software: you can redistribute it and/or modify it 11## under the terms of the GNU General Public License as published by 12## the Free Software Foundation, either version 3 of the License, or 13## (at your option) any later version. 14## 15## Octave is distributed in the hope that it will be useful, but 16## WITHOUT ANY WARRANTY; without even the implied warranty of 17## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18## GNU General Public License for more details. 19## 20## You should have received a copy of the GNU General Public License 21## along with Octave; see the file COPYING. If not, see 22## <https://www.gnu.org/licenses/>. 23## 24######################################################################## 25 26## -*- texinfo -*- 27## @deftypefn {} {@var{y} =} shiftdim (@var{x}, @var{n}) 28## @deftypefnx {} {[@var{y}, @var{ns}] =} shiftdim (@var{x}) 29## Shift the dimensions of @var{x} by @var{n}, where @var{n} must be 30## an integer scalar. 31## 32## When @var{n} is positive, the dimensions of @var{x} are shifted to the left, 33## with the leading dimensions circulated to the end. If @var{n} is negative, 34## then the dimensions of @var{x} are shifted to the right, with @var{n} 35## leading singleton dimensions added. 36## 37## Called with a single argument, @code{shiftdim}, removes the leading 38## singleton dimensions, returning the number of dimensions removed in the 39## second output argument @var{ns}. 40## 41## For example: 42## 43## @example 44## @group 45## x = ones (1, 2, 3); 46## size (shiftdim (x, -1)) 47## @result{} 1 1 2 3 48## size (shiftdim (x, 1)) 49## @result{} 2 3 50## [b, ns] = shiftdim (x) 51## @result{} b = 52## 1 1 1 53## 1 1 1 54## @result{} ns = 1 55## @end group 56## @end example 57## @seealso{reshape, permute, ipermute, circshift, squeeze} 58## @end deftypefn 59 60function [y, ns] = shiftdim (x, n) 61 62 if (nargin < 1 || nargin > 2) 63 print_usage (); 64 endif 65 66 nd = ndims (x); 67 orig_dims = size (x); 68 69 if (nargin == 1) 70 ## Find the first non-singleton dimension. 71 (n = find (orig_dims != 1, 1) - 1) || (n = nd); 72 elseif (! (isscalar (n) && n == fix (n))) 73 error ("shiftdim: N must be a scalar integer"); 74 endif 75 76 if (n >= nd) 77 n = rem (n, nd); 78 endif 79 80 if (n < 0) 81 singleton_dims = ones (1, -n); 82 y = reshape (x, [singleton_dims, orig_dims]); 83 elseif (n > 0) 84 ## We need permute here instead of reshape to shift values in a 85 ## compatible way. 86 y = permute (x, [n+1:nd 1:n]); 87 else 88 y = x; 89 endif 90 91 ns = n; 92 93endfunction 94 95 96%!test 97%! x = rand (1, 1, 4, 2); 98%! [y, ns] = shiftdim (x); 99%! assert (size (y), [4 2]); 100%! assert (ns, 2); 101%! assert (shiftdim (y, -2), x); 102%! assert (size (shiftdim (x, 2)), [4 2]); 103 104%!assert (size (shiftdim (rand (0, 1, 2))), [0 1 2]) 105 106## Test input validation 107%!error (shiftdim ()) 108%!error (shiftdim (1,2,3)) 109%!error (shiftdim (1, ones (2))) 110%!error (shiftdim (1, 1.5)) 111