Tôi về cơ bản đang cố gắng dịch mã Matlab trong mã C. Đây là phần mở rộng của số question trước đó của tôi.Đọc tệp .mat sử dụng C: cách đọc cấu trúc ô đúng cách
Trong Matlab, tôi đã sử dụng cell-structures
nắm giữ matrices (double) of variable sizes
. Dưới đây là một ví dụ đồ chơi về những gì file * .mat của tôi là supposed to store
:
Matlab Mã số:
A = [[1 2 3]; [5 7 1]; [3 5 9]];
B = [[2 4];[5 7]];
Creator = 'DKumar';
nFilters = 2;
Filters{1} = [[-1.0 -1.0 -1.0]; [-1.0 8 -1.0]; [-1.0 -1.0 -1.0]];
Filters{2} = 2.0*[[-1.0 -1.0]; [-1.0 8]; [-1.0 -1.0]];
cd('/home/dkumar/CPP_ExampleCodes_DKU/Read_mat_File');
save('Test_FILE.mat', 'A', 'B', 'Creator', 'nFilters', 'Filters');
C-code: Chức năng "matread_Matrix" reads matrices stored in *.mat properly
. Đó là hàm "matread_Cell"
, được cho là đọc cấu trúc ô, là not working
.
#include <stdio.h>
#include <stdlib.h>
#include "/usr/local/MATLAB/R2011b/extern/include/mat.h"
mxArray *arr;
mxArray *C_CELL;
/* declare a 2 x 1 array of pointers to access the cell array in C */
mxArray *cellArray[2];
struct stDoubleMat{
double* pValueInField;
int nRows, nCols;
};
void matread_Matrix(const char *file, const char *FieldName2Read, struct stDoubleMat* poDoubleMat_LOC)
{
printf("Reading file %s...\n\n", file);
//Open file to get directory
MATFile* pmat = matOpen(file, "r");
if (pmat == NULL) {
printf("Error opening file %s\n", file);
return;
}
// extract the specified variable
arr = matGetVariable(pmat, FieldName2Read);
double *pr;
if (arr != NULL && !mxIsEmpty(arr)) {
// copy data
mwSize num = mxGetNumberOfElements(arr);
pr = mxGetPr(arr);
if (pr != NULL) {
poDoubleMat_LOC->pValueInField = pr;
poDoubleMat_LOC->nRows = mxGetM(arr);
poDoubleMat_LOC->nCols = mxGetN(arr);
}
printf("matread_Matrix \n") ;
printf("oDoubleMat_LOC.nRows %i ; oDoubleMat_LOC.nCols %i \n", poDoubleMat_LOC->nRows , poDoubleMat_LOC->nCols);
}else{
printf("nothing to read \n") ;
}
// close the file
matClose(pmat);
return;
}
void matread_Cell(const char *file, const char *FieldName2Read, int CellIndex)
{
printf("Reading file %s...\n\n", file);
//Open file to get directory
MATFile* pmat = matOpen(file, "r");
if (pmat == NULL) {
printf("Error opening file %s\n", file);
return;
}
// extract the specified variable
C_CELL = matGetVariable(pmat, FieldName2Read);
cellArray[CellIndex] = mxGetCell(C_CELL, CellIndex);
double* p2 = (double*)cellArray[CellIndex];
int nRows = mxGetM(cellArray[CellIndex]);
int nCols = mxGetN(cellArray[CellIndex]);
printf(" From inside matread_Cell : nRows %i and nCols %i \n", nRows, nCols);
int i2;
for (i2 = 0; i2 < nRows*nCols; i2++)
{
printf(" copied value : %f \n", *p2);
p2 = p2 +1;
}
// close the file
matClose(pmat);
}
int main(int argc, char **argv)
{
const char *FileName = "/home/dkumar/CPP_ExampleCodes_DKU/Read_mat_File/Test_FILE.mat";
const char *FieldName2Read = "A";
struct stDoubleMat oDoubleMat;
matread_Matrix(FileName, FieldName2Read, &oDoubleMat);
double* v = oDoubleMat.pValueInField;
printf("From main \n");
printf("oDoubleMat.nRows %i ; oDoubleMat.nCols %i \n", oDoubleMat.nRows , oDoubleMat.nCols);
int i;
for (i = 0; i < oDoubleMat.nCols*oDoubleMat.nRows; i++)
{
printf(" copied value : %f \n", *v);
v = v +1;
}
// Reading the structure
const char *FieldName2Read2 = "Filters";
matread_Cell(FileName, FieldName2Read2, 0);
matread_Cell(FileName, FieldName2Read2, 1);
// cleanup the mex-array
mxDestroyArray(arr);
mxDestroyArray(C_CELL);
/* How to delete mxArray of pointer : should this be a array of pointers */
//mxDestroyArray(cellArray[0]);
//mxDestroyArray(cellArray[1]);
return 0;
}
Output:
$ gcc -g -o Test Read_MatFile_DKU_2.c -I/usr/local/MATLAB/R2011b/extern/include -L/usr/local/MATLAB/R2011b/bin/glnxa64 -lmat -lmx
$ ./Test
Reading file /home/dkumar/CPP_ExampleCodes_DKU/Read_mat_File/Test_FILE.mat...
matread_Matrix
oDoubleMat_LOC.nRows 3 ; oDoubleMat_LOC.nCols 3
From main
oDoubleMat.nRows 3 ; oDoubleMat.nCols 3
copied value : 1.000000
copied value : 5.000000
copied value : 3.000000
copied value : 2.000000
copied value : 7.000000
copied value : 5.000000
copied value : 3.000000
copied value : 1.000000
copied value : 9.000000
Reading file /home/dkumar/CPP_ExampleCodes_DKU/Read_mat_File/Test_FILE.mat...
From inside matread_Cell : nRows 3 and nCols 3
copied value : 0.000000
copied value : 0.000000
copied value : 0.000000
copied value : 0.000000
copied value : 0.000000
copied value : 0.000000
copied value : 0.000000
copied value : 0.000000
copied value : 0.000000
Reading file /home/dkumar/CPP_ExampleCodes_DKU/Read_mat_File/Test_FILE.mat...
From inside matread_Cell : nRows 3 and nCols 2
copied value : 0.000000
copied value : 0.000000
copied value : 0.000000
copied value : 0.000000
copied value : 0.000000
copied value : 0.000000
Ngoài ra, tôi không thể đọc lĩnh vực này đúng cách cũng như: Đấng Tạo Hóa = 'DKumar';
UPDATE:
Dựa trên đề nghị của @Sherwin
C-Mã của tôi:
#include <stdio.h>
#include <stdlib.h>
#include "/usr/local/MATLAB/R2011b/extern/include/mat.h"
mxArray *arr;
mxArray *C_CELL;
/* declare a 2 x 1 array of pointers to access the cell array in C */
mxArray *cellArray[2];
struct stDoubleMat{
double* pValueInField;
int nRows, nCols;
};
void matread_Matrix(MATFile* pmat , const char *FieldName2Read, struct stDoubleMat* poDoubleMat_LOC)
{
// extract the specified variable
arr = matGetVariable(pmat, FieldName2Read);
double *pr;
if (arr != NULL && !mxIsEmpty(arr)) {
// copy data
mwSize num = mxGetNumberOfElements(arr);
pr = mxGetPr(arr);
if (pr != NULL) {
poDoubleMat_LOC->pValueInField = pr;
poDoubleMat_LOC->nRows = mxGetM(arr);
poDoubleMat_LOC->nCols = mxGetN(arr);
}
printf("matread_Matrix \n") ;
printf("oDoubleMat_LOC.nRows %i ; oDoubleMat_LOC.nCols %i \n", poDoubleMat_LOC->nRows , poDoubleMat_LOC->nCols);
}else{
printf("nothing to read \n") ;
}
return;
}
void matread_String(MATFile* pmat , const char *FieldName2Read)
{
// extract the specified variable
arr = matGetVariable(pmat, FieldName2Read);
double *pr;
if (arr != NULL && !mxIsEmpty(arr)) {
// copy data
mwSize num = mxGetNumberOfElements(arr);
pr = mxGetPr(arr);
if (pr != NULL) {
char *p2 = (char*) pr;
// Printing and checking
int i2;
for (i2 = 0; i2 < num; i2++)
{
printf(" copied value : %s \n", p2);
p2 = p2 +1;
}
}
}else{
printf("nothing to read \n") ;
}
return;
}
void matread_Cell(MATFile* pmat , const char *FieldName2Read, int CellIndex)
{
// extract the specified variable
C_CELL = matGetVariable(pmat, FieldName2Read);
cellArray[CellIndex] = mxGetCell(C_CELL, CellIndex);
double *p2 = (double*) mxGetPr(cellArray[CellIndex]);
int nRows = mxGetM(cellArray[CellIndex]);
int nCols = mxGetN(cellArray[CellIndex]);
printf(" From inside matread_Cell : nRows %i and nCols %i \n", nRows, nCols);
int i2;
for (i2 = 0; i2 < nRows*nCols; i2++)
{
printf(" copied value : %f \n", *p2);
p2 = p2 +1;
}
}
int main(int argc, char **argv)
{
const char *FileName = "/home/dkumar/CPP_ExampleCodes_DKU/Read_mat_File/Test_FILE.mat";
const char *FieldName2Read = "A";
//Open file to get directory
printf("Reading file %s...\n\n", FileName);
MATFile* pmat = matOpen(FileName, "r");
if (pmat == NULL) {
printf("Error opening file %s\n", FileName);
return;
}
struct stDoubleMat oDoubleMat;
matread_Matrix(pmat, FieldName2Read, &oDoubleMat);
double* v = oDoubleMat.pValueInField;
int i;
for (i = 0; i < oDoubleMat.nCols*oDoubleMat.nRows; i++)
{
printf(" copied value : %f \n", *v);
v = v +1;
}
// Reading the structure
const char *FieldName2Read2 = "Filters";
matread_Cell(pmat, FieldName2Read2, 0);
matread_Cell(pmat, FieldName2Read2, 1);
// Reading the string
const char *FieldName2Read3 = "Creator";
matread_String(pmat, FieldName2Read3);
// cleanup the mex-array
mxDestroyArray(arr);
mxDestroyArray(C_CELL);
/* How to delete mxArray of pointer : should this be a array of pointers */
//mxDestroyArray(cellArray[0]);
//mxDestroyArray(cellArray[1]);
// close the file
matClose(pmat);
return 0;
}
Output:
oDoubleMat.nRows 3 ; oDoubleMat.nCols 3
copied value : 1.000000
copied value : 5.000000
copied value : 3.000000
copied value : 2.000000
copied value : 7.000000
copied value : 5.000000
copied value : 3.000000
copied value : 1.000000
copied value : 9.000000
From inside matread_Cell : nRows 3 and nCols 3
copied value : -1.000000
copied value : -1.000000
copied value : -1.000000
copied value : -1.000000
copied value : 8.000000
copied value : -1.000000
copied value : -1.000000
copied value : -1.000000
copied value : -1.000000
From inside matread_Cell : nRows 3 and nCols 2
copied value : -2.000000
copied value : -2.000000
copied value : -2.000000
copied value : -2.000000
copied value : 16.000000
copied value : -2.000000
copied value : D
copied value :
copied value : K
copied value :
copied value : u
copied value :
copied value :
Vấn đề: 1) Chuỗi giá trị được lưu trữ trong người sáng tạo không được hiển thị đúng cách.
2) Cách xóa cellArray [2])?
tại sao bạn lưu dữ liệu ở định dạng 'MAT' nếu bạn đọc nó bên ngoài Matlab? tại sao không xuất dữ liệu (trong Matlab) sang, nói, hdf5 và sử dụng các công cụ hiện có để đọc dữ liệu nhị phân hdf5? – Shai
Tôi chưa bao giờ sử dụng định dạng hdf5 trước đây và tôi không biết liệu nó có thể lưu trữ và truy cập vào cấu trúc ô. –
Matlab lưu các tệp MAT ở định dạng hdf5 (cho phiên bản 7.3 trở lên, AFAIK). Vì vậy, về nguyên tắc nó có thể làm bất cứ điều gì bạn cần. Bạn sẽ phải làm cho bàn tay của bạn bẩn và học cách giao tiếp với hdf5, nhưng xem xét thực tế rằng bạn đang trải qua quá trình (đau đớn) với định dạng MAT, tôi nghĩ bạn nên học một công cụ linh hoạt hơn (HDF5) thay vì tập trung vào MAT rất hạn chế ... Nhưng đây chỉ là ý kiến của tôi. – Shai