Arrays 如何在Fortran代码中将二维数组转换为一维数组?

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

如何将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 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实际参数关联
我们可以扩展这两种方法

以最简单的形式返回所需的秩1数组。作为替代方案,我们可以说形式为
[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