如何使外部功能与F2PY一起使用?

发布于 2025-02-01 16:51:14 字数 1192 浏览 3 评论 0原文

我试图用f2py编译一块旧的Fortran代码,以便可以在Python中调用。 但是,具有外部功能的零件是行不通的。 这是MWE,首先我有test.f

      function f(x)
      implicit double precision (a-z)

      f = x * x

      return
      end function f

      subroutine gauss(fun)
      implicit double precision (a-h, j-z)
      ! external fun

      x = 1.5
      write(*,*) fun(x)

      return
      end subroutine gauss

后来用makefile

f2py -c --quiet --fcompiler=gnu95 \
        --f90flags=“-Wtabs” \
        -m test \
        test.f

最后是从python调用的:

import test
f = lambda x: x
test.gauss(test.f)

给出错误typeerror: test.gauss()1st参数(fun)不能转换为double

second 尝试中,我在subroutine gauss中删除行外部有趣,并在编译过程中获取以下错误消息:

/tmp/tmpet9sk3e9/src.linux-x86_64-3.7/testmodule.c: In function ‘cb_fun_in_gauss__user__routines’:
/tmp/tmpet9sk3e9/src.linux-x86_64-3.7/testmodule.c:313:8: error: variable or field ‘return_value’ declared void

我用完了想法,任何帮助将不胜感激!

I am trying to compile a piece of old Fortran code with f2py so that it can be called within Python.
However, the part with external function wouldn’t work.
Here is an MWE, first I have the test.f:

      function f(x)
      implicit double precision (a-z)

      f = x * x

      return
      end function f

      subroutine gauss(fun)
      implicit double precision (a-h, j-z)
      ! external fun

      x = 1.5
      write(*,*) fun(x)

      return
      end subroutine gauss

which is later compiled with makefile:

f2py -c --quiet --fcompiler=gnu95 \
        --f90flags=“-Wtabs” \
        -m test \
        test.f

Lastly it is called from Python:

import test
f = lambda x: x
test.gauss(test.f)

and gives the error TypeError: test.gauss() 1st argument (fun) can’t be converted to double.

In a second attempt, I uncomment the line external fun in the subroutine gauss and get the following error message during compilation:

/tmp/tmpet9sk3e9/src.linux-x86_64-3.7/testmodule.c: In function ‘cb_fun_in_gauss__user__routines’:
/tmp/tmpet9sk3e9/src.linux-x86_64-3.7/testmodule.c:313:8: error: variable or field ‘return_value’ declared void

I am running out of ideas, any help will be greatly appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

丑疤怪 2025-02-08 16:51:14

我(部分)弄清楚了:f2py需要您明确指定功能的使用。
以下是:

      function f(x)
      implicit double precision (a-z)

      f = x * x

      return
      end function f

      subroutine gauss(fun)
      implicit double precision (a-h, j-z)
      !! <-------- updates starts HERE
      external fun
!f2py real*8 y
!f2py y = fun(y)
      double precision fun
      !! <-------- updates ends HERE

      x = 1.5
      write(*,*) fun(x)

      return
      end subroutine gauss

进行编译

main:
    f2py -c --quiet --fcompiler=gnu95 \
        --f90flags=“-Wtabs” \
        -m test \
        test.f

然后使用您可以测试

import test
f = lambda x: x
test.gauss(test.f)
test.gauss(f)

,并看到外部功能适用于Fortran和Python函数。


两个旁注:

  1. 尽管文档> )有趣的是必要的,我发现代码可以在没有它的情况下工作。
  2. 您可以使用相同的语法指定多个外部函数,甚至可以为所有这些语法使用相同的虚拟输入变量y为所有这些变量(虽然不是一个好练习)。

I have (partly) figured it out: f2py needs you to explicitly specify the use of the function.
Here is how:

      function f(x)
      implicit double precision (a-z)

      f = x * x

      return
      end function f

      subroutine gauss(fun)
      implicit double precision (a-h, j-z)
      !! <-------- updates starts HERE
      external fun
!f2py real*8 y
!f2py y = fun(y)
      double precision fun
      !! <-------- updates ends HERE

      x = 1.5
      write(*,*) fun(x)

      return
      end subroutine gauss

then compile it using

main:
    f2py -c --quiet --fcompiler=gnu95 \
        --f90flags=“-Wtabs” \
        -m test \
        test.f

You can test with

import test
f = lambda x: x
test.gauss(test.f)
test.gauss(f)

and see that the external function works for both Fortran and Python functions.


Two side notes:

  1. Although the documentation says !f2py intent(callback) fun is necessary, I find the code can work without it.
  2. You can specify multiple external functions using the same syntax, you can even use the same dummy input variable y for all of them (maybe not a good practice though).
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文