每次迭代的变量值

时间:2017-10-28 16:42:51

标签: fortran gfortran

这是我的代码:

Program Arrays_0

Implicit none

Integer :: i , Read_number , Vig_Position , Vipg_Position , n_iter
Integer , parameter :: Br_gra = 12
Integer , parameter , dimension ( Br_gra ) :: Vig = [ ( i , i = 1 , Br_gra) ]
Integer , parameter , dimension ( Br_gra ) :: Vipg = [ 0 , 1 , 1 , 1 , 2 , 2 , 3 , 4 , 4 , 7 , 7 , 7 ]
Integer :: Result_of_calculation

Write(*,*)"Enter the number (From 1 to Br_gra):"
Read(*,*) Read_number

Vig_Position = Vig(Read_number)
Vipg_Position = Vipg(Vig_Position)

   n_iter = 0

   Result_of_calculation = Vig_Position

   Do while( Vipg_Position .ne. Vipg(1) )

      n_iter = n_iter + 1

      Vig_Position = Vipg_Position

      Result_of_calculation = Result_of_calculation + Vig_Position

      Vipg_Position = Vipg(Vig_Position)

   End Do

Write(*,'(a,1x,i0)')"The number of iteration is:",n_iter
Write(*,'(a,1x,i0)')"The result of calculation is:",Result_of_calculation

End Program Arrays_0

意图是在变量的每次迭代中获得值: Vig_Position , Result_of_calculation and Vipg_position。 如何为这种计算声明变量? 一般来说,还有其他计算迭代次数的方法吗? 如何在迭代次数函数中声明变量是否是代码集的数量,如计算结果?

1 个答案:

答案 0 :(得分:2)

现在问题已经澄清,这是解决Fortran问题的典型方法。这不是唯一可能的方式,但它是最普遍的。例程调整大小以使旧大小加倍的策略是合理的 - 您希望最小化调用它的次数。示例程序中的数据集很小,因此要显示我分配数组的效果非常小。实际上,您需要一个相当大的初始分配(例如,至少100)。

请注意使用从其主机继承vals_t类型的内部过程。

Program Arrays_0

Implicit none

Integer :: i , Read_number , Vig_Position , Vipg_Position , n_iter
Integer , parameter :: Br_gra = 12
Integer , parameter , dimension ( Br_gra ) :: Vig = [ ( i , i = 1 , Br_gra) ]
Integer , parameter , dimension ( Br_gra ) :: Vipg = [ 0 , 1 , 1 , 1 , 2 , 2 , 3 , 4 , 4 , 7 , 7 , 7 ]
Integer :: Result_of_calculation

! Declare a type that will hold one iteration's values
type vals_t
    integer Vig_Position
    integer Vipg_Position
    integer Result_of_calculation
end type vals_t
! Declare an allocatable array to hold the values
! Initial size doesn't matter, but should be close
! to a lower limit of possible sizes
type(vals_t), allocatable :: vals(:)
allocate (vals(2))

Write(*,*)"Enter the number (From 1 to Br_gra):"
Read(*,*) Read_number

Vig_Position = Vig(Read_number)
Vipg_Position = Vipg(Vig_Position)

   n_iter = 0

   Result_of_calculation = Vig_Position

   Do while( Vipg_Position .ne. Vipg(1) )

      n_iter = n_iter + 1

      Vig_Position = Vipg_Position

      Result_of_calculation = Result_of_calculation + Vig_Position

      Vipg_Position = Vipg(Vig_Position)

      ! Do we need to make vals bigger?
      if (n_iter > size(vals)) call resize(vals)
      vals(n_iter) = vals_t(Vig_Position,Vipg_Position,Result_of_calculation)

   End Do

Write(*,'(a,1x,i0)')"The number of iteration is:",n_iter
Write(*,'(a,1x,i0)')"The result of calculation is:",Result_of_calculation

! Now vals is an array of size(vals) of the sets of values
! For demonstration, print the size of the array and the values
Write(*,'(a,1x,i0)')"Size of vals is:", size(vals)
Write(*,'(3i7)') vals(1:n_iter)

    contains
    ! Subroutine resize reallocates the array passed to it
    ! with double the current size, copies the old data to
    ! the new array, and transfers the allocation to the
    ! input array
    subroutine resize(old_array)
    type(vals_t), allocatable, intent(inout) :: old_array(:)
    type(vals_t), allocatable :: new_array(:)

    ! Allocate a new array at double the size
    allocate (new_array(2*size(old_array)))
    write (*,*) "Allocated new array of size ", size(new_array)

    ! Copy the data
    new_array(1:size(old_array)) = old_array

    ! Transfer the allocation to old_array
    call MOVE_ALLOC (FROM=new_array, TO=old_array)

    ! new_array is now deallocated

    return
    end subroutine resize

End Program Arrays_0

示例输出:

 Enter the number (From 1 to Br_gra):
12
 Allocated new array of size            4
The number of iteration is: 3
The result of calculation is: 23
Size of vals is: 4
      7      3     19
      3      1     22
      1      0     23