Counting average on huge matrix with conditional

2 vues (au cours des 30 derniers jours)
Amin Rois Sinung Nugroho
Amin Rois Sinung Nugroho le 28 Juin 2016
The following code runs forever on 10^5 square matrix A. It runs a few seconds on 10^3 square matrix. Is there any way to speed it up?
function [meanNV]=calcMeanNV_k(A,V,d)
%A: input matrix (n x n)
%V: eigenvectors of k-th largest eigenvalues (n x 1)
%d: degrees of each node (n x 1)
%meanNV: mean of neighbors vectors (n x 1)
m=size(A,2);
meanNV=zeros(113336);
for i=1:m
sumNode = 0;
for j=1:m
if A(i,j)==1
sumNode=sumNode+V(j);
end
end
[meanNV(i)]=sumNode/d(i);
end
  2 commentaires
Brendan Hamm
Brendan Hamm le 28 Juin 2016
What exactly is this code supposed to be doing?
It seems as though you are finding the last 1 in each row of A. You are taking the corresponding value of V (at the location from A). You are then dividing this by the corresponding value in d.
  • The size of a 10^5x10^5 double matrix would be 74.5GB. Do you have enough memory to support this?
  • I am doubting that the code does what you are thinking it does, but I can't tell either because I don't know what A represents. It does exactly what I describe above.
  • Does meanNV need to be a 113336x113336 matrix? You mention A has similar dimensions to this, but you are only storing m elements in meanNV (one for each row of A), so I think you mean to make this:
meanNV = zeros(m,1); % Save lots of space here.
  • You can avoid for loops to improve speed. Use logical criteria. The variable below contains a one in every location where A(i,j) == 1 with no need for a loop.
idx = A == 1; % Or is A logical already?
  • Now we can loop through the rows and find the last element with a 1:
for k = 1:m
col = find(idx(k,:));
col = col(end);
meanNV(k) = V(col)/d(k);
end
Amin Rois Sinung Nugroho
Amin Rois Sinung Nugroho le 30 Juin 2016
Hi Brendan, Thanks for your reply.
I made a mistake in the previous code. The initialization of sumNode=0; should be outside of the inner for loop. A represents links between nodes. If node i and j are connected, then A(i,j) = 1. Otherwise, A(i,j) = 0.
I want to get the average of all the eigen vectors of neighbor nodes of i. Neighbor nodes are all nodes that have connection with node i, where A(i,j) = 1. It should accumulate all V(j) that has 1 in the corresponding location in A. Then divide the sum with d(i). d(i) represents the degree/total number of connections from node i.
Thank you.

Connectez-vous pour commenter.

Réponse acceptée

Brendan Hamm
Brendan Hamm le 1 Juil 2016
It seems this is likely what you are looking for then:
function [meanNV]=calcMeanNV_k(A,V,d)
%A: input matrix (n x n)
%V: eigenvectors of k-th largest eigenvalues (n x 1)
%d: degrees of each node (n x 1)
%meanNV: mean of neighbors vectors (n x 1)
m=size(A,2);
meanNV=zeros(113336);
idx = A == 1;
for k = 1:m
meanNV = sum(V(idx(k,:)));
end
meanNV = meanNV./d
  1 commentaire
Amin Rois Sinung Nugroho
Amin Rois Sinung Nugroho le 1 Juil 2016
It works. But I change the 7th line to meanNV=zeros(m,1); Thanks.

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Logical dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by