Home > FMAToolbox > General > CircularShift.m

CircularShift

PURPOSE ^

CircularShift - Shift matrix rows or columns circularly.

SYNOPSIS ^

function shifted = CircularShift(m,s)

DESCRIPTION ^

CircularShift - Shift matrix rows or columns circularly.

  Shift each matrix row (or column) circularly by a different amount.

  USAGE

    shifted = CircularShift(m,s)

    m              matrix to rotate
    s              shift amount for each row (horizontal vector) or
                   column (vertical vector)

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function shifted = CircularShift(m,s)
0002 
0003 %CircularShift - Shift matrix rows or columns circularly.
0004 %
0005 %  Shift each matrix row (or column) circularly by a different amount.
0006 %
0007 %  USAGE
0008 %
0009 %    shifted = CircularShift(m,s)
0010 %
0011 %    m              matrix to rotate
0012 %    s              shift amount for each row (horizontal vector) or
0013 %                   column (vertical vector)
0014 
0015 % Copyright (C) 2012 by Michaƫl Zugaro
0016 %
0017 % This program is free software; you can redistribute it and/or modify
0018 % it under the terms of the GNU General Public License as published by
0019 % the Free Software Foundation; either version 3 of the License, or
0020 % (at your option) any later version.
0021 
0022 % Check number of parameters
0023 if nargin < 2,
0024   error('Incorrect number of parameters (type ''help <a href="matlab:help CircularShift">CircularShift</a>'' for details).');
0025 end
0026 
0027 [mm,nm] = size(m);
0028 [ms,ns] = size(s);
0029 
0030 % Check parameter sizes
0031 if ~isivector(s),
0032     error('Second parameter is not a vector of integers (type ''help <a href="matlab:help CircularShift">CircularShift</a>'' for details).');
0033 end
0034 if mm ~= ms && nm ~= ns,
0035     error('Incompatible parameter sizes (type ''help <a href="matlab:help CircularShift">CircularShift</a>'' for details).');
0036 end
0037 
0038 % The algorithm below works along columns; transpose if necessary
0039 s = -s(:)';
0040 if ns == 1,
0041     m = m';
0042     [mm,nm] = size(m);
0043 end
0044 
0045 % Shift matrix S, where Sij is the vertical shift for element ij
0046 shift = repmat(s,mm,1);
0047 
0048 % Before we start, each element Mij has a linear index Aij. After circularly shifting the rows, it will have a linear index Bij.
0049 % We now construct Bij.
0050 
0051 % First, create matrix C where each item Cij = i (row number)
0052 lines = repmat((1:mm)',1,nm);
0053 % Next, update C so that Cij becomes the target row number (after circular shift)
0054 lines = mod(lines+shift,mm);
0055 lines(lines==0) = mm;
0056 % Finally, transform Cij into a linear index, yielding Bij
0057 indices = lines + repmat((0:nm-1).*mm,mm,1);
0058 
0059 % Circular shift (reshape so that it is not transformed into a vector)
0060 shifted = reshape(m(indices),mm,nm);
0061 
0062 % Transpose back if necessary
0063 if ns == 1,
0064     shifted = shifted';
0065 end

Generated on Fri 16-Mar-2018 13:00:20 by m2html © 2005