3

我在 Linux 集群上的 C 程序中生成长双浮点数据。我需要将数据导出到集群上未安装的 Matlab。

什么是最好的方法?我的顾问说要使用printf语句导出。我假设他的意思是将数据发送到逗号分隔的文件(和fprintf)。但在我看来,这可能会很慢并且使用太多内存,我们可能会失去很多精度。

我找到了这个用于读取和写入 .MAT 文件的网页,但我并不真正理解我复制到集群但无法编译的页面或示例(因为它缺少显然来自的库MATLAB。

将数据从 Linux/C 导出到 Windows/MATLAB 的最佳、最简单或最快的方法是什么?我如何开始使用这种方法?当您回答我对 C 很陌生,并且可能需要帮助来弄清楚如何获取、安装、配置和链接任何库时,请注意。但是一旦完成,我认为我很擅长学习使用它们。

4

3 回答 3

2

Why do you think you would you lose precision? The only drawback with CSVs is that ASCII files require much more storage than binary files, but in this day and age where you get terabytes of storage for the price of a good haircut, that hardly seems like a problem.

It will only be noticeably slower if you're writing gigabytes upon gigabytes, but normally calculations take so much longer that the difference between ASCII and binary is completely negligible (and if the calculations don't take so long: why do you need a cluster then?)

In any case, I'd go for ASCII -- how to write and read some binary blob needs to be documented in two places, it's easier to create bugs in both the writing end and the reading end, it's harder to solve them since no human can read the file, etc. Also, MAT file formats may change in the next Matlab release (as they have in the past).

With ASCII, you have none of these problems, the only drawback I can think of is that you have to write a small cluster-specific file reader in Matlab (which is still a lot less work than working out all the bugs and maintaining a MAT file writer).

Anyway, there's tons of tools available in Matlab for ASCII: textread, dlmread, importdata, to name a few. On the C-end, indeed just use fprintf (documentation here).

于 2012-11-01T07:09:11.273 回答
1

我曾经也遇到过这个问题(嗯,有点......)并使用简单的二进制格式来完成这项工作。

如果您的数据格式是静态的,这意味着如果它永远不会改变,您可以将自己限制在您需要的内容中,并在加载程序中硬编码确切的格式。但是,如果您想灵活地添加和删除列,您应该定义一种标题来添加有关数据格式的信息并在读取时对其进行评估。

简单导入数据的技巧如下:

  • 让 MATLAB 程序知道您的数据记录有多长以及它们是如何组成的。
  • 读取数据

    rest = fread(fid, 'uchar=>uint8', 'b').';
    

    为了得到uint8s 的行向量。

  • 重塑数据

    rest = reshape(rest, recordlength, []).';
    

    为了在recordlength列和尽可能多的行中获取您的数据。

  • 对于每个数据列,将相关uint8行组合成一个“子矩阵”,使用reshapetypecast、的组合对swapbytes数据进行适当的分组并将它们转换为所需的格式。

    这里最重要的是typecast()函数,它接受“按字节”数据作为第一个参数,所需的数据类型作为第二个参数。有多种可接受的数据类型,例如intXX, uintXX(使用,和(AFAIK)XX之一)以及and 。8163264floatdouble

    例如,typecast([1, 1], 'uint16')给你257,同时typecast([0, 0, 96, 64], 'float')给你3.5

这样做后,与文本文件相比,您可以将阅读速度提高 20 倍左右。(至少,在我编写的应用程序中就是这种情况:每 10 毫秒大约有 10 个不同的测量值,一次测量可能是几分钟甚至几小时,我想尽可能快地读入这样的文件. 所以我将这些东西从文本重新编码为二进制并获得了大约 20 倍,或者可能是 15 倍 - 不确切知道。但它很多......)

于 2012-10-31T23:25:23.940 回答
0

正如你所说,我会将工作区保存为 .MAT 文件。然后,您可以将所有当前变量中包含的任何值保存为当时的工作区。但是,如果您正在读取千兆字节长的数组(您的数据),那么您可能会逐块读取它们(可能是由于 RAM 限制?)并且在这种情况下保存工作空间可能对您没有帮助。

我永远不会打印任何东西来运输。在我的工作中(长时间渐近,所以我有大量的输出),我使用 fwrite 将所有内容保存为二进制文件。据我所知,转换为文本既慢又昂贵。

我希望这会有所帮助!

于 2012-10-31T23:01:59.297 回答