3

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

4

1 回答 1

6

如果有单个标量返回值,则 codegen 实用程序创建一个函数,否则创建一个子例程。对数组有一些支持,但是除非您向 codegen 提供类似表达式的数组,否则不会触发数组功能。文档比较分散,给大家指点一下:

查看自动包装文档中的矩阵向​​量示例: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
于 2014-08-27T19:09:59.083 回答