Read and access MAT file data in C

8 views (last 30 days)
JM
JM on 16 Aug 2017
Commented: JM on 31 Aug 2017
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
Jan
Jan on 24 Aug 2017
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
JM
JM on 24 Aug 2017
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
JM
JM on 31 Aug 2017
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

Community Treasure Hunt

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

Start Hunting!