【问题标题】:What are ways in which an arbitrary number of nested loops be created in Fortran?在 Fortran 中创建任意数量的嵌套循环的方法是什么?
【发布时间】:2016-07-19 06:22:06
【问题描述】:

在 Fortran 中创建任意数量的嵌套循环有哪些方法?例如,可以在运行时确定嵌套循环的数量 k:

do i1 = 1,n1
do i2 = 1,n2
do i3 = 1,n3
do i4 = 1,n4
...
! use i1,i2,i3,i4,....,ik for something
...
enddo
enddo
enddo
enddo

【问题讨论】:

  • 我曾经不得不这样做,作为对某个问题(在 C 中)的一个非常基本且糟糕的解决方案。简而言之,据我回忆,我有一个包装脚本,它用所需的嵌套循环写出文件,然后编译并运行使用它的项目。它确实有效。
  • 这确实引发了一个问题你为什么要这样做?例如,如果你环顾四周,你会发现一些问题询问如何进行任意深度循环答案是 Use an elemental function 的嵌套。对于其他人来说,递归方法是合适的。那么,你为什么要这样做呢?
  • 我想用这个来转换任意等级的张量,并且仍然有一个在物理方面看起来“透明”的代码。

标签: loops recursion nested fortran fortran90


【解决方案1】:

因此,如果我理解正确,您需要制作嵌套循环(通常希望将嵌套循环保持在最低限度)。

但是在编译时,你甚至不知道你需要做多少个嵌套。

如果我遇到这个问题,我可能会将嵌套展开成一个循环,然后从头开始计算各种索引。这是我刚刚尝试过的一个示例:

program nested
    implicit none
    integer :: num_nests, i
    integer, dimension(:), allocatable :: nest_limits
    integer, dimension(:), allocatable :: nests

    print *, "Please enter number of nests:"
    read(*, *) num_nests
    allocate(nest_limits(num_nests))
    allocate(nests(num_nests))

    print *, "Please enter nest limits:"
    read(*, *) nest_limits

    nests(:) = 1
    outer_loop : do
        print *, nests(:)
        i = 1
        ! Calculate the next indices:
        inner_loop : do  
            nests(i) = nests(i) + 1 

            ! If this is still a valid index, exit the inner 
            ! loop and go for the next iteration
            if (nests(i) <= nest_limits(i)) exit inner_loop

            ! The index has overflown, so reset it to 1 and
            ! move to next index.
            nests(i) = 1
            i = i + 1

            ! If the next index would be outside of num_nests, 
            ! the whole loop is finished.
            if (i > num_nests) exit outer_loop

        end do inner_loop
    end do outer_loop
end program nested

【讨论】:

    【解决方案2】:

    chw21 提供的方法有效。但是,我很快就遇到了深层嵌套循环的问题。工作量变得太大而无法处理。幸运的是,在我的案例中,只有不同的索引是有意义的。此外,顺序并不重要,即索引 5、3、2 将产生与 2、3、5 相同的结果。基本上问题退化为在彩票上提供所有组合。如果您的问题属于这种性质,那么下面的代码可能会引起您的兴趣。

    program indices
    implicit none
    integer, dimension(:), allocatable :: ns
    integer   :: i,j,k,ni,np,nt,ntmp
    integer*8 :: nc
    
    print *, "Number of towns to visit"
    read(*, *) np
    allocate(ns(np))
    
    print *, "Total number of towns"
    read(*, *) nt
    
    if (nt<=0) then
      print*,' Error: Please provide a positive value'
      stop
    endif
    
    if(nt<np) then
       print*,' Error: Number of towns to visit must be less'
       print*,'        than or eqaul to total number of towns.'
       stop
    endif
    
    ! Initialize .....
    do i=1,np
      ns(i)=i   
    enddo
    ntmp=nt-np
    nc=0
    ! ................
    print*,' Combinations of towns to visit..:' 
    do 
       print*,ns(:)
       ! Do the appropriate work with ns here.
       !          .......
       !
       ! Provide a new combination:
       nc=nc+1
       if (ns(np)<nt) then
          ns(np)=ns(np)+1
       elseif (ns(1)==(ntmp+1)) then
          exit
       else
          do i=2,np
            if(ns(i)==(ntmp+i)) then
               ni=ns(i-1)
               k=0
               do j=i-1,np
                  k=k+1
                  ns(j)=ni+k
               enddo
               exit
             endif
          enddo
      endif
    enddo
    print*,' Number of combinations..........:',nc
    end program indices
    

    【讨论】:

      猜你喜欢
      • 2021-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-14
      • 1970-01-01
      • 2021-12-25
      相关资源
      最近更新 更多