MATLAB: Moving Complex Data to a .mat file from a C Program

ccomplexdatafilematmoving

[EDIT: 20110621 12:22 CDT – reformat – WDR]
I'm running Matlab r2010a on a Redhat Linux platform compiling with gcc.
I want to move complex data in C into a .mat file. I've successfully moved real data with the following.
_realDat = mxCreateDoubleMatrix(numRow, 1, mxREAL) ;
mRealP = mxGetPr(realDat) ;
memcpy ((void *) mRealP, (void *) rArrayP, numRow * sizeof(real)) ;
I understand mxGetPr and mxGetPi get pointers to the the real and imaginary part of complex data in a mxArray. So, if I have an array of complex data in C, cArrayP, how do I move it to an mxArray of complex data, compData? Do I use both mxGetPr and mxGetPi? If I do, how do I use two memcpy statements? Do I need to create two additional arrays in C using the creal and cimag functions to get the real and imaginary parts of the complex data? Is there a way to move the complex data from a C array into an mxArray in one fell swoop?
_compData = mxCreateDoubleMatrix(numRow, numCol, mxCOMPLEX);
mCompPr = mxGetPr(compData); ?? or mCompPi = mxGetPi(compData); ?? or both?
memcpy ((void *) which pointer?, (void *) cArrayP or creal array or cimag array or both?, correct size);
??
I'm sorry the C statements run together … I don't know how to fix that. [Fixed – WDR]
Thanks,
Tom

Best Answer

The answer will depend on how the data is currently stored in your C variable.
If the C data is stored as a single variable in interleaved fashion (e.g., via a native complex type or a user-defined struct of some type) then the best way is to create your mxArray with mxCOMPLEX, use mxGetPr and mxGetPi to get pointers to the real and imaginary data areas. Then do some pointer sleight of hand casting to get a double * to the first complex element (this will point to the real part), and another double * that is 1 more than the real part which will point to the imaginary part of the first element. Then write a single for loop to copy the contents one-by-one into the pr and pi parts of the mxArray. You want to do this in a single for loop (rather than two for loops) so that your complex C array is dragged through the high level cache only once.
If the C data is stored as two separate real and imaginary parts, then you can use memcpy like you show above.
e.g.,
mwSize i, n;
double *cp;
:
compData = mxCreateDoubleMatrix(numRow, numCol, mxCOMPLEX);
mCompPr = mxGetPr(compData);
mCompPi = mxGetPi(compData);
n = numRow * numCol;
cp = (double *) &cArrayP;
for( i=0; i<n; i++ ) {
*mCompPr++ = *cp++;
*mCompPi++ = *cp++;
}