填充多维数组

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 的组件并直接分配到那里。