Search code examples
matlabsparse-matrix

filling sparse matrices efficiently matlab


I am working with a sparse matrix of very large size:

  U = sparse(a,b)   % a and b are very large

On the hand, there exists the cell Ind which has 'a' rows. In each row, there exists a 'variate' number of elements, e.g. :

  Ind{1} = [1 3 5 19 1000 1340]
  Ind{2} = [9 100 1500 1600 8000 b]
    ...
  Ind{a} = [3 5 6 90 1000 4300 5712 9480]

as could be seen the maximum index number in Ind{i} can be 'b'. For each of these index vector also exists a content matrix like 'c' :

 c = [2 3 1 6 3 5 1 3 4 1 2 ... 5]   

Here is the question, for each element in Ind{i}, I want to fill the 'row = i' and the 'col=Ind{i}' with c(Ind{i}), i.e.

  for i = 1 : a
      U(i,Ind{i}) = c(Ind{i}) ;
  end

the problem is 'a' is very large and the loop takes long time to be computed. Any idea to avoid looping?


Solution

  • I'm not sure if there is a way to avoid the loop, but I do get a factor of 2-to-20 speed increase (I ranged a from 3 to 5,000 with b fixed at 10,000) by building three large vectors (two for row and column indices and one for values) and building the sparse matrix after the loop:

    strides = cellfun(@numel,Ind);
    n       = sum(strides);
    I(n,1)  = 0;
    J(n,1)  = 0;
    S(n,1)  = 0;
    bot     = 1;
    
    for k = 1:a
        top  = bot + strides(k) - 1 ;
        mask = bot:top              ;
        %
        I(mask) = k         ;
        J(mask) = Ind{k}    ;
        S(mask) = c(Ind{k}) ;
        %
        bot = top + 1;
    end
    U = sparse(I,J,S,a,b);
    

    This is the recommend usage of sparse because assignments to a sparse matrix are more costly than regular arrays.