在Python中调用Fortran子例程返回';非类型';

在Python中调用Fortran子例程返回';非类型';,python,r,fortran,fortran77,f2py,Python,R,Fortran,Fortran77,F2py,我想编写一个Python包,其中包含Brian Ripley维护的R包的基本特性。R的大部分代码都是用Fortran77语法编写的。因此,基本上模仿Brian Ripley在R中所做的,我的计划是将代码导入Python并编写相应的用户界面。首先,我想将Fortran77子例程rlbin.f(下面的代码)放在Python函数中 c Part of R package KernSmooth c Copyright (C) 1995 M. P. Wand c c Unlimited use a

我想编写一个Python包,其中包含Brian Ripley维护的R包的基本特性。R的大部分代码都是用Fortran77语法编写的。因此,基本上模仿Brian Ripley在R中所做的,我的计划是将代码导入Python并编写相应的用户界面。首先,我想将Fortran77子例程rlbin.f(下面的代码)放在Python函数中

c  Part of R package KernSmooth
c  Copyright (C) 1995  M. P. Wand
c
c  Unlimited use and distribution (see LICENCE).

cccccccccc FORTRAN subroutine rlbin.f cccccccccc

c Obtains bin counts for univariate regression data
c via the linear binning strategy. If "trun=0" then
c weight from end observations is given to corresponding
c end grid points. If "trun=1" then end observations
c are truncated.

c Last changed: 26 MAR 2009

      subroutine rlbin(X,Y,n,a,b,M,trun,xcnts,ycnts)
      double precision X(*),Y(*),a,b,xcnts(*),ycnts(*),lxi,delta,rem
      integer n,M,i,li,trun

c     Initialize grid counts to zero

      do 10 i=1,M
         xcnts(i) = dble(0)
         ycnts(i) = dble(0)
10    continue

      delta = (b-a)/(M-1)
      do 20 i=1,n
         lxi = ((X(i)-a)/delta) + 1

c        Find integer part of "lxi"

         li = int(lxi) 
         rem = lxi - li
         if (li.ge.1.and.li.lt.M) then
            xcnts(li) = xcnts(li) + (1-rem)
            xcnts(li+1) = xcnts(li+1) + rem
            ycnts(li) = ycnts(li) + (1-rem)*y(i)
            ycnts(li+1) = ycnts(li+1) + rem*y(i)
         endif

         if (li.lt.1.and.trun.eq.0) then
            xcnts(1) = xcnts(1) + 1
            ycnts(1) = ycnts(1) + y(i)
         endif      

         if (li.ge.M.and.trun.eq.0) then 
               xcnts(M) = xcnts(M) + 1
               ycnts(M) = ycnts(M) + y(i)
         endif

20    continue

      return
      end

cccccccccc End of rlbin.f cccccccccc
我已经成功地编译了Fortran代码并将其导入Python

在我键入的unixshell中

f2py -c -m rlbin rlbin.f
创建我导入Python的共享库rlbin.so:

导入rlbin
打印(rlbin.\uuuu doc\uuuu)
输出:

This module 'rlbin' is auto-generated with f2py (version:2).
Functions:
  rlbin(x,y,n,a,b,m,trun,xcnts,ycnts)
.
rlbin(x,y,n,a,b,m,trun,xcnts,ycnts)

Wrapper for ``rlbin``.

Parameters
----------
x : input rank-1 array('d') with bounds (*)
y : input rank-1 array('d') with bounds (*)
n : input int
a : input float
b : input float
m : input int
trun : input int
xcnts : input rank-1 array('d') with bounds (*)
ycnts : input rank-1 array('d') with bounds (*)
打印(rlbin.rlbin.\uuuuu文档)
输出:

This module 'rlbin' is auto-generated with f2py (version:2).
Functions:
  rlbin(x,y,n,a,b,m,trun,xcnts,ycnts)
.
rlbin(x,y,n,a,b,m,trun,xcnts,ycnts)

Wrapper for ``rlbin``.

Parameters
----------
x : input rank-1 array('d') with bounds (*)
y : input rank-1 array('d') with bounds (*)
n : input int
a : input float
b : input float
m : input int
trun : input int
xcnts : input rank-1 array('d') with bounds (*)
ycnts : input rank-1 array('d') with bounds (*)
我指定输入参数如下:

将numpy导入为np
#创建随机x和y阵列
x=np.ndarray(shape=(2000),dtype=float,order='F')
y=np.ndarray(shape=(2000),dtype=float,order='F')
n=len(x)
a=0.05
b=0.995
M=500
trun=1
xcents=np.零(M)
ycnts=np.零(M)
我检查了数据类型:a和b确实是浮点数;n、 M和trun是整数;x、 y、xcnst和YCNT是numpy阵列

并调用Fortran子程序

out=rlbin.rlbin(x,y,n,a,b,M,trun,xcnts,ycnts)
执行时不会出错。类似地,调用不会抛出错误,但也不会返回任何内容

type(out)
但是返回
NoneType
print(out)
返回
None

我在R中尝试了相同的过程(编译、导入、调用),它没有任何问题

对于感兴趣的人,相应的R调用将是(取自脚本第713-724行):


out您能否
import inspect
然后在python中
inspect.getsource(rlbin)
?嘿,Chillie,
inspect.getsource(rlbin)
抛出一个大约500个字符的错误。最后它说
OSError:sourcecode不可用
在python中,空的
return
语句从函数返回
None
。您的fortran代码似乎有一个返回语句,后面没有变量/值。这就是为什么自动生成的代码也不会返回任何结果吗?我使用我提到的教程的子例程运行了inspect.getsource(*)命令,它们抛出了相同的错误
OSError:source code not available
,但函数在Python中工作正常。fortran中的Soubroutines通常会修改(其中一些)他们的论点并没有返回任何东西。您能检查通话后
xcnts
ycnts
是否发生了变化吗?