[英]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.