如何用SymPy代码生成Fortran子程序



我想用SymPy编码实用程序生成Fortran子程序。我可以用codegen(("f", x*y*z), "f95", "filename")生成一个Fortran函数,没有问题。但是我想生成一个Fortran子程序这样我就可以修改输入数组了。我该怎么做呢?

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

查看autorap文档中的矩阵向量示例:http://docs.sympy.org/latest/modules/utilities/autowrap.html。Autowrap在幕后使用代码。

在当前的开发者版本中,还提供了生成与具有符号元素的矩阵对应的代码的功能。fcode()的示例见http://docs.sympy.org/dev/modules/printing.html#fortran-printing。

下面的示例代码应该输出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

最新更新