Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将回调函数与f2py一起使用时出错_Python_Fortran_F2py - Fatal编程技术网

Python 将回调函数与f2py一起使用时出错

Python 将回调函数与f2py一起使用时出错,python,fortran,f2py,Python,Fortran,F2py,我试图将python函数传递给f2py生成的函数。当python函数的输入和输出是一个数组时,我不知道如何做到这一点。(我是f2py的新手!) 这是我的fortran代码(num_Dg.f): 我使用f2py编译:f2py-cnum_Dg.f-mnum_Dg。它编译时没有错误。但是,当将函数导入python时,我得到以下结果: >>> from num_Dg import num_dg >>> print(num_dg.__doc__) jacob = num

我试图将python函数传递给f2py生成的函数。当python函数的输入和输出是一个数组时,我不知道如何做到这一点。(我是f2py的新手!)

这是我的fortran代码(num_Dg.f):

我使用f2py编译:
f2py-cnum_Dg.f-mnum_Dg
。它编译时没有错误。但是,当将函数导入python时,我得到以下结果:

>>> from num_Dg import num_dg
>>> print(num_dg.__doc__)
jacob = num_dg(func,u,[n,func_extra_args])

Wrapper for ``num_dg``.

Parameters
----------
func : call-back function
u : input rank-1 array('d') with bounds (n)

Other Parameters
----------------
func_extra_args : input tuple, optional
    Default: ()
n : input int, optional
    Default: len(u)

Returns
-------
jacob : rank-2 array('d') with bounds (n,n)

Notes
-----
Call-back functions::

  def func(up,gvalp,[n]): return 
  Required arguments:
    up : input rank-1 array('d') with bounds (n)
    gvalp : input rank-1 array('d') with bounds (n)
  Optional arguments:
    n : input int, optional
    Default: len(up)
回调函数
func
有问题。输入应为数组
U
,输出应为
gval
。相反,
U
gval
都是输入,没有输出

我假设这就是以下python脚本返回垃圾的原因:

import num_Dg

def func(x):
    return [x[0]**2,x[1],x[2]]

val = [0.2,0.1,0.1]

num_Dg.num_dg(func,val)

如何更改fortran子例程,使回调函数正常工作?任何建议都将不胜感激!谢谢

我终于弄明白了。我认为它不起作用的原因是因为我缺少一行
cf2py intent(out),depend(n)::g_valp
。可以使用f2py以正常方式编译脚本:
f2py-c num_Dg.f-m num_Dg

      subroutine num_Dg(U,jacob,n)
cf2py   intent(callback) func
        external func
        integer n
        double precision :: U(n)
        double precision :: jacob(n,n)
        double precision Up(n), Um(n)
        double precision g_valp(n),g_valm(n)
        double precision :: rel_eps = 2.e-5
        double precision eps
        integer i, j

cf2py   intent(in,copy), depend(n) :: U
cf2py   intent(hide) :: n
cf2py   intent(out), depend(n) :: jacob
cf2py   intent(out), depend(n) :: g_valp

        eps = minval(U)*rel_eps
        do j=1,n
          do i=1,n
            if (i .eq. j) then
            Up(i) = U(i)+(eps)
            Um(i) = U(i)-(eps)
            else
            Up(i) = 0
            Um(i) = 0
            endif
          enddo

          call func(n,Up,g_valp)
          call func(n,Um,g_valm)

          do i=1,n
            jacob(i,j) = (g_valp(i)-g_valm(i))/(2*eps)

          enddo

        enddo
      end subroutine

我终于弄明白了。我认为它不起作用的原因是因为我缺少一行
cf2py intent(out),depend(n)::g_valp
。可以使用f2py以正常方式编译脚本:
f2py-c num_Dg.f-m num_Dg

      subroutine num_Dg(U,jacob,n)
cf2py   intent(callback) func
        external func
        integer n
        double precision :: U(n)
        double precision :: jacob(n,n)
        double precision Up(n), Um(n)
        double precision g_valp(n),g_valm(n)
        double precision :: rel_eps = 2.e-5
        double precision eps
        integer i, j

cf2py   intent(in,copy), depend(n) :: U
cf2py   intent(hide) :: n
cf2py   intent(out), depend(n) :: jacob
cf2py   intent(out), depend(n) :: g_valp

        eps = minval(U)*rel_eps
        do j=1,n
          do i=1,n
            if (i .eq. j) then
            Up(i) = U(i)+(eps)
            Um(i) = U(i)-(eps)
            else
            Up(i) = 0
            Um(i) = 0
            endif
          enddo

          call func(n,Up,g_valp)
          call func(n,Um,g_valm)

          do i=1,n
            jacob(i,j) = (g_valp(i)-g_valm(i))/(2*eps)

          enddo

        enddo
      end subroutine

欢迎光临,我建议您坐飞机。是否尝试为函数编写接口块?当它是外部的时,函数签名实际上并没有精确定义。F2py可能试图以某种方式从调用中推断。您在对
func
的两个调用中都使用
Up
,而看起来您应该依次使用
Up
Um
。另外,为什么不调用
func
作为
gvalp=func(Up)
?或者在参数中包含
n
?声明为外部的函数对其语法的检查为零,这可能是有限的。谢谢!你说得对<在
func
的第二次调用中,code>Up应替换为
Um
。我更改了代码,以便
g_valp=func(Up,n)
,其中n是
Up
的维度。现在,当我执行
打印(num_dg.\uu doc_uuu)
时,我得到了一个看起来合理的回调函数格式。但是,当我从python调用程序时,仍然没有得到好的结果。从fortran程序中使用print语句来看,原因似乎是对func的调用工作不正常@VladimirF,我使用f2py为函数生成接口块。欢迎使用,我建议使用。是否尝试为函数编写接口块?当它是外部的时,函数签名实际上并没有精确定义。F2py可能试图以某种方式从调用中推断。您在对
func
的两个调用中都使用
Up
,而看起来您应该依次使用
Up
Um
。另外,为什么不调用
func
作为
gvalp=func(Up)
?或者在参数中包含
n
?声明为外部的函数对其语法的检查为零,这可能是有限的。谢谢!你说得对<在
func
的第二次调用中,code>Up应替换为
Um
。我更改了代码,以便
g_valp=func(Up,n)
,其中n是
Up
的维度。现在,当我执行
打印(num_dg.\uu doc_uuu)
时,我得到了一个看起来合理的回调函数格式。但是,当我从python调用程序时,仍然没有得到好的结果。从fortran程序中使用print语句来看,原因似乎是对func的调用工作不正常@VladimirF,我使用f2py为函数生成接口块。