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 commentaire

Jan
Jan le 24 Août 2017
It would be useful, if you mention which error messages you see. Then we do not have to guess them ;-)

Connectez-vous pour commenter.

 Réponse acceptée

James Tursa
James Tursa le 16 Août 2017
Modifié(e) : James Tursa le 18 Août 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 commentaires

JM
JM le 19 Août 2017
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
James Tursa
James Tursa le 20 Août 2017
Can you write out, in m-code or pseudo-code, the equivalent of what you want the mex function to do?
JM
JM le 24 Août 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 le 31 Août 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.

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

Tags

Question posée :

JM
le 16 Août 2017

Commenté :

JM
le 31 Août 2017

Community Treasure Hunt

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

Start Hunting!

Translated by