如何在Matlab中保存多维矩阵的二进制并将其加载为C ++结构?

乔波尔

我在Matlab中有一个多维矩阵,我将其保存为二进制文件,如下所示:

mat = reshape(1:90, 9,5,2);
fileName = 'mat.bin';
fid = fopen(fileName, 'w');
fwrite(fid, mat, 'int32');
fclose(fid);

C ++中,我像这样加载它:

struct Mat {
    int32_t arr[9][5][2];
};

std:ifstream input("mat.bin");
Mat* m = new Mat();
input.read(reinterpret_cast<char*>(m), sizeof(Mat));
input.close();

问题是,例如,装入的数据在内存中的排列方式不同:

访问arr[1][1][1]将产生Matlab索引数组的值mat(5,2,1)

(当然要考虑Matlab的索引从1开始)

在将矩阵(和任何其他多维矩阵)写入二进制文件之前,该如何将其布置arr[i][j][k]为与mat(i+1, j+1, k+1)

编辑:

当前解决方案
对于2D情况,矩阵转置可解决该问题。

对于xD,我发现我可以像这样改变向量的顺序,permute(mat, [D D-1 D-2 ... 1])就像散布向量(这与在C ++中映射内存的方式一样),我仍然在寻找更通用的代码,而不必编写尺寸向量(有时会改变)

谢谢。

克里斯·伦戈

始终最好将数组存储为纯1D数组并固定访问方式。mat[5][2][1]等于mat[1 + 2*2 + 5*10]在进行动态内存分配时,创建索引为索引mat[5][2][1]的数组意味着将指针数组分配给数据数组的指针。这在内存分配中涉及巨大的开销(这是非常昂贵的),并导致内存碎片和较差的缓存性能。相反,分配一个可以保存数据的普通数组,然后从3个索引中计算线性索引是非常简单且便宜的。

这是动态分配的3D数组的简单实现(不进行任何形式的检查):

struct Mat {
   using value_type = int32_t;
   std::vector<value_type> data;
   int size[3] = {0, 0, 0};
   Mat(int s1, int s2, int s3) {
      size[0] = s1; size[1] = s2; size[2] = s3;
      data.resize(s1 * s2 * s3);
   }
   value_type operator()(int i, int j, int k) {
      return data[(k * size[1] + j) * size[0] + i];
   }
};

当然,您可以将其class隐藏适当的数据,等等。或者您可以只使用存在的实现此类数组的众多库之一。有一个()用于索引的重载运算符m(5,2,1)转换为适当的索引到1D array中m.data(在这里,我没有费心通过引用返回索引元素,但这当然更有意义)。


这是测试它的完整程序。输入数据按主要列存储顺序为整数1:90,在MATLAB中,我看到以下内容:

>> mat(6,3,2)
ans =  69

C ++程序输出以下内容:

m(5,2,1) = 69

源代码:

#include <vector>
#include <fstream>
#include <iostream>

struct Mat {
   using value_type = int32_t;
   std::vector<value_type> data;
   int size[3] = {0, 0, 0};
   Mat(int s1, int s2, int s3) {
      size[0] = s1; size[1] = s2; size[2] = s3;
      data.resize(s1 * s2 * s3);
   }
   value_type operator()(int i, int j, int k) {
      return data[(k * size[1] + j) * size[0] + i];
   }
};

int main() {
   std::ifstream input("mat.bin");
   Mat m(9, 5, 2);
   input.read(reinterpret_cast<char*>(m.data.data()), m.data.size() * sizeof(Mat::value_type));
   input.close();
   std::cout << "m(5,2,1) = " << m(5,2,1) << '\n';
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在C中将二进制文件读取到结构

来自分类Dev

二进制数据的Python结构

来自分类Dev

Word文件的二进制结构

来自分类Dev

结构化为二进制

来自分类Dev

如何从二进制文件读取多个结构

来自分类Dev

二进制文件写入顺序如何结构?

来自分类Dev

如何从二进制文件读取多个结构

来自分类Dev

如何更新二进制文件中的结构项

来自分类Dev

读取结构化二进制文件c ++

来自分类Dev

从C ++中的二进制文件中删除结构

来自分类Dev

在C ++ 11中定义二进制文件的结构

来自分类Dev

在二进制文件C ++中写入并加载结构的向量

来自分类Dev

如何从Rust中的二进制文件读取C结构?

来自分类Dev

如何通过引用传递用于二进制搜索的结构C ++

来自分类Dev

如何复制结构(结构中的结构)并将其填充到C ++中的结构数组中

来自分类Dev

使用ifstream将二进制数据读入结构

来自分类Dev

用二进制文件填充结构

来自分类Dev

从二进制文件到屏幕的printf结构

来自分类Dev

使用ifstream将二进制数据读入结构

来自分类Dev

在 R 中读取二进制结构

来自分类Dev

使用 ifstream read() 读取二进制结构

来自分类Dev

无法从二进制文件中读取结构

来自分类Dev

解析混合结构的二进制文件

来自分类Dev

如何将二进制文件中的结构写入另一个二进制文件中的嵌套结构?

来自分类Dev

通过readinto()将二进制数据解析为ctypes结构对象

来自分类Dev

如何在Rust中保存借来的结构

来自分类Dev

分配结构矩阵的存储结构

来自分类Dev

错误:对二进制==无效的操作数(具有“结构演示”和“结构演示”)

来自分类Dev

保存并加载结构数组MATLAB

Related 相关文章

热门标签

归档