f2py,返回数组的Python函数(向量值函数) [英] f2py, Python function that returns an array (vector-valued function)

查看:147
本文介绍了f2py,返回数组的Python函数(向量值函数)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的Python中,由func返回的数组中包含五个函数,我必须对其进行集成.该代码调用使用f2py生成的外部Fortran模块:

In the following Python I have five functions contained in the array returned by func which I have to integrate. The code calls an external Fortran module generated using f2py:

import numpy as np
from numpy import cos, sin , exp
from trapzdv import trapzdv
def func(x):
    return np.array([x**2, x**3, cos(x), sin(x), exp(x)])

if __name__ == '__main__':
    xs = np.linspace(0.,20.,100)
    ans =  trapzdv(func,xs,5)
    print 'from Fortran:', ans
    print 'exact:', np.array([20**3/3., 20**4/4., sin(20.), -cos(20.), exp(20.)])

Fortran例程是:

The Fortran routine is:

      subroutine trapzdv(f,xs,nf,nxs,result)
          integer :: I
          double precision :: x1,x2
          integer, intent(in) :: nf, nxs
          double precision, dimension(nf) :: fx1,fx2
          double precision, intent(in), dimension(nxs) :: xs
          double precision, intent(out), dimension(nf) :: result
          external :: f 
          result = 0.0
          do I = 2,nxs
            x1 = xs(I-1)
            x2 = xs(I)
            fx1 = f(x1)
            fx2 = f(x2)
            result = result + (fx1+fx2)*(x2-x1)/2
          enddo
          return
      end 

问题在于,Fortran仅在func(x)中集成了第一个功能. 查看打印结果:

The problem is that Fortran is only integrating the first function in func(x). See the print result:

from Fortran: [ 2666.80270721  2666.80270721  2666.80270721  2666.80270721  2666.80270721]
exact: [  2.66666667e+03   4.00000000e+04   9.12945251e-01  -4.08082062e-01 4.85165195e+08]

一种工作方式是修改func(x)以返回给定值 在函数数组中的位置:

One way to workarond that is to modify func(x) to return the value of a given position in the array of functions:

def func(x,i):
    return np.array([x**2, x**3, cos(x), sin(x), exp(x)])[i-1]

然后更改Fortran例程以使用两个参数来调用该函数:

And then change the Fortran routine to call the function with two parameters:

      subroutine trapzdv(f,xs,nf,nxs,result)
          integer :: I
          double precision :: x1,x2,fx1,fx2
          integer, intent(in) :: nf, nxs
          double precision, intent(in), dimension(nxs) :: xs
          double precision, intent(out), dimension(nf) :: result
          external :: f 
          result = 0.0
          do I = 2,nxs
            x1 = xs(I-1)
            x2 = xs(I)
            do J = 1,nf
                fx1 = f(x1,J)
                fx2 = f(x2,J)
                result(J) = result(J) + (fx1+fx2)*(x2-x1)/2
            enddo
          enddo
          return
      end 

哪个作品:

from Fortran: [  2.66680271e+03   4.00040812e+04   9.09838195e-01   5.89903440e-01 4.86814128e+08]
exact: [  2.66666667e+03   4.00000000e+04   9.12945251e-01  -4.08082062e-01 4.85165195e+08]

但是这里func的调用次数是必要次数的5倍(在实际情况下,func 具有300多个功能,因此将被调用300次以上.

But here func is called 5 times more than necessary (in the real case func has above 300 functions, so it will be called 300 times more than necessary).

  • 有人知道更好的解决方案以使Fortran识别func(x)返回的所有数组吗?换句话说,使Fortran将fx1 = f(x1)构建为具有5个与func(x)中的功能相对应的元素的数组.
  • Does anyone know a better solution to make Fortran recognizes all the array returned by func(x)? In other words, make Fortran build fx1 = f(x1) as an array with 5 elements corresponding to the functions in func(x).

OBS:我正在使用f2py -c --compiler=mingw32 -m trapzdv trapzdv.f90

OBS: I am compiling using f2py -c --compiler=mingw32 -m trapzdv trapzdv.f90

推荐答案

不幸的是,您无法将数组从python函数返回到Fortran中.为此,您将需要一个子例程(这意味着使用call语句调用它),而f2py不允许您这样做.

Unfortunately, you cannot return the array from the python function into Fortran. You would need a subroutine for that (meaning it is called with the call statement), and this is something that f2py does not let you do.

在Fortran 90中,您可以创建返回数组的函数,但这又不是f2py可以做的,尤其是因为您的函数不是Fortran函数.

In Fortran 90 you can create functions that return arrays, but again this is not something that f2py can do, especially since your function is not a Fortran function.

您唯一的选择是使用循环解决方法,或者重新设计您希望python和Fortran交互的方式.

Your only option is to use your looping workaround, or a redesign of how you want python and Fortran to interact.

这篇关于f2py,返回数组的Python函数(向量值函数)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆