1

I am using MATLAB. I have very large sparse matrices, and I want to perform a logical or bsxfun on each column of this matrix. There is a single for loop where in it is a single operation of logical to fill a sparse matrix. Here I include a sample function with some fake small data to see what I am trying to do;

function maskMat()
graph_temp = round(rand(10,10));
tic;
com_mat = round(rand(10,10));
com = round(rand(10,1));
for ii=1:length(graph_temp)    
    com_mat(:,ii) = logical(com ~= com(ii));
    %bsxfun works too but is slightly slower
    %com_mat(:,ii) =  bsxfun(@ne,com,com(ii));
end
toc;
com_mat = graph_temp .* com_mat;

graph_temp and com_mat are much bigger with around 1M rows and columns and the code is horribly slow do to the for loop. There is another relevant question here on SO, but I have not understood the theory behind it to see if I can apply those solutions to this problem as well.

I was thinking to either write a mex c++ function or try to get some sort of nested arrayfun so that each logical/bsxfun operation is called as a subroutine of a greater function to avoid the for loop bottle neck.

Community
  • 1
  • 1
Vass
  • 2,682
  • 13
  • 41
  • 60
  • Are you sure you don't want to combine `com` with `com_mat`? Otherwise I don't understand why you initialize `com_mat` with `rand` instead of just `zeros`. – Dennis Jaheruddin Apr 25 '13 at 12:37
  • @DennisJaheruddin, `com_mat` before being *masked* at the end by `graph_temp`, is simply the matrix of logicals for set of all `(i,j)` pairs that equal each other. Where in the `com` vector it is the expansion of the pairwise comparisons. So if we had half of `com` being `0` and the other half `1`, I want `com_mat`, before the last step, to be the matrix of which association are not equal. Make sense? – Vass Apr 25 '13 at 12:54

2 Answers2

6

I'm not sure I followed your code all the way. So, to make sure, is com_mat(ii,jj) equals to com(ii) ~= com(jj)?

If so try the following options

com_mat = bsxfun( @ne, com, com' ); %' creates entire matrix at once
com_mat = graph_temp .* com_mat;  % do the masking

Since you are dealing with sparse matrices, why don't you take advantage of it

[ii jj] = find( graph_temp );
[m n] = size( graph_temp );
com_mat = sparse( ii, jj, com(ii) ~= com(jj), m, n );
Shai
  • 111,146
  • 38
  • 238
  • 371
1

I would try this way, but I don't have access to Matlab at the moment

arrayfun(@(i) ~isequal(A(:,i),B),1:10,'UniformOutput',false)

fpe
  • 2,700
  • 2
  • 23
  • 47
  • 1
    If you're after speed performance, `arrayfun` isn't necessarily faster than an ordinary for loop: [link](http://stackoverflow.com/questions/12522888/arrayfun-can-be-significantly-slower-than-an-explicit-loop-in-matlab-why). – Gunther Struyf Apr 25 '13 at 12:56
  • I know but perhaps the OP has a pre JIT Matlab release. – fpe Apr 25 '13 at 12:58