Search code examples
arraysmatlabuniquepermutation

Matlab: Creating a blockwise permutation


I have a vector from 1 to 40 and want to shuffle it in such a way that each block of four integers (ten blocks in total) are shuffled only with themselves.

For example: 3 4 2 1 | 7 6 5 8 | 9 11 10 12 | ...

My original idea was to append ten permutation vectors to eachother and then add a 1 to 40 vector to the big permutation vector, but it didn't work at all as expected and was logically wrong.

Has anyone an idea how to solve this?


Solution

  • data = 10:10:120;    % input: values to be permuted
    group_size = 4;      % input: group size
    D = reshape(data, group_size, []);                            % step 1
    [~, ind] = sort(rand(size(D)), 1);                            % step 2
    result = D(bsxfun(@plus, ind, (0:size(D,2)-1)*group_size));   % step 3
    result = result(:).';                                         % step 4
    

    Example result:

    result =
        20    10    30    40    60    50    70    80   110   100   120    90
    

    How it works

    1. Reshape the data vector into a matrix D, such that each group is a column. This is done with reshape.
    2. Generate a matrix, ind, where each column contains the indices of a permutation of the corresponding column of D. This is done generating independent, uniform random values (rand), sorting each column, and getting the indices of the sorting (second output of sort).
    3. Apply ind as column indices into D. This requires converting to linear indices, which can be done with bsxfun (or with sub2ind, but that's usually slower).
    4. Reshape back into a vector.