6

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 へのコピーを効率的かつ安全に作成するにはどうすればよいかということです。

4

3 に答える 3

10

以下は、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 
于 2014-10-07T17:14:48.873 に答える
4

ここに別のアイデアがあります。C++ コードのベア ポインターにアレルギーがある場合 (ちなみに、それらに問題はありません)、ベア ポインターをブーストまたは 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

于 2014-10-07T13:55:08.510 に答える