2

Fortran の配列で大きな割り当て可能なベクトルの束をどのように組み合わせることができますか? reshape配列が大きいため、コピーと再形成を避けたいと思います。私が実現したい効果はequivalence、説明するために Fortran の のようなものです。

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

ただし、これは割付け配列では機能しません。行列のベクトルにアクセスする場合は、ポインターを介して簡単に実装できます。しかし、2 次元配列でベクトルを組み合わせるにはどうすればよいでしょうか。今まで私は問題のあるポインタの配列にしか来ませんでした:

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

別々の1Dアレイから始める場合、これは不可能です。割り当て可能な配列は、メモリ内のどこにあってもかまいません。Fortran配列は連続している必要はありませんが、いくつかの進歩のシステムが必要です。

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

次の要素のアドレスを単純に計算できないため、Fortran標準では禁止されています。1D配列は、同じ長さであることが保証されていません。

またreshape、それ自体が非効率的である必要はないので、構文的にインデックス作成に役立つ場合がありますが、データにはまったく触れないでください。

ポインタは優れたツールであり、ここで役立つ場合があります。1D配列の使用方法は少し異なります。たとえば、長い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 に答える