Vectorizing a very slow code

1 回表示 (過去 30 日間)
France Poirier
France Poirier 2020 年 10 月 26 日
回答済み: Rohit Pappu 2020 年 10 月 29 日
Hi,
I have a code that works, but is extremely slow that I would like to vectorize. I don't know anything about vecotrization. I am not really looking for anyone to re-write the code, that would be too much to ask, but I'd be grateful if someone could point me in the right direction as to which functions or basic building blocks I should look at.
Basically, what I am trying to do is to create a network of social contacts. I have a number of individuals and a total number of contacts each one of them has. Then I iterate over individuals and create the network of contact. Starting with person 1, I randomly pick the names of the correct number of individuals (say, individuals 5 and 10), add them to the list of contacts of individual 1, and then add individual 1 to the contact lists of individuals 5 and 10. Then I update the number of contacts left for individuals 1, 5, and 10.
The code that I have works fine for a small number of people, but it's very slow when the number of people increases significantly. I'd be grateful for any ideas as to how I can vectorize it. Here is what I have:
% Creating work contact network
bb1 = find(Employed == 1);
bb2 = length(bb1); % finding unique school numbers
for aa = 1:bb2 % looping over school numbers
abb2 = find(Employed == 1 & WCleft(:,1) > 0); % finding all the people in a given school
if ~isempty(length(abb2)) % looping over people in school
bb5 = find(abb2 ~= bb1(aa,1)); % find people who are different from the index person
abb5 = randperm(length(bb5)); % randomize the selection so that workplace contacts are not all in order
if length(bb5) >= WCleft(bb1(aa,1),1)
abb6 = abb5(1,1:WCleft(bb1(aa,1),1)); % pick a subset of these people equal to the number of workplace contacts the index person has
if ~isempty(abb6)
b7 = find(Wcontacts(bb1(aa,1),:) == 0); % find the first empty spot in the array of contacts
Wcontacts(bb1(aa,1),b7(1,1):b7(1,1) + WCleft(bb1(aa,1),1) - 1) = abb2(abb6,1)'; % add contacts to the index person
WCleft(bb1(aa,1),1) = WCleft(bb1(aa,1),1) - length(abb2(abb6,1)); % subtract the number of contacts from the total number of contacts the index person has
% Need to assign reciprocal contacts
for aa2 = 1:length(abb2(abb6,1)) % looping over people in that class
bb6 = find(Wcontacts(abb2(abb6(1,aa2),1),:) == 0); % find the first available spot in the contact matrix
if ~isempty(bb6)
Wcontacts(abb2(abb6(1,aa2),1),bb6(1,1)) = bb1(aa,1); % Putting the index individual as a contact for all of his contacts
WCleft(abb2(abb6(1,aa2),1),1) = WCleft(abb2(abb6(1,aa2),1),1) - 1; % Subtacting one contact from the number of available contacts
end
end
end
else
abb6 = abb5;
if ~isempty(abb6)
b7 = find(Wcontacts(bb1(aa,1),:) == 0); % find the first empty spot in the array of contacts
Wcontacts(bb1(aa,1),b7(1,1):b7(1,1) + length(abb6) - 1) = abb2(abb6,1)'; % add contacts to the index person
WCleft(bb1(aa,1),1) = WCleft(bb1(aa,1),1) - length(abb2(abb6,1)); % subtract the number of contacts from the total number of contacts the index person has
% Need to assign reciprocal contacts
for aa2 = 1:length(abb2(abb6,1)) % looping over people in that class
bb6 = find(Wcontacts(abb2(abb6(1,aa2),1),:) == 0); % find the first available spot in the contact matrix
if ~isempty(bb6)
Wcontacts(abb2(abb6(1,aa2),1),bb6(1,1)) = bb1(aa,1); % Putting the index individual as a contact for all of his contacts
WCleft(abb2(abb6(1,aa2),1),1) = WCleft(abb2(abb6(1,aa2),1),1) - 1; % Subtacting one contact from the number of available contacts
end
end
end
end
end
end

回答 (1 件)

Rohit Pappu
Rohit Pappu 2020 年 10 月 29 日
Documentation about Vectorization in MATLAB can be found here

カテゴリ

Help Center および File ExchangeLoops and Conditional Statements についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by