【问题标题】:Linear Indexing of Multi-Dimension Arrays in FortranFortran 中多维数组的线性索引
【发布时间】:2014-06-29 00:36:05
【问题描述】:

令 A 为 DIMENSION(m,n,p) 的多维数组。 Fortran 中是否允许对 A 进行线性索引(使用单个索引)?如果是这样,线性索引和多维索引之间的对应关系是什么?

也就是说A(i)是否允许,A(i)对应的是哪个元素(遍历的维度是什么顺序)?

【问题讨论】:

    标签: arrays fortran


    【解决方案1】:

    http://www.obliquity.com/computer/fortran/array.html 解释说数组是以“列为主”的形式存储的,所以最左边的索引变化最快,其次是最左边的第二个,依此类推(我相信这与 C 正好相反) .尝试像一维一样索引多维数组似乎很不明智,但正如上面链接的页面所解释的那样,您的编译器将生成执行此操作的代码(因此非常快)您以正确的顺序嵌套循环

    【讨论】:

      【解决方案2】:

      您可以将 3D 数组传递给函数或子例程,就好像它是 1D 数组一样,如下面的代码所示。我不推荐使用此功能,但您会在 Fortran 90 之前的代码中看到它。

      program xarray
      implicit none
      ! demonstrate storage association
      integer, parameter :: n1 = 2, n2 = 4, n3 = 3
      integer :: i1,i2,i3,arr(n1,n2,n3)
      forall (i1=1:n1,i2=1:n2,i3=1:n3) arr(i1,i2,i3) = i1 + 10*i2 + 100*i3
      print*,"arr =",arr
      ! output: arr = 111 112 121 122 131 132 141 142 211 212 221 222 231 232 241 242 311 312 321 322 331 332 341 342
      call print_array(arr,n1*n2*n3)
      end program xarray
      
      subroutine print_array(arr,n)
      implicit none
      integer, intent(in) :: arr(n)
      integer, intent(in) :: n
      print*,"arr(1), arr(n) =",arr(1),arr(n)
      ! output: arr(1), arr(n) = 111 342
      end subroutine print_array
      

      【讨论】:

      • 离题问题:是否缺少子程序 print_array(arr,n):integer, intent(in) :: n ?
      • 这实际上与我的另一个问题直接相关 - 你能看看这个吗? stackoverflow.com/questions/24472907/…
      • 我添加了隐式 none 和 n 的声明,尽管它不是必需的。
      • 哦,没错。只有在使用隐式 none 时才需要。谢谢 Fortranner。
      【解决方案3】:

      对于声明为dimension A(m,n,p) 的数组,它不允许像A(i) 那样引用。但是,线性索引,即所谓的数组元素顺序是一个重要的概念。正如another answer 中所述,最左边的索引是变化最快的。 A(1,1,1) 紧接在 A(2,1,1)、...、A(1,2,1) 等之前。

      数组元素顺序由于各种关联等而变得有用。例如 - 除非有真正需要,否则我不会推荐它们 - equivalence 和与假定大小数组的参数关联允许很多相同的事情。

      作为一项更现代的功能,可以使用pointer bounds remapping。当然,还有一个副本,reshape 内在函数。

      【讨论】:

        【解决方案4】:

        我会添加以下可能性,即使我从未使用过它,因为我觉得它令人困惑。有人(Nek5000,见第 22 页)声称它更快。

        do i=1,nx1*ny1*nz1*nelv
            u(i,1,1,1) = vx(i,1,1,1)
        enddo
        

        这等同于但优于(为什么?):

        do e=1,nelv
            do k=1,nz1
                do j=1,ny1
                    do i=1,nx1
                        u(i,j,k,e) = vx(i,j,k,e)
                    enddo
                enddo
            enddo
        enddo
        

        这等同于但大大优于(为什么?):

        do i=1,nx1
            do j=1,ny1
                do k=1,nz1
                    do e=1,nelv
                        u(i,j,k,e) = vx(i,j,k,e)
                    enddo
                enddo
            enddo
        enddo
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-07-17
          • 2013-11-22
          • 2015-11-04
          • 1970-01-01
          相关资源
          最近更新 更多