mgilson mgilson - 3 years ago 152
Python Question

f2py -- prevent array reordering

I have an array which is read from a fortran subroutine as a 1D array via f2py. Then in python, that array gets reshaped:

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


Now I would like to pass that array back to fortran as a 3D array.

some_data=fortran_routine(a)


The problem is that f2py keeps trying to transpose a before passing to fortran_routine.
fortran routine looks like:

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


How do I prevent all the transposing back and forth? (I'm entirely happy to use the different array indexing conventions in the two languages).

EDIT

It seems that
np.asfortranarray
or
np.flags.f_contiguous
should have some part in the solution, I just can't seem to figure out what part that is (or maybe a
ravel
followed by a
reshape(shape,order='F')
?

EDIT

It seems this post has caused some confusion. The problem here is that
f2py
attempts to preserve the indexing scheme instead of the memory layout. So, If I have a numpy array (in C order) with shape
(nz, ny, nx)
, then f2py tries to make the array have shape
(nz, ny, nx)
in fortran too. If f2py were preserving memory layout, the array would have shape
(nz, ny, nx)
in python and
(nx, ny ,nz)
in fortran. I want to preserve the memory layout.

Answer Source

It looks like the answer is reasonably simple:

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

works, but apparently, this is the same thing as:

b=a.T

since transpose returns a view and a quick look at b.flags compared with a.flags shows that this is what I want. (b.flags is F_CONTIGUOUS).

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download