# Avoid loops to make code run faster

1 view (last 30 days)
Betina Isbak on 3 Dec 2013
Commented: Betina Isbak on 5 Dec 2013
Hi Everyone,
I have some code I want to make faster, and therefore I want to delete my for loops. I have a matrix, TTF_Live_Q, with 3 columns – datenums, bid prices & ask prices. In that matrix I have quarterly prices, so there is only a date/price in every third cell. It could look like this:
0 0 0
0 0 0
735690 26.90 27
0 0 0
0 0 0
735781 28.10 28.20
0 0 0
0 0 0
I want the prices in 2. & 3. column to be repeated 3 times, this I have done with:
for i=1:length(TTF_Live_Q)
if L_Q(i) == 1
TTF_Live_Q(i+1,2:3) = TTF_Live_Q(i,2:3);
TTF_Live_Q(i+2,2:3) = TTF_Live_Q(i,2:3);
end
end
Where L_Q is an index vector. The matrix will now look like:
0 0 0
0 0 0
735690 26.90 27
0 26.90 27
0 26.90 27
735781 28.10 28.20
0 28.10 28.20
0 28.10 28.20
I have tried kron, but that doesn’t work, as there are 0 between the quarterly prices. I am sure you guys have a smarter way to do it.
Next thing I want to improve is the loop for the dates. I need the date number for the beginning of each month. It should look like this:
0 0 0
0 0 0
735690 26.90 27
735720 26.90 27
735751 26.90 27
735781 28.10 28.20
735812 28.10 28.20
735843 28.10 28.20
I have a vector with all the correct dates; Here is the loop that makes the date numbers come into the matrix.
Index_Q = zeros(size(TTF_Live_Q,1),1);
for i=1:3:size(TTF_Live_Q,1)-2
Index_Q(i) = find(TTF_Live_Q(i,1)==Date_Vector);
TTF_Live_Q(i+1,1) = Date_Vector(Index_Q(i)+1);
TTF_Live_Q(i+2,1) = Date_Vector(Index_Q(i)+2);
end
Can you please tell me a smarter way to do it? Thanks a lot!

Andrei Bobrov on 5 Dec 2013
Edited: Andrei Bobrov on 5 Dec 2013
data = [0 0 0
0 0 0
735690 26.90 27
0 0 0
0 0 0
735781 28.10 28.20
0 0 0
0 0 0];
out = data;
l = all(cumsum(data)~=0,2);
d0 = data(l,:);
[y,m,dd] = datevec(d0(1));
out(l,1) = datenum(y,m+(0:size(d0,1)-1)',dd);
d1 = d0(:,2:3);
l1 = d1(:,1)>0;
d2 = d1(l1,:);
out(l,2:3) = d2(cumsum(l1),:);
data = [0 0 0
0 0 0
735690 26.90 nan
0 0 0
0 0 0
735781 28.10 28.20
0 0 0
0 0 0];
out = data;
l = all(cumsum(data)~=0,2);
d0 = data(l,:);
[y,m,dd] = datevec(d0(1));
out(l,1) = datenum(y,m+(0:size(d0,1)-1)',dd);
d1 = d0(:,2:3);
p = d1(all(d1>0 | isnan(d1),2),:);
ii = find(isnan(p));
p(ii) = p(ii+1);
out(l,2:3) = kron(p,ones(3,1));

Andrei Bobrov on 5 Dec 2013
Simon on 5 Dec 2013
So, you can mix it with Andrei's answer. Just replace in my answer the ":" with "2:3" in the last two rows.
Betina Isbak on 5 Dec 2013
Yeah, that was my thought too.. It works great! Thank you to both of you..