How vectorize this operation

조회 수: 3 (최근 30일)
Cybernetics
Cybernetics 2019년 10월 7일
댓글: Cybernetics 2019년 10월 8일
I habe two vectors and with . I am implemented the following code
z = rand(length(x),1);% Just some fake data to define the size of z. could also be z=zeros(size(x))
for i=m+1:n+1
z(i)=x(i-m:i-1)'*y;
end
Knowing that n get have over a few million elements and m is less than 200, the computations rapidely become slow. How can I vectorize this operation to optimize it?
Thanks for your help!
  댓글 수: 6
Cybernetics
Cybernetics 2019년 10월 7일
Sorry there was a typo in the code. I just changed it
Rik
Rik 2019년 10월 7일
편집: Rik 2019년 10월 7일
This is very close to being a convolution. I can't find out why it isn't, but it is fairly close, as you can see with the example below (the goal would be to make sure the two cols in z_mat are equal).
clearvars,clc
n=20;m=4;
x=(1:n)';y=(1:m)';
z=zeros(n+1,1);
for k=(m+1):(n+1)
z(k)=x((k-m):(k-1))'*y;
end
tmp=conv(x,y,'same');
z_conv=zeros(size(z));
z_conv((m+1):(n+1))=tmp((m-1):(n-1));
z_mat=[z,z_conv];
disp(z_mat)

댓글을 달려면 로그인하십시오.

채택된 답변

Bruno Luong
Bruno Luong 2019년 10월 8일
n=10
m=3
x=rand(n,1)
y=rand(m,1)
% your method
z = nan(length(x),1);% Just some fake data to define the size of z. could also be z=zeros(size(x))
for i=m+1:n+1
z(i)=x(i-m:i-1)'*y;
end
z
% My method
z = [nan(m,1); conv(x,flip(y),'valid')]
  댓글 수: 3
Bruno Luong
Bruno Luong 2019년 10월 8일
Well that comes straighforward from the definition of CONV, it performs a slighding sum with one of the array that is straight and another is flipped.
So if one doesn't want to flip dusing the sum, one have to flip the array before calling CONV.
Cybernetics
Cybernetics 2019년 10월 8일
Thanks for the the elegant solution.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Daniel M
Daniel M 2019년 10월 7일
편집: Daniel M 2019년 10월 7일
If you have the signal toolbox, you can use the buffer() command to an array of the x values that you require, then do the matrix multiplication in one shot.
x = 1:50;
m = 6;
L = 15;
n = 48;
z = buffer(x(L+1-m:n),m+1,m,'nodelay'); % size(z) = [7,33]
y = 1:7; % size(y) = [1,7]
vals = y*z; % size = [1,33]
% if no signal toolbox, try
% ind = (L+1:n)-m + (0:m)';
% z = x(ind);
I'm not sure if this will be faster. It could require a lot of memory. But it is vectorized, so test it out and see.
  댓글 수: 4
Daniel M
Daniel M 2019년 10월 7일
So do it in chunks. I don't know your computer specifications. It works on my computer fine, and takes 34 seconds to make an array that large. You say the code is slow, but not how slow. You say you want it faster but don't specify what will satisfy your goals.
Are you just impatient? Or is there a strict requirement to compute in a certain time?
I suggest either waiting for the computations to finish, buy a better computer, or reevaluate your code and maybe you don't need to do this calculation in the first place.
Cybernetics
Cybernetics 2019년 10월 8일
My computer specifications are: intel core i7 7th generation and 16GB of RAM. The computation in a loop workds fine. I am just wondering, if there a way do avoind the loop, have a more elegent implementation and thus more efficient.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Functional Programming에 대해 자세히 알아보기

태그

Community Treasure Hunt

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

Start Hunting!

Translated by