填充多维数组
Filling Multidimensional Arrays
我创建了一个派生类型来访问多维数组。对于每个数组,我在数组 nm 中关联一个名称。
我的问题是分配内存后如何填充数组值。
最初的想法是使用多维数组作为输入。但是,如果我存储两个副本,我可能 运行 会遇到内存问题,因为数组可能很大。一个更好的想法可能是传递一个一维数组,其中包含沿第一维的数据以及关于数据应驻留的第二和第三维位置的规范。
如果有人有使用大数据集的经验,我会重视一些关于将数组填充到派生类型的可能更好方法的建议。
Type :: Multia
Character (Len=65) :: nm(3)
Real, Allocatable :: ma(:,:,:)
Real, Allocatable :: mb(:,:,:)
Real, Allocatable :: mc(:,:,:)
Contains
Procedure :: set
End Type Multia
Subroutine set (m, nm, u, i, j)
Class (Multia), Intent (InOut) :: m
Character (Len=65) :: nm
Real, Intent (In) :: u(:)
Integer, Intent (In) :: i, j
If (nm .e. (m% nm(1))) Then
m% ma(:,i,j) = u
Else If (nm .e. (m% nm(2))) Then
m% mb(:,i,j) = u
Else If (nm .e. (m% nm(3))) Then
m% mc(:,i,j) = u
End If
End Subroutine set
如果您担心数组重复,例如 in
m%ma = [...] ! Humongous array
然后 Fortran 2003 提供了 move_alloc
内在函数,它将分配(包括值)从一个变量移动到另一个变量。
Subroutine set (m, u, v, w)
Class (Multia), Intent (InOut) :: m
Real, Intent (InOut), allocatable, dimension(:,:,:) :: u, v, w
call move_alloc(u, m%ma)
call move_alloc(v, m%mb)
call move_alloc(w, m%mc)
End Subroutine set
叫做
type(Multia) m
real, dimension(:,:,:), allocatable :: u, v, w
! ... allocating and setting u, v, w
call m%set(u, v, w)
! Components of m now allocated, u, v, w, not allocated
来自该内在的注释(在 Fortran 2008 中):
It is expected that the implementation of allocatable objects will typically involve descriptors to locate the allocated storage; MOVE ALLOC could then be implemented by transferring the contents of the descriptor
for FROM to the descriptor for TO and clearing the descriptor for FROM.
也就是说,预期不会复制数据或临时数组。
当然,这假定您不能只分配 m
的组件并直接分配到那里。
我创建了一个派生类型来访问多维数组。对于每个数组,我在数组 nm 中关联一个名称。
我的问题是分配内存后如何填充数组值。
最初的想法是使用多维数组作为输入。但是,如果我存储两个副本,我可能 运行 会遇到内存问题,因为数组可能很大。一个更好的想法可能是传递一个一维数组,其中包含沿第一维的数据以及关于数据应驻留的第二和第三维位置的规范。
如果有人有使用大数据集的经验,我会重视一些关于将数组填充到派生类型的可能更好方法的建议。
Type :: Multia
Character (Len=65) :: nm(3)
Real, Allocatable :: ma(:,:,:)
Real, Allocatable :: mb(:,:,:)
Real, Allocatable :: mc(:,:,:)
Contains
Procedure :: set
End Type Multia
Subroutine set (m, nm, u, i, j)
Class (Multia), Intent (InOut) :: m
Character (Len=65) :: nm
Real, Intent (In) :: u(:)
Integer, Intent (In) :: i, j
If (nm .e. (m% nm(1))) Then
m% ma(:,i,j) = u
Else If (nm .e. (m% nm(2))) Then
m% mb(:,i,j) = u
Else If (nm .e. (m% nm(3))) Then
m% mc(:,i,j) = u
End If
End Subroutine set
如果您担心数组重复,例如 in
m%ma = [...] ! Humongous array
然后 Fortran 2003 提供了 move_alloc
内在函数,它将分配(包括值)从一个变量移动到另一个变量。
Subroutine set (m, u, v, w)
Class (Multia), Intent (InOut) :: m
Real, Intent (InOut), allocatable, dimension(:,:,:) :: u, v, w
call move_alloc(u, m%ma)
call move_alloc(v, m%mb)
call move_alloc(w, m%mc)
End Subroutine set
叫做
type(Multia) m
real, dimension(:,:,:), allocatable :: u, v, w
! ... allocating and setting u, v, w
call m%set(u, v, w)
! Components of m now allocated, u, v, w, not allocated
来自该内在的注释(在 Fortran 2008 中):
It is expected that the implementation of allocatable objects will typically involve descriptors to locate the allocated storage; MOVE ALLOC could then be implemented by transferring the contents of the descriptor for FROM to the descriptor for TO and clearing the descriptor for FROM.
也就是说,预期不会复制数据或临时数组。
当然,这假定您不能只分配 m
的组件并直接分配到那里。