在没有可分配属性的情况下,在程序中组织11个相似但大小可变的数组的最佳方法是什么?
我在想像这样的东西:
TYPE MyType(i)
integer, intent(in) :: i
integer, dimension(i,i) :: A
integer, dimension(2*i,i) :: B
integer, dimension(i,2*i) :: C
end type MyType
然后在主程序中,我可以这样声明:
type(mytype), dimension(N) :: Array
其中“数组”的第i个元素可以访问三个数组A,B和C,这三个数组的大小各不相同。
我目前遇到的问题是我正在解决一个质量管理问题,我有11个不同的数组,它们的大小各不相同,但是都取决于相同的参数(因为大小A,B和C都取决于i)。这些数组的实际值也不改变。
我的程序着眼于不同类型的系统,每个系统都有自己的A,B和C(只是为了保持类比),并且在每个系统中,A,B和C都有唯一的大小。
如果我知道我正在研究6种不同的系统,则需要6种不同的A,B和C副本。
当前,A,B和C不是派生类型的一部分,而是可分配的,并在每次迭代时重新计算。对于较大的系统,此计算需要十分之一秒的时间。但是我的平均结果约为100,000次,这意味着可以节省大量时间。另外,我也不缺少记忆。
我尝试在另一个程序中计算这些数组,并将它们写入文件并在需要时读取它们,但是不幸的是,这并不比同时重新计算要快。
注意:这是我实际的数组:
integer, dimension(:,:), allocatable :: fock_states
integer, dimension(:,:), allocatable :: PES_down, PES_up
integer, dimension(:,:), allocatable :: IPES_down, IPES_up
integer, dimension(:,:), allocatable :: phase_PES_down, phase_PES_up
integer, dimension(:,:), allocatable :: phase_IPES_down, phase_IPES_up
integer, dimension(:,:), allocatable :: msize
integer, dimension(:,:), allocatable :: mblock
每个系统的每个数组大小都不相同。
编辑:
所以我真正需要的是此编辑上方列表中N个数组的副本。属于第i个副本的数组的大小与i成比例(例如PES_down的维度为(i,4 ** i))。据我了解,这意味着我需要N个类型为'MyType'的变量声明。通常可以,但是问题是N是在编译时定义的,但是可以在运行之间进行更改。
N确实有一个定义的最大值,但是当我知道我不会使用数组时,似乎浪费了很多内存。
答案 0 :(得分:2)
(有关this answer的详细说明)。
正如@roygvib在他的评论中所说,是的,在这种情况下不仅可以使用参数化派生类型,还可以完美匹配。这是PDT旨在解决的主要问题之一。
type :: MyType(i)
integer, len :: i
integer, dimension(i,i) :: A
integer, dimension(2*i,i) :: B
integer, dimension(i,2*i) :: C
! (...)
end type
然后,在主程序中,您将这样声明对象(其中i
是当前系统类型的已知长度参数):
type(mytype(i)), dimension(N) :: Array
但是首先,请检查编译器中此功能的可用性。
答案 1 :(得分:1)
我猜想,使用包含大小变量A
的{{1}},B
和C
的派生类型并为每个{{ 1}}使用一些初始化例程(此处为i
)。
i
结果(使用gfortran 8.1):
MyType_init()
主程序中的module mytype_mod
implicit none
type MyType
integer :: i
integer, dimension(:,:), allocatable :: A, B, C
end type
contains
subroutine MyType_init( this, i )
type(MyType), intent(inout) :: this
integer, intent(in) :: i
allocate( this % A( i, i ), &
this % B( 2*i, i ), &
this % C( i, 2*i ) )
this % A = 0 !! initial values
this % B = 0
this % C = 0
end subroutine
end module
program main
use mytype_mod
implicit none
integer, parameter :: N = 2
type(MyType) :: array( N )
integer i
do i = 1, N
call MyType_init( array( i ), i )
array( i ) % A(:,:) = i * 10 !! dummy data for check
array( i ) % B(:,:) = i * 20
array( i ) % C(:,:) = i * 30
enddo
do i = 1, N
print *
print *, "i = ", i
print *, " A = ", array( i ) % A(:,:)
print *, " B = ", array( i ) % B(:,:)
print *, " C = ", array( i ) % C(:,:)
enddo
end program
可以分配,这样
i = 1
A = 10
B = 20 20
C = 30 30
i = 2
A = 20 20 20 20
B = 40 40 40 40 40 40 40 40
C = 60 60 60 60 60 60 60 60
当从输入文件中读取array(:)
时可能有用。此外,我们可以通过使用下面的type(MyType), allocatable :: array(:)
N = 6
allocate( array( N ) )
更改行以使用OO样式,从N
创建一个类型绑定过程。
MyType_init()