首页 文章

Fortran:选择可分配数组的等级

提问于
浏览
1

我正在尝试编写一个程序,我希望可分配数组 A 的等级为1,2或3,具体取决于我在运行时的输入 . 我想这样做,因为 A 上的后续操作是类似的,并且我在模块中定义了一个接口 work ,其模块过程在 A 上作用时,给出了所需的结果 .

我目前正在做的是:

program main
implicit none
integer :: rank,n=10
real*8, allocatable :: A1(:)
real*8, allocatable :: A2(:,:)
read (*,*) rank

if (rank.eq.1) then
    allocate (A1(n))
else if (rank.eq.2) then
    allocate (A2(n,n))
end if

! operate on the array
if (rank.eq.1) then
    call work(A1)
else if (rank.eq.2) then
    call work(A2)
end if

end program

如果以某种方式我可以选择 A 的等级,事情会容易得多,因为那时不需要 if 语句 . 也许这是不可能的,但所有的帮助都表示赞赏 .

2 回答

  • 1

    下一个Fortran标准(2015)的 select rank 结构类似于 select case . 我的示例在假定秩虚拟变量的 rank 内在函数上使用 select case 构造 .

    module my_type
    
      use, intrinsic :: iso_fortran_env, &
           ip => INT32, &
           wp => REAL64
    
      implicit none
      private
      public :: MyType
    
      type MyType
         real (wp)              :: rank0
         real (wp), allocatable :: rank1(:)
         real (wp), allocatable :: rank2(:,:)
         real (wp), allocatable :: rank3(:,:,:)
       contains
         procedure :: create => create_my_type
         procedure :: destroy => destroy_my_type
      end type MyType
    
    contains
    
      subroutine create_my_type(this, array)
        ! calling arguments
        class (MyType), intent (in out) :: this
        real (wp),      intent (in)     :: array(..) !! Assumed-rank dummy variable
    
        ! local variables
        integer (ip), allocatable :: r(:)
    
        select case(rank(array))
        case (0)
           return
        case (1)
           r = shape(array)
           allocate( this%rank1(r(1)) )
        case (2)
           r = shape(array)
           allocate( this%rank2(r(1), r(2)) )
        case (3)
           r = shape(array)
           allocate( this%rank3(r(1), r(2), r(3)) )
        case default
           error stop 'array must have rank 0,1,2, or 3'
        end select
    
        ! Release memory
        if (allocated(r)) deallocate( r )
    
      end subroutine create_my_type
    
    
      subroutine destroy_my_type(this)
        ! calling arguments
        class (MyType), intent (in out) :: this
    
        if (allocated(this%rank1)) deallocate( this%rank1 )
        if (allocated(this%rank2)) deallocate( this%rank2 )
        if (allocated(this%rank3)) deallocate( this%rank3 )
    
      end subroutine destroy_my_type
    
    end module my_type
    
    program main
    
      use, intrinsic :: iso_fortran_env, only: &
           ip => INT32, &
           wp => REAL64
    
      use my_type, only: &
           MyType
    
      implicit none
    
      type (MyType) :: foo
      real (wp)     :: a0, a1(42), a2(42,42), a3(42,42,42)
    
      print *, rank(a0)
      print *, rank(a1)
      print *, rank(a2)
      print *, rank(a3)
    
      ! Allocate array of rank 3
      call foo%create(a3)
    
      print *, rank(foo%rank3)
      print *, shape(foo%rank3)
      print *, size(foo%rank3)
    
      ! Release memory
      call foo%destroy()
    
    end program main
    
  • 2

    声明数组为三级 . 如果需要较低级别的数组,请将相关的尾随维度分配为大小为1 .

    real, allocatable :: array(:,:,:)
    ...
    select case (desired_rank)
    case (1) ; allocate(array(n,1,1))
    case (2) ; allocate(array(n,n,1))
    case (3) ; allocate(array(n,n,n))
    case default ; error stop 'bad desired rank'
    end select
    

    然后,您可以使用数组部分来获得与所需等级一致的连续切片 array . 或者,编写对数组进行操作的相关过程以获取三级参数,并使它们了解更高维度的大小一个范围的含义 .

相关问题