sympy CSE:避免 pow/powf

2024-01-12

当 Sympy 生成 C 代码时, 有没有办法对表达式中的 pow(或 powf)出现强制执行 CSE 优化?

例如,这段代码片段

c, s = symbols('c s')
myexpr = c**6/1800 - c**5/100 - 0.00833333333333333*c**4*s**2 + 19*c**4/200 + 0.1*c**3*s**2 - 9*c**3/20 + c**2*s**4/120 - 0.57*c**2*s**2 + 43*c**2/40 - c*s**4/20 + 1.35*c*s**2 + 23*c/50 - 0.000555555555555556*s**6 + 19*s**4/200 - 1.075*s**2 - 2107/1800
import sympy
from sympy.codegen.ast import real, float64
sub_exprs,final_expr = sympy.cse([myexpr])
for var,expr in sub_exprs : print "const real", printing.ccode(expr, standard='C99', assign_to=var, type_aliases={real: float64})
print "return ",printing.ccode(final_expr[0], standard='C99', type_aliases={real: float64}),";"

产生以下令人失望的输出:

const real x0 = pow(c, 2); 
const real x1 = pow(c, 3); 
const real x2 = pow(c, 4); 
const real x3 = pow(s, 2); 
const real x4 = pow(s, 4); 

return (1.0/1800.0)*pow(c, 6) - 1.0/100.0*pow(c, 5) + 1.3500000000000001*c*x3 - 1.0/20.0*c*x4 + (23.0/50.0)*c - 0.00055555555555555599*pow(s, 6) - 0.56999999999999995*x0*x3 + (1.0/120.0)*x0*x4 + (43.0/40.0)*x0 + 0.10000000000000001*x1*x3 - 9.0/20.0*x1 - 0.0083333333333333297*x2*x3 + (19.0/200.0)*x2 - 1.075*x3 + (19.0/200.0)*x4 - 2107.0/1800.0 ;

Pow 优化已被完全忽略。

解决这个问题的方法是什么?

备注:我看到这个问题有部分提到here https://docs.sympy.org/latest/modules/codegen.html: “在许多情况下,代码打印机不会打印最佳代码。这方面的一个例子是 C 中的 powers。x**2 打印为 pow(x, 2) 而不是 x*x。应该进行其他优化(例如数学简化)在代码打印机之前。”


sympy 中的 CSE 例程并不完美(改进的 CSE 是listed https://github.com/sympy/sympy/wiki/GSoC-2018-Ideas作为需要改进的领域),例如:

>>> sympy.cse([x**4, x**3*y])
([], [x**4, x**3*y])

扩展pow在打印机中或在打印机安装之前讨论过 https://github.com/sympy/sympy/pull/14139有一段时间,现在有一个创建扩展pow https://docs.sympy.org/latest/modules/codegen.html#sympy.codegen.rewriting.create_expand_pow_optimization优化可以帮助一些人:

>>> expand_opt = create_expand_pow_optimization(3)
>>> expand_opt(x**5 + x**3)
x**5 + x*x*x

但请注意,如果您向它们传递正确的优化标志,大多数编译器将已经生成最佳汇编(无论源代码中的 CSE)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

sympy CSE:避免 pow/powf 的相关文章

  • 如何使用 python sympy 进行 z 变换?

    z变换在信号处理中非常重要 我可以在sympy教程中找到傅里叶 拉普拉斯 余弦变换等 但我不知道如何使用 sympy 进行 z 变换 你能告诉我该怎么做吗 SymPy 尚未将其实现为变换函数 但您可以直接表示求和 然而 经过一番使用后 它看
  • 如何使用 sympy 定义条件函数?

    我希望能够定义一个表达式 该表达式获取定义变量的所有值并将表达式计算为0当它没有定义时 与此类似 import numpy as np import sympy as sp def expr k1 k2 x y sp symbols x y
  • SymPy 自动处理表达式

    我一直在使用 SymPy 将表达式转换为乳胶 然后由 Matplotlib 渲染 例如 from sympy import latex sympify from sympy abc import x str 2 x 3 x TeX late
  • 如何使用 SymPy codegen 生成 Fortran 子例程

    我想使用 SymPy codegen 实用程序生成 Fortran 子例程 我可以毫无问题地生成 Fortran 函数codegen f x y z f95 filename 但我想生成一个 Fortran 子例程 以便可以修改输入数组 我
  • 如果表达式包含 sympy 对象,则 Lambdify 表达式与数组一起使用时会引发 TypeError

    我正在使用 sympy 创建一个表达式 然后将其显示为乳胶sympy init printing http docs sympy org dev tutorial printing html setting up pretty printi
  • 没有名为 sympy 的模块

    你好 我正在 Edx 课程中使用 python 学习线性代数 http nbviewer ipython org github ULAFF notebooks tree may 14 2014 http nbviewer ipython o
  • sympy CSE:避免 pow/powf

    当 Sympy 生成 C 代码时 有没有办法对表达式中的 pow 或 powf 出现强制执行 CSE 优化 例如 这段代码片段 c s symbols c s myexpr c 6 1800 c 5 100 0 00833333333333
  • Python 求解一个变量的方程

    我正在尝试使用 SymPy 求解 python 中的方程 我有一个生成的方程 类似于function y 8 0 y 3 0 我将其与 SymPy 一起使用来创建一个如下所示的新方程 eq sympy Eq function 2 哪个输出y
  • Sympy:指数相乘而不是总和指数相乘

    我正在搜索如何告诉 SymPy 使用指数乘法而不是总和的指数 也就是说 它当前给我 exp a b 我想要得到 exp a exp b 一定有一个相当简单的方法 但我似乎找不到 你可以使用expand http docs sympy org
  • 当我对符号矩阵进行行归约时,为什么 SymPy 给出了错误的答案?

    如果我要求 SymPy 对奇异矩阵进行行归约 nu Symbol nu lamb Symbol lambda A3 Matrix 3 nu 1 0 0 3 nu 2 nu 1 2 0 0 2 nu 1 nu lamb 2 3 0 0 nu
  • 有没有办法在 SymPy 中处理常量函数参数?

    我正在生成符号函数并使用 SymPy 来简化它们 现在我想要一种方法来 简化 表示尚未拟合的函数中的常量参数的符号 例如 如果我生成一个多项式 我可能会生成一个像这样的字符串 C x x C x C x C SymPy 会变成 C x 2
  • 使用 SymPy codegen 为方程组生成 Fortran 子例程

    以我发现的以前的例子为基础here https stackoverflow com questions 25327845 how to generate fortran subroutine with sympy codegen 我尝试找出
  • Python Sympy 求解返回列表与字典

    我正在使用 sympy 及其求解函数 但我注意到它有时返回列表中的字典 但在其他情况下仅返回字典 没有列表 from sympy import x y symbols x y q 16 x 0 5 y 0 5 solve diff q x
  • 如何在 sympy 中求解简并方程组

    我有很多方程组 其中一些未指定 我想找到一个非零解 如果存在 或报告不存在 然而 sympy 似乎在试图找到所有解决方案时停滞不前 这是一个极端的例子 from sympy import A Matrix 0 0 0 0 0 0 0 0 0
  • Python 如何获取某一特定点的导数值?

    from sympy import x Symbol x y x 2 dx diff y x 这段代码可以得到y的导数 这很容易dx 2 x 现在我想得到的值dx for x 2 清楚地 dx 2 2 4 when x 2 但是我如何用Py
  • 用Python绘制不等式图

    我正在创建一个程序 它将随机生成线 即不等式 并显示满足约束的区域 我不介意使用哪些库 所以可以随意使用 sympy numpy 等 我将显示我当前的代码 但这只是填充了两行之间的区域 并且根本不使用不等式 如果可能的话 有一个图例就好了
  • SymPy 的多彩图

    我试图在 SymPy 中绘制函数 x 2 的图 并希望用线 x 3 y 9 覆盖它 然后在某些点周围画一个圆 我已经用代码完成了上述所有操作 import sympy as sp x sp Symbol x first plot the f
  • Sympy - 分数操作

    我基本上希望 Sympy 生成乳胶代码 frac x 1 3 y 但每当我要求它生成事物的 Tex 组件时 Sympy 总是返回 frac x 3 frac 1 3 如何避免分解方程 并将等于运算符分配给另一个变量 我还没有尝试将 y 部分
  • Sympy autowrap (cython):为 sympy.Max、sympy.Heaviside 定义“助手”

    我有一个 sympy Matrix 称为 J sym 我想自动包装它 最好使用 cython 后端 相应的符号存储在列表list args中 然而 我遇到的问题是显然不支持某些 sympy 函数 在我的例子中特别是 sympy Max 和
  • Sympy:从表达式获取函数

    要从 sympy 表达式中获取所有变量 可以调用 free symbols在表达上 我想找回全部功能用在表达式中 例如 从y in from sympy import f Function f g Function g x Symbol x

随机推荐