changeset 13277:9f2e568123ea

circshift.m: Recode to do away with some for loops. * circshift.m: Use colon indexing to do away with some for loops. Improve input validation and add tests for it.
author Rik <octave@nomad.inbox5.com>
date Wed, 05 Oct 2011 11:43:05 -0700
parents d5c8c2fe2eed
children 04edb15d7966
files scripts/general/circshift.m
diffstat 1 files changed, 45 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/general/circshift.m
+++ b/scripts/general/circshift.m
@@ -47,53 +47,58 @@
 
 function y = circshift (x, n)
 
-  if (nargin == 2)
-    if (isempty (x))
-      y = x;
-    else
-      nd = ndims (x);
-      sz = size (x);
-
-      if (! isvector (n) && length (n) > nd)
-        error ("circshift: N must be a vector, no longer than the number of dimension in X");
-      endif
-
-      if (any (n != floor (n)))
-        error ("circshift: all values of N must be integers");
-      endif
-
-      idx = cell ();
-      for i = 1:length (n);
-        nn = n(i);
-        if (nn < 0)
-          while (sz(i) <= -nn)
-            nn = nn + sz(i);
-          endwhile
-          idx{i} = [(1-nn):sz(i), 1:-nn];
-        else
-          while (sz(i) <= nn)
-            nn = nn - sz(i);
-          endwhile
-          idx{i} = [(sz(i)-nn+1):sz(i), 1:(sz(i)-nn)];
-        endif
-      endfor
-      for i = (length(n) + 1) : nd
-        idx{i} = 1:sz(i);
-      endfor
-      y = x(idx{:});
-    endif
-  else
+  if (nargin != 2)
     print_usage ();
   endif
+
+  if (isempty (x))
+    y = x;
+    return;
+  endif
+
+  nd = ndims (x);
+  sz = size (x);
+
+  if (! isvector (n) || length (n) > nd)
+    error ("circshift: N must be a vector, no longer than the number of dimension in X");
+  elseif (any (n != fix (n)))
+    error ("circshift: all values of N must be integers");
+  endif
+
+  idx = repmat ({':'}, 1, nd);
+  for i = 1:length (n);
+    b = n(i);
+    d = sz(i);
+    if (b > 0)
+      b = rem (b, d);
+      idx{i} = [d-b+1:d, 1:d-b];
+    elseif (b < 0)
+      b = rem (abs (b), d);
+      idx{i} = [b+1:d, 1:b];
+    endif
+  endfor
+
+  y = x(idx{:});
+
 endfunction
 
+
 %!shared x
 %! x = [1, 2, 3; 4, 5, 6; 7, 8, 9];
 
 %!assert (circshift (x, 1), [7, 8, 9; 1, 2, 3; 4, 5, 6])
 %!assert (circshift (x, -2), [7, 8, 9; 1, 2, 3; 4, 5, 6])
-%!assert (circshift (x, [0, 1]), [3, 1, 2; 6, 4, 5; 9, 7, 8]);
-%!assert (circshift ([],1), [])
+%!assert (circshift (x, [0, 1]), [3, 1, 2; 6, 4, 5; 9, 7, 8])
+%!assert (circshift ([], 1), [])
+
+%!assert (circshift (eye (3), 1), circshift (eye (3), 1))
+%!assert (circshift (eye (3), 1), [0,0,1;1,0,0;0,1,0])
 
-%!assert (full (circshift (eye (3), 1)), circshift (full (eye (3)), 1))
-%!assert (full (circshift (eye (3), 1)), [0,0,1;1,0,0;0,1,0])
+%% Test input validation
+%!error circshift ()
+%!error circshift (1)
+%!error circshift (1,2,3)
+%!error circshift (1, ones(2,2))
+%!error circshift (1, [1 2 3])
+%!error circshift (1, 1.5)
+