簡體   English   中英

在 matlab 中讀取未格式化的 fortran 文件 - 哪個精度?

[英]reading unformatted fortran file in matlab - which precision?

我剛剛寫了一個文件:

 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" 所以我不能那樣做。 我需要添加一些庫還是這是一個字節序問題?

===== 進步 =====

好的進展。 我只是寫出 x 值(列向量),而不是我的 ndim*ndim*ndim 矩陣:

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”。 我的意思是它讀“密集”但最小/最大/平均值是錯誤的。

這很可能是一個字節序問題,因為粗略的有序猜測對我來說是一個更合理的數字。 我不確定解決方案是什么,所以我將提供 3 種可能的解決方案,其中一種應該可以解決問題。 這取決於您的源文件。

訣竅是簡單地將fopen語句更改為以下之一:

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

您的 Fortran 代碼顯示您正在編寫所謂的無格式順序文件。 這是一種基於記錄的文件格式。 典型的實現(Fortran 編譯器/平台特定)是編譯器將附加記錄結構信息寫入文件 - 通常(包括 gfortran)記錄長度寫入每條記錄的開頭和結尾。 您的原始 Matlab 代碼似乎沒有考慮到這一點。

Fortran 2003 引入了流訪問(將ACCESS='STREAM'說明符添加到 OPEN 語句)。 gfortran 支持此功能,FORM='BINARY' 在某些編譯器上是非標准同義詞。 使用流訪問創建的無格式文件沒有記錄結構 - 它是類似於 C 流的字節流。 這可能更適合您。

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');

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM