我在Linux集群上的C程序中生成长双浮点数据。我需要将数据导出到Matlab,而Matlab没有安装在集群上。
最好的方法是什么?我的顾问说要使用printf
语句导出。我认为他的意思是将数据发送到逗号分隔文件(和fprintf
)。但在我看来,这可能会很慢并且使用太多内存,我们可能会失去很多精确度。
我发现this web page用于读写.MAT文件,但我真的不理解我复制到我的集群的页面或the example,但无法编译(因为它是遗漏的库显然来自MATLAB。
将数据从Linux / C导出到Windows / MATLAB的最佳,最简单或最快的方法是什么?我如何开始使用该方法?当你回答我是C的新手时,请注意,并且可能需要帮助找出如何获取,安装,配置和链接任何库。但是一旦完成,我认为我很擅长学习使用它们。
答案 0 :(得分:2)
为什么你认为你会失去精确度? CSV的唯一缺点是ASCII文件比二进制文件需要更多的存储空间,但是在这个时代,你以理发的价格获得了数TB的存储空间,这似乎不是一个问题。
如果你在千兆字节上写千兆字节,它只会明显变慢,但通常计算需要花费的时间太长以至于ASCII和二进制之间的差异完全可以忽略不计(并且如果计算不花了这么长时间:为什么你需要一个集群?)
在任何情况下,我都会选择ASCII - 如何编写和读取一些二进制blob需要在两个地方进行记录,在写入结束和读取结束时更容易创建错误,它更难解决因为没有人可以读取文件等。另外,MAT文件格式可能会在下一个Matlab版本中发生变化(就像过去一样)。
使用ASCII,你没有这些问题,我能想到的唯一缺点就是你必须在Matlab中编写一个小的特定于群集的文件阅读器(这比编写所有的bug还要少得多)维护MAT文件编写器)。
无论如何,Matlab中有大量可用于ASCII的工具:textread
,dlmread
,importdata
,仅举几例。在C端,确实只是使用fprintf
(文档here)。
答案 1 :(得分:1)
我曾经遇到过这个问题(好吧,有点......)并使用简单的二进制格式来完成这项工作。
如果您的数据格式是静态的,这意味着如果它永远不会改变,您可以将自己限制在您需要的范围内,并在加载程序中硬编码确切的格式。但是,如果要保持灵活添加和删除列,则应定义一种标题以添加有关数据格式的信息,并在阅读时对其进行评估。
简单导入数据的技巧如下:
使用
读取数据rest = fread(fid, 'uchar=>uint8', 'b').';
为了具有uint8
s。
使用
重塑数据rest = reshape(rest, recordlength, []).';
以便在recordlength
列和您需要的行中获取数据。
对于每个数据列,使用uint8
,reshape
,typecast
的组合将相关的swapbytes
行合并为“子矩阵”适当地对数据进行分组并将其转换为所需的格式。
这里最重要的是typecast()
function,它接受“逐字节”数据作为1st,将有用数据类型作为第二参数接受。有大量已接受的数据类型,例如intXX
,uintXX
(XX
个8
,16
,32
和(AFAIK)64
)以及float
和double
。
例如,typecast([1, 1], 'uint16')
为您提供257
,而typecast([0, 0, 96, 64], 'float')
则为您提供3.5
。
一旦这样做,您可以将阅读速度 - 与文本文件相比 - 提高20倍左右。 (至少,在我为此编写的应用程序中就是这种情况:每10毫秒有大约10个不同的度量值,一个度量可能是几分钟甚至几小时,我想尽可能快地读取这样的文件所以我把这些东西从文本重新编码为二进制,并获得了大约20倍,或者15倍 - 不完全确切。但它确实很多......)
答案 2 :(得分:0)
我会将工作区保存为.MAT文件,正如您所说。然后,您拥有当时保存为工作空间的所有当前变量中包含的任何值。但是,如果您正在读取长度为千兆字节的数组(您的数据),那么您可能会按块读取它们(由于RAM限制可能?)并且在这种情况下保存工作区可能对您没有帮助。
我绝不会打印任何东西用于运输。在我的工作中(长时间的渐近,所以我有巨大的输出),我使用fwrite将所有内容保存为二进制文件。据我所知,转换为文本既缓慢又昂贵。
我希望这有点帮助!