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!