How to replace the elements in a big sparse matrix

2019-08-03 19:02发布

I have quite a big sparse matrix, about 150,000*150,000. I need to access into its rows, extract the non-zero elements and replace these values following the rule as as the code below:

H = [];
for i = 1: size(A,2)
    [a,b,c] = find(A(i,:)); % extract the rows
    if size(c,2)==1  % only 2
        add = 0;
    elseif size(c,2) > 1 && any(c<2)== 0 % many 2s
        add = c;
        add(1)   = -2;
        add(end) = 2;
        add(2:end-1) = 0;
    elseif size(c,2) > 1 && any(c<2)~= 0 % 2 and 1
        k = find(diff(c)==-1); % find right 2 position
        add = c;
        add(1)   = -1;
        add(end) = -1;
        add(k) = 2;
        add(2:k-1) = 0;
        add(k+1:end-1) = 0;
    end
    %add = diff([0 c(2:end) 0]); % the replacing rule
    aa = i*ones(1,size(a,2)); % return back the old position of rows
    G0 = [aa' b' add']; % put it back the old position with replaced values 
    H = [H; G0];    
end

The rule is

  • Keep the element 2 on the very right in the row
  • The first and last elements in the row are replaced by -1
  • All other elements become 0.
  • In case there is just only one element 2, it will be replaced by 0.
  • In case there are two or more 2s, the very right one will remain and the very left one will be replaced by -2, the middle elementsare replaced by 0.

and here is the figure that visualises these rules enter image description here

The left figure is non-zero elements of rows extracted from the sparse matrix and I want the output to be like the right figure. I just selected some examples to explain the rules.

I did ask a similar question here and got a wonderful answer. The rule was differences between 2 adjacent elements in the row so that it could be integrated into the accumarray function. But in this case, the rule is a bit different and I don't know how to perform this task quickly. The sparse matrix is quite big so the for loop is a terrible thing to do here.

Thank you very much.

0条回答
登录 后发表回答