f2py - 函数参数的顺序搞砸了
f2py - order of function arguments messed up
我已经编写了一个小的 Fortran 函数并使用 f2py 在 Python 中将参数传递给它。不知何故,在传输过程中参数的顺序搞乱了,我不明白为什么。
Fortran 函数的相关部分(位于名为 calc_density.f95 的文件中):
subroutine calc_density(position, nparticles, ncells, L, density)
implicit none
integer, intent(in) :: nparticles
integer, intent(in) :: ncells
double precision, intent(in) :: L
double precision, dimension(nparticles), intent(in) :: position
double precision, dimension(ncells), intent(out) :: density
double precision :: sumBuf, offSum
integer :: pLower, pUpper, pBuf, numBuf, last, idx
double precision, dimension(nparticles) :: sorted
print *, 'Fortran ', 'position length ', size(position), &
'density length ', size(density), 'nparticles ', nparticles, &
'ncells ', ncells, 'L ', L
end subroutine calc_density
f2py编译命令:
f2py -c --fcompiler=gnu95 -m fortran_calc_density calc_density.f95
Python代码的相关部分:
from fortran_calc_density import calc_density as densityCalc
from numpy import array, float64
def calc_density(position, ncells, L):
arg = array(position, dtype = float64, order = 'F')
nparticles = len(position)
density = densityCalc(position, nparticles, ncells, L)
print 'Python ', 'position length ', len(position), 'density length', len(density), 'nparticles ', nparticles, 'ncells ', ncells, 'L ', L
return density
显示所有传输变量不匹配的屏幕输出示例:
Fortran position length 12 density length 100 nparticles 12 ncells 100 L 20.000000000000000
Python position length 100 density length 100 nparticles 100 ncells 20 L 12.5663706144
Python 的打印输出显示了值,但密度数组的长度除外,密度数组的长度应等于 ncells,因此 Fortran 函数的设计应为 20,与它们应该的完全一样。
然而,Fortran 值完全不对,所以在传输过程中一定发生了一些事情,这扰乱了争论。
我做错了什么?
查看由 f2py 创建的文档(使用 gfortran-5.3.0 编译):
>>> print calc_density.__doc__
Wrapper for ``calc_density``.
Parameters
----------
position : input rank-1 array('d') with bounds (nparticles)
ncells : input int
l : input float
Other Parameters
----------------
nparticles : input int, optional
Default: len(position)
Returns
-------
density : rank-1 array('d') with bounds (cells)
你可以看到 nparticles
是可选的(这是由 f2py 自动完成的)并且默认值为 len(position)
。默认情况下,可选参数被移动到参数列表的末尾。因此,在您的调用中,最后一个参数被解释为 nparticles
。
您可以将 nparticles
保留在函数调用之外或将其移至最后一个参数。两者:
density = densityCalc(position, ncells, L)
density = densityCalc(position, ncells, L, nparticles)
应该会产生正确的结果。如果要保持fortran子程序参数列表的顺序,也可以使用关键字:
density = densityCalc(position=position, nparticles=nparticles, ncells=ncells, l=L)
请注意,fortran 不区分大小写,因此关键字必须小写 l = L
。
我已经编写了一个小的 Fortran 函数并使用 f2py 在 Python 中将参数传递给它。不知何故,在传输过程中参数的顺序搞乱了,我不明白为什么。
Fortran 函数的相关部分(位于名为 calc_density.f95 的文件中):
subroutine calc_density(position, nparticles, ncells, L, density)
implicit none
integer, intent(in) :: nparticles
integer, intent(in) :: ncells
double precision, intent(in) :: L
double precision, dimension(nparticles), intent(in) :: position
double precision, dimension(ncells), intent(out) :: density
double precision :: sumBuf, offSum
integer :: pLower, pUpper, pBuf, numBuf, last, idx
double precision, dimension(nparticles) :: sorted
print *, 'Fortran ', 'position length ', size(position), &
'density length ', size(density), 'nparticles ', nparticles, &
'ncells ', ncells, 'L ', L
end subroutine calc_density
f2py编译命令:
f2py -c --fcompiler=gnu95 -m fortran_calc_density calc_density.f95
Python代码的相关部分:
from fortran_calc_density import calc_density as densityCalc
from numpy import array, float64
def calc_density(position, ncells, L):
arg = array(position, dtype = float64, order = 'F')
nparticles = len(position)
density = densityCalc(position, nparticles, ncells, L)
print 'Python ', 'position length ', len(position), 'density length', len(density), 'nparticles ', nparticles, 'ncells ', ncells, 'L ', L
return density
显示所有传输变量不匹配的屏幕输出示例:
Fortran position length 12 density length 100 nparticles 12 ncells 100 L 20.000000000000000
Python position length 100 density length 100 nparticles 100 ncells 20 L 12.5663706144
Python 的打印输出显示了值,但密度数组的长度除外,密度数组的长度应等于 ncells,因此 Fortran 函数的设计应为 20,与它们应该的完全一样。 然而,Fortran 值完全不对,所以在传输过程中一定发生了一些事情,这扰乱了争论。
我做错了什么?
查看由 f2py 创建的文档(使用 gfortran-5.3.0 编译):
>>> print calc_density.__doc__
Wrapper for ``calc_density``.
Parameters
----------
position : input rank-1 array('d') with bounds (nparticles)
ncells : input int
l : input float
Other Parameters
----------------
nparticles : input int, optional
Default: len(position)
Returns
-------
density : rank-1 array('d') with bounds (cells)
你可以看到 nparticles
是可选的(这是由 f2py 自动完成的)并且默认值为 len(position)
。默认情况下,可选参数被移动到参数列表的末尾。因此,在您的调用中,最后一个参数被解释为 nparticles
。
您可以将 nparticles
保留在函数调用之外或将其移至最后一个参数。两者:
density = densityCalc(position, ncells, L)
density = densityCalc(position, ncells, L, nparticles)
应该会产生正确的结果。如果要保持fortran子程序参数列表的顺序,也可以使用关键字:
density = densityCalc(position=position, nparticles=nparticles, ncells=ncells, l=L)
请注意,fortran 不区分大小写,因此关键字必须小写 l = L
。