如何在Fortran中的数组中组合一堆大的可分配向量?我想避免使用reshape
进行复制和重新整形,因为数组是 large 。我想要实现的效果就像Fortran的equivalence
一样,用来说明:
program test_equiv
integer x(10), y(10), z(10), xyz(10,3)
equivalence (x, xyz(1,1))
equivalence (y, xyz(1,2))
equivalence (z, xyz(1,3))
x = 1
y = 2
z = 3
! and we can use just normal array syntax
print *, xyz(3,:)
end program
然而,这将不适用于可分配数组。如果它是关于访问矩阵的向量,则可以通过指针轻松实现。但是如何在二维数组中组合矢量?直到现在我才遇到有问题的指针数组:
program test_arofpntrs
implicit none
integer :: i
integer, allocatable, target :: xs(:), ys(:), zs(:)
type t_p_xs
integer, pointer :: p_xs(:)
end type t_p_xs
type(t_p_xs), allocatable :: coords(:)
allocate(coords(3), xs(10), ys(10), zs(10))
xs = 1
ys = 2
zs = 3
coords(1) % p_xs => xs
coords(2) % p_xs => ys
coords(3) % p_xs => zs
print *, coords(1) % p_xs(:)
! this fails:
!print *, coords(:) % p_xs(1)
end program
这很难看,无法访问xs(i),ys(i),zs(i)。是否有可能在没有副本的情况下做我想做的事情?
答案 0 :(得分:3)
如果从单独的1D阵列开始,这将无法实现。可分配的数组可以在存储器中的任何位置。尽管Fortran阵列不必是连续的,但必须有一些步幅系统。
! this fails:
!print *, coords(:) % p_xs(1)
Fortran标准禁止,因为无法简单地计算下一个元素的地址。 1D阵列甚至不能保证具有相同的长度。
同样reshape
本身不一定是低效的,它可能只是语法上有助于索引,但根本不触及数据。
指针是一个很好的工具,可能会有所帮助。您必须以不同方式使用1D阵列。例如,分配一个长1D数组,并为其中的一部分和一个2D指针作为一个整体提供1D指针,或者更好地反过来:
real,allocatable,target :: xyz(:,:)
real,pointer :: x(:),y(:),z(:)
allocate(xyz(1:10,1:3))
x => xyz(:,1)
y => xyz(:,2)
z => xyz(:,3)
甚至可以使用其他索引顺序,即xyz(3,10); x => xyz(1,:)
。
你也可以
long1D(1:size(xyz)) => xyz
但请注意,这是此方向的Fortran 2008功能(2003年另有规定)。