Row-normalizing large sparse matrix

1 view (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
Edited: 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)

Categories

Find more on Images in Help Center and File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!