How to generate Fortran subroutine with SymPy codegen

血红的双手。 提交于 2019-12-06 08:35:16

问题


I want to generate a Fortran subroutine with SymPy codegen utility. I can generate a Fortran function without problem with codegen(("f", x*y*z), "f95", "filename"). But I want to generate a Fortran subroutine so I can modify input arrays. How can I do this? The documentation is very poor.


回答1:


The codegen utility creates a function if there is a single scalar return value, and a subroutine otherwise. There is some support for arrays, but the array functionality won't be triggered unless you feed codegen an array like expression. The documentation is scattered, so I'll give you some pointers:

Take a look at the matrix-vector example in the autowrap documentation: http://docs.sympy.org/latest/modules/utilities/autowrap.html. Autowrap uses codegen behind the scenes.

In the current developer version there is also functionality for generating code that correspond to matrices with symbolic elements. See the examples for fcode() at http://docs.sympy.org/dev/modules/printing.html#fortran-printing.

Here is sample code that should output a Fortran 95 subroutine for a matrix-vector product:

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]

By saving these lines to my_file.py and running python my_file.py, I get the following output:

!******************************************************************************
!*                    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


来源:https://stackoverflow.com/questions/25327845/how-to-generate-fortran-subroutine-with-sympy-codegen

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!