如何使用SymPy codegen生成Fortran子例程

时间:2014-08-15 14:02:14

标签: sympy codegen

我想使用SymPy codegen实用程序生成Fortran子例程。我可以codegen(("f", x*y*z), "f95", "filename")生成一个没有问题的Fortran函数。但我想生成一个Fortran子例程,以便我可以修改输入数组。我怎样才能做到这一点?文档很差。

1 个答案:

答案 0 :(得分:4)

如果存在单个标量返回值,则codegen实用程序会创建一个函数,否则会创建一个子例程。对数组有一些支持,但除非你为codegen提供类似表达式的数组,否则不会触发数组功能。文档是分散的,所以我会给你一些指示:

查看autowrap文档中的matrix-vector示例:http://docs.sympy.org/latest/modules/utilities/autowrap.html。 Autowrap在幕后使用codegen。

在当前的开发人员版本中,还有用于生成与具有符号元素的矩阵相对应的代码的功能。请参阅http://docs.sympy.org/dev/modules/printing.html#fortran-printing上的fcode()示例。

以下是应输出矩阵向量积的Fortran 95子例程的示例代码:

from sympy import *
from sympy.utilities.codegen import codegen
A, B, C = symbols('A B C', cls=IndexedBase)
m, n = symbols('m n', integer=True)
i = Idx('i', m)
j = Idx('j', n)
expr = Eq(C[i], A[i, j]*B[j])
result = codegen(('my_function', expr), 'f95', 'my_project')
print result[0][1]

通过将这些行保存到my_file.py并运行python my_file.py,我得到以下输出:

!******************************************************************************
!*                    Code generated with sympy 0.7.5-git                     *
!*                                                                            *
!*              See http://www.sympy.org/ for more information.               *
!*                                                                            *
!*                       This file is part of 'project'                       *
!******************************************************************************

subroutine my_function(A, B, m, n, C)
implicit none
INTEGER*4, intent(in) :: m
INTEGER*4, intent(in) :: n
REAL*8, intent(in), dimension(1:m, 1:n) :: A
REAL*8, intent(in), dimension(1:n) :: B
REAL*8, intent(out), dimension(1:m) :: C
INTEGER*4 :: i
INTEGER*4 :: j

do i = 1, m
   C(i) = 0
end do
do i = 1, m
   do j = 1, n
      C(i) = B(j)*A(i, j) + C(i)
   end do
end do

end subroutine