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:
The following code builds a linear index as the sum of two parts:
repelem
), andrepmat
).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