arraysmatlabmatrixtoeplitz

How to print a circulant matrix (toeplitz), in MATLAB, where each input is a 3D matrix of dimention m x m x 3?


I know how to use toeplitz function in MATLAB to create a circulant matrix of 1 D vector. However, I am trying to create a circulant block

For example, I have 3 matrices of size (2,2,3) where third dimension is R,G, B: Below I am showing the sample values of row and column of each matrix. First Matrix:

# 01  02
# 03  04

Second Matrix:

# 05  06
# 07  08

Third Matrix:

# 09  10
# 11  12

Now I want to create a circulant matrix which looks like this

# 01  02  05  06  09  10
# 03  04  07  08  11  12
# 09  10  01  02  05  06
# 11  12  03  04  07  08
# 03  04  09  10  01  02
# 05  06  11  12  03  04

Note, I want to be able to move the entire block of the matrix to the right in the subsequent lines, and not just the first line of the matrix. Please note, i want to preserve the third dimensions of these matrices w(which has color dimension in them)

Can someone tell me how to go ahead with it? I thought of making an array I already have a 3D matrix, and don't know how to make an array of the array here, if it will help at all.

References:


Solution

  • The following code builds a linear index as the sum of two parts:

    Applying this index to the original matrix produces the desired result.

    data = cat(3, [1 2; 3 4], [5 6; 7 8], [9 10; 11 12]); % example data
    [L, M, N] = size(data);
    ind_outer = repelem(mod(bsxfun(@minus, 0:N-1, (0:N-1).'), N), L, M);
    ind_inner = repmat(reshape(1:L*M, L, M), N, N);
    ind = ind_outer*L*M + ind_inner;
    result = data(ind);
    

    This gives

    result =
         1     2     5     6     9    10
         3     4     7     8    11    12
         9    10     1     2     5     6
        11    12     3     4     7     8
         5     6     9    10     1     2
         7     8    11    12     3     4
    

    To better understand how this works, see the outer and inner indexing patterns (and if needed read about linear indexing):

    >> ind_outer
    ind_outer =
         0     0     1     1     2     2
         0     0     1     1     2     2
         2     2     0     0     1     1
         2     2     0     0     1     1
         1     1     2     2     0     0
         1     1     2     2     0     0
    
    >> ind_inner
    ind_inner =
         1     3     1     3     1     3
         2     4     2     4     2     4
         1     3     1     3     1     3
         2     4     2     4     2     4
         1     3     1     3     1     3
         2     4     2     4     2     4