A time killing loop

1 view (last 30 days)
joseph Frank on 8 Sep 2011
Edited: Jan on 27 Feb 2017
Hi,
I have a loop which is taking ages. I am wondering if someone can make it more efficient.
%%x1 is a vector of date rows for which I need to find the price
for k=1:length(x1)
%%x2 finds the rows in the original data file for each specific date (A is a vector of 6320 dates,ID is the unique identifier of a bond issued by a firm. The first column in data is the column of unique bond identifiers and the second column is a column of dates . Finally,the third column of data is the column of prices )
x2=find(data(:,2)==A(x1(k))&data(:,1)==ID);
%%%IssueMatrix is a matrix of prices; the first column is equal to the date vector A , and then each column refers to the prices of a different bond j issued by a firm.
if isnan(IssueMatrix(x1(k),j+1))==1
%%if I don't have any price on a date A(x1(k) for a specific bond issue then assign a price which is the average price of bonds supplied by different bond dealers.
IssueMatrix(x1(k),j+1)=nanmean(data(x2,3));
else
%%%if I have a price assigned for this bond added it to other prices supplied by dealers and then take the average
IssueMatrix(x1(k),j+1)=nanmean([data(x2,3);IssueMatrix(x1(k),j+1)]);
end
Jan on 8 Sep 2011
Please format the posted code and provide some test data, such that we can read and run your code.
joseph Frank on 8 Sep 2011
I did my best to simplify the codes and to post some sample data. I hope these can be understood easily.

Jan on 8 Sep 2011
Edited: Jan on 27 Feb 2017
Did you pre-allocate IssueMatrix ?
Can you create the IssueMatrix at first and apply FEX:nancumsum afterwards?
joseph Frank on 8 Sep 2011
as per the codes in my second post I created IssueMatrix (IM in the new codes) when I applied 0 votes
Did you pre-allocate IssueMatrix ?
Can you create the IssueMatrix at first and apply FEX:nancumcum I received an error.

joseph Frank on 8 Sep 2011
I changed the names of the variables so that they can appear in a readable format and I cut my huge data to a very small sample to make it available for you.Kindly, can we speed up the loop ?(it is fast for the data posted because of the small data size but for my large data it is extremely slow.
UIr=unique(I(:,2));
for i=1:length(UIr)
x0=find(I(:,2)==UIr(i));
UI=unique(I(x0,1));
IM=nan(length(A),length(UI)+1);
IM(:,1)=A;
for j=1:size(UI,1)
for j=1:size(UI,1)
ID=UI(j,1);
ID2=repmat(ID,size(A));
x1=find(ismember(IM(:,1),unique(D(:,2))) & ismember(ID2,D(:,1)));
for k=1:length(x1)
x2=find(D(:,2)==A(x1(k))& D(:,1)==ID);
if isnan(IM(x1(k),j+1))==1
IM(x1(k),j+1)=nanmean(D(x2,3));
else
IM(x1(k),j+1)=nanmean([D(x2,3);IM(x1(k),j+1)]);
end
end
end
end
end
A=728185
728186
728187
728188
728189
728190
728191
728192
728193
728194
728195
728196
728197
728187
728188
728189
728190
728191
728192
728193
728194
728195
728196
728197
728198
728199
728200
728201];
D=[458 731015 100 133
458 731015 100 133
458 731015 100 133
458 730948 100 133
458 730463 103 133
458 730463 103 133
458 729837 108 133
458 729722 110 133
458 729574 111 133
458 728187 111 133
475 728188 111 133
475 728189 111 133
475 728190 111 133
475 728191 111 133
475 728192 111 133
475 728193 111 133
475 728194 111 133
475 728195 111 133
475 728196 111 133
475 728197 110 133
475 728198 116 133
475 728199 117 133
475 728200 116 133
475 728201 115 133
475 728187 113 133
475 728188 110 133
475 728189 108 133
475 728190 109 133
475 728191 105 133
475 728192 105 133
475 728193 109 133
475 728194 113 133
475 728195 105 133
475 728196 108 133
475 728197 110 133
475 728198 110 133
475 728199 109 133
475 728200 109 133
475 728201 107 133
475 728187 107 133
475 728188 111 133
475 728189 110 133
475 728190 108 133
475 728191 107 133
456 728192 108 133
456 728193 107 133
456 728194 108 133
456 728195 104 133
456 728196 100 133
456 728197 100 133
456 728198 113 133
456 728199 114 133
456 728200 113 133
456 728201 100 133
456 728187 113 133
456 728188 116 133
456 728189 100 133
456 728190 116 133
456 728191 111 133
456 728192 112 133
456 728193 111 133
456 728194 112 133
456 728195 103 133
456 728196 103 133
456 728197 103 133
456 728198 103 133
456 728193 103 133
456 728194 104 133
456 728195 104 133
456 728196 104 133
456 728193 104 133
456 728194 104 133
456 728195 104 133
456 728196 107 133];
I=[456 133 3353
458 133 3353
475 133 1021];
3 CommentsShow 1 older commentHide 1 older comment
joseph Frank on 8 Sep 2011
oh . Thanks a million Jan
Jan on 8 Sep 2011
Replace:
ID=UI(j,1); ID2=repmat(ID,size(A));
x1=find(ismember(IM(:,1),unique(D(:,2))) & ismember(ID2,D(:,1)));
by:
x1 = find(ismember(IM(:,1),unique(D(:,2))) & (UI(j)==D(:,1)));

Oleg Komarov on 8 Sep 2011
This a vectorized way to obtain intersected means, then it's up to you to replicate the matrix anc concatenate as you wish:
% Row subs
[idx,rsub] = ismember(D(:,2),A);
Dmemb = D(idx,:);
rsub = rsub(idx);
% Col subs
[idx,csub] = ismember(Dmemb(:,1),I(:,1));
% Accumarray
out = [unique(Dmemb(:,2)) accumarray([rsub-min(rsub)+1, csub],Dmemb(:,3),[],@mean,NaN)]