mxCreateNumericMatrix and sparse matrix in C/Matlab hybrid programming

1 view (last 30 days)
Hi,
I was doing C/Matlab hybrid programming. Basically I need to load into Matlab a sparse matrix with entries in M and indeices in MI and MJ.
Below is what I have, and the error message I received is:
Undefined function 'sparse' for input arguments of type 'int16'
I am not sure whether I create the matrices MI and MJ wrongly, or Matlab does not support sparse operation in this manner.
Thanks!
Paul
------------------
M_matlab = mxCreateDoubleMatrix(1, nzero, mxREAL);
MI_matlab = mxCreateNumericMatrix(1, nzero, mxINT16_CLASS, mxREAL);
MJ_matlab = mxCreateNumericMatrix(1, nzero, mxINT16_CLASS, mxREAL);
memcpy((void *)mxGetPr(M_matlab), (void *)M, sizeof(M));
memcpy((void *)mxGetPr(MI_matlab), (void *)MI, sizeof(MI));
memcpy((void *)mxGetPr(MJ_matlab), (void *)MJ, sizeof(MJ));
engPutVariable(ep, "M", M_matlab);
engPutVariable(ep, "MI", MI_matlab);
engPutVariable(ep, "MJ", MJ_matlab);
engEvalString(ep, "MS=sparse(MI,MJ,M);");

Accepted Answer

Bruno Luong
Bruno Luong on 18 Jul 2020
I am not sure whether I create the matrices MI and MJ wrongly, or Matlab does not support sparse operation in this manner.
Thet later one.
Matlab mxArray and internal storage cannot be mixed with C-array and MATLAB array. You can not mix those three things.
Sorry but you have to go to the nasty road of building the sparse matrix with the internal storage by using function such as mxSetJc, mxSetIr, mxSetPr etc... That requires a full understand of how data are stored in sparse matrix internally.

More Answers (1)

James Tursa
James Tursa on 18 Jul 2020
Edited: James Tursa on 19 Jul 2020
Convert the index arrays to double either inside the C code or on the Engine side. E.g.,
engEvalString(ep, "MS=sparse(double(MI),double(MJ),M);");
P.S. Your memcpy stuff will only work if M and MI and MJ are arrays. It won't work if M and MI and MJ are pointers because the sizeof(etc) will not give you the number of bytes to copy ... they will only give you the size of the pointers. You would need an expression involving nzero instead if M and MI and MJ are pointers. E.g.,
memcpy(mxGetData(M_matlab), M, nzero*sizeof(*M));
memcpy(mxGetData(MI_matlab), MI, nzero*sizeof(*MI));
memcpy(mxGetData(MJ_matlab), MJ, nzero*sizeof(*MJ));
or
mwSize i;
double *mi, *mj;
MI_matlab = mxCreateDoubleMatrix(1, nzero, mxREAL);
MJ_matlab = mxCreateDoubleMatrix(1, nzero, mxREAL);
mi = (double *) mxGetData(MI_matlab);
mj = (double *) mxGetData(MJ_matlab);
for( i=0; i<nzero; i++ ) {
mi[i] = MI[i];
mj[i] = MJ[i];
}
SIDE NOTE: Note that your method has four deep copies of the data floating around in memory at the same time:
1) The original data inside your C code
2) A copy of the data in your C code in your mxArray variables
3) A copy of the data when you put the mxArray variables into the Engine via engPutVariable
4) A copy of the data when you called the sparse( ) function in the Engine
What are you doing with that sparse matrix downstream in your code? Maybe some of this data duplication can be eliminated by changing things.
  5 Comments
Bruno Luong
Bruno Luong on 5 Aug 2020
Migh I suggest - if not already done- that you break the mex in two parts
  • generating the sparse matrix
  • Processing of solution of sparse matrix
in between MATLAB will get the sparse matrix as LHS of the first mex and call "\" or whatever operator to compute the solution the feed the solution as RHS of the second mex.
It seems more natural and more clealy architectured like that than making a big C-mex code with usage of engEvalString, mxCallMatlab to perform the MATLAB task in betwenn as you seem to intend to carry out the task.
Rylan
Rylan on 9 Jan 2022
Hi, @Paul Zhou, how about creating the sparse matrix in C and processing of the solution in C, i.e. we don't transfer the sparse matrix back to matlab. If so, maybe this process can be much faster. Is this possible?

Sign in to comment.

Categories

Find more on Sparse Matrices in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!