2

如何在 Fortran 的数组中组合一堆大的可分配向量?我想避免使用复制和重塑,reshape因为数组很大。我想要达到的效果就像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)。没有副本可以做我想做的事吗?

4

1 回答 1

3

如果您从单独的一维数组开始,这将是不可能的。可分配数组可能位于内存中的任何位置。尽管 Fortran 数组不必是连续的,但必须有一些跨步系统。

! this fails:
!print *, coords(:) % p_xs(1)

Fortran 标准禁止使用,因为不能简单地计算下一个元素的地址。一维数组甚至不能保证具有相同的长度。

同样reshape,它不一定是低效的,它可能只是在语法上有助于索引,但根本不接触数据。

指针是一个很好的工具,在这里可能会有所帮助。您必须以不同的方式使用一维数组。例如,分配一个长的 1D 数组,并为它的一部分分配 1D 指针,并将 2D 指针作为一个整体,或者反过来更好:

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)。

于 2012-10-25T20:12:12.477 回答