8

f2pyを介して1D配列としてfortranサブルーチンから読み取られる配列があります。次に、Python では、その配列が再形成されます。

a=np.zeros(nx*ny*nz)
read_fortran_array(a)
a=a.reshape(nz,ny,nx)  #in fortran, the order is a(nx,ny,nz), C/Python it is reversed

次に、その配列を 3D 配列として fortran に戻したいと思います。

some_data=fortran_routine(a)

問題は、f2py が fortran_routine に渡す前に a を転置しようとし続けることです。fortran ルーチンは次のようになります。

subroutine fortran_routine(nx,ny,nz,a,b)
real a
real b
integer nx,ny,nz
!f2py intent(hidden) nx,ny,nz
!f2py intent(in) a
!f2py intent(out) b
...
end subroutine

すべての転置を前後に防ぐにはどうすればよいですか? (私は、2 つの言語で異なる配列のインデックス付け規則を使用できることを非常に嬉しく思います)。

編集

解決策の一部であるように思われますが、それがどの部分であるかを理解できないようです(または、の後np.asfortranarrayに? が続く可能性があります)。np.flags.f_contiguousravelreshape(shape,order='F')

編集

この投稿は混乱を招いたようです。ここでの問題は、メモリ レイアウトではなくインデックス スキームf2pyを保持しようとすることです。そのため、 shape を持つ numpy 配列 (C オーダー) がある場合、f2py は fortran でも配列に shape を持たせようとします。f2py がメモリ レイアウトを保持していた場合、配列はPython とFortran で形状を持つことになります。メモリ レイアウトを保持したい。(nz, ny, nx)(nz, ny, nx)(nz, ny, nx)(nx, ny ,nz)

4

2 に答える 2

4

Fortran は軸の順序を逆にしません。C/Python とは異なり、メモリにデータを格納するだけです。numpy に Fortran の順序でデータを格納するように指示できますが、これは軸を逆にすることとは異なります。

私はあなたのコードをこのように書き直します

a=np.zeros(nx*ny*nz)
read_fortran_array(a)
a=a.reshape(nx,ny,nz, order='F') # It is now in Fortran order

これで、f2py は配列を渡すときに配列を並べ替えようとしなくなりました。

補足として、これも機能します

a=a.reshape(nx,ny,nz) # Store in C order

C オーダーの配列を Fortran ルーチンに渡すと、f2py はバックグラウンドでこれらの操作を実行するためです。

a=a.flatten() # Flatten array (Make 1-D)
a=a.reshape(nx,ny,nz, order='F')  # Place into Fortran order

もちろん、最初から Fortran 順に格納した方が効率的です。

一般に、f2py がこれを処理するため、パフォーマンスが重要なセクションがない限り、配列の順序について心配する必要はありません。

于 2012-06-28T15:55:02.473 に答える
3

答えはかなり単純なようです:

b=np.ravel(a).reshape(tuple(reversed(a.shape)),order='F')

動作しますが、明らかに、これは次と同じです。

b=a.T

b.flags転置はビューを返すため、と比較して簡単に見ると、a.flagsこれが私が望むものであることがわかります。( b.flagsF_CONTIGUOUS です)。

于 2012-07-02T12:31:06.617 に答える