[英]Can I pass a variable to a derived type such that each instance of my derived type could have arrays of different lengths?
在沒有可分配屬性的情況下,在程序中組織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
其中'Array'的第i個元素可以訪問三個數組A,B和C,並且這三個數組中的每一個都具有不同的大小。
我目前的問題是我正在解決QM問題,我有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確實有一個定義的最大值但是當我知道我不會使用數組時,它看起來像浪費了很多內存。
(與此答案相關,以獲得更詳細的解釋)。
正如@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
但首先,請檢查編譯器中此功能的可用性。
我想最簡單的方法是使用包含A
, B
和C
的派生類型和大小變量i
並使用一些初始化例程(此處為MyType_init()
)為每個i
分配它們。
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
結果(使用gfortran 8.1):
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 ) )
當從輸入文件中讀入N
時,這可能很有用。 此外,我們可以通過更改下面帶(*)
的行(使用OO樣式)從MyType_init()
創建一個類型綁定過程。
module mytype_m
implicit none
type MyType
integer :: i
integer, dimension(:,:), allocatable :: A, B, C
contains
procedure :: init => MyType_init ! (*) a type-bound procedure
end type
contains
subroutine MyType_init( this, i )
class(MyType), intent(inout) :: this ! (*) use "class" instead of "type"
...
end subroutine
end module
program main
...
do i = 1, N
call array( i ) % init( i ) ! (*) use a type-bound procedure
...
enddo
...
end program
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.