代码生成#

SymPy中的几个子模块允许从SymPy表达式中直接用各种不同的编程语言生成可编译和可执行的代码。此外,还有一些函数可以生成Python可导入对象,这些对象可以非常高效地计算SymPy表达式。

我们将首先简要介绍组成SymPy代码生成功能的组件。

介绍#

抽象有四个主要层次:

expression
   |
code printers
   |
code generators
   |
autowrap

sympy.utilities.autowrap 使用codegen,而codegen使用代码打印机。 sympy.utilities.autowrap 做所有事情:它让您在同一个Python进程中一步从SymPy表达式转到数值函数。Codegen是实际的代码生成,即以后编译和使用,或者包含在某个更大的项目中。

代码打印机将SymPy对象转换成实际的代码,比如 abs(x) -> fabs(x) (代表C)。

代码打印机在很多情况下不会打印出最佳的代码。一个例子是C语言中的powers。 x**2 打印为 pow(x, 2) 而不是 x*x . 其他优化(如数学简化)应该在代码打印机之前进行。

目前, sympy.simplify.cse_main.cse() 不会自动应用于此链中的任何位置。理想情况下,它发生在codegen级别,或者高于它的某个地方。

我们将迭代以下级别。

以下三行将用于设置每个示例:

>>> from sympy import *
>>> init_printing(use_unicode=True)
>>> from sympy.abc import a, e, k, n, r, t, x, y, z, T, Z
>>> from sympy.abc import beta, omega, tau
>>> f, g = symbols('f, g', cls=Function)

代码打印机(sympy.印刷)#

This is where the meat of code generation is; the translation of SymPy actually more like a lightweight version of codegen for Python, and Python (sympy.printing.pycode.pycode()), and sympy.printing.lambdarepr.lambdarepr(), which supports many libraries (like NumPy), and Aesara (sympy.printing.aesaracode.aesara_function()). The code printers are special cases of the other prints in SymPy (str printer, pretty printer, etc.).

一个重要的区别是代码打印机必须处理赋值(使用 sympy.codegen.ast.Assignment 对象)。这是代码打印机的构建块,因此 codegen 模块。一个示例显示了 Assignment C代码:

>>> from sympy.codegen.ast import Assignment
>>> print(ccode(Assignment(x, y + 1)))
x = y + 1;

下面是另一个简单的示例,用于打印SymPy表达式的C版本:

>>> expr = (Rational(-1, 2) * Z * k * (e**2) / r)
>>> expr
    2
-Z⋅e ⋅k
────────
  2⋅r
>>> ccode(expr)
-1.0/2.0*Z*pow(e, 2)*k/r
>>> from sympy.codegen.ast import real, float80
>>> ccode(expr, assign_to="E", type_aliases={real: float80})
E = -1.0L/2.0L*Z*powl(e, 2)*k/r;

要使用C99标准提供的一些数学函数生成代码,我们需要从中导入函数 sympy.codegen.cfunctions ::

>>> from sympy.codegen.cfunctions import expm1
>>> ccode(expm1(x), standard='C99')
expm1(x)

Piecewise 表达式被转换成条件句。如果 assign_to 变量提供一个if语句,否则使用三元运算符。注意如果 Piecewise 缺少默认术语,表示为 (expr, True) 然后抛出一个错误。这是为了防止生成一个可能无法计算任何结果的表达式。的一个用例 Piecewise ::

>>> expr = Piecewise((x + 1, x > 0), (x, True))
>>> print(fcode(expr, tau))
      if (x > 0) then
         tau = x + 1
      else
         tau = x
      end if

各种打印机也倾向于支持 Indexed 对象很好。与 contract=True 这些表达式将变成循环,而 contract=False 将只打印应该循环的赋值表达式::

>>> len_y = 5
>>> mat_1 = IndexedBase('mat_1', shape=(len_y,))
>>> mat_2 = IndexedBase('mat_2', shape=(len_y,))
>>> Dy = IndexedBase('Dy', shape=(len_y-1,))
>>> i = Idx('i', len_y-1)
>>> eq = Eq(Dy[i], (mat_1[i+1] - mat_1[i]) / (mat_2[i+1] - mat_2[i]))
>>> print(jscode(eq.rhs, assign_to=eq.lhs, contract=False))
Dy[i] = (mat_1[i + 1] - mat_1[i])/(mat_2[i + 1] - mat_2[i]);
>>> Res = IndexedBase('Res', shape=(len_y,))
>>> j = Idx('j', len_y)
>>> eq = Eq(Res[j], mat_1[j]*mat_2[j])
>>> print(jscode(eq.rhs, assign_to=eq.lhs, contract=True))
for (var j=0; j<5; j++){
   Res[j] = 0;
}
for (var j=0; j<5; j++){
   for (var j=0; j<5; j++){
      Res[j] = Res[j] + mat_1[j]*mat_2[j];
   }
}
>>> print(jscode(eq.rhs, assign_to=eq.lhs, contract=False))
Res[j] = mat_1[j]*mat_2[j];

通过将“type”:“function”字典传递给 user_functions 夸克。或者,字典值可以是元组的列表,即。, [(argument_test, cfunction_string)] . 这可用于调用自定义倍频程函数:

>>> custom_functions = {
...   "f": "existing_octave_fcn",
...   "g": [(lambda x: x.is_Matrix, "my_mat_fcn"),
...         (lambda x: not x.is_Matrix, "my_fcn")]
... }
>>> mat = Matrix([[1, x]])
>>> octave_code(f(x) + g(x) + g(mat), user_functions=custom_functions)
existing_octave_fcn(x) + my_fcn(x) + my_mat_fcn([1 x])

Mathematica代码打印机示例:

>>> x_ = Function('x')
>>> expr = x_(n*T) * sin((t - n*T) / T)
>>> expr = expr / ((-T*n + t) / T)
>>> expr
            ⎛-T⋅n + t⎞
T⋅x(T⋅n)⋅sin⎜────────⎟
            ⎝   T    ⎠
──────────────────────
       -T⋅n + t

>>> expr = summation(expr, (n, -1, 1))
>>> mathematica_code(expr)
T*(x[-T]*Sin[(T + t)/T]/(T + t) + x[T]*Sin[(-T + t)/T]/(-T + t) + x[0]*Sin[t/T ↪

↪ ]/t)

我们可以使用我们支持的不同语言查看一个通用表达式,看看它是如何工作的:

>>> k, g1, g2, r, I, S = symbols("k, gamma_1, gamma_2, r, I, S")
>>> expr = k * g1 * g2 / (r**3)
>>> expr = expr * 2 * I * S * (3 * (cos(beta))**2 - 1) / 2
>>> expr
            ⎛     2       ⎞
I⋅S⋅γ₁⋅γ₂⋅k⋅⎝3⋅cos (β) - 1⎠
───────────────────────────
              3
             r
>>> print(jscode(expr, assign_to="H_is"))
H_is = I*S*gamma_1*gamma_2*k*(3*Math.pow(Math.cos(beta), 2) - 1)/Math.pow(r, 3);
>>> print(ccode(expr, assign_to="H_is", standard='C89'))
H_is = I*S*gamma_1*gamma_2*k*(3*pow(cos(beta), 2) - 1)/pow(r, 3);
>>> print(fcode(expr, assign_to="H_is"))
      H_is = I*S*gamma_1*gamma_2*k*(3*cos(beta)**2 - 1)/r**3
>>> print(julia_code(expr, assign_to="H_is"))
H_is = I .* S .* gamma_1 .* gamma_2 .* k .* (3 * cos(beta) .^ 2 - 1) ./ r .^ 3
>>> print(octave_code(expr, assign_to="H_is"))
H_is = I.*S.*gamma_1.*gamma_2.*k.*(3*cos(beta).^2 - 1)./r.^3;
>>> print(rust_code(expr, assign_to="H_is"))
H_is = I*S*gamma_1*gamma_2*k*(3*beta.cos().powi(2) - 1)/r.powi(3);
>>> print(mathematica_code(expr))
I*S*gamma_1*gamma_2*k*(3*Cos[beta]^2 - 1)/r^3

代码生成(sympy.utilities.codegen)#

本模块处理如何从SymPy表达式创建可编译代码。这比autowrap级别低,因为它实际上并不试图编译代码,而是比打印机级别高,因为它生成可编译的文件(包括头文件),而不仅仅是代码片段。

这里的用户友好功能是 codegenmake_routine . codegen 列出一个 (variable, expression) pairs和a语言(支持C、F95和Octave/Matlab)。它以字符串的形式返回代码文件和头文件(对于相关语言)。变量作为函数创建,这些函数将表达式的值作为输出返回。

备注

这个 codegen 首先不能自动导入它 codegensympy.utilities.codegen

例如::

>>> from sympy.utilities.codegen import codegen
>>> length, breadth, height = symbols('length, breadth, height')
>>> [(c_name, c_code), (h_name, c_header)] = \
... codegen(('volume', length*breadth*height), "C99", "test",
...         header=False, empty=False)
>>> print(c_name)
test.c
>>> print(c_code)
#include "test.h"
#include <math.h>
double volume(double breadth, double height, double length) {
   double volume_result;
   volume_result = breadth*height*length;
   return volume_result;
}
>>> print(h_name)
test.h
>>> print(c_header)
#ifndef PROJECT__TEST__H
#define PROJECT__TEST__H
double volume(double breadth, double height, double length);
#endif

各种旗帜 codegen 让你修改东西。预处理器指令的项目名称可以使用 project . 在arg中列为全局变量的变量 global_vars 不会显示为函数参数。

language 指示源代码语言的不区分大小写的字符串。目前, CF95Octave 支持。 Octave 生成与倍频程和Matlab兼容的代码。

header 如果为True,则在每个源文件的顶部写入头。 empty 如果为True,则使用空行来构造代码。与 argument_sequence 可以按优先顺序定义例程的参数序列。

prefix 定义包含源代码的文件名的前缀。如果省略,则使用第一个名称表达式元组的名称。

to_files 如果为True,则代码将写入一个或多个具有给定前缀的文件。

下面是一个例子:

>>> [(f_name, f_code), header] = codegen(("volume", length*breadth*height),
...     "F95", header=False, empty=False, argument_sequence=(breadth, length),
...     global_vars=(height,))
>>> print(f_code)
REAL*8 function volume(breadth, length)
implicit none
REAL*8, intent(in) :: breadth
REAL*8, intent(in) :: length
volume = breadth*height*length
end function

方法 make_routine 创建一个 Routine 对象,它表示一组表达式的求值例程。这只适用于CodeGen对象的内部使用,作为从SymPy表达式到生成代码的中间表示。不建议 Routine 反对你自己。你应该改用 make_routine 方法。 make_routine 反过来调用 routine 方法,具体取决于所选语言。这将创建表示赋值等的内部对象,并创建 Routine 和他们一起上课。

各种codegen对象,例如 RoutineVariable 不是SymPy对象(它们不是Basic的子类)。

例如::

>>> from sympy.utilities.codegen import make_routine
>>> from sympy.physics.hydrogen import R_nl
>>> expr = R_nl(3, y, x, 6)
>>> routine = make_routine('my_routine', expr)
>>> [arg.result_var for arg in routine.results]   
[result₅₁₄₂₃₄₁₆₈₁₃₉₇₇₁₉₄₂₈]
>>> [arg.expr for arg in routine.results]
⎡                __________                                          ⎤
⎢          y    ╱ (2 - y)!   -2⋅x                                    ⎥
⎢4⋅√6⋅(4⋅x) ⋅  ╱  ──────── ⋅ℯ    ⋅assoc_laguerre(2 - y, 2⋅y + 1, 4⋅x)⎥
⎢            ╲╱   (y + 3)!                                           ⎥
⎢────────────────────────────────────────────────────────────────────⎥
⎣                                 3                                  ⎦
>>> [arg.name for arg in routine.arguments]
[x, y]

另一个更复杂的例子,它混合了指定的和自动指定的名称。也有矩阵输出:

>>> routine = make_routine('fcn', [x*y, Eq(a, 1), Eq(r, x + r), Matrix([[x, 2]])])
>>> [arg.result_var for arg in routine.results]   
[result_5397460570204848505]
>>> [arg.expr for arg in routine.results]
[x⋅y]
>>> [arg.name for arg in routine.arguments]   
[x, y, a, r, out_8598435338387848786]

我们可以更仔细地研究各种论点:

>>> from sympy.utilities.codegen import (InputArgument, OutputArgument,
...                                      InOutArgument)
>>> [a.name for a in routine.arguments if isinstance(a, InputArgument)]
[x, y]

>>> [a.name for a in routine.arguments if isinstance(a, OutputArgument)]  
[a, out_8598435338387848786]
>>> [a.expr for a in routine.arguments if isinstance(a, OutputArgument)]
[1, [x  2]]

>>> [a.name for a in routine.arguments if isinstance(a, InOutArgument)]
[r]
>>> [a.expr for a in routine.arguments if isinstance(a, InOutArgument)]
[r + x]

可以查看完整的API引用 here .

自动换行#

自动换行自动生成代码、将其写入磁盘、编译并将其导入当前会话。该模块的主要功能是 autowrapbinary_functionufuncify .

它还自动转换包含 Indexed 对象合并为求和。IndexedBase、Indexed和Idx类表示矩阵元素M [i, j] . 见 张量 更多信息。

autowrap 使用f2py或Cython创建包装器并创建一个数值函数。

备注

这个 autowrap 首先不能自动导入它 autowrapsympy.utilities.autowrap

从autowrap()返回的可调用函数是一个二进制Python函数,而不是SymPy对象。例如::

>>> from sympy.utilities.autowrap import autowrap
>>> expr = ((x - y + z)**(13)).expand()
>>> binary_func = autowrap(expr)    
>>> binary_func(1, 4, 2)    
-1.0

autowrap()提供的各种标志有助于修改该方法提供的服务。争论 tempdir 告诉autowrap在特定目录中编译代码,完成后保持文件不变。例如::

>>> from sympy.utilities.autowrap import autowrap
>>> from sympy.physics.qho_1d import psi_n
>>> x_ = IndexedBase('x')
>>> y_ = IndexedBase('y')
>>> m = symbols('m', integer=True)
>>> i = Idx('i', m)
>>> qho = autowrap(Eq(y_[i], psi_n(0, x_[i], m, omega)), tempdir='/tmp')  

检查指定目录中的Fortran源代码可以发现:

subroutine autofunc(m, omega, x, y)
implicit none
INTEGER*4, intent(in) :: m
REAL*8, intent(in) :: omega
REAL*8, intent(in), dimension(1:m) :: x
REAL*8, intent(out), dimension(1:m) :: y
INTEGER*4 :: i

REAL*8, parameter :: hbar = 1.05457162d-34
REAL*8, parameter :: pi = 3.14159265358979d0
do i = 1, m
   y(i) = (m*omega)**(1.0d0/4.0d0)*exp(-4.74126166983329d+33*m*omega*x(i &
         )**2)/(hbar**(1.0d0/4.0d0)*pi**(1.0d0/4.0d0))
end do

end subroutine

使用参数 args 同时改变参数序列:

>>> eq = Eq(y_[i], psi_n(0, x_[i], m, omega))
>>> qho = autowrap(eq, tempdir='/tmp', args=[y, x, m, omega])  

产量::

subroutine autofunc(y, x, m, omega)
implicit none
INTEGER*4, intent(in) :: m
REAL*8, intent(in) :: omega
REAL*8, intent(out), dimension(1:m) :: y
REAL*8, intent(in), dimension(1:m) :: x
INTEGER*4 :: i

REAL*8, parameter :: hbar = 1.05457162d-34
REAL*8, parameter :: pi = 3.14159265358979d0
do i = 1, m
   y(i) = (m*omega)**(1.0d0/4.0d0)*exp(-4.74126166983329d+33*m*omega*x(i &
         )**2)/(hbar**(1.0d0/4.0d0)*pi**(1.0d0/4.0d0))
end do

end subroutine

争论 verbose 为布尔值,可选,如果为True,则自动换行不会使命令行后端静音。这有助于调试。

争论 languagebackend 用于更改默认值: Fortranf2pyCCython . 参数助手用于定义主表达式所需的辅助表达式。如果主表达式需要调用专用函数,则应将其放在 helpers 很好。Autowrap将确保编译后的主表达式可以链接到helper例程。项应该是元组 (<function_name>, <sympy_expression>, <arguments>) . 必须向helper例程提供参数序列。

Another method available at the autowrap level is binary_function. It returns a sympy function. The advantage is that we can have very fast functions as compared to SymPy speeds. This is because we will be using compiled functions with SymPy attributes and methods. An illustration:

>>> from sympy.utilities.autowrap import binary_function
>>> from sympy.physics.hydrogen import R_nl
>>> psi_nl = R_nl(1, 0, a, r)
>>> f = binary_function('f', psi_nl)    
>>> f(a, r).evalf(3, subs={a: 1, r: 2})  
0.766

虽然NumPy操作对于矢量化数据非常有效,但是当它们链接在一起时,它们有时会产生不必要的成本。考虑以下操作

>>> x = get_numpy_array(...) 
>>> y = sin(x) / x

运营商 sin and / call routines that execute tight for loops in `` C```。得到的计算结果如下所示

for(int i = 0; i < n; i++)
{
    temp[i] = sin(x[i]);
}
for(int i = i; i < n; i++)
{
    y[i] = temp[i] / x[i];
}

这是稍微次优的,因为

  1. 我们分配了一个额外的 temp 数组

  2. 我们走过去 x 记忆两次,一次就足够了

更好的解决方案是将两个元素操作合并到一个for循环中

for(int i = i; i < n; i++)
{
    y[i] = sin(x[i]) / x[i];
}

像MPY这样的静态优化是无法利用的。幸运的是,SymPy能够生成高效的低级C或Fortran代码。然后它可以依赖于像 Cythonf2py 将代码编译并重新连接到Python。幸运的是,这个过程自动化程度很高,希望使用此代码生成的SymPy用户应该调用 ufuncify 功能。

ufuncify is the third method available with Autowrap module. It basically implies 'Universal functions' and follows an ideology set by NumPy. The main point of ufuncify as compared to autowrap is that it allows arrays as arguments and can operate in an element-by-element fashion. The core operation done element-wise is in accordance to Numpy's array broadcasting rules. See this for more.

>>> from sympy import *
>>> from sympy.abc import x
>>> expr = sin(x)/x
>>> from sympy.utilities.autowrap import ufuncify
>>> f = ufuncify([x], expr) 

这个函数 f 使用并返回NumPy数组。一般情况下 ufuncify 表现至少和 lambdify . 如果表达式很复杂 ufuncify 通常显著优于NumPy支持的解决方案。詹森有一个好的 blog post 关于这个话题。

让我们看一个定量分析的例子:

>>> from sympy.physics.hydrogen import R_nl
>>> expr = R_nl(3, 1, x, 6)
>>> expr
               -2⋅x
8⋅x⋅(4 - 4⋅x)⋅ℯ
───────────────────
         3

lambdify函数利用各种数值库将SymPy表达式转换为Python函数。默认情况下,lambdify依赖于 math 标准库。自然,原始Python比SymPy快。但是它也支持 mpmath 最值得注意的是, numpy . 通过使用NumPy库,生成的函数可以访问由编译的C代码支持的强大的矢量化ufunc。

让我们比较一下速度:

>>> from sympy.utilities.autowrap import ufuncify
>>> from sympy.utilities.lambdify import lambdify
>>> fn_numpy = lambdify(x, expr, 'numpy')   
>>> fn_fortran = ufuncify([x], expr, backend='f2py')    
>>> from numpy import linspace  
>>> xx = linspace(0, 1, 5)  
>>> fn_numpy(xx)    
[ 0.          1.21306132  0.98101184  0.44626032  0.        ]
>>> fn_fortran(xx)  
[ 0.          1.21306132  0.98101184  0.44626032  0.        ]
>>> import timeit
>>> timeit.timeit('fn_numpy(xx)', 'from __main__ import fn_numpy, xx', number=10000)    
0.18891601900395472
>>> timeit.timeit('fn_fortran(xx)', 'from __main__ import fn_fortran, xx', number=10000)    
0.004707066000264604

ufuncify提供的选项与可用的选项大致相同 autowrap .

SymPy还提供其他工具来进行有效的数值计算。看到了吗 this 翻页查看他们之间的比较。

重写表达式的类和函数(sympy.codegen.重写)#

用于重写表达式以优化代码生成的类和函数。有些语言(或其标准),如C99,提供了专门的数学函数以获得更好的性能和/或精度。

使用 optimize 函数,以及一组规则(表示为 Optimization ),可以为此重写表达式:

>>> from sympy import Symbol, exp, log
>>> from sympy.codegen.rewriting import optimize, optims_c99
>>> x = Symbol('x')
>>> optimize(3*exp(2*x) - 3, optims_c99)
3*expm1(2*x)
>>> optimize(exp(2*x) - 1 - exp(-33), optims_c99)
expm1(2*x) - exp(-33)
>>> optimize(log(3*x + 3), optims_c99)
log1p(x) + log(3)
>>> optimize(log(2*x + 3), optims_c99)
log(2*x + 3)

这个 optims_c99 上面导入的是包含以下实例的元组(可以从 sympy.codegen.rewriting ):

  • expm1_opt

  • log1p_opt

  • exp2_opt

  • log2_opt

  • log2const_opt

class sympy.codegen.rewriting.FuncMinusOneOptim(func, func_m_1, opportunistic=True)[源代码]#

Specialization of ReplaceOptim for functions evaluating "f(x) - 1".

参数:

func :

The function which is subtracted by one.

func_m_1 :

The specialized function evaluating func(x) - 1.

opportunistic : bool

When True, apply the transformation as long as the magnitude of the remaining number terms decreases. When False, only apply the transformation if it completely eliminates the number term.

解释

Numerical functions which go toward one as x go toward zero is often best implemented by a dedicated function in order to avoid catastrophic cancellation. One such example is expm1(x) in the C standard library which evaluates exp(x) - 1. Such functions preserves many more significant digits when its argument is much smaller than one, compared to subtracting one afterwards.

实例

>>> from sympy import symbols, exp
>>> from sympy.codegen.rewriting import FuncMinusOneOptim
>>> from sympy.codegen.cfunctions import expm1
>>> x, y = symbols('x y')
>>> expm1_opt = FuncMinusOneOptim(exp, expm1)
>>> expm1_opt(exp(x) + 2*exp(5*y) - 3)
expm1(x) + 2*expm1(5*y)
replace_in_Add(e)[源代码]#

passed as second argument to Basic.replace(...)

class sympy.codegen.rewriting.Optimization(cost_function=None, priority=1)[源代码]#

重写优化的抽象基类。

应实现子类 __call__ 以一个表达式作为参数。

参数:

cost_function :可回拨号码

优先 :编号

class sympy.codegen.rewriting.ReplaceOptim(query, value, **kwargs)[源代码]#

重写优化调用replace on表达式。

参数:

query :

First argument passed to replace.

value :

Second argument passed to replace.

解释

实例可以用作表达式上的函数,它将对其应用 replace 方法(见) sympy.core.basic.Basic.replace()

实例

>>> from sympy import Symbol
>>> from sympy.codegen.rewriting import ReplaceOptim
>>> from sympy.codegen.cfunctions import exp2
>>> x = Symbol('x')
>>> exp2_opt = ReplaceOptim(lambda p: p.is_Pow and p.base == 2,
...     lambda p: exp2(p.exp))
>>> exp2_opt(2**x)
exp2(x)
sympy.codegen.rewriting.create_expand_pow_optimization(limit, *, base_req=<function <lambda>>)[源代码]#

创建的实例 ReplaceOptim 用于扩展 Pow .

参数:

限制 :内景

扩展为乘法的最高幂。

base_req : function returning bool

Requirement on base for expansion to happen, default is to return the is_symbol attribute of the base.

解释

展开的要求是,基础需要是符号,指数需要是整数(并且小于或等于 limit

实例

>>> from sympy import Symbol, sin
>>> from sympy.codegen.rewriting import create_expand_pow_optimization
>>> x = Symbol('x')
>>> expand_opt = create_expand_pow_optimization(3)
>>> expand_opt(x**5 + x**3)
x**5 + x*x*x
>>> expand_opt(x**5 + x**3 + sin(x)**3)
x**5 + sin(x)**3 + x*x*x
>>> opt2 = create_expand_pow_optimization(3, base_req=lambda b: not b.is_Function)
>>> opt2((x+1)**2 + sin(x)**2)
sin(x)**2 + (x + 1)*(x + 1)
sympy.codegen.rewriting.optimize(expr, optimizations)[源代码]#

对表达式应用优化。

参数:

expr :表达式

优化 :iterable of Optimization 实例

优化将根据 priority (最高优先)。

实例

>>> from sympy import log, Symbol
>>> from sympy.codegen.rewriting import optims_c99, optimize
>>> x = Symbol('x')
>>> optimize(log(x+3)/log(2) + log(x**2 + 1), optims_c99)
log1p(x**2) + log2(x + 3)

矩阵操作的附加AST节点。此模块中的节点用于表示codegen目标语言中无法用SymPy表达式表示的矩阵表达式的优化。

作为一个例子,我们可以使用 sympy.codegen.rewriting.optimize() 以及 matin_opt 中提供的优化 sympy.codegen.rewriting 在某些假设下变换矩阵乘法:

>>> from sympy import symbols, MatrixSymbol
>>> n = symbols('n', integer=True)
>>> A = MatrixSymbol('A', n, n)
>>> x = MatrixSymbol('x', n, 1)
>>> expr = A**(-1) * x
>>> from sympy import assuming, Q
>>> from sympy.codegen.rewriting import matinv_opt, optimize
>>> with assuming(Q.fullrank(A)):
...     optimize(expr, [matinv_opt])
MatrixSolve(A, vector=x)
class sympy.codegen.matrix_nodes.MatrixSolve(*args, **kwargs)[源代码]#

表示求解线性矩阵方程的操作。

参数:

矩阵 :矩阵符号

表示线性方程中变量系数的矩阵。该矩阵必须是平方和满秩(即所有列必须线性无关),这样求解操作才有效。

矢量 :矩阵符号

一列矩阵,表示 matrix .

实例

>>> from sympy import symbols, MatrixSymbol
>>> from sympy.codegen.matrix_nodes import MatrixSolve
>>> n = symbols('n', integer=True)
>>> A = MatrixSymbol('A', n, n)
>>> x = MatrixSymbol('x', n, 1)
>>> from sympy.printing.numpy import NumPyPrinter
>>> NumPyPrinter().doprint(MatrixSolve(A, x))
'numpy.linalg.solve(A, x)'
>>> from sympy import octave_code
>>> octave_code(MatrixSolve(A, x))
'A \\ x'

使用近似简化表达式的工具(sympy.codegen.近似值)#

class sympy.codegen.approximations.SeriesApprox(bounds, reltol, max_order=4, n_point_checks=4, **kwargs)[源代码]#

Approximates functions by expanding them as a series.

参数:

界限 :dict命令

将表达式映射到长度2元组的边界(低、高)。

雷托 :编号

何时忽略术语的阈值。相对于界中最大的下界。

max_order :内景

系列扩展中包含的最大订单

n_point_checks :int(偶数)

扩展(相对于reltol)的有效性在离散点(变量边界上线性间隔)进行检查。此数值检查中使用的点数由该数字给出。

实例

>>> from sympy import sin, pi
>>> from sympy.abc import x, y
>>> from sympy.codegen.rewriting import optimize
>>> from sympy.codegen.approximations import SeriesApprox
>>> bounds = {x: (-.1, .1), y: (pi-1, pi+1)}
>>> series_approx2 = SeriesApprox(bounds, reltol=1e-2)
>>> series_approx3 = SeriesApprox(bounds, reltol=1e-3)
>>> series_approx8 = SeriesApprox(bounds, reltol=1e-8)
>>> expr = sin(x)*sin(y)
>>> optimize(expr, [series_approx2])
x*(-y + (y - pi)**3/6 + pi)
>>> optimize(expr, [series_approx3])
(-x**3/6 + x)*sin(y)
>>> optimize(expr, [series_approx8])
sin(x)*sin(y)
class sympy.codegen.approximations.SumApprox(bounds, reltol, **kwargs)[源代码]#

Approximates sum by neglecting small terms.

参数:

界限 :dict命令

将表达式映射到长度2元组的边界(低、高)。

雷托 :编号

何时忽略术语的阈值。相对于界中最大的下界。

解释

如果术语是可以确定为单调的表达式,那么这些表达式的边界将被添加。

实例

>>> from sympy import exp
>>> from sympy.abc import x, y, z
>>> from sympy.codegen.rewriting import optimize
>>> from sympy.codegen.approximations import SumApprox
>>> bounds = {x: (-1, 1), y: (1000, 2000), z: (-10, 3)}
>>> sum_approx3 = SumApprox(bounds, reltol=1e-3)
>>> sum_approx2 = SumApprox(bounds, reltol=1e-2)
>>> sum_approx1 = SumApprox(bounds, reltol=1e-1)
>>> expr = 3*(x + y + exp(z))
>>> optimize(expr, [sum_approx3])
3*(x + y + exp(z))
>>> optimize(expr, [sum_approx2])
3*y + 3*exp(z)
>>> optimize(expr, [sum_approx1])
3*y

抽象语法树的类(sympy.codegen.ast)#

用于将完整函数/模块表示为抽象语法树的类型。

大多数类型都很小,仅用作AST中的标记。下面提供了一个树形图来说明AST类型之间的关系。

AST类型树#

*Basic*
     |
     |
 CodegenAST
     |
     |--->AssignmentBase
     |             |--->Assignment
     |             |--->AugmentedAssignment
     |                                    |--->AddAugmentedAssignment
     |                                    |--->SubAugmentedAssignment
     |                                    |--->MulAugmentedAssignment
     |                                    |--->DivAugmentedAssignment
     |                                    |--->ModAugmentedAssignment
     |
     |--->CodeBlock
     |
     |
     |--->Token
              |--->Attribute
              |--->For
              |--->String
              |       |--->QuotedString
              |       |--->Comment
              |--->Type
              |       |--->IntBaseType
              |       |              |--->_SizedIntType
              |       |                               |--->SignedIntType
              |       |                               |--->UnsignedIntType
              |       |--->FloatBaseType
              |                        |--->FloatType
              |                        |--->ComplexBaseType
              |                                           |--->ComplexType
              |--->Node
              |       |--->Variable
              |       |           |---> Pointer
              |       |--->FunctionPrototype
              |                            |--->FunctionDefinition
              |--->Element
              |--->Declaration
              |--->While
              |--->Scope
              |--->Stream
              |--->Print
              |--->FunctionCall
              |--->BreakToken
              |--->ContinueToken
              |--->NoneToken
              |--->Return

预定义类型#

一些 Type 实例在中提供 sympy.codegen.ast 模块方便。代码生成(数字代码)最常见的两种方法是 float32float64 (分别称为单精度和双精度)。还有一些类型的精确泛型版本(代码打印机在打印时选择底层数据类型): realintegercomplex_bool_ .

其他的 Type 定义的实例包括:

  • intc :C的“int”使用的整数类型。

  • intp :C的“无符号”使用的整数类型。

  • int8int16int32int64 :n位整数。

  • uint8uint16uint32uint64 :n位无符号整数。

  • float80 :在现代x86/amd64硬件上被称为“扩展精度”。

  • complex64 :用2表示的复数 float32 数字

  • complex128 :用2表示的复数 float64 数字

使用节点#

可以使用AST节点构造简单的算法。让我们用牛顿法构造一个回路:

>>> from sympy import symbols, cos
>>> from sympy.codegen.ast import While, Assignment, aug_assign, Print, QuotedString
>>> t, dx, x = symbols('tol delta val')
>>> expr = cos(x) - x**3
>>> whl = While(abs(dx) > t, [
...     Assignment(dx, -expr/expr.diff(x)),
...     aug_assign(x, '+', dx),
...     Print([x])
... ])
>>> from sympy import pycode
>>> py_str = pycode(whl)
>>> print(py_str)
while (abs(delta) > tol):
    delta = (val**3 - math.cos(val))/(-3*val**2 - math.sin(val))
    val += delta
    print(val)
>>> import math
>>> tol, val, delta = 1e-5, 0.5, float('inf')
>>> exec(py_str)
1.1121416371
0.909672693737
0.867263818209
0.865477135298
0.865474033111
>>> print('%3.1g' % (math.cos(val) - val**3))
-3e-11

如果我们想为我们简单调用的while循环生成Fortran代码 fcode ::

>>> from sympy import fcode
>>> print(fcode(whl, standard=2003, source_format='free'))
do while (abs(delta) > tol)
   delta = (val**3 - cos(val))/(-3*val**2 - sin(val))
   val = val + delta
   print *, val
end do

sympy.codegen.algorithms .

class sympy.codegen.ast.Assignment(lhs, rhs)[源代码]#

表示用于代码生成的变量赋值。

参数:

lhs :表达式

SymPy object representing the lhs of the expression. These should be singular objects, such as one would use in writing code. Notable types include Symbol, MatrixSymbol, MatrixElement, and Indexed. Types that subclass these types are also supported.

rhs :表达式

SymPy object representing the rhs of the expression. This can be any type, provided its shape corresponds to that of the lhs. For example, a Matrix type can be assigned to MatrixSymbol, but not to Symbol, as the dimensions will not align.

实例

>>> from sympy import symbols, MatrixSymbol, Matrix
>>> from sympy.codegen.ast import Assignment
>>> x, y, z = symbols('x, y, z')
>>> Assignment(x, y)
Assignment(x, y)
>>> Assignment(x, 0)
Assignment(x, 0)
>>> A = MatrixSymbol('A', 1, 3)
>>> mat = Matrix([x, y, z]).T
>>> Assignment(A, mat)
Assignment(A, Matrix([[x, y, z]]))
>>> Assignment(A[0, 1], x)
Assignment(A[0, 1], x)
class sympy.codegen.ast.AssignmentBase(lhs, rhs)[源代码]#

赋值和扩充赋值的抽象基类。

属性:

运算STR

赋值运算符的符号,例如“=”、“+=”等。

class sympy.codegen.ast.Attribute(possibly parametrized)[源代码]#

供使用 sympy.codegen.ast.Node (以 Attribute 作为 attrs

参数:

name :结构

参数 :元组

实例

>>> from sympy.codegen.ast import Attribute
>>> volatile = Attribute('volatile')
>>> volatile
volatile
>>> print(repr(volatile))
Attribute(String('volatile'))
>>> a = Attribute('foo', [1, 2, 3])
>>> a
foo(1, 2, 3)
>>> a.parameters == (1, 2, 3)
True
class sympy.codegen.ast.AugmentedAssignment(lhs, rhs)[源代码]#

扩展赋值的基类。

属性:

比诺普STR

在赋值中应用的二进制运算符号,如“+”、“*”等。

class sympy.codegen.ast.BreakToken(*args, **kwargs)[源代码]#

表示Fortran中C/Python('exit'中的'break'。

使用预制实例 break_ 或手动实例化。

实例

>>> from sympy import ccode, fcode
>>> from sympy.codegen.ast import break_
>>> ccode(break_)
'break'
>>> fcode(break_, source_format='free')
'exit'
class sympy.codegen.ast.CodeBlock(*args)[源代码]#

Represents a block of code.

解释

目前只支持分配。这一限制今后将取消。

此对象的有用属性包括:

left_hand_sides

作业左侧的元组,按顺序排列。

left_hand_sides

作业右侧的元组,按顺序排列。

free_symbols :右侧表达式的自由符号

不会出现在作业的左侧。

此对象的有用方法有:

topological_sort

类方法。在返回变量之前分配了一个代码块赋值,这样它们就被排序了。

cse

返回一个新的代码块,其中删除了公共子表达式并将其作为赋值拉出。

实例

>>> from sympy import symbols, ccode
>>> from sympy.codegen.ast import CodeBlock, Assignment
>>> x, y = symbols('x y')
>>> c = CodeBlock(Assignment(x, 1), Assignment(y, x + 1))
>>> print(ccode(c))
x = 1;
y = x + 1;
cse(symbols=None, optimizations=None, postprocess=None, order='canonical')[源代码]#

Return a new code block with common subexpressions eliminated.

解释

请参见的docstring sympy.simplify.cse_main.cse() 更多信息。

实例

>>> from sympy import symbols, sin
>>> from sympy.codegen.ast import CodeBlock, Assignment
>>> x, y, z = symbols('x y z')
>>> c = CodeBlock(
...     Assignment(x, 1),
...     Assignment(y, sin(x) + 1),
...     Assignment(z, sin(x) - 1),
... )
...
>>> c.cse()
CodeBlock(
    Assignment(x, 1),
    Assignment(x0, sin(x)),
    Assignment(y, x0 + 1),
    Assignment(z, x0 - 1)
)
classmethod topological_sort(assignments)[源代码]#

返回具有拓扑排序赋值的代码块,以便在使用变量之前分配变量。

实例

尽可能保留现有的分配顺序。

此函数假定变量只分配一次。

这是一个类构造函数,因此当变量在赋值之前被使用时,CodeBlock的默认构造函数可能会出错。

>>> from sympy import symbols
>>> from sympy.codegen.ast import CodeBlock, Assignment
>>> x, y, z = symbols('x y z')
>>> assignments = [
...     Assignment(x, y + z),
...     Assignment(y, z + 1),
...     Assignment(z, 2),
... ]
>>> CodeBlock.topological_sort(assignments)
CodeBlock(
    Assignment(z, 2),
    Assignment(y, z + 1),
    Assignment(x, y + z)
)
class sympy.codegen.ast.Comment(*args, **kwargs)[源代码]#

表示注释。

class sympy.codegen.ast.ComplexType(*args, **kwargs)[源代码]#

表示复杂浮点数。

class sympy.codegen.ast.ContinueToken(*args, **kwargs)[源代码]#

表示C/Python中的“continue”(在Fortran中为“cycle”)

使用预制实例 continue_ 或手动实例化。

实例

>>> from sympy import ccode, fcode
>>> from sympy.codegen.ast import continue_
>>> ccode(continue_)
'continue'
>>> fcode(continue_, source_format='free')
'cycle'
class sympy.codegen.ast.Declaration(*args, **kwargs)[源代码]#

表示变量声明

参数:

变量 :变量

实例

>>> from sympy.codegen.ast import Declaration, NoneToken, untyped
>>> z = Declaration('z')
>>> z.variable.type == untyped
True
>>> # value is special NoneToken() which must be tested with == operator
>>> z.variable.value is None  # won't work
False
>>> z.variable.value == None  # not PEP-8 compliant
True
>>> z.variable.value == NoneToken()  # OK
True
class sympy.codegen.ast.Element(*args, **kwargs)[源代码]#

(可能是N维)数组中的元素。

实例

>>> from sympy.codegen.ast import Element
>>> elem = Element('x', 'ijk')
>>> elem.symbol.name == 'x'
True
>>> elem.indices
(i, j, k)
>>> from sympy import ccode
>>> ccode(elem)
'x[i][j][k]'
>>> ccode(Element('x', 'ijk', strides='lmn', offset='o'))
'x[i*l + j*m + k*n + o]'
class sympy.codegen.ast.FloatBaseType(*args, **kwargs)[源代码]#

表示浮点数类型。

cast_nocheck[源代码]#

Float 的别名

class sympy.codegen.ast.FloatType(*args, **kwargs)[源代码]#

表示具有固定位宽度的浮点类型。

基数2&假定有一个符号位。

参数:

name :结构

类型的名称。

国家统计局 :整数

使用的位数(存储)。

恩曼特 :整数

用于表示尾数的位数。

nexp :整数

用于表示尾数的位数。

实例

>>> from sympy import S
>>> from sympy.codegen.ast import FloatType
>>> half_precision = FloatType('f16', nbits=16, nmant=10, nexp=5)
>>> half_precision.max
65504
>>> half_precision.tiny == S(2)**-14
True
>>> half_precision.eps == S(2)**-10
True
>>> half_precision.dig == 3
True
>>> half_precision.decimal_dig == 5
True
>>> half_precision.cast_check(1.0)
1.0
>>> half_precision.cast_check(1e5)  
Traceback (most recent call last):
  ...
ValueError: Maximum value for data type smaller than new value.
cast_nocheck(value)[源代码]#

不检查是否越界或低于正常值。

property decimal_dig#

存储和加载所需的位数。

解释

要保证两个十进制数的转换->保证浮点数是连续的。作为一个有用的文本存储时,不要将此值作为一个浮点值进行舍入。

property dig#

保证在文本中保留的小数位数。

在转换text->float->text时,至少保证 dig 保留有关舍入或溢出的位数。

property eps#

1.0与下一个可表示值之间的差。

property max#

可代表的最大值。

property max_exponent#

最大正数n,使得2**(n-1)是可表示的有限值。

property min_exponent#

最小的负数n,使得2**(n-1)是一个有效的规范化数。

property tiny#

最小正规范化值。

class sympy.codegen.ast.For(*args, **kwargs)[源代码]#

表示代码中的“for循环”。

表达式的形式如下:
“对于iter中的目标:

body..."

参数:

目标 :符号

iter:iterable主体:代码块或iterable

! 当传递一个iterable时,它被用来实例化一个代码块。

实例

>>> from sympy import symbols, Range
>>> from sympy.codegen.ast import aug_assign, For
>>> x, i, j, k = symbols('x i j k')
>>> for_i = For(i, Range(10), [aug_assign(x, '+', i*j*k)])
>>> for_i  
For(i, iterable=Range(0, 10, 1), body=CodeBlock(
    AddAugmentedAssignment(x, i*j*k)
))
>>> for_ji = For(j, Range(7), [for_i])
>>> for_ji  
For(j, iterable=Range(0, 7, 1), body=CodeBlock(
    For(i, iterable=Range(0, 10, 1), body=CodeBlock(
        AddAugmentedAssignment(x, i*j*k)
    ))
))
>>> for_kji =For(k, Range(5), [for_ji])
>>> for_kji  
For(k, iterable=Range(0, 5, 1), body=CodeBlock(
    For(j, iterable=Range(0, 7, 1), body=CodeBlock(
        For(i, iterable=Range(0, 10, 1), body=CodeBlock(
            AddAugmentedAssignment(x, i*j*k)
        ))
    ))
))
class sympy.codegen.ast.FunctionCall(*args, **kwargs)[源代码]#

表示对代码中函数的调用。

参数:

name :结构

function_args :元组

实例

>>> from sympy.codegen.ast import FunctionCall
>>> from sympy import pycode
>>> fcall = FunctionCall('foo', 'bar baz'.split())
>>> print(pycode(fcall))
foo(bar, baz)
class sympy.codegen.ast.FunctionDefinition(*args, **kwargs)[源代码]#

表示代码中的函数定义。

参数:

return_type :类型

name :结构

参数:变量实例的iterable

body :代码块或iterable

阿特斯 :iterable属性实例

实例

>>> from sympy import ccode, symbols
>>> from sympy.codegen.ast import real, FunctionPrototype
>>> x, y = symbols('x y', real=True)
>>> fp = FunctionPrototype(real, 'foo', [x, y])
>>> ccode(fp)
'double foo(double x, double y)'
>>> from sympy.codegen.ast import FunctionDefinition, Return
>>> body = [Return(x*y)]
>>> fd = FunctionDefinition.from_FunctionPrototype(fp, body)
>>> print(ccode(fd))
double foo(double x, double y){
    return x*y;
}
class sympy.codegen.ast.FunctionPrototype(*args, **kwargs)[源代码]#

表示函数原型

允许用户在C/C++中生成正向声明。

参数:

return_type :类型

name :结构

参数:变量实例的iterable

阿特斯 :iterable属性实例

实例

>>> from sympy import ccode, symbols
>>> from sympy.codegen.ast import real, FunctionPrototype
>>> x, y = symbols('x y', real=True)
>>> fp = FunctionPrototype(real, 'foo', [x, y])
>>> ccode(fp)
'double foo(double x, double y)'
class sympy.codegen.ast.IntBaseType(*args, **kwargs)[源代码]#

整数基类型,不包含大小信息。

class sympy.codegen.ast.Node(*args, **kwargs)[源代码]#

Token的子类,带有属性“attrs”(Tuple)

实例

>>> from sympy.codegen.ast import Node, value_const, pointer_const
>>> n1 = Node([value_const])
>>> n1.attr_params('value_const')  # get the parameters of attribute (by name)
()
>>> from sympy.codegen.fnodes import dimension
>>> n2 = Node([value_const, dimension(5, 3)])
>>> n2.attr_params(value_const)  # get the parameters of attribute (by Attribute instance)
()
>>> n2.attr_params('dimension')  # get the parameters of attribute (by name)
(5, 3)
>>> n2.attr_params(pointer_const) is None
True
attr_params(looking_for)[源代码]#

返回名为的属性的参数 looking_for 在自我属性

class sympy.codegen.ast.NoneToken(*args, **kwargs)[源代码]#

Python非类型的AST等价性

Python的相应实例 Nonenone .

实例

>>> from sympy.codegen.ast import none, Variable
>>> from sympy import pycode
>>> print(pycode(Variable('x').as_Declaration(value=none)))
x = None
class sympy.codegen.ast.Pointer(*args, **kwargs)[源代码]#

表示指针。看到了吗 Variable .

实例

可以创建的实例 Element

>>> from sympy import Symbol
>>> from sympy.codegen.ast import Pointer
>>> i = Symbol('i', integer=True)
>>> p = Pointer('x')
>>> p[i+1]
Element(x, indices=(i + 1,))
class sympy.codegen.ast.Print(*args, **kwargs)[源代码]#

表示代码中的打印命令。

参数:

格式字符串 :结构

*args :基本实例(或通过sympify转换为基本实例)

实例

>>> from sympy.codegen.ast import Print
>>> from sympy import pycode
>>> print(pycode(Print('x y'.split(), "coordinate: %12.5g %12.5g\\n")))
print("coordinate: %12.5g %12.5g\n" % (x, y), end="")
class sympy.codegen.ast.QuotedString(*args, **kwargs)[源代码]#

表示应使用引号打印的字符串。

class sympy.codegen.ast.Raise(*args, **kwargs)[源代码]#

Prints as 'raise ...' in Python, 'throw ...' in C++

class sympy.codegen.ast.Return(*args, **kwargs)[源代码]#

表示代码中的返回命令。

参数:

return : Basic

实例

>>> from sympy.codegen.ast import Return
>>> from sympy.printing.pycode import pycode
>>> from sympy import Symbol
>>> x = Symbol('x')
>>> print(pycode(Return(x)))
return x
class sympy.codegen.ast.RuntimeError_(*args, **kwargs)[源代码]#

Represents 'std::runtime_error' in C++ and 'RuntimeError' in Python.

Note that the latter is uncommon, and you might want to use e.g. ValueError.

class sympy.codegen.ast.Scope(*args, **kwargs)[源代码]#

表示代码中的范围。

参数:

body :代码块或iterable

当传递一个iterable时,它被用来实例化一个代码块。

class sympy.codegen.ast.SignedIntType(*args, **kwargs)[源代码]#

表示有符号整数类型。

class sympy.codegen.ast.Stream(*args, **kwargs)[源代码]#

表示流。

有两个预定义的流实例 stdout & stderr .

参数:

name :结构

实例

>>> from sympy import pycode, Symbol
>>> from sympy.codegen.ast import Print, stderr, QuotedString
>>> print(pycode(Print(['x'], file=stderr)))
print(x, file=sys.stderr)
>>> x = Symbol('x')
>>> print(pycode(Print([QuotedString('x')], file=stderr)))  # print literally "x"
print("x", file=sys.stderr)
class sympy.codegen.ast.String(*args, **kwargs)[源代码]#

表示字符串的SymPy对象。

不是表达式的原子对象(与符号相反)。

参数:

text :结构

实例

>>> from sympy.codegen.ast import String
>>> f = String('foo')
>>> f
foo
>>> str(f)
'foo'
>>> f.text
'foo'
>>> print(repr(f))
String('foo')
class sympy.codegen.ast.Token(*args, **kwargs)[源代码]#

AST类型的基类。

解释

Defining fields are set in _fields. Attributes (defined in _fields) are only allowed to contain instances of Basic (unless atomic, see String). The arguments to __new__() correspond to the attributes in the order defined in _fields`. The ``defaults class attribute is a dictionary mapping attribute names to their default values.

子类不应该重写 __new__() 方法。它们可以定义一个名为 _construct_<attr> 对于要处理传递给的值的每个属性 __new__() . 类中列出的属性 not_in_args 不传递给 Basic .

kwargs(exclude=(), apply=None)[源代码]#

获取实例的属性作为关键字参数的dict。

参数:

排除 :str集合

要排除的关键字集合。

应用 :可调用,可选

函数应用于所有值。

class sympy.codegen.ast.Type(*args, **kwargs)[源代码]#

表示类型。

参数:

name :结构

类型的名称,例如。 objectint16float16 (如果后两个将使用 Type 子类 IntTypeFloatType 分别)。如果 Type 实例,则返回所述实例。

解释

命名是NumPy命名的超级集合。类型具有classmethod from_expr 提供类型扣除。它也有一个方法 cast_check 它将参数强制转换为其类型,如果舍入误差不在公差范围内,或者值不能由基础数据类型表示(例如无符号整数),则可能引发异常。

实例

>>> from sympy.codegen.ast import Type
>>> t = Type.from_expr(42)
>>> t
integer
>>> print(repr(t))
IntBaseType(String('integer'))
>>> from sympy.codegen.ast import uint8
>>> uint8.cast_check(-1)   
Traceback (most recent call last):
  ...
ValueError: Minimum value for data type bigger than new value.
>>> from sympy.codegen.ast import float32
>>> v6 = 0.123456
>>> float32.cast_check(v6)
0.123456
>>> v10 = 12345.67894
>>> float32.cast_check(v10)  
Traceback (most recent call last):
  ...
ValueError: Casting gives a significantly different value.
>>> boost_mp50 = Type('boost::multiprecision::cpp_dec_float_50')
>>> from sympy import cxxcode
>>> from sympy.codegen.ast import Declaration, Variable
>>> cxxcode(Declaration(Variable('x', type=boost_mp50)))
'boost::multiprecision::cpp_dec_float_50 x'

工具书类

cast_check(value, rtol=None, atol=0, precision_targets=None)[源代码]#

将值强制转换为实例的数据类型。

参数:

价值 :编号

rtol :浮点数

相对公差。(如未给出,将扣除)。

atol :浮点数

绝对公差(除 rtol

type_aliases :dict命令

映射类型的替换,例如{integer:int64,real:float32}

实例

>>> from sympy.codegen.ast import integer, float32, int8
>>> integer.cast_check(3.0) == 3
True
>>> float32.cast_check(1e-40)  
Traceback (most recent call last):
  ...
ValueError: Minimum value for data type bigger than new value.
>>> int8.cast_check(256)  
Traceback (most recent call last):
  ...
ValueError: Maximum value for data type smaller than new value.
>>> v10 = 12345.67894
>>> float32.cast_check(v10)  
Traceback (most recent call last):
  ...
ValueError: Casting gives a significantly different value.
>>> from sympy.codegen.ast import float64
>>> float64.cast_check(v10)
12345.67894
>>> from sympy import Float
>>> v18 = Float('0.123456789012345646')
>>> float64.cast_check(v18)
Traceback (most recent call last):
  ...
ValueError: Casting gives a significantly different value.
>>> from sympy.codegen.ast import float80
>>> float80.cast_check(v18)
0.123456789012345649
classmethod from_expr(expr)[源代码]#

从表达式或 Symbol .

参数:

expr :number或SymPy对象

类型将从类型或属性派生。

加薪:

类型扣除失败时的值错误。

实例

>>> from sympy.codegen.ast import Type, integer, complex_
>>> Type.from_expr(2) == integer
True
>>> from sympy import Symbol
>>> Type.from_expr(Symbol('z', complex=True)) == complex_
True
>>> Type.from_expr(sum)  
Traceback (most recent call last):
  ...
ValueError: Could not deduce type from expr.
class sympy.codegen.ast.UnsignedIntType(*args, **kwargs)[源代码]#

表示无符号整数类型。

class sympy.codegen.ast.Variable(*args, **kwargs)[源代码]#

Represents a variable.

参数:

符号 :符号

type :类型(可选)

变量的类型。

阿特斯 :iterable属性实例

将作为元组存储。

实例

>>> from sympy import Symbol
>>> from sympy.codegen.ast import Variable, float32, integer
>>> x = Symbol('x')
>>> v = Variable(x, type=float32)
>>> v.attrs
()
>>> v == Variable('x')
False
>>> v == Variable('x', type=float32)
True
>>> v
Variable(x, type=float32)

你也可以构造一个 Variable 使用 deduced 分类方法:

>>> i = Symbol('i', integer=True)
>>> v = Variable.deduced(i)
>>> v.type == integer
True
>>> v == Variable('i')
False
>>> from sympy.codegen.ast import value_const
>>> value_const in v.attrs
False
>>> w = Variable('w', attrs=[value_const])
>>> w
Variable(w, attrs=(value_const,))
>>> value_const in w.attrs
True
>>> w.as_Declaration(value=42)
Declaration(Variable(w, value=42, attrs=(value_const,)))
as_Declaration(**kwargs)[源代码]#

用于创建声明实例的便利方法。

解释

如果声明的变量需要包装一个修改过的变量,则可以传递关键字参数(重写 value 变量实例)。

实例

>>> from sympy.codegen.ast import Variable, NoneToken
>>> x = Variable('x')
>>> decl1 = x.as_Declaration()
>>> # value is special NoneToken() which must be tested with == operator
>>> decl1.variable.value is None  # won't work
False
>>> decl1.variable.value == None  # not PEP-8 compliant
True
>>> decl1.variable.value == NoneToken()  # OK
True
>>> decl2 = x.as_Declaration(value=42.0)
>>> decl2.variable.value == 42.0
True
classmethod deduced(symbol, value=None, attrs=(), cast_check=True)[源代码]#

从中扣除类型的替代构造函数 Type.from_expr .

主要从 symbol ,其次是 value .

参数:

符号 :符号

价值 :表达式

(可选)变量的值。

阿特斯 :iterable属性实例

cast_check 布尔

是否申请 Type.cast_checkvalue .

实例

>>> from sympy import Symbol
>>> from sympy.codegen.ast import Variable, complex_
>>> n = Symbol('n', integer=True)
>>> str(Variable.deduced(n).type)
'integer'
>>> x = Symbol('x', real=True)
>>> v = Variable.deduced(x)
>>> v.type
real
>>> z = Symbol('z', complex=True)
>>> Variable.deduced(z).type == complex_
True
class sympy.codegen.ast.While(*args, **kwargs)[源代码]#

表示代码中的“for循环”。

表达式的形式如下:
“while条件:

body..."

参数:

条件 :可转换为布尔值的表达式

body :代码块或iterable

当传递一个iterable时,它被用来实例化一个代码块。

实例

>>> from sympy import symbols, Gt, Abs
>>> from sympy.codegen import aug_assign, Assignment, While
>>> x, dx = symbols('x dx')
>>> expr = 1 - x**2
>>> whl = While(Gt(Abs(dx), 1e-9), [
...     Assignment(dx, -expr/expr.diff(x)),
...     aug_assign(x, '+', dx)
... ])
sympy.codegen.ast.aug_assign(lhs, op, rhs)[源代码]#

创建“lhs op=rhs”。

参数:

lhs :表达式

SymPy object representing the lhs of the expression. These should be singular objects, such as one would use in writing code. Notable types include Symbol, MatrixSymbol, MatrixElement, and Indexed. Types that subclass these types are also supported.

op :结构

运算符(+,-,/, * , %).

rhs :表达式

SymPy object representing the rhs of the expression. This can be any type, provided its shape corresponds to that of the lhs. For example, a Matrix type can be assigned to MatrixSymbol, but not to Symbol, as the dimensions will not align.

解释

表示用于代码生成的扩充变量赋值。这是一个方便的函数。您也可以直接使用AugmentedAssignment类,比如AddAugmentedAssignment(x,y)。

实例

>>> from sympy import symbols
>>> from sympy.codegen.ast import aug_assign
>>> x, y = symbols('x, y')
>>> aug_assign(x, '+', y)
AddAugmentedAssignment(x, y)

特殊C数学函数(sympy.codegen.c函数)#

该模块包含与C标准库中的特殊数学函数对应的SmithCype MathCin(因为C99,也可以在C++ 11中使用)。

此模块中定义的函数允许用户表达诸如 expm1 作为符号操作的一个符号函数。

class sympy.codegen.cfunctions.Cbrt(*args)[源代码]#

表示立方根函数。

解释

为什么人们会使用 Cbrt(x) 结束 cbrt(x) 后者在内部表示为 Pow(x, Rational(1, 3)) 这可能不是我们在生成代码时想要的。

实例

>>> from sympy.abc import x
>>> from sympy.codegen.cfunctions import Cbrt
>>> Cbrt(x)
Cbrt(x)
>>> Cbrt(x).diff(x)
1/(3*x**(2/3))

参见

Sqrt

fdiff(argindex=1)[源代码]#

返回此函数的一阶导数。

class sympy.codegen.cfunctions.Sqrt(*args)[源代码]#

表示平方根函数。

解释

为什么人们会使用 Sqrt(x) 结束 sqrt(x) 后者在内部表示为 Pow(x, S.Half) 这可能不是我们在生成代码时想要的。

实例

>>> from sympy.abc import x
>>> from sympy.codegen.cfunctions import Sqrt
>>> Sqrt(x)
Sqrt(x)
>>> Sqrt(x).diff(x)
1/(2*sqrt(x))

参见

Cbrt

fdiff(argindex=1)[源代码]#

返回此函数的一阶导数。

class sympy.codegen.cfunctions.exp2(arg)[源代码]#

表示基数为2的指数函数。

解释

使用的好处 exp2(x) 结束 2**x 在有限精度算法下,后者的效率并不高。

实例

>>> from sympy.abc import x
>>> from sympy.codegen.cfunctions import exp2
>>> exp2(2).evalf() == 4.0
True
>>> exp2(x).diff(x)
log(2)*exp2(x)

参见

log2

fdiff(argindex=1)[源代码]#

返回此函数的一阶导数。

class sympy.codegen.cfunctions.expm1(arg)[源代码]#

表示指数函数减去1。

解释

使用的好处 expm1(x) 结束 exp(x) - 1 在有限精度算法下,当x接近于零时,后者容易被抵消。

实例

>>> from sympy.abc import x
>>> from sympy.codegen.cfunctions import expm1
>>> '%.0e' % expm1(1e-99).evalf()
'1e-99'
>>> from math import exp
>>> exp(1e-99) - 1
0.0
>>> expm1(x).diff(x)
exp(x)

参见

log1p

fdiff(argindex=1)[源代码]#

返回此函数的一阶导数。

class sympy.codegen.cfunctions.fma(*args)[源代码]#

表示“融合乘法加法”。

解释

使用的好处 fma(x, y, z) 结束 x*y + z 在有限精度算法下,前者由一些cpu上的特殊指令支持。

实例

>>> from sympy.abc import x, y, z
>>> from sympy.codegen.cfunctions import fma
>>> fma(x, y, z).diff(x)
y
fdiff(argindex=1)[源代码]#

返回此函数的一阶导数。

class sympy.codegen.cfunctions.hypot(*args)[源代码]#

表示斜边函数。

解释

斜边函数是由C99标准中的数学库提供的,因此在生成代码时可能需要象征性地表示该函数。

实例

>>> from sympy.abc import x, y
>>> from sympy.codegen.cfunctions import hypot
>>> hypot(3, 4).evalf() == 5.0
True
>>> hypot(x, y)
hypot(x, y)
>>> hypot(x, y).diff(x)
x/hypot(x, y)
fdiff(argindex=1)[源代码]#

返回此函数的一阶导数。

class sympy.codegen.cfunctions.log10(arg)[源代码]#

表示以10为底的对数函数。

实例

>>> from sympy.abc import x
>>> from sympy.codegen.cfunctions import log10
>>> log10(100).evalf() == 2.0
True
>>> log10(x).diff(x)
1/(x*log(10))

参见

log2

fdiff(argindex=1)[源代码]#

返回此函数的一阶导数。

class sympy.codegen.cfunctions.log1p(arg)[源代码]#

表示数字加1的自然对数。

解释

使用的好处 log1p(x) 结束 log(x + 1) 在有限精度算法下,当x接近于零时,后者容易被抵消。

实例

>>> from sympy.abc import x
>>> from sympy.codegen.cfunctions import log1p
>>> from sympy import expand_log
>>> '%.0e' % expand_log(log1p(1e-99)).evalf()
'1e-99'
>>> from math import log
>>> log(1 + 1e-99)
0.0
>>> log1p(x).diff(x)
1/(x + 1)

参见

expm1

fdiff(argindex=1)[源代码]#

返回此函数的一阶导数。

class sympy.codegen.cfunctions.log2(arg)[源代码]#

表示以2为底的对数函数。

解释

使用的好处 log2(x) 结束 log(x)/log(2) 在有限精度算法下,后者的效率并不高。

实例

>>> from sympy.abc import x
>>> from sympy.codegen.cfunctions import log2
>>> log2(4).evalf() == 2.0
True
>>> log2(x).diff(x)
1/(x*log(2))

参见

exp2, log10

fdiff(argindex=1)[源代码]#

返回此函数的一阶导数。

特定于C的AST节点(sympy.codegen.cnodes公司)#

特定于C语言家族的AST节点

class sympy.codegen.cnodes.CommaOperator(*args)[源代码]#

表示C中的逗号运算符

class sympy.codegen.cnodes.Label(*args, **kwargs)[源代码]#

与goto语句一起使用的标签。

实例

>>> from sympy import ccode, Symbol
>>> from sympy.codegen.cnodes import Label, PreIncrement
>>> print(ccode(Label('foo')))
foo:
>>> print(ccode(Label('bar', [PreIncrement(Symbol('a'))])))
bar:
++(a);
class sympy.codegen.cnodes.PostDecrement(*args)[源代码]#

表示后递减运算符

实例

>>> from sympy.abc import x
>>> from sympy.codegen.cnodes import PostDecrement
>>> from sympy import ccode
>>> ccode(PostDecrement(x))
'(x)--'
class sympy.codegen.cnodes.PostIncrement(*args)[源代码]#

表示后增量运算符

实例

>>> from sympy.abc import x
>>> from sympy.codegen.cnodes import PostIncrement
>>> from sympy import ccode
>>> ccode(PostIncrement(x))
'(x)++'
class sympy.codegen.cnodes.PreDecrement(*args)[源代码]#

表示预减量运算符

实例

>>> from sympy.abc import x
>>> from sympy.codegen.cnodes import PreDecrement
>>> from sympy import ccode
>>> ccode(PreDecrement(x))
'--(x)'
class sympy.codegen.cnodes.PreIncrement(*args)[源代码]#

表示预增量运算符

实例

>>> from sympy.abc import x
>>> from sympy.codegen.cnodes import PreIncrement
>>> from sympy import ccode
>>> ccode(PreIncrement(x))
'++(x)'
sympy.codegen.cnodes.alignof(arg)[源代码]#

生成用于调用“alignof”的FunctionCall实例

class sympy.codegen.cnodes.goto(*args, **kwargs)[源代码]#

表示C中的goto

sympy.codegen.cnodes.sizeof(arg)[源代码]#

生成用于调用“sizeof”的FunctionCall实例

实例

>>> from sympy.codegen.ast import real
>>> from sympy.codegen.cnodes import sizeof
>>> from sympy import ccode
>>> ccode(sizeof(real))
'sizeof(double)'
class sympy.codegen.cnodes.struct(*args, **kwargs)[源代码]#

表示C中的结构

class sympy.codegen.cnodes.union(*args, **kwargs)[源代码]#

表示C中的联合

C++专用AST节点(英文)sympy.codegen.cxx节点)#

特定于C++的AST节点。

class sympy.codegen.cxxnodes.using(*args, **kwargs)[源代码]#

表示C++中的“使用”语句

Fortran特定的AST节点(sympy.codegen.fnodes公司)#

Fortran特有的AST节点。

此模块中定义的函数允许用户表达诸如 dsign 作为符号操作的一个符号函数。

class sympy.codegen.fnodes.ArrayConstructor(*args, **kwargs)[源代码]#

Represents an array constructor.

实例

>>> from sympy import fcode
>>> from sympy.codegen.fnodes import ArrayConstructor
>>> ac = ArrayConstructor([1, 2, 3])
>>> fcode(ac, standard=95, source_format='free')
'(/1, 2, 3/)'
>>> fcode(ac, standard=2003, source_format='free')
'[1, 2, 3]'
class sympy.codegen.fnodes.Do(*args, **kwargs)[源代码]#

Represents a Do loop in in Fortran.

实例

>>> from sympy import fcode, symbols
>>> from sympy.codegen.ast import aug_assign, Print
>>> from sympy.codegen.fnodes import Do
>>> i, n = symbols('i n', integer=True)
>>> r = symbols('r', real=True)
>>> body = [aug_assign(r, '+', 1/i), Print([i, r])]
>>> do1 = Do(body, i, 1, n)
>>> print(fcode(do1, source_format='free'))
do i = 1, n
    r = r + 1d0/i
    print *, i, r
end do
>>> do2 = Do(body, i, 1, n, 2)
>>> print(fcode(do2, source_format='free'))
do i = 1, n, 2
    r = r + 1d0/i
    print *, i, r
end do
class sympy.codegen.fnodes.Extent(*args)[源代码]#

表示维度范围。

实例

>>> from sympy.codegen.fnodes import Extent
>>> e = Extent(-3, 3)  # -3, -2, -1, 0, 1, 2, 3
>>> from sympy import fcode
>>> fcode(e, source_format='free')
'-3:3'
>>> from sympy.codegen.ast import Variable, real
>>> from sympy.codegen.fnodes import dimension, intent_out
>>> dim = dimension(e, e)
>>> arr = Variable('x', real, attrs=[dim, intent_out])
>>> fcode(arr.as_Declaration(), source_format='free', standard=2003)
'real*8, dimension(-3:3, -3:3), intent(out) :: x'
class sympy.codegen.fnodes.FortranReturn(*args, **kwargs)[源代码]#

AST节点显式映射到fortran“return”。

解释

因为fortran中的return语句与C不同,为了帮助代码gen ASTs的重用,普通的 .codegen.ast.Return 被解释为对函数的结果变量赋值。如果出于某种原因需要生成fortran返回语句,则应使用此节点。

实例

>>> from sympy.codegen.fnodes import FortranReturn
>>> from sympy import fcode
>>> fcode(FortranReturn('x'))
'       return x'
class sympy.codegen.fnodes.GoTo(*args, **kwargs)[源代码]#

表示Fortran中的goto语句

实例

>>> from sympy.codegen.fnodes import GoTo
>>> go = GoTo([10, 20, 30], 'i')
>>> from sympy import fcode
>>> fcode(go, source_format='free')
'go to (10, 20, 30), i'
class sympy.codegen.fnodes.ImpliedDoLoop(*args, **kwargs)[源代码]#

Represents an implied do loop in Fortran.

实例

>>> from sympy import Symbol, fcode
>>> from sympy.codegen.fnodes import ImpliedDoLoop, ArrayConstructor
>>> i = Symbol('i', integer=True)
>>> idl = ImpliedDoLoop(i**3, i, -3, 3, 2)  # -27, -1, 1, 27
>>> ac = ArrayConstructor([-28, idl, 28]) # -28, -27, -1, 1, 27, 28
>>> fcode(ac, standard=2003, source_format='free')
'[-28, (i**3, i = -3, 3, 2), 28]'
class sympy.codegen.fnodes.Module(*args, **kwargs)[源代码]#

Represents a module in Fortran.

实例

>>> from sympy.codegen.fnodes import Module
>>> from sympy import fcode
>>> print(fcode(Module('signallib', ['implicit none'], []), source_format='free'))
module signallib
implicit none

contains


end module
class sympy.codegen.fnodes.Program(*args, **kwargs)[源代码]#

Represents a 'program' block in Fortran.

实例

>>> from sympy.codegen.ast import Print
>>> from sympy.codegen.fnodes import Program
>>> prog = Program('myprogram', [Print([42])])
>>> from sympy import fcode
>>> print(fcode(prog, source_format='free'))
program myprogram
    print *, 42
end program
class sympy.codegen.fnodes.Subroutine(*args, **kwargs)[源代码]#

Represents a subroutine in Fortran.

实例

>>> from sympy import fcode, symbols
>>> from sympy.codegen.ast import Print
>>> from sympy.codegen.fnodes import Subroutine
>>> x, y = symbols('x y', real=True)
>>> sub = Subroutine('mysub', [x, y], [Print([x**2 + y**2, x*y])])
>>> print(fcode(sub, source_format='free', standard=2003))
subroutine mysub(x, y)
real*8 :: x
real*8 :: y
print *, x**2 + y**2, x*y
end subroutine
class sympy.codegen.fnodes.SubroutineCall(*args, **kwargs)[源代码]#

Represents a call to a subroutine in Fortran.

实例

>>> from sympy.codegen.fnodes import SubroutineCall
>>> from sympy import fcode
>>> fcode(SubroutineCall('mysub', 'x y'.split()))
'       call mysub(x, y)'
sympy.codegen.fnodes.allocated(array)[源代码]#

为Fortran的“allocated(…)”函数调用创建AST节点

实例

>>> from sympy import fcode
>>> from sympy.codegen.fnodes import allocated
>>> alloc = allocated('x')
>>> fcode(alloc, source_format='free')
'allocated(x)'
sympy.codegen.fnodes.array(symbol, dim, intent=None, *, attrs=(), value=None, type=None)[源代码]#

Convenience function for creating a Variable instance for a Fortran array.

参数:

符号 :符号

dim :属性或iterable

If dim is an Attribute it need to have the name 'dimension'. If it is not an Attribute, then it is passed to dimension() as *dim

意图 :结构

“in”、“out”、“inout”或None之一

**kwargs:

的关键字参数 Variable (“类型”和“值”)

实例

>>> from sympy import fcode
>>> from sympy.codegen.ast import integer, real
>>> from sympy.codegen.fnodes import array
>>> arr = array('a', '*', 'in', type=integer)
>>> print(fcode(arr.as_Declaration(), source_format='free', standard=2003))
integer*4, dimension(*), intent(in) :: a
>>> x = array('x', [3, ':', ':'], intent='out', type=real)
>>> print(fcode(x.as_Declaration(value=1), source_format='free', standard=2003))
real*8, dimension(3, :, :), intent(out) :: x = 1
sympy.codegen.fnodes.bind_C(name=None)[源代码]#

Creates an Attribute bind_C with a name.

参数:

name :结构

实例

>>> from sympy import fcode, Symbol
>>> from sympy.codegen.ast import FunctionDefinition, real, Return
>>> from sympy.codegen.fnodes import array, sum_, bind_C
>>> a = Symbol('a', real=True)
>>> s = Symbol('s', integer=True)
>>> arr = array(a, dim=[s], intent='in')
>>> body = [Return((sum_(a**2)/s)**.5)]
>>> fd = FunctionDefinition(real, 'rms', [arr, s], body, attrs=[bind_C('rms')])
>>> print(fcode(fd, source_format='free', standard=2003))
real*8 function rms(a, s) bind(C, name="rms")
real*8, dimension(s), intent(in) :: a
integer*4 :: s
rms = sqrt(sum(a**2)/s)
end function
class sympy.codegen.fnodes.cmplx(*args)[源代码]#

Fortran复杂转换函数。

sympy.codegen.fnodes.dimension(*args)[源代码]#

创建具有(最多7个)范围的“dimension”属性。

实例

>>> from sympy import fcode
>>> from sympy.codegen.fnodes import dimension, intent_in
>>> dim = dimension('2', ':')  # 2 rows, runtime determined number of columns
>>> from sympy.codegen.ast import Variable, integer
>>> arr = Variable('a', integer, attrs=[dim, intent_in])
>>> fcode(arr.as_Declaration(), source_format='free', standard=2003)
'integer*4, dimension(2, :), intent(in) :: a'
class sympy.codegen.fnodes.dsign(*args)[源代码]#

双精度参数的Fortran符号内在函数。

class sympy.codegen.fnodes.isign(*args)[源代码]#

整数参数的Fortran符号内在函数。

class sympy.codegen.fnodes.kind(*args)[源代码]#

Fortran类函数。

sympy.codegen.fnodes.lbound(array, dim=None, kind=None)[源代码]#

为Fortran的“lbound(…)”函数调用创建一个AST节点

参数:

数组 :符号或字符串

dim :表达式

kind :表达式

实例

>>> from sympy import fcode
>>> from sympy.codegen.fnodes import lbound
>>> lb = lbound('arr', dim=2)
>>> fcode(lb, source_format='free')
'lbound(arr, 2)'
class sympy.codegen.fnodes.literal_dp(num, dps=None, precision=None)[源代码]#

Fortran双精度实数字面值

class sympy.codegen.fnodes.literal_sp(num, dps=None, precision=None)[源代码]#

Fortran单精度实数字面值

class sympy.codegen.fnodes.merge(*args)[源代码]#

Fortran合并函数

sympy.codegen.fnodes.reshape(source, shape, pad=None, order=None)[源代码]#

创建一个AST节点来调用Fortran的“reshee(…)”

参数:

来源 :符号或字符串

形状 :ArrayExpr

sympy.codegen.fnodes.shape(source, kind=None)[源代码]#

为Fortran的“shape(…)”函数调用创建一个AST节点

参数:

来源 :符号或字符串

kind :表达式

实例

>>> from sympy import fcode
>>> from sympy.codegen.fnodes import shape
>>> shp = shape('x')
>>> fcode(shp, source_format='free')
'shape(x)'
sympy.codegen.fnodes.size(array, dim=None, kind=None)[源代码]#

为Fortran的“size(…)”函数调用创建一个AST节点

实例

>>> from sympy import fcode, Symbol
>>> from sympy.codegen.ast import FunctionDefinition, real, Return
>>> from sympy.codegen.fnodes import array, sum_, size
>>> a = Symbol('a', real=True)
>>> body = [Return((sum_(a**2)/size(a))**.5)]
>>> arr = array(a, dim=[':'], intent='in')
>>> fd = FunctionDefinition(real, 'rms', [arr], body)
>>> print(fcode(fd, source_format='free', standard=2003))
real*8 function rms(a)
real*8, dimension(:), intent(in) :: a
rms = sqrt(sum(a**2)*1d0/size(a))
end function
class sympy.codegen.fnodes.use(*args, **kwargs)[源代码]#

Represents a use statement in Fortran.

实例

>>> from sympy.codegen.fnodes import use
>>> from sympy import fcode
>>> fcode(use('signallib'), source_format='free')
'use signallib'
>>> fcode(use('signallib', [('metric', 'snr')]), source_format='free')
'use signallib, metric => snr'
>>> fcode(use('signallib', only=['snr', 'convolution2d']), source_format='free')
'use signallib, only: snr, convolution2d'
class sympy.codegen.fnodes.use_rename(*args, **kwargs)[源代码]#

Represents a renaming in a use statement in Fortran.

实例

>>> from sympy.codegen.fnodes import use_rename, use
>>> from sympy import fcode
>>> ren = use_rename("thingy", "convolution2d")
>>> print(fcode(ren, source_format='free'))
thingy => convolution2d
>>> full = use('signallib', only=['snr', ren])
>>> print(fcode(full, source_format='free'))
use signallib, only: snr, thingy => convolution2d

算法(sympy.codegen.算法)#

sympy.codegen.algorithms.newtons_method(expr, wrt, atol=1e-12, delta=None, *, rtol=4e-16, debug=False, itermax=None, counter=None, delta_fn=<function <lambda>>, cse=False, handle_nan=None, bounds=None)[源代码]#

为Newton-Raphson方法(一种寻根算法)生成一个AST。

参数:

expr :表达式

wrt :符号

关于,即变量是什么。

atol : number or expression

绝对公差(停止标准)

rtol : number or expression

Relative tolerance (stopping criterion)

三角洲 :符号

会是一个 Dummy 如果 None .

调试 布尔

是否在迭代期间打印收敛信息

itermax公司 :数字或表达式

最大迭代次数。

柜台 :符号

会是一个 Dummy 如果 None .

delta_fn: Callable[[Expr, Symbol], Expr]

computes the step, default is newtons method. For e.g. Halley's method use delta_fn=lambda e, x: -2*e*e.diff(x)/(2*e.diff(x)**2 - e*e.diff(x, 2))

cse: bool

Perform common sub-expression elimination on delta expression

handle_nan: Token

How to handle occurrence of not-a-number (NaN).

bounds: Optional[tuple[Expr, Expr]]

Perform optimization within bounds

解释

返回基于的抽象语法树(AST) sympy.codegen.ast 对于Netwon的根查找方法。

实例

>>> from sympy import symbols, cos
>>> from sympy.codegen.ast import Assignment
>>> from sympy.codegen.algorithms import newtons_method
>>> x, dx, atol = symbols('x dx atol')
>>> expr = cos(x) - x**3
>>> algo = newtons_method(expr, x, atol=atol, delta=dx)
>>> algo.has(Assignment(dx, -expr/expr.diff(x)))
True

工具书类

sympy.codegen.algorithms.newtons_method_function(expr, wrt, params=None, func_name='newton', attrs=(), *, delta=None, **kwargs)[源代码]#

为实现Newton-Raphson方法的函数生成AST。

参数:

expr :表达式

wrt :符号

关于,即变量是什么

帕拉姆 :i符号表

在迭代过程中,这些常数将被视为在表达式中被接受的符号。

func_name :结构

生成函数的名称。

阿特斯 :元组

作为传递的属性实例 attrsFunctionDefinition .

**kwargs :

传递给的关键字参数 sympy.codegen.algorithms.newtons_method() .

实例

>>> from sympy import symbols, cos
>>> from sympy.codegen.algorithms import newtons_method_function
>>> from sympy.codegen.pyutils import render_as_module
>>> x = symbols('x')
>>> expr = cos(x) - x**3
>>> func = newtons_method_function(expr, x)
>>> py_mod = render_as_module(func)  # source code as string
>>> namespace = {}
>>> exec(py_mod, namespace, namespace)
>>> res = eval('newton(0.5)', namespace)
>>> abs(res - 0.865474033102) < 1e-12
True

Python实用程序(辛普森.代码根.pyutils)#

sympy.codegen.pyutils.render_as_module(content, standard='python3')[源代码]#

Renders Python code as a module (with the required imports).

参数:

standard :

查看参数 standard 在里面 sympy.printing.pycode.pycode()

C公用事业(角质层)#

sympy.codegen.cutils.render_as_source_file(content, Printer=<class 'sympy.printing.c.C99CodePrinter'>, settings=None)[源代码]#

呈现C源文件(使用必需的#include语句)

Fortran实用程序(辛普森。科德根。福蒂斯)#

sympy.codegen.futils.render_as_module(definitions, name, declarations=(), printer_settings=None)[源代码]#

创建一个 Module 实例并将其呈现为字符串。

这将为具有正确 use 声明。

参数:

定义 :i可读取

name :结构

声明 :i可读取

传递给 sympy.codegen.fnodes.Module . 它将使用use语句、“implicit none”和从 definitions .

printer_settings :dict命令

传递给 FCodePrinter (默认: {{'standard': 2003, 'source_format': 'free'}}