mxCreateNumericMatrix and sparse matrix in C/Matlab hybrid programming
显示 更早的评论
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);");
采纳的回答
更多回答(1 个)
James Tursa
2020-7-18
编辑:James Tursa
2020-7-19
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 个评论
Paul Zhou
2020-8-4
James Tursa
2020-8-4
编辑:James Tursa
2020-8-4
Any suggestions would depend on where this sparse data is originally coming from. Generated by your C/C++ code, or read from a file, or ...?
Once you solve the linear system, do you pull the solution back into your C/C++ code?
Are you open to using a mex routine instead of an Engine application?
Paul Zhou
2020-8-5
Bruno Luong
2020-8-5
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
2022-1-9
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?
类别
在 帮助中心 和 File Exchange 中查找有关 Resizing and Reshaping Matrices 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!