Search code examples
matlabsparse-matrixeigenmex

Why does my mexed eigen code print out the wrong entries of the matrix?


The following is a C++ code that takes a sparse matrix from Matlab.

#include "mex.h"
#include <Eigen/Sparse>
#include<iostream>
using namespace Eigen;
using namespace std;


void mexFunction( int nlhs, mxArray *plhs[],
        int nrhs, const mxArray *prhs[]) {

    mwSize     m = mxGetM (prhs[0]);
    mwSize     n = mxGetN (prhs[0]);
    mwSize    nz = mxGetNzmax (prhs[0]);
    double  * pr = mxGetPr (prhs[0]);
    int * ir = (int*) mxGetIr (prhs[0]);
    int * jc = (int*) mxGetJc (prhs[0]);
    Map<SparseMatrix<double> > gmap (m, n, nz, jc, ir, pr);

    cout << gmap.coeffRef(0,0);
    cout << gmap.coeffRef(0,1)<< "\n";

    cout << gmap.coeffRef(1,0);
    cout << gmap.coeffRef(1,1)<< "\n";

}

I simply pass it a small sparse format 2x2 matrix and print out the entries. Why are the entries wrong? Here's the output from the Matlab command window:

>> a=magic(2)

a =

     1     3
     4     2

>> example(sparse(a))
11
13

Update: solved thanks to suggestions in comments. I'll post an answer.


Solution

  • I've updated the code with suggestions from the comments and it works now.

    1. I've changed int* to mwIndex*.

    2. I've copied the mwIndex* arrays ir and jc arrays re-casting each entry to int so it will be compatible with Eigen. This compiles successfully. Here is the revised working code:

      #include "mex.h"
      #include <Eigen/Sparse>
      #include<iostream>
      using namespace Eigen;
      using namespace std;
      
      
      void mexFunction( int nlhs, mxArray *plhs[],
              int nrhs, const mxArray *prhs[]) {
      
          mwSize     m = mxGetM (prhs[0]);
          mwSize     n = mxGetN (prhs[0]);
          mwSize    nz = mxGetNzmax (prhs[0]);
          double  * pr = mxGetPr (prhs[0]);
          mwIndex * ir = mxGetIr (prhs[0]);
          mwIndex * jc = mxGetJc (prhs[0]);
      
          //copy and cast mwIndex
          int* ir_int=(int*)mxMalloc(nz*sizeof(int));
          int* jc_int=(int*)mxMalloc(nz*sizeof(int));
          for (int ii=0;ii<nz;ii++){
             ir_int[ii]=(int) ir[ii];   
             jc_int[ii]=(int) jc[ii]; 
          }
      
          Map<SparseMatrix<double> > gmap (m, n, nz, jc_int, ir_int, pr);
      
          cout << gmap.coeffRef(0,0);
          cout << gmap.coeffRef(0,1)<< "\n";
      
          cout << gmap.coeffRef(1,0);
          cout << gmap.coeffRef(1,1)<< "\n";
      
      }
      

      magic(2)

      ans =

       1     3
       4     2
      

      example(sparse(magic(2))) 13 42