【问题标题】:How to generate Fortran subroutine with SymPy codegen如何使用 SymPy codegen 生成 Fortran 子例程
【发布时间】:2014-10-09 06:33:37
【问题描述】:

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

【问题讨论】:

    标签: sympy codegen


    【解决方案1】:

    如果有单个标量返回值,则 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
    

    【讨论】:

    • 我正在查看您的第二个链接,但我无法将标准设置为 Fortran 95。当我写 fcode(x, standard=95) 时,它会显示 TypeError: Unknown setting 'standard'。你知道有什么问题吗?我正在使用 python 2.7 和 SymPy 0.7.5
    • 看来 'standard' 参数必须是最近添加的,并且可能在 0.7.6 中可用。要获得更现代的代码格式,您可以使用fcode(x, source_format='free')
    • 抱歉,我就是无法让它工作。您能否给我展示一个使用 python codegen 生成 Fortran 子例程的具体示例?我的目标是生成可编译的 Fortran 代码。我是 python 新手,我正在使用 sympy 来促进编写长数学表达式的工作。
    • 顺便说一句,我最近从 git repo 更新了我的 sympy,现在 fcode(x, standard=95) 可以工作了。它缺少文档中显示的许多功能。
    • 第二个链接指向当前正在开发的版本的文档。
    猜你喜欢
    • 2016-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-25
    • 2021-04-23
    • 1970-01-01
    • 1970-01-01
    • 2016-06-02
    相关资源
    最近更新 更多