I have one question related to the Mex problem as follows:
-------------------------------------------------------------------------------------------
double **candidates;
candidates = new double*[num_candidates];
for(int i=0; i<num_candidates; i++)
candidates[i] = new double[dim];
-------------------------------------------------------------------------------------------
Then after some operation in C code.
I would like to output candidates with double pointer. how to do it?
My code is :
-------------------------------------------------------------------------------------------
plhs[0] = mxCreateDoubleMatrix(num_candidates, dim, mxREAL);
double *candi = new double[num_candidates*dim];
for(int i=0; i<num_candidates; i++)
{
memcpy(&candi[dim*i], candidates[i], sizeof(double)*dim);
}
mwSize dims_candidates[2];
dims_candidates[0] = num_candidates;
dims_candidates[1] = dim;
mxSetPr (plhs[0], candi);
mxSetDimensions (plhs[0], dims_candidates, 2);
-------------------------------------------------------------------------------------------
But it seems doesn't work. Please help me.
|
|
0
|
|
|
|
Reply
|
Alex
|
1/29/2011 3:29:07 PM |
|
Dear Alex,
> plhs[0] = mxCreateDoubleMatrix(num_candidates, dim, mxREAL);
Now copy the values in the array obtained by mxGetPr(plhs[0]):
> double *candi = mxGetPr(plhs[0]);
> for(int i=0; i<num_candidates; i++)
> {
> memcpy(&candi[dim*i], candidates[i], sizeof(double)*dim);
> }
That's it. No further setting of mxsetPr or mxSetN.
Good luck, Jan
|
|
0
|
|
|
|
Reply
|
Jan
|
1/29/2011 4:39:04 PM
|
|
"Jan Simon" wrote in message <ii1fr7$7rv$1@fred.mathworks.com>...
> Dear Alex,
>
> > plhs[0] = mxCreateDoubleMatrix(num_candidates, dim, mxREAL);
> Now copy the values in the array obtained by mxGetPr(plhs[0]):
>
> > double *candi = mxGetPr(plhs[0]);
> > for(int i=0; i<num_candidates; i++)
> > {
> > memcpy(&candi[dim*i], candidates[i], sizeof(double)*dim);
> > }
>
> That's it. No further setting of mxsetPr or mxSetN.
>
> Good luck, Jan
It works now, thank you so much. Jan. Regards.
|
|
0
|
|
|
|
Reply
|
Alex
|
1/29/2011 4:52:03 PM
|
|
"Alex Lu" <luzhaojin@gmail.com> wrote in message <ii1bo3$hip$1@fred.mathworks.com>...
> I have one question related to the Mex problem as follows:
> -------------------------------------------------------------------------------------------
> double **candidates;
> candidates = new double*[num_candidates];
> for(int i=0; i<num_candidates; i++)
> candidates[i] = new double[dim];
> -------------------------------------------------------------------------------------------
> Then after some operation in C code.
>
> I would like to output candidates with double pointer. how to do it?
>
> My code is :
> -------------------------------------------------------------------------------------------
> plhs[0] = mxCreateDoubleMatrix(num_candidates, dim, mxREAL);
> double *candi = new double[num_candidates*dim];
> for(int i=0; i<num_candidates; i++)
> {
> memcpy(&candi[dim*i], candidates[i], sizeof(double)*dim);
> }
>
> mwSize dims_candidates[2];
> dims_candidates[0] = num_candidates;
> dims_candidates[1] = dim;
> mxSetPr (plhs[0], candi);
> mxSetDimensions (plhs[0], dims_candidates, 2);
> -------------------------------------------------------------------------------------------
> But it seems doesn't work. Please help me.
You have two major problems.
1) You cannot mix mxArray memory with C/C++ native memory. By that I mean that you cannot use local variable memory or memory allocated with new, malloc, calloc, etc in an mxArray. That will mess up the MATLAB memory manager and likely lead to a program bomb. So you cannot do this:
mxSetPr(plhs[0], candi);
because candi is pointing to native C++ memory allocated with the new operator:
double *candi = new double[num_candidates*dim];
To do this kind of thing you would need to allocate candi with mxMalloc or mxCalloc.
2) MATLAB stores 2D matrices in column order, whereas in your C++ setup the data is stored in rows. If you are copying from a 2D C++ variable into a MATLAB 2D variable you will need to create the MATLAB variable as the transpose of the C++ variable, then copy the data over, then transpose the result on the MATLAB side. Either that, or write special copying code that does the transpose as part of the copy. e.g., you would need to change this creation:
plhs[0] = mxCreateDoubleMatrix(num_candidates, dim, mxREAL);
to this:
plhs[0] = mxCreateDoubleMatrix(dim, num_candidates, mxREAL);
and then transpose the result once it got back to MATLAB.
A minor problem:
3) You are leaking memory with this statement:
mxSetPr(plhs[0], candi);
The mxSetPr function does *not* free any existing allocated memory before replacing its internal pr pointer with candi. So all that memory you just allocated with the mxCreateDoubleMatrix function call gets leaked. The proper way to do this is as follows:
mxFree(mxGetPr(plhs[0]));
mxSetPr(plhs[0], candi);
That way the existing memory is freed before you replace the pointer with your candi pointer.
-- BUT --
Having pointed out your errors, I would hasten to add that you are going about this in the most inefficient way possible. All that C++ memory allocation, then copying, etc, can be avoided if you simply create the MATLAB mxArray *first* and then just point into it to use it. e.g., something like this:
double **candidates;
double *candi;
// Do this first
plhs[0] = mxCreateDoubleMatrix(dim, num_candidates, mxREAL);
// Then get pointers to the data area
candi = mxGetPr(plhs[0]);
// Then set up candidates if you really want to preserve the 2D indexing
candidates = mxMalloc(num_candidates*sizeof(*candidates));
for(int i=0; i<num_candidates; i++) {
candidates[i] = candi + i * dim;
}
// Use candi and candidates here
// Then free your temporary memory
mxFree(candidates);
James Tursa
|
|
0
|
|
|
|
Reply
|
James
|
1/29/2011 5:04:03 PM
|
|
"Jan Simon" wrote in message <ii1fr7$7rv$1@fred.mathworks.com>...
> Dear Alex,
>
> > plhs[0] = mxCreateDoubleMatrix(num_candidates, dim, mxREAL);
> Now copy the values in the array obtained by mxGetPr(plhs[0]):
>
> > double *candi = mxGetPr(plhs[0]);
> > for(int i=0; i<num_candidates; i++)
> > {
> > memcpy(&candi[dim*i], candidates[i], sizeof(double)*dim);
> > }
>
> That's it. No further setting of mxsetPr or mxSetN.
Almost. This doesn't account for the transpose row vs column issue since the plhs[0] variable is num_candidates x dim, not dim x num_candidates. See my other post.
James Tursa
|
|
0
|
|
|
|
Reply
|
James
|
1/29/2011 8:28:03 PM
|
|
|
4 Replies
376 Views
(page loaded in 0.065 seconds)
Similiar Articles: How to return a 2D double array in Mex - comp.soft-sys.matlab ...I have one question related to the Mex problem as follows: ----- double ... double mxarray to int mxarray in mex file - comp.soft-sys.matlab ...Convert C array into mxArray Type - comp.soft-sys.matlab ..... g., > > double x[1792]; > double *data; > int i; > mxArray ... How to return a 2D double array in Mex ... What() is:bad allocation Error in mex file - comp.soft-sys.matlab ...How to return a 2D double array in Mex - comp.soft-sys.matlab ...-- BUT -- Having pointed out your errors, I would ... All that C++ memory allocation, then copying ... int32 to double - comp.soft-sys.matlabdouble mxarray to int mxarray in mex file - comp.soft-sys.matlab ... Reading mat file in C++ (VS) - comp.soft-sys.matlab In my mat file I have arrays of type double and ... plotting two dimension grid array - comp.lang.idl-pvwave ...How to return a 2D double array in Mex - comp.soft-sys.matlab ... plotting two dimension grid array - comp.lang.idl-pvwave ... How to return a 2D double array in Mex ... Modifying MEX arguments in place? - comp.soft-sys.matlab ...... frame2, .... , frame25) Hence I am currently modifying ... there any other function I should or could use in place ... How to return a 2D double array in Mex - comp.soft ... argument of type "double" is incompatible with parameter of type ...The array has type type Matrix is array(Positive ... but this cannot be used as modifiable actual argument or ... How to return a 2D double array in Mex - comp.soft-sys ... Copying rows in a two dimensional array. - comp.lang.ada ...How to return a 2D double array in Mex - comp.soft-sys.matlab ... How to return a 2D double array in Mex - comp.soft-sys.matlab ... Please help me. Sourced allocation - how is the value copied? - comp.lang.fortran ...How to return a 2D double array in Mex - comp.soft-sys.matlab ... All that C++ memory allocation, then copying, etc, can be ... Int value in a double variable - comp.lang ... Stored procedures and cursors - comp.databases.mysqlHow to return a 2D double array in Mex - comp.soft-sys.matlab ..... order, whereas in your C++ setup the data is stored in ... dim, num_candidates, mxREAL); // Then get ... How to return a 2D double array in Mex - comp.soft-sys.matlab ...I have one question related to the Mex problem as follows: ----- double ... Returning 2d int array in mex - Newsreader - MATLAB CentralHow do I return a 2d int array (int **) and a signed char (signed char*) array in mex as the output ... creating the delta array? Is this just so that you can use double ... 7/23/2012 10:49:12 AM
|