matrix of circulating vectors without loop

hi all , I want to built a matrix of circulating vectors without using loops
for example
input:
1 2 3 4
4 5 6 7
3 8 4 6
output :
1 2 3 4
4 1 2 3
3 4 1 2
2 3 4 1
4 5 6 7
7 4 5 6
6 7 4 5
5 6 7 4
3 8 4 6
6 3 8 4
4 6 3 8
8 4 6 3
I use the code
v =[1,2,3,4;4,5,6,7;3,8,4,6]
%notice the length of each vector in v is equal
len_rows=length(v(:,1));
len_cols=length(v(1,:));
mat_shifted=zeros(len_rows*len_cols,len_cols);
j=1;
for i=1:len_rows
vec=v(i,:);
mat=toeplitz([vec(1) fliplr(vec(2:end))], vec)
mat_shifted(j:j+len_cols-1,:)=mat
j=j+len_cols;
end
is there a smart way to do it without using loops , thanks in advance

 採用された回答

Honglei Chen
Honglei Chen 2018 年 5 月 4 日

1 投票

Not necessarily better in performance, but if you really want to avoid explicitly calling a loop, try
y = arrayfun(@(r)gallery('circul',x(r,:)),1:size(x,1),'UniformOutput',false);
cat(1,y{:})
HTH

4 件のコメント

fatema hamodi
fatema hamodi 2018 年 5 月 4 日
hi , thanks :) , I want to avoid using loops since I want to work with huge matrix so I want matlab to use all the possible processors of the computer , so for my purpose do you think that the way you suggested would be better ?
Stephen23
Stephen23 2018 年 5 月 4 日
"do you think that the way you suggested would be better ?"
Using arrayfun will be slower than using a for loop. The main advantage of arrayfun / cellfun is more compact code. For a large array you probably would not want to swap a fast loop for slow arrayfun.
Honglei Chen
Honglei Chen 2018 年 5 月 4 日
Here is another way which should be more efficient and without explicit loop usage. But overall you want to find a tradeoff between time and memory when you deal with large data set.
x = [1 2 3 4;4 5 6 7;3 8 4 6];
[M,N] = size(x);
r = kron((1:M)',ones(N));
c = repmat(gallery('circul',1:N),M,1);
x(sub2ind([M,N],r,c))
HTH
fatema hamodi
fatema hamodi 2018 年 5 月 4 日
thanks a lot !!

サインインしてコメントする。

その他の回答 (2 件)

Stephen23
Stephen23 2018 年 5 月 4 日
編集済み: Stephen23 2018 年 5 月 4 日

1 投票

I think your concept is quite reasonable You could simplify the code a bit by using a cell array for the output, rather than keeping track of the rows:
M = [1,2,3,4;4,5,6,7;3,8,4,6];
N = size(M,1);
C = cell(N,1);
for k = 1:N
V = M(k,:);
C{k} = toeplitz([V(1),V(end:-1:2)],V);
end
Z = vertcat(C{:})
Carlos Sanchis
Carlos Sanchis 2018 年 5 月 4 日

1 投票

Still with a for loop, but somewhat more readable...
input = [1 2 3 4; ...
4 5 6 7; ...
3 8 4 6];
[m, n] = size(input);
output = zeros(m * n, n);
for s = 0:n-1
output((0:m-1) * n + s + 1, :) = circshift(input, s, 2);
end
expected = [1 2 3 4; 4 1 2 3; 3 4 1 2; 2 3 4 1; ...
4 5 6 7; 7 4 5 6; 6 7 4 5; 5 6 7 4; ...
3 8 4 6; 6 3 8 4; 4 6 3 8; 8 4 6 3];
assert(isequal(output, expected));

1 件のコメント

fatema hamodi
fatema hamodi 2018 年 5 月 4 日
編集済み: fatema hamodi 2018 年 5 月 4 日
thanks for your suggestion

サインインしてコメントする。

カテゴリ

ヘルプ センター および File ExchangeLoops and Conditional Statements についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by