Read and access MAT file data in C

Hi everyone,
I'm new to the C programmation with the API library in Matlab and I'm trying to read and access a mat file data which is a 3d array. In my C code "p" is a pointer to the 3d array which values I'm trying to print, but when I compile (mex MyCode.c) I have a errors, here's my C code:
#include "mex.h"
#include "matrix.h"
#include "mat.h"
void mexFunction( int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[] )
{
MATFile *pmat;
double x;
mxArray *pa;
int n;
const char *name;
const char **dir;
int ndir;
int i,c;
int num_of_dim, num_of_fields, rows, col, bands,r,cc,b;
const int *dim_array;
mxArray ***p;
/*
* Open file to get directory
*/
pmat = matOpen("data3.mat", "r");
if (pmat == NULL)
{
printf("Error creating file \n");
printf("(Do you have write permission in this directory?)\n");
return(EXIT_FAILURE);
}
/*
* get directory of MAT-file
*/
dir = (const char **)matGetDir(pmat, &ndir);
if (dir == NULL) {
printf("Error reading directory of file ");
return(EXIT_FAILURE);
}
mxFree(dir);
if (matClose(pmat) != 0)
{
printf("Error closing file \n");
return(EXIT_FAILURE);
}
pmat = matOpen("data3.mat", "r");
if (pmat == NULL) {
printf("Error reopening file \n");
return(EXIT_FAILURE);
}
/* Read in each array. */
printf("\nReading in the actual array contents:\n");
for (i=0; i<ndir; i++)
{
pa = matGetNextVariable(pmat, name);
if (pa == NULL)
{
printf("Error reading in file \n");
return(EXIT_FAILURE);
}
}
/* Get the number of dimensions in array */
num_of_dim=mxGetNumberOfDimensions(pa);
dim_array = mxGetDimensions(pa);
printf("the number of dimensions are %d \n",num_of_dim);
for (c=0; c<num_of_dim; c++)
{
mexPrintf("%d\n", *(dim_array+c));
}
rows = *(dim_array);
col = *(dim_array+1);
bands = *(dim_array+2);
p=mxGetData(pmat);
/* Display the values of the mat file */
for (r=0;r<rows;r++,printf("\n"))
{
for(cc=0;cc<col;cc++,printf("\n"))
{
for(b=0;b,<bands;b++,printf("\n"))
{
mexPrintf("%d\n",*(p + col*bands*r + bands*cc + b));
}
}
}
}
I will be really grateful to know what's wrong with my C code.
Thanks.
-J

1 Comment

It would be useful, if you mention which error messages you see. Then we do not have to guess them ;-)

Sign in to comment.

 Accepted Answer

James Tursa
James Tursa on 16 Aug 2017
Edited: James Tursa on 18 Aug 2017
This:
const int *dim_array;
should probably be this
const mwSize *dim_array;
Also, this
mxArray ***p;
should probably be this, assuming the array is double class (you should check this in your code)
double *p;
And if the values really are double, then you should be using a format other than %d for printing, since that is for integer types. E.g., this
mexPrintf("%d\n",*(p + col*bands*r + bands*cc + b));
should be something like this instead
mexPrintf("%g\n",*(p + col*bands*r + bands*cc + b));
And this
p=mxGetData(pmat);
should probably be this
p = mxGetData(pa);
And you should have this at the end of your outer loop
mxDestroyArray(pa);
This might not be totally correct either ... seems like you would need to free the name strings as well:
mxFree(dir);
Finally, it is not clear to me which variable you are trying to display here. You read them all in a loop, and then display only the last one? Is that intended?
And then in the following call, I think "name" needs to have memory allocated behind it prior to the call ... I will have to check on this later.
pa = matGetNextVariable(pmat, name);
EDIT:
I checked, and that last line should be this:
pa = matGetNextVariable(pmat, &name);

4 Comments

Thank you for your answer. I corrected my code and took into account your suggestions and I managed to display the content of my mat file like this :
res=rows*col*bands;
for (r=0;r<res;r++)
{
mexPrintf("%.4g \n",*p++);
}
but I couldn't display each matrix of my 3D array pointed to by "pa".
The goal of my C code is to speed up my matlab code where I used to compare small 3D parts of my main 3D array. I tried many things but it's still not clear to me how I can access each 2D matrix of my 3D array and then access each element of each 2D matrix. It's the handling of a pointer of type "mxArray*" that is still a mystery to me. I hope I made myself clear but don't hesitate to ask for further details if it's not the case.
Thank you.
-J
Can you write out, in m-code or pseudo-code, the equivalent of what you want the mex function to do?
Basically my m-code consists of six nested loop and does this:
%the first three nested loops are for the extraction the first 3D cube
for f=idx_start:idx_end
for i=idx_start:idx_end
for j=idx_start:idx_end
% the saving of the first 3D cube
tmp_1=image_3d(i-pace:i+pace,j-pace:j+pace,f-pace:f+pace)
% the last three nested loop are for the extraction of the second 3D cube
idx1=formula();
for ff=idx_start:idx_end
for ii=idx_start:idx_end
for jj=idx_start:idx_end
% the saving of the second 3D cube
tmp_2=image_3d(ii-pace:ii+pace,jj-pace:jj+pace,ff-pace:ff+pace)
idx2=formula();
%computing the l2 norm between the two 3d cubes
res=sum(sum(sum((tmp_1-tmp_2).^2)));
%saving the data in a 1D arrays
tab(1,id1)=res;
tab_indices(1,id1)=idx2;
end
end
end
% saving the data in a sparse matrix
weights(idx1,tab_indices)=tab;
end
end
end
I have many arrays and sparse matrices in my m-code, is it obligatory to work with pointers all the time when I'm using the API library in matlab ?
Thanks in advance,
-J
I'm getting through mex programming little by little, I managed to display the content of my MAT-file like this:
for(b=0;b<bands;b++,printf("\n"))
{
for (r=0;r<rows;r++,printf("\n"))
{
for(cc=0;cc<col;cc++)
{
printf("%.4g \t",p[b*rows*col+cc*rows+r]);
}
}
}
where "b*rows*col+cc*rows+r" is the conversion to 1D indexing from the coordinates (r,cc,b) with the fact that data are stored in column. Thank you for your comments and answers.

Sign in to comment.

More Answers (0)

Tags

Asked:

JM
on 16 Aug 2017

Commented:

JM
on 31 Aug 2017

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!