6

How to create a 2d sparse matrix in a MEX-file written in C. After creating the matrix how to access the elements individually like in C , say mat[i][j]?

I tired using mxCreateNumericArray function but I wasn't able to access the elements and also make it as a sparse matrix.

Please help

Amro
  • 123,847
  • 25
  • 243
  • 454
koder
  • 325
  • 3
  • 13

1 Answers1

10

See this page on mxCreateSparse. Then you'll want to look at mxSetPr, mxSetIr and mxSetJc and the corresponding "get" versions.

Here's an example of how to allocate a sparse matrix. I realize this is an old link, but to the best of my knowledge, it hasn't changed.

Basically, how it works is that the ir data contains the row indices. The jr data contains a list of indices into the ir array. For instance, in the link on how to allocate a sparse matrix, the code:

...
static double  static_pr_data[NZMAX] = {5.8, 6.2, 5.9, 6.1};
static int     static_ir_data[NZMAX] = {0, 2, 1, 3};
static int     static_jc_data[COLS+1] = {0, 2, 4};
...

the array static_jc_data tells you that indices static_jc_data[c] through static_jc_data[c+1]-1 of static_pr_data and static_ir_data correspond to the column c of the matrix. Within that range (static_jc_data[c] to static_jc_data[c+1]-1) the entries of static_pr_data gives you the values in the matrix and static_ir_data gives you the correct rows.

For example, the matrix here would be:

A = [ 5.8  0
      0    5.9
      6.2  0
      0    6.1];

To answer your questions about how to access elements individually, you have to search for whether the i,jth element exists and if it does return it, otherwise return 0. To do this, you'd search from static_ir_data[static_jc_data[j]] through static_ir_data[static_jc_data[j+1]-1] to see whether your i exists. If it does, then the corresponding entry in static_pr_data will contain your entry. If it doesn't, then return 0.

However, typically with sparse matrix usage, if you're doing a lot of searching through the matrix to see if a certain element exists, you may want to think about how you're using it. Typically, it's much better to perform whatever operation you're doing by only going through the non-zero elements once instead of searching for each i,jth entry.

Oh, and one last thing. Keep in mind that in the MEX code, all your indices are 0 based, but they are 1 based in MATLAB. That should add to the fun.

Amro
  • 123,847
  • 25
  • 243
  • 454
Chris A.
  • 6,817
  • 2
  • 25
  • 43
  • I understood ur example , but how do i create the jc array, i dint understand that part..the thing is i have to make a 2d matrix in which i fill in the values at some locations through some calculation..say w[1][2]= some formula .. Now do i have to create a prdata array which contains all the non zero elements? – koder May 24 '11 at 10:43
  • 2
    Jc array is one more than the number of columns. It's the cumulative sum of the number of nonzero elements in the columns thus far. This allows one efficiently determine the number of elements in a given column. – peakxu May 24 '11 at 13:09
  • @pxu - if you think about it carefully, this is exactly consistent with what I said. – Chris A. May 24 '11 at 13:58
  • It is. Just trying to give a one liner to address rohit's question. I personally dislike playing with Matlab sparse matrices in mex. If you are concerned about performance, use a library like CSparse and std::map to sort the keys. – peakxu May 24 '11 at 14:11
  • @rohit, yes, see pxu's comment for how to create the jc array. To give you a hint, element jc[0] will always be 0, and element jc[c+1] will tell you the cumulative number of elements seen thus far (in all columns up to and including column `c` (assuming `c` is 0-based) – Chris A. May 24 '11 at 15:42
  • 1
    +1 Nice writeup on sparse matrices in MEX. I wish I could upvote more than once... – SCFrench May 28 '11 at 23:48