Code covered by the BSD License  

Highlights from
mexSparseLogical0Diag

Be the first to rate this file! 1 Download (last 30 days) File Size: 2.01 KB File ID: #25147

mexSparseLogical0Diag

by Guy

 

27 Aug 2009

Change all the elements on the main diagonal of a logical sparse matrix to 0.

| Watch this File

File Information
Description

Because of memory constraints, it is often impossible to change by subscript all the elements of a large sparse matrix to zero. This leads to changing the elements in a loop, which is horrendously slow.
This mex solves that problem.
Usage: B = mexSparseLogical0Diag(A).

This problem is very common when dealing with adjacency matrices used in clustering - an adjacency matrix is a logical matrix, where the main diagonal is all zeros (no element is a neighbour of itself).

MATLAB release MATLAB 7.8 (R2009a)
Other requirements This is a mex file, it must be compiled to be used ("mex mexSparseLogical0Diag.c")
Tags for This File  
Everyone's Tags
Tags I've Applied
Add New Tags Please login to tag files.
Comments and Ratings (2)
28 Aug 2009 James Tursa

A few suggestions for improvement:

1) Don't use bool to point to the MATLAB logical data. MATLAB supplies a data type for this, mxLogical. Using bool only sets you up for an unexpected failure on machines where sizeof(bool) is not 1.

2) Don't use nz to allocate the memory for the new array. There might be a lot of wasted space involved in the input array and there is not point in propagating that waste. Instead, just go get the actual number of current non-zero elements and use that, since you know your result will not be larger than this. e.g.,

    mwSize n, n2;
    jc = mxGetJc(prhs[0]);
    n = mxGetN(prhs[0]);
    nz = jc[n];
        :
    v = mxCreateSparseLogicalMatrix (m, n, nz);

3) There is no code to realloc the memory if a large percentage was reset to zero. e.g., an input matrix that is nearly the same as an identity matrix. Although not an error, you might think about including this.

4) I know you supplied an m-file with the help (very good), but it might be good to copy the calling info into the cpp source file so that a user can have this all in one file when editing the source. Again, not an error but it helps others to read your code.

5) Your nlhs test isn't the best, as it doesn't cover some possible erroneous inputs (e.g., what if user tries to fill two output variables?):

if (nlhs > 0)
plhs[0] = v;

 A better method is as follows:

// at the beginning of your code:
    if( nlhs > 1 ) {
        mexErrMsgTxt("Too many outputs, expecting at most one.");
}

// at the end of your code
    plhs[0] = v;

i.e., at the end of your code don't do any test, just set plhs[0]. That way it will work if the user doesn't try to set the result to any variable ... in that case the result simply goes into ans. This always works, even if nlhs == 0.

6) You might consider making this a self-building mex routine. For an example of this, see one of my submissions, e.g.,

http://www.mathworks.com/matlabcentral/fileexchange/22239

7) With some very minor tweaking, you could also supply a C source code version so the users that only have access to the supplied lcc compiler can use this out of the box.

The code appears to work fine, and is indeed much faster than a loop. I would probably rate it a 3 at this point, but I will wait for author's response to my comments before rating and may go higher.

28 Aug 2009 Guy

Thanks for the tips James!

I especially appreciate the tips regarding where failure could occur (using bool instead of mxLogical, and the nlhs test).

The rest of the comments are also helpful (even though I doubt that this code will be used out of its context very often, so I won't bother to change things like memory allocation).

When I get back to university in a week or so, I'll definitely fix the error causing issues.

Thanks!

Please login to add a comment or rating.
Tag Activity for this File
Tag Applied By Date/Time
mex Guy 27 Aug 2009 10:00:51
sparse Guy 27 Aug 2009 10:00:52
logical Guy 27 Aug 2009 10:00:52

Contact us at files@mathworks.com