【问题标题】:reading unformatted fortran file in matlab - which precision?在matlab中读取未格式化的fortran文件-精度是多少?
【发布时间】:2012-11-15 16:44:38
【问题描述】:

我刚刚写了一个文件:

 real*8                         :: vol_cel
 real*8, dimension(256,256,256) :: dense

[... some operations]

open(unit=8,file=fname,form="unformatted")
write(8)dense(:,:,:)/vol_cell
close(8)

我在 Matlab 中读取的代码:

fid = fopen(fname,'r');
mesh_raw = fread(fid,256*256*256,'double');
fclose(fid);

最小值和最大值清楚地表明它没有正确读取它(最小值为 0,最大值为较大的正实数 *8)。

min =
   3.3622e+38
max =
  -3.3661e+38

我需要在 Matlab 中设置什么精度才能将其读取到未格式化的 Fortran 文件中?

一个有点相关的问题:我使用的这个 Matlab 代码可以读取二进制文件,但不能读取未格式化的文件。虽然我正在使用 gfortran 在我的 Mac OSX 上生成这些新数据。它不识别 form="binary" 所以我不能那样做。我需要添加一些库还是这是一个字节序问题?

===== 进度=====

确定进度。而不是我的 ndim*ndim*ndim 矩阵,我只是这样写出 x 值(列向量):

open(unit=8,file=fnamex,form="unformatted")
write(8)x0
close(8)

然后Matlab读取:

fid =    fopen(nfilename,'r');
hr3=fread(fid, 1, 'int32');
x0 = fread(fid,Ntot,'float32');
hr4=fread(fid, 1, 'int32');
fclose(fid);

这行得通。然后我尝试了原始的ndim**3矩阵,我尝试阅读:

fid =    fopen(nfilename,'r');
hr3=fread(fid, 1, 'int32');
mesh_raw = fread(fid,ndim*ndim*ndim,'float32');
hr4=fread(fid, 1, 'int32');
fclose(fid);

但这给了我垃圾。也许在这里:

real*4,     dimension(:),   allocatable    :: x0
real*8,     dimension(256,256,256)         :: dense

是否需要更改:mesh_raw = fread(fid,ndim*ndim*ndim,'float32');确保它读取的是真实的* 8?那会是什么?当然只是逐字使用'real * 8'应该有效吗?我的意思是 x 矢量作品的“真实* 4”。我的意思是它读作“密集”,但最小值/最大值/平均值是错误的。

【问题讨论】:

  • 'uint32' 可能是解决方案...

标签: matlab binary precision fortran90 read-write


【解决方案1】:

您的 Fortran 代码显示您正在编写所谓的无格式顺序文件。这是一种基于记录的文件格式。典型的实现(Fortran 编译器/平台特定)是编译器将附加记录结构信息写入文件 - 通常(包括 gfortran)记录长度写在每个记录的开头和结尾。您的原始 Matlab 代码似乎没有考虑到这一点。

Fortran 2003 引入了流访问(将 ACCESS='STREAM' 说明符添加到 OPEN 语句中)。 gfortran 支持此功能, FORM='BINARY' 在某些编译器上是非标准同义词。使用流访问创建的未格式化文件没有记录结构 - 它是类似于 C 流的字节流。这可能更适合您。

【讨论】:

  • 我的代码在我的 macbook 上编译,但是当我尝试在具有相同版本 gfortran 的集群上编译它时,它在基本读取语句中失败 - 如果相同的代码在一台机器上编译而不是另一台机器,它总是硬件吗?
  • 没有。您需要提供额外信息(可能在新问题中),以允许此处的用户发表有用的评论。
【解决方案2】:

这很可能是一个字节序问题,因为粗略的有序猜测对我来说是一个更合理的数字。我不确定解决方案是什么,所以我将为您提供 3 个可能的解决方案,其中一个应该可以解决问题。这取决于您的源文件。

诀窍就是将fopen 语句更改为以下之一:

fid = fopen(fname,'rn');  %Native format (Default usually)
fid = fopen(fname,'rl');  %Little Endian
fid = fopen(fname,'rb');  %Big Endian

【讨论】:

  • 不,不幸的是那没有用。当 Fortran 写出未格式化的文件时,它们的头尾条目不是吗?我仍然不知道如何阅读这个文件。 :(
  • 翻转字节序的结果是什么?
  • 我在上面添加了一些进度作为编辑。 ndimndimndim 矩阵读取仍有问题。
【解决方案3】:
fid =    fopen(nfilename,'r');
hr3=fread(fid, 1, 'int32');
mesh_raw = fread(fid,ndim*ndim*ndim,'float32');
hr4=fread(fid, 1, 'int32');
fclose(fid);

这是正确的,除非你用 fortran 写 real*8,你需要有

mesh_raw = fread(fid,ndim*ndim*ndim,'double');

【讨论】:

  • 这是问题的原始代码(第一个 Matlab 代码),它应该如何提供帮助?
猜你喜欢
  • 1970-01-01
  • 2014-06-12
  • 2013-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-14
相关资源
最近更新 更多