【问题标题】:How to obtain the starting index of a Fortran array?如何获取 Fortran 数组的起始索引?
【发布时间】:2014-04-06 09:32:27
【问题描述】:

在 Fortran 中定义一个数组:

real, dimension(a,b) :: matrix

如果给定matrix,我如何获得a 和b?

【问题讨论】:

    标签: arrays fortran fortran90


    【解决方案1】:

    了解 Fortran 90 内部函数 SHAPE、SIZE、UBOUND、LBOUND。

    您可能想要size(matrix,1) 和size(matrix,2) 或ubound(matrix,1) 和ubound(matrix,2)。但是,这是数组的最后一个索引(上限)。

    您显示的数组的起始索引隐式为 1。以不同索引开始的数组声明如下:

    real, dimension(0:a,0:b) :: matrix
    

    您可以使用lbound(matrix,1) 和lbound(matrix,2) 获取起始索引(下限)。

    【讨论】:

      【解决方案2】:

      Vladimir F's answer 说明了我们真正需要了解的关于问题的数组matrix 的所有信息。但是,我们可以更笼统地涵盖其他情况及其局限性。

      在此之前,一些术语。数组具有rank(维度或下标的数量)、extents(每个维度中的元素数量)以及上下边界。标量的秩为零。

      matrix 问题有:

      • 排名第二
      • 范围a 和b
      • 下界1和1;上限 a 和 b。

      可以使用内部函数查询这些属性中的每一个(仅来自 Fortran 2018 的排名):

      • RANK(a) 返回一个等级为 a 的标量整数
      • SIZE(a,dim=i) 返回一个标量整数,其范围为a 的i-th 维度(SIZE(a) 返回所有a 中的元素总数)
      • SHAPE(a) 返回一个整数数组,其大小等于 a 的秩(对于标量 a 为零),每个元素对应一个维度的范围
      • LBOUND(a) 和 UBOUND(a) 返回相似的整数数组,每个元素都是维度的下限和上限
      • LBOUND(a,i) 和 UBOUND(a,i) 返回具有 i-th 维度下限和上限的标量整数。

      对于显式形状数组,除非指定了维度的下限,否则它将为1,并且维度的范围将与指定的上限相同。类似地,对于假定形状的虚拟参数数组,除非另​​外给出,否则下限为 1,无论实际参数的边界如何:

      real, intent(in) :: a(:,:)   ! Lower bounds 1
      

      范围与实际参数相同。

      延迟形状数组(可分配和指针)也可以使用这些内在函数进行查询,但必须分配可分配且指针必须与指针关联:

      real, intent(in), allocatable :: a(:,:)   ! Same bounds as the actual argument if allocated
      real, intent(out), allocatable :: b(:,:)  ! Definitely not allocated: no bounds
      

      这里a 与假定的形状参数不同,它的下限可能不同于1,但LBOUND 会安全地告诉我们。

      对于假定的 size 参数,情况有所不同:

      real, intent(in) :: a(2:5,*)
      

      在这里,我们不能使用SHAPE来询问a,但我们可以放心地使用LBOUND,并且我们可以在某些方面使用UBOUND和SIZE:

      LBOUND(a)    ! Allowed: can ask about lower bound for all dimensions
      LBOUND(a,1)
      LBOUND(a,2)  ! Both allowed individually
      
      UBOUND(a)    ! Not allowed: this would include asking about the second upper bound
      UBOUND(a,1)  ! Allowed: first bound is defined
      UBOUND(a,2)  ! Not allowed: bad second bound
      
      SIZE(a)      ! Not alllowed: as for UBOUND
      SIZE(a,1)    ! Allowed
      SIZE(a,2)    ! Not allowed
      
      RANK(a)      ! Allowed (we know it will be 2).
      

      (Fortran 2018)假设 rank 参数仍然略有不同:

      real, dimension(..), intent(in) :: a
      
      print *, RANK(a)     ! Allowed
      print *, SHAPE(a)    ! ""
      print *, LBOUND(a)   ! ""
      print *, UBOUND(a)   ! ""
      print *, SIZE(a)     ! ""
      
      print *, LBOUND(a,1) ! Allowed only if a is rank at least 1
      print *, UBOUND(a,1) ! ""
      print *, SIZE(a,1)   ! ""
      

      如果假定的排名变量是标量,则不允许该维度的值(0,这是必要的,在任何情况下都不是有效维度)。

      但事情可能会变得很奇怪:SHAPE(a) 可能会为某些元素返回 -1:

        implicit none
      
        real a(6)
        call s1(a)
        
      contains
      
        subroutine s1(a)
          real a(2,*)
          call s2(a)
        end subroutine s1
      
        subroutine s2(a)
          real a(..)
          print *, SHAPE(a)
        end subroutine s2
        
      end program
      

      如果你确实得到了-1,你就知道你不能使用UBOUND 来获取相应维度的上限,也不能使用SIZE 来获取其范围。但是,您可以使用 LBOUND 来获得它的下限。

      最后,数组表达式在每个维度上总是有下界1,上界等于extent:

      real a(4:7)
      
      print *, LBOUND(a), UBOUND(a)
      print *, LBOUND(a(:)), UBOUND(a:))
      print *, LBOUND(a+1), UBOUND(a+1)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-09-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多