[英]Read in array data into different sized Fortran arrays
Let's say I have a 5 x 5 array of floating points in a file array.txt
: 假设我在
array.txt
文件中有一个5 x 5的浮点数array.txt
:
1.0 1.1 0.0 0.0 0.0
1.2 1.3 1.4 0.0 0.0
0.0 1.5 1.6 1.7 0.0
0.0 0.0 1.8 1.9 1.0
0.0 0.0 0.0 1.1 1.2
I know this is probably a strange thing to do, but I'm just trying to learn the read
statements better: I want to create two 3x3 arrays in Fortran, ie real, dimension(3,3) :: array1, array2
and try reading in the first 9 values by row into array1
and the following 9 values into array2
. 我知道这样做可能很奇怪,但是我只是想更好地学习
read
语句:我想在Fortran中创建两个3x3数组,即real, dimension(3,3) :: array1, array2
并尝试按行将前9个值读入array1
,将后9个值读入array2
。 That is, I would like arrays to have the form 也就是说,我希望数组具有以下形式
array1 = 1.0 1.1 0.0
0.0 0.0 1.2
1.3 1.4 0.0
array2 = 0.0 0.0 1.5
1.6 1.7 0.0
0.0 0.0 1.8
Next I want to try to do the same by columns: 接下来,我想按列尝试执行相同操作:
array1 = 1.0 1.2 0.0
0.0 0.0 1.1
1.3 1.5 0.0
array2 = 0.0 0.0 1.4
1.6 1.8 0.0
0.0 0.0 1.7
My "closest" attempt for row-wise: 我的“最接近”尝试逐行:
program scratch
implicit none
real, dimension(3,3) :: array1, array2
integer :: i
open(12, file="array.txt")
!read in values
do i = 1,3
read(12,'(3F4.1)', advance="no") array1(i,:)
end do
end program scratch
My questions: 我的问题:
A. How to advance to next record when at the end? A.结束时如何前进到下一个记录?
B. How to do the same for reading in column-wise? B.如何进行逐列阅读?
C. Why is '(3F4.1)'
needed, as opposed to '(3F3.1)'
? C.为什么需要
'(3F4.1)'
,而不是'(3F3.1)'
?
because of the requirement to "assign by columns" i would advise reading the whole works into a 5x5 array: 因为需要“按列分配”,所以我建议将整个作品读入5x5数组中:
real tmp(5,5)
read(unit,*)tmp
(note no format specification required) (请注意,不需要格式说明)
Then do the assignments you need using array operations. 然后使用数组操作完成所需的分配。
for this small array, the simplest thing to do seems to be: 对于这个小数组,最简单的操作似乎是:
real tmp(5,5),flat(25),array1(3,3),array2(3,3)
read(unit,*)tmp
flat=reshape(tmp,shape(flat))
array1=reshape(flat(:9),shape(array1))
array2=reshape(flat(10:18),shape(array2))
then the transposed version is simply: 那么转置版本就是:
flat=reshape(transpose(tmp),shape(flat))
array1=reshape(flat(:9),shape(array1))
array2=reshape(flat(10:18),shape(array2))
If it was a really big array I'd think of a way that avoided making an extra copy of the data. 如果这是一个非常大的数组,我会考虑一种避免制作额外数据副本的方法。
Note you can wrap each of those assignments in transpose
if needed depending on how you really want the data represented, eg. 注意:您可以在每个包裹这些任务的
transpose
,如果这取决于你如何真正想要的数据来表示,如需要。
array1=transpose(reshape(flat(:9),shape(array1)))
Reading by line is easy : 逐行阅读很容易:
READ(12,*) ((array1(i,j),j=1,3),i=1,3),((array2(i,j),j=1,3),i=1,3)
"advance='no'" is necessary only if you use 2 read statements instead of 1 (and only on the first READ). 仅当您使用2条read语句而不是1条(并且仅在第一次READ上)时才需要“ advance ='no'”。 But this works only with explicit format ...
但这仅适用于显式格式...
Reading a file by column is not so obvious, especially because reading a file is usually an expensive task. 按列读取文件并不是很明显,尤其是因为读取文件通常是一项昂贵的任务。 I suggest you read the file in a larger table and then you distribute the values into your two arrays.
建议您在更大的表中读取文件,然后将值分配到两个数组中。 For instance :
例如 :
real :: table(5,5)
integer :: i,j,ii,jj,k
..
read(12,*) ((table(i,j),j=1,5),i=1,5)
k=0
do j=1,3
do i=1,3
k=k+1
jj=(k-1)/5+1
ii=k-(jj-1)*5
array1(i,j)=table(ii,jj)
enddo
enddo
do j=1,3
do i=1,3
k=k+1
jj=(k-1)/5+1
ii=k-(jj-1)*5
array2(i,j)=table(ii,jj)
enddo
enddo
(3F4.1) is better than (3F3.1) because each number occupies 4 bytes in fact (3 for the digits and 1 for the space between numbers). (3F4.1)优于(3F3.1),因为每个数字实际上占用4个字节(数字3个,数字之间的空格1个)。 But as you see, I have used * which avoids to think about such detail.
但是如您所见,我使用*可以避免考虑此类细节。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.