【问题标题】:Efficiently appending data to a variable using Matlab's C API使用 Matlab 的 C API 有效地将数据附加到变量
【发布时间】:2019-12-10 03:31:51
【问题描述】:

我有一个 C 程序,它重复执行算法并在每次迭代后输出其中间结果。数据将使用 Matlab R2019a 进行处理。

我正在使用C Matrix API 创建 .MAT 文件,并且可以将矩阵写入 .MAT 文件:

  MATFile *m = matOpen("matlab.MAT", "w");
  mxArray *a = mxCreateDoubleMatrix(1, 1, mxREAL);
  *mxGetPr(a) = nxm;
  matPutVariable(m, "nxm", a);
  mxDestroyArray(a);
  matClose(m);

但是,[maxPutVariable](https://www.mathworks.com/help/matlab/apiref/matputvariable.html) 的文档指出,如果我两次使用相同的变量名,第二次将覆盖第一次。

我不想将所有中间值存储在内存中。也许我可以读入矩阵,扩展它以包含一个新值,然后再写出来。

有没有使用 C API 的不错的方法来做到这一点,还是我应该只编写 Matlab 代码来解析不同的输出格式?

【问题讨论】:

  • MAT 文件格式对于数值数组数据非常有效。你的中间结果有多大? I/O 性能在这里很重要吗?并且您的下游 Matlab 进程是否需要在您的 C 程序仍在运行时处理一些结果,还是可以等到 C 程序完成并一次处理它们?
  • (我暂时认为您会将每个中间结果放入不同的 nxmNNNN 变量中,其中 NNNN 是您的循环索引或其他任何内容,然后将其读入 Matlab 并拥有它cat() 所有的 nxmNNN 变量;那只是几行代码。)

标签: matlab


【解决方案1】:

您可以将多个命名变量保存在一个 MAT 文件中。当您向 MAT 文件添加新变量时,它会附加到文件的末尾,因此即使您现有的文件相对较大,这在 I/O 上也不错。所以我要做的是让你的 C 程序的每个循环迭代将其输出存储到 MAT 文件中一个名为 nxm<NNN> 的新变量中,然后让你的 Matlab 程序读取文件并将它们连接在一起。

在您的 C 代码中:

MATFILE *m = matOpen("matlab.mat", "w");
[...]
char var_name[1024];
for (i = 0; i < n_iterations; i++) {
  [... do work to produce nxm ...]
  mxArray *a = mxCreateDoubleMatrix(1, 1, mxREAL);
  *mxGetPr(a) = nxm;
  sprintf(var_name, "nxm%d", i);
  matPutVariable(m, var_name, a);
  mxDestroyArray(a);
}
matClose(m);

然后在 Matlab 端完成所有操作:

s = load('matlab.mat');
c = struct2cell(s);
all_data = cat(1, c{:});

您还可以编写代码,以便每次传递都读取前一次传递的输出,扩展数组,并将其写回同一个命名变量。但这会在 C 中进行更多的编码,并且(我认为)如果您的中间结果很大,而不是这些单个数字,则性能会降低。

就此而言,因为看起来您正在处理一个小型数据集 - nxm 是一个标量 double - 您可以将您的 nxm 值 fprintf("%d\n", nxm) 保存到一个文本文件中,每个文件上都有一个数字行,然后使用fscanfstr2double 将其读入Matlab。

【讨论】:

  • 谢谢。假设我在同一个文件中有多个数组,例如nxmnym。我可以这样连接所有nxm_inym_j 吗?
  • 是的。让您的 Matlab 代码执行 s = load(...); vars = fieldnames(s); 以获取所有变量的列表,然后使用 regexpstartsWith 检测文件中存储的哪些变量与这些模式匹配,并应按组连接成不同的输出变量.
  • 或者,如果您甚至不提前知道文件中所有变量的名称,请使用 target_var = regexprep(vars, '_.*') 将文件 var 名称映射到目标代码 var 名称,调用 unique(target_var)获取结果“压缩”变量的列表,并使用ismember(target_var, vars) 决定应连接文件中的哪些输入变量以生成每个压缩输出变量。
猜你喜欢
  • 2015-09-28
  • 2013-11-28
  • 2015-12-21
  • 2021-05-12
  • 2014-02-25
  • 1970-01-01
  • 2018-03-07
  • 2017-06-19
  • 2013-05-08
相关资源
最近更新 更多