Shift columns of a matrix with different values
Afficher commentaires plus anciens
Hi,
first of all: I know that my question is not a really new one, however, I do not fully understand some of the solutions proposed in other threads, so I hope someone can help me out. I want to shift rows of a matrix by different amounts. A similiar question was asked here:
The solution suggested by Azzi Abdelmalek in this thread works for me, but I would like to know if the bsxfun()-based approach by Andrei Bobrov, also suggested in this thread, is faster. Unfortunately I am not able to re-implement his code...
This Code shows what I want to do:
A = [10, 12, 14, 11;
8 , 10, 13, 10;
7 , 8, 12, 8;
6 , 7, 10, 7;
5 , 6, 8, 6;
3 , 5, 7, 5;
1 , 3, 6, 3];
ShiftVector = -[0,1,3,1];
origStart = abs(max(ShiftVector))+1;
origEnd = origStart + size(A ,1) - 1;
B = [zeros(abs(max(ShiftVector)),size(A,2)); ...
A; ...
zeros(abs(min(ShiftVector)),size(A,2))];
out=cell2mat(arrayfun(@(x) circshift(B(:,x),[ShiftVector(x) 1]),(1:numel(ShiftVector)),'un',0));
shiftedMatrix = out(origStart:origEnd,1:size(A,2))
The shifted Matrix is:
shiftedMatrix =
10 10 10 10
8 8 8 8
7 7 7 7
6 6 6 6
5 5 0 5
3 3 0 3
1 0 0 0
I dont want a circular shift of each row but want to append zeros, to fill each shifted rows, as it can be seen in the example above.
I would like to know if there is a faster alternative on how this could be implemented. As I said before Andrei Bobrov proposed a bsxfun()-based solution to a similar problem, but I do not understand how bsxfun could help me out here...
I would be very grateful for any suggestions!
6 commentaires
Adam Danz
le 5 Mar 2021
You said Azzi's solution works for you, which uses circshift, but then you said you want to circularly shift each row. That's confusing.
Marvin H.
le 5 Mar 2021
Adam Danz
le 5 Mar 2021
I see... I removed my answer for now. Maybe I'll have time to give it another hack later.
Marvin H.
le 5 Mar 2021
Maybe I still don't understand the question because the solutions in the link you referred to are circularly shifting each row by different amounts but the example you gave and the solution the skillful Matt J gave seem to be doing something else.
function y=circshift (x,M)
if abs (M)>length (x)
M=rem (M,length(x));
end
if M<0
M=M+length(x);
end
y=[x(M+1:length(x))x(1:M)];
function y = circonv(x1,x2)
L1=length(x1);
L2=lenth(x2);
if L1=L2,error(('the sequence with different length'));
end
y=zeros(1,L1);
x2tr=[x2(1)x2(L2:-1.2)];
for 1=1:L1
sh=circshift(x2tr,1-k);
h=x1,*sh;
y(k)=sum(h);
end
What is the meaning of the command “rem” in above function “circshift”? What are the function of the function “circshift” and “circonv”? Write the program to realize the Circular shift M samples of the sequence x[n]={0,1,2,3,4,5,6,7,8,9}.
Réponse acceptée
Plus de réponses (2)
A = [10, 12, 14, 11;
8 , 10, 13, 10;
7 , 8, 12, 8;
6 , 7, 10, 7;
5 , 6, 8, 6;
3 , 5, 7, 5;
1 , 3, 6, 3];
ShiftVector = -[0,1,3,1];
[m,n]=size(A);
J=repmat(1:n,m,1);
Inew=(1:m).'+ ShiftVector;
idx=(1<=Inew) & (Inew<=m);
shiftedMatrix=accumarray([Inew(idx),J(idx)], A(idx),[m,n])
1 commentaire
Marvin H.
le 5 Mar 2021
A = [10, 12, 14, 11;
8 , 10, 13, 10;
7 , 8, 12, 8;
6 , 7, 10, 7;
5 , 6, 8, 6;
3 , 5, 7, 5;
1 , 3, 6, 3];
ShiftVector = -[0,1,3,1];
[m,n]=size(A);
mask=(1:m).'<=(m+ShiftVector);
shiftedMatrix = mask.*round(ifft(fft(A) .* exp(-2i*pi/m*(0:m-1).'*ShiftVector)) )
Catégories
En savoir plus sur Linear Algebra dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!