MATLAB Answers

Row-normalizing large sparse matrix

23 views (last 30 days)
Samuel L. Polk
Samuel L. Polk on 20 Feb 2021
Edited: Matt J on 20 Feb 2021
I have a large (n x n), sparse matrix with N entries per row, named W. I would like to normalize this matrix so that each row sums to 1, but I'm running into some numerical issues.
I store the nonzero values in the following matrix:
vals_W(i,j) = % jth nonzero entry in ith row of W.
I then calculate the matrix W, which I want to row-normalize, and normalize it as follows:
% idx and jdx reflect the row and column indices respectively.
W = sparse(idx, jdx, reshape(vals_W,1,NN*n)); % Matrix we wish to row-normlaize
sum_vals = sum(W,2); % sum of rows in W
W_normalized = sparse(idx, jdx, reshape(vals_W./sum_vals,1,NN*n)); % W, but row-normalized.
However, the following two yield very different values:
sum1 = sum(vals_W./sum_vals,2);
sum2 = sum(W_normalized,2));
They seem like they should be theoretically equivalent. Is there something about the sparsity that causes this issue? Or am I just coding this incorrectly? What's the best way to get around this problem?
Thank you.
  2 Comments
Matt J
Matt J on 20 Feb 2021
Just as a remark, there is no need to reshape vals_W or any other arguments to sparse() into a row vector. You can build W simply by doing,
[idx,~] = ndgrid( 1:size(vals_W,1), 1:size(vals_W,2));
jdx=...
W=sparse(idx,jdx,vals_W);

Sign in to comment.

Accepted Answer

Matt J
Matt J on 20 Feb 2021
Edited: Matt J on 20 Feb 2021
The attempt you've posted will only work if vals_W is the same size as sum_vals, which can only occur when there is exactly one non-zero element per row in W. What you really want is,
s=sum(W,2);
s(~s)=1; %avoid division by 0
W_normalized=W./s;

More Answers (0)

Tags

Community Treasure Hunt

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

Start Hunting!