sympy-未赋值expr和交换属性-保持浮点数未赋值

sympy-未赋值expr和交换属性-保持浮点数未赋值,sympy,Sympy,我有以下表达式:Bg=(pi/H)**2+(2.405/R)**2。在我的计算中,我希望保持浮点数2.405未计算,否则我的表达式中会出现长的浮点数 我想我可以用sympyUnevaluatedExpr来表示那个浮点数。这很好地发展了我的表情。问题是,包含UnevaluatedExpr的表达式是非交换的,因此我不能使用solve(),factor(),collect()。。。否则,它们会抛出错误,抱怨表达式的非交换性质 下面的代码显示表达式是非交换的,因为我使用了UnevaluatedExpr

我有以下表达式:
Bg=(pi/H)**2+(2.405/R)**2
。在我的计算中,我希望保持浮点数
2.405
未计算,否则我的表达式中会出现长的浮点数

我想我可以用sympy
UnevaluatedExpr
来表示那个浮点数。这很好地发展了我的表情。问题是,包含
UnevaluatedExpr
的表达式是非交换的,因此我不能使用
solve()
factor()
collect()
。。。否则,它们会抛出错误,抱怨表达式的非交换性质

下面的代码显示表达式是非交换的,因为我使用了
UnevaluatedExpr

import sympy as sp
R, H = sp.symbols("R, H", real=True, positive=True)

Bg = (sp.pi / H)**2 + (sp.UnevaluatedExpr(2.405) / R)**2
print(Bg)
print(Bg.is_commutative)

>>> 2.405**2/R**2 + pi**2/H**2
>>> False
尽管计算了浮点数,但以下代码表明表达式是可交换的:

Bg = (sp.pi / H)**2 + (2.405 / R)**2
print(Bg)
print(Bg.is_commutative)

>>> 5.784025/R**2 + pi**2/H**2
>>> True
问题:

  • UnevaluatedExpr
    和交换行为会是一个bug吗
  • 处理浮点数并防止其评估的最佳方法是什么?我想用一个符号来代替这个数字:对于我的简单示例来说,这很好,但是如果我使用更大的表达式,它很快就会变成一团乱麻

  • 是的,我会认为这是一个错误。我建议就此事展开讨论

    您可以使用符号。另一个想法是使用一个显式包装浮点的类,如

    class UnevaluatedFloat(Expr):
    定义新(cls,arg):
    返回表达式\uuuuuuuuuuuuuuuuuuuuu新(cls,浮点(arg))
    def _eval _evalf(自身、预处理):
    返回自参数[0]。\u eval\u evalf(prec)
    def_sympystr(自身、打印机):
    返回打印机.doprint(self.args[0])
    
    这将创建一个类,该类在调用
    evalf
    时提供浮点值,否则将保持未计算状态。它还打印为浮动。我添加了str打印机,但您也可以用同样的方式定义您关心的其他打印方法,如
    \u pretty
    \u latex
    等等。在中搜索“printmethod”

    范例

    >>> UnevaluatedFloat(1.0) + 1
    1 + 1.0
    >>> (UnevaluatedFloat(1.0) + 1).evalf()
    2.00000000000000
    

    用一个符号替换要跟踪的多位数是如何变得混乱的?一个符号就可以了,没有混乱。但当我有十几个或更多的浮点数要用不同的符号来代替时,情况就发生了巨大的变化。
    UnevaluatedExpr
    方法很有吸引力,因为每当表达式显示浮点时,我都可以调用一个自定义方法,用
    UnevaluatedExpr(digit)
    替换浮点数字。如果拼写
    UnevaluatedExpr=lambda x:Symbol(str(x))
    它将用一个名为float值的字符串替换float。