Arrays 如何在Fortran代码中将二维数组转换为一维数组?
如何将r(I,j)转换为一维数组,以便对数字进行轻松排序Arrays 如何在Fortran代码中将二维数组转换为一维数组?,arrays,fortran,gfortran,Arrays,Fortran,Gfortran,如何将r(I,j)转换为一维数组,以便对数字进行轻松排序 program sort implicit none character CN*8,O*7 integer j,iconf,nconf integer i,nbins,t integer n,nmax,ind,num,b parameter (n=216) double precision xbox,rq parameter (nmax=3091,nconf=1) double precision at
program sort
implicit none
character CN*8,O*7
integer j,iconf,nconf
integer i,nbins,t
integer n,nmax,ind,num,b
parameter (n=216)
double precision xbox,rq
parameter (nmax=3091,nconf=1)
double precision atom(nmax),id(nmax),ox(nmax),oy(nmax),oz(nmax)
double precision xij,yij,zij,rij
double precision r(n,n),A(n)
open(unit=10,status='unknown',file='1000.gro')
do iconf= 1,nconf
write(*,*)iconf
read(10,*)
read(10,*)
do i=1,n
read(10,'(A8,A7,1i5,3f8.3)')CN,O,num,ox(i),oy(i),oz(i)
enddo
read(10,*)xbox ! read the xbox for PBC
open(unit=3,file='dist.txt')
do i=1,n
do j=1,n
if(i .ne. j) then
xij=ox(i)-ox(j)
yij=oy(i)-oy(j)
zij=oz(i)-oz(j)
r(i,j)=dsqrt(xij**2 + yij**2 + zij**2)
write(3,'(i3,2x,i3,4x,f17.15)') i,j, r(i,j)
endif
enddo
enddo
enddo
END
我必须计算距离并将其保存在数组中为
r(I,j)
。我想把r(I,j)
转换成一维数组,这样我就可以轻松地对r(I,j)
进行排序 可以将r(1,1)传递给一个子例程,该子例程将参数声明为一维数组。这在Fortran中是合法的(有些限制不适用于您的代码),并且使用了一种称为“序列关联”的功能。这似乎是为整形函数量身定做的:在这个小示例中,整形首先用于生成二维数组a,然后再次调用整形来生成一维数组C
Program reshape_demo
use, intrinsic :: iso_c_binding
implicit none
real(kind=c_float),allocatable :: A(:,:),C(:)
integer(kind=c_int) :: krow
allocate(A(3,3))
A=reshape((/1,2,3,4,5,6,7,8,9/),(/3,3/))
do krow=1,3
write(*,fmt="(1p3e10.3)")A(krow,:)
end do
C=reshape(A,(/9/))
write(*,fmt="(9(1x,f4.1))")C
End Program reshape_demo
前面的两个答案研究了如何将中的秩-2数组“转换”为秩-1数组的字面问题。他们使用不同的方法:
- 将中的值复制到新的秩1数组中李>
- 在end子例程中,将秩1伪参数与秩2实际参数关联
[x]
的数组构造函数也可以:
real r1d(6), r2d(3,2)
r2d=5.
r1d = [r2d]
当实际参数是数组伪参数时,数组中包含并位于实际参数之后的元素是顺序关联的
通过序列关联,虚拟数组将假定为大小或显式形状。在本例中,我们对整个阵列感兴趣,我们可以传递整个阵列:
real r2d(3,2)
call sub(r2d)
在哪里
这里重要的是,对于显式形状和假定大小的伪参数,秩不必与实际参数的秩匹配
如前所述,第一组方法涉及创建一个新数组。序列关联的使用不起作用。第三种方法也是可用的:让秩1指针指向秩2目标。当然,创建副本也意味着任何更改都不会反映在原始秩2数组中。序列关联和指针将看到传递的更改
关于这些问题中任何一个的更多细节可以在其他问题和答案中找到
对于排序而言,将秩-2数组视为秩-1数组是否有意义是另一个考虑因素。嗯,几乎是F77。。。只有DO..END DO不在F77中。但是,是的,现在询问F77是没有意义的。自由格式,隐式无,以及注释的感叹号这里的输入数据是
ox
,oy
,和oz
。您也可以决定将距离r
存储在长度为n*(n-1)/2的一维数组中,索引为“(i-1)*n+j”(其中i是两个索引中的最小值)。重塑也是一个选项,但最好编写一个在二维数组上工作的小例程,因为底层数据本质上是二维的。但是Claudia很可能不想排序,而是想对数组进行排序或索引,而不是对数组进行排序,因此她保留了哪对索引处于什么距离。但这不属于政府的职权范围stackoverflow@lanBush如果你能帮我对2d数组进行排序,它保留了i,j,并且只对r(i,j)进行排序,这会生成一个数组的副本-可能不是我们想要的。事实上,在这个过程中,它甚至可能复制两个副本。此外,更美观的现代Fortran数组构造函数应该是方括号[]
,而不是“(/)。在从2D到1D的转换过程中,如何控制元素的顺序?简单的[]
或重塑
以列的第一顺序给出元素。如何以第一行的顺序获取该值。对于二维数组,可以使用转置
获得具有其他顺序元素的中间数组;或者在数组构造函数中使用更复杂的表达式,如[(a(i,:),i=1,n)]
。当然,如果这样做,很可能会产生一份副本。
subroutine sub(r1d)
real r1d(*) ! or r1d(6), etc.
end subroutine