Matlab API 从 c 读取 .mat 文件,使用 STL 容器

新手上路,请多包涵

我必须从 c++ 中读取一些 .mat 数据文件,我通读了文档,但我想知道如何以干净优雅的方式处理数据,例如使用 std:vector(modest .mat file size(10M~ 1G),但内存问题要认真对待)

我的功能是这样的:

 #include <stdio.h>
#include "mat.h"
#include <vector>

int matread(const char *file, const vector<double>& pdata_v) {

MATFile *pmat;

pmat=matOpen("data.mat","r");
if (pmat == NULL) {
    printf("Error opening file %s\n", file);
    return(1);
}
mxArray *pdata = matGetVariable(pmat, "LocalDouble");

// pdata -> pdata_v

mxDestroy pa1;  // clean up
return 0;
}

所以,问题是,如何有效且安全地从 mxArray *pdata 数组复制到向量 pdata_v?

原文由 lorniper 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 708
2 个回答

以下是使用 MAT-API 的示例:

test_mat.cpp

 #include "mat.h"
#include <iostream>
#include <vector>

void matread(const char *file, std::vector<double>& v)
{
    // open MAT-file
    MATFile *pmat = matOpen(file, "r");
    if (pmat == NULL) return;

    // extract the specified variable
    mxArray *arr = matGetVariable(pmat, "LocalDouble");
    if (arr != NULL && mxIsDouble(arr) && !mxIsEmpty(arr)) {
        // copy data
        mwSize num = mxGetNumberOfElements(arr);
        double *pr = mxGetPr(arr);
        if (pr != NULL) {
            v.reserve(num); //is faster than resize :-)
            v.assign(pr, pr+num);
        }
    }

    // cleanup
    mxDestroyArray(arr);
    matClose(pmat);
}

int main()
{
    std::vector<double> v;
    matread("data.mat", v);
    for (size_t i=0; i<v.size(); ++i)
        std::cout << v[i] << std::endl;
    return 0;
}

首先,我们构建独立程序,并将一些测试数据创建为 MAT 文件:

 >> mex -client engine -largeArrayDims test_mat.cpp

>> LocalDouble = magic(4)
LocalDouble =
    16     2     3    13
     5    11    10     8
     9     7     6    12
     4    14    15     1

>> save data.mat LocalDouble

现在我们运行程序:

 C:\> test_mat.exe
16
5
9
4
2
11
7
14
3
10
6
15
13
8
12
1

原文由 Amro 发布,翻译遵循 CC BY-SA 4.0 许可协议

这是另一个想法。如果您对 C++ 代码中的裸指针过敏(顺便说一句,它们并没有错),您可以将裸指针包装在 boost 或 C++11 智能指针中,并使用调用正确的删除器 mxDestroyArray() 当指针超出范围时。这样您就不需要副本,您的用户代码也不需要知道如何正确解除分配。

 typedef shared_ptr<mxArray> mxSmartPtr;

mxSmartPtr readMATarray(MATFile *pmat, const char *varname)
{
    mxSmartPtr pdata(matGetVariable(pmat, varname),
                     mxDestroyArray);  // set deleter
    return pdata;
}

int some_function() {
    mxSmartPtr pdata = readMATarray(pmat, "LocalDouble");
    ...
    // pdata goes out of scope, and mxDestroy automatically called
}

取自这里的想法:http: //www.boost.org/doc/libs/1_56_0/libs/smart_ptr/sp_techniques.html#incomplete

原文由 Peter 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏