Reputation: 540
I'm trying to figure out how to access a matrix that is stored in a field in a matlab structure from a mex function.
That's awfully long winded... Let me explain:
I have a matlab struct that was defined like the following:
matrixStruct = struct('matrix', {4, 4, 4; 5, 5, 5; 6, 6 ,6})
I have a mex function in which I would like to be able to receive a pointer to the first element in the matrix (matrix[0][0], in c terms), but I've been unable to figure out how to do that.
I have tried the following:
/* Pointer to the first element in the matrix (supposedly)... */
double *ptr = mxGetPr(mxGetField(prhs[0], 0, "matrix");
/* Incrementing the pointer to access all values in the matrix */
for(i = 0; i < 3; i++){
printf("%f\n", *(ptr + (i * 3)));
printf("%f\n", *(ptr + 1 + (i * 3)));
printf("%f\n", *(ptr + 2 + (i * 3)));
}
What this ends up printing is the following:
4.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
I have also tried variations of the following, thinking that perhaps it was something wonky with nested function calls, but to no avail:
/* Pointer to the first location of the mxArray */
mxArray *fieldValuePtr = mxGetField(prhs[0], 0, "matrix");
/* Get the double pointer to the first location in the matrix */
double *ptr = mxGetPr(fieldValuePtr);
/* Same for loop code here as written above */
Does anyone have an idea as to how I can achieve what I'm trying to, or what I am potentially doing wrong?
Thanks!
Edit: As per yuk's comment, I tried doing similar operations on a struct that has a field called array which is a one-dimensional array of doubles.
The struct containing the array is defined as follows:
arrayStruct = struct('array', {4.44, 5.55, 6.66})
I tried the following on the arrayStruct from within the mex function:
mptr = mxGetPr(mxGetField(prhs[0], 0, "array"));
printf("%f\n", *(mptr));
printf("%f\n", *(mptr + 1));
printf("%f\n", *(mptr + 2));
...but the output followed what was printed earlier:
4.440000
0.000000
0.000000
Upvotes: 6
Views: 4279
Reputation: 26333
I have been through this: I have a struct with a field which is a matrix. In C++ the corresponding structure is a double**
for instance. Trying to access the field with engGetVariable(engine,MyStruct.theField)
fails. I use a temp variable to store the MyStruct.theField
and then use engGetVariable(engine, tempVar)
, and code to get the matrix field from the struct looks like that
// Fetch struct field using a temp variable
std::string tempName = std::string(field_name) + "_temp";
std::string fetchField = tempName + " = " + std::string(struct_name)
+ "." + std::string(field_name) + "; ";
matlabExecute(ep, fetchField);
mxArray *matlabArray = engGetVariable(ep, tempName.c_str());
// Get variable elements
const int count = mxGetNumberOfElements(matlabArray);
T *data = (T*) mxGetData(matlabArray);
for (int i = 0; i < count; i++)
vector[i] = _isnan(data[i]) ? (T) (int) -9999 : (T) data[i];
// Clear temp variable
std::string clearTempVar = "clear " + tempName + "; ";
matlabExecute(ep, clearTempVar);
// Destroy mx object
mxDestroyArray(matlabArray);
Very similarly to set the matrix field to the struct I did that
// Create temp variable
mxArray* array = convertVectorToMxArray(mat, nb_rows, nb_cols);
const std::string temp_name = array_name + "_temp";
int ret = engPutVariable(ep, temp_name.c_str(), array);
// Set variable to struct field
const std::string cmd = std::string(array_name + " = " + temp_name + "; ");
matlabExecute(ep, cmd);
// Delete array
mxDestroyArray(array);
Upvotes: 0
Reputation: 8374
struct('field', {a b c})
is a special form of the struct constructor which creates a struct array that is the same size as the cell array, putting each element of the cell into field 'field' of the corresponding element of the struct. That is, this:
s = struct('field', {a b c});
produces the same result as this:
s(1).field = a;
s(2).field = b;
s(3).field = c;
The solution to your problem is to use square brackets to form a regular (non-cell) array, like this:
matrixStruct = struct('matrix', [4, 4, 4; 5, 5, 5; 6, 6 ,6]);
Upvotes: 5
Reputation: 19880
You are trying to access the variable which is cell array in MATLAB. Are you sure the data are stored consequently? What happens if you put double array into the structure?
matrixStruct = struct('matrix', [4, 4, 4; 5, 5, 5; 6, 6 ,6])
I think the problem is how MATLAB stores data in cell array. Try to run this:
double1 = 1;
double2 = 1:2;
cellempty = {[]};
celldouble1 = {1};
celldouble2 = {1:2};
cell2doubles = {1,2};
whos
The output:
Name Size Bytes Class Attributes
cell2doubles 1x2 136 cell
celldouble1 1x1 68 cell
celldouble2 1x1 76 cell
cellempty 1x1 60 cell
double1 1x1 8 double
double2 1x2 16 double
You can see that each element of cell array occupy additional 60 bytes to the size of numbers.
Upvotes: 1