在IPython笔记本中使用fortranmagic排序数组:无返回值

2024-06-28 15:31:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我不得不说我根本不是Fortran程序员。我通常只使用Python和C++,但有时同事编写了很棒的FORTRAN函数,这将极大地实现我的Python代码的效率。我正要通过IPython的魔法函数来尝试f2py模块。在

对于一个简单的测试,我有下面的bubblesort实现,我想对Python列表进行适当的排序(我将其转换为以Fortran样式在内存中布局的numpy数组;我假设这将比使用Python列表更有效,对吗?)在

但是,函数在这里没有返回值(None),我想知道我的错误在哪里!?在

安装和加载使用f2py的fortranmagic的命令

%install_ext https://raw.github.com/mgaitan/fortran_magic/master/fortranmagic.py
%load_ext fortranmagic

Fortran bubblesort代码:

^{pr2}$

执行:

x = np.asfortranarray([3,2,1])
y = fortran_bubblesort(x)
print(x, y)

结果是:

[3 2 1] None

=======

为了测试一般情况下是否可以返回值,我运行了以下代码,该代码工作正常:

%%fortran
SUBROUTINE fortran_sum(x, y, z)
    REAL, INTENT(in) :: x,y
    REAL, INTENT(out) :: z

    z = x + y

END SUBROUTINE fortran_sum

执行:

fortran_sum(3, 4)

退货:

7.0

Tags: 函数代码none列表realextsumfortran
2条回答

你面临的问题与数组维数有关。看起来该子例程是从模块中取出的,因为它使用了一个假定形状的伪数组a。这需要一个显式接口,我不知道f2py是否和/或如何处理它。我只使用过假设大小的伪数组f2py,它处理得很好。代码如下:

SUBROUTINE fortran_bubblesort(a,n)
  INTEGER, INTENT(in) :: n
  REAL, INTENT(in out), DIMENSION(n) :: a
  REAL :: temp
  INTEGER :: i, j
  LOGICAL :: swapped = .TRUE.

  DO j = SIZE(a)-1, 1, -1
    swapped = .FALSE.
    DO i = 1, j
      IF (a(i) > a(i+1)) THEN
        temp = a(i)
        a(i) = a(i+1)
        a(i+1) = temp
        swapped = .TRUE.
      END IF
    END DO
    IF (.NOT. swapped) EXIT
  END DO
END SUBROUTINE fortran_bubblesort

在本例中,f2py将注意到n只是数组维,它将使其成为python函数中的可选参数。在

我用Fortran语言编写了这个问题的原始代码,将“REAL”语句替换为“REAL(kind=8)”语句。这样,Fortran的变量与Python的变量匹配。
此外,为了使执行正常工作并避免“None”输出,我建议以下几行(注意,我已经通过浮点数据更改了整数输入,以获得正确的匹配):

import numpy as np
x = np.asfortranarray([3.,0., 2.,1.])
print(x)
fortran_bubblesort(x)
print(x)

执行:

[ 3. 0. 2. 1.]
[ 0. 1. 2. 3.]

请注意,我还添加了数字0以使其更具Python味;-)

相关问题 更多 >