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 Kommentare

Kevin Phung
Kevin Phung am 7 Okt. 2019
I do not understand what you are trying to do, it would be helpful for you to provide what x,m,L, and y are.
Why are you defining z to be fake data, but then also rewriting it in the loop?
Rik
Rik am 7 Okt. 2019
As Kevin mentions, it is as as important to know what is the exact operation you want to do as it is to know the shapes of the variables involved.
Cybernetics
Cybernetics am 7 Okt. 2019
Bearbeitet: Cybernetics am 7 Okt. 2019
As stated above: x and y are two vectors of size n and m, respectively, with . I am assigning to z some randon data in order to define the size of the vector. So the elements of the vector z are computed as in the loop. The first m elements are arbitrary.
Is there a typo in the code you posted? In the first iteration of the loop, i==m+1, therefore
x(i-m:i)'
is
x(1:m+1)'
This vector is one element longer than y, one cannot do the matrix operation inside the for loop.
(Or maybe I messed something up?)
Cybernetics
Cybernetics am 7 Okt. 2019
Sorry there was a typo in the code. I just changed it
Rik
Rik am 7 Okt. 2019
Bearbeitet: Rik am 7 Okt. 2019
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)

Melden Sie sich an, um zu kommentieren.

 Akzeptierte Antwort

Bruno Luong
Bruno Luong am 8 Okt. 2019

1 Stimme

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 Kommentare

Rik
Rik am 8 Okt. 2019
Bearbeitet: Rik am 8 Okt. 2019
I knew it could be done with a convolution. Can you explain why you need to flip the y to get it to match the loop version?
Bruno Luong
Bruno Luong am 8 Okt. 2019
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 am 8 Okt. 2019
Thanks for the the elegant solution.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Daniel M
Daniel M am 7 Okt. 2019
Bearbeitet: Daniel M am 7 Okt. 2019

0 Stimmen

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 Kommentare

Cybernetics
Cybernetics am 7 Okt. 2019
Bearbeitet: Cybernetics am 7 Okt. 2019
This works well for small arrays x Thanks. I have a array x with 20 million elements. Than I get the error message
Requested 150x20479851 (22.9GB) array exceeds maximum array size preference. Creation of arrays greater than this limit may
take a long time and cause MATLAB to become unresponsive. See array size limit or preference panel for more information.
% if no signal toolbox, try
% ind = (L+1:n)-m + (0:m)';
% z = x(ind);
This also induced an error due to the big vector x with 20 million elements
Daniel M
Daniel M am 7 Okt. 2019
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 am 8 Okt. 2019
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.

Melden Sie sich an, um zu kommentieren.

Community Treasure Hunt

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

Start Hunting!

Translated by