Avoid loops to make code run faster

1 view (last 30 days)
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!

Accepted Answer

Andrei Bobrov
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),:);
ADD
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));
  6 Comments
Simon
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
Betina Isbak on 5 Dec 2013
Yeah, that was my thought too.. It works great! Thank you to both of you..

Sign in to comment.

More Answers (0)

Categories

Find more on Dialog Boxes in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!