我想了解F2PY是如何工作的。为此,我编写了一个简单的Fortran函数,它以数组作为输入,并返回数组元素的和。在
我为同一个函数编写了三个不同的版本,我希望得到相同的结果:
function rsum(arr)
real, dimension(:), intent(in) :: arr
real :: rsum
rsum=sum(arr)
end function rsum
function rsum1(arr)
real(8), dimension(:), intent(in) :: arr
real(8) :: rsum1
rsum1=sum(arr)
end function rsum1
function rsum2(arr) result(s)
real, dimension(:), intent(in) :: arr
real :: s
s=sum(arr)
end function rsum2
function rsum3(arr) result(s)
real(8), dimension(:), intent(in) :: arr
real(8) :: s
s=sum(arr)
end function rsum3
测试这些函数的python脚本如下:
^{pr2}$但结果是:
^{3}$所有结果都是正确的,除了rsum1
中的一个是{rsum3
,其中我只更改了函数结果的名称(或者,至少,我认为我正在这样做),工作非常完美!在
我知道这与Fortran和numpy之间的类型转换有关,但我不明白问题出在哪里。在
附言:我最近才学过Fortran。在
简短回答和解决方法
问题的根本原因与函数中使用假定形状伪参数(即
arr
)有关。Fortran要求这些函数具有显式接口。@弗拉基米尔夫给了你一个很好的答案(相关?)问题here正是关于这一点,这表明首选的解决方案是将函数放入模块中。假设您的函数代码列表保存在一个名为funcs.f90
的文件中,您可以简单地将它们放入一个模块中,例如mod_funcs.f90
,如下所示:用F2PY
^{pr2}$python -m numpy.f2py -m ftest -c mod_funcs.f90
包装它,将python测试脚本中的import语句更新为from ftest import mod_funcs as f
,然后运行它以获得预期的结果:更长的答案和解释
Fortran
function
由F2PY包装在subroutine
s中。为了以符合Fortran标准的方式支持假定形状数组,F2PY创建的子例程包装器包含interface
s,用于用户定义的函数和假定的形状伪参数。当用F2PY包装时,可以通过指定带有build-dir
标志的构建目录来查看这些包装器,例如:查看为有问题的函数
rsum1
创建的包装器揭示了这一点(我正在从ftest-f2pywrappers.f
中逐字复制,保留F2PY的缩进):注意,由于implicit data typing rules,
rsum1
的interface
意味着一个具有real
数据类型的函数,不是预期的real(8)
,因此接口中存在数据类型不匹配的情况!这解释了为什么带有显式result
语句(rsum3
)的函数在原始示例中返回正确的结果,其结果具有正确的数据类型。幸运的是,在命名函数时,rsum
有正确的接口。如果您将rsum
的名称更改为例如isum
,那么在其F2PY子例程包装器接口中的隐式数据类型规则将意味着它有一个integer
结果,并且您将从python脚本(经过修改以反映名称从fsum
更改为isum
)中得到以下输出:因此,在我看来,F2PY如何为带有假定形状伪参数的函数创建接口(可以通过直接将这些函数放入模块中,或通过使用
result
显式声明函数的返回值来绕过这个问题)。在为了完整起见,我使用了}。在
Python 3.6.3 :: Intel Corporation
,与NumPy 1.14.3
和{相关问题 更多 >
编程相关推荐