0

我们在pythonevalf()的包中找不到任何东西。symengine有没有存在?

更详细地解释我们的问题。

我们正在尝试切换到,symengine而不是sympy因为我们感知到必要的加速。我们使用符号代数工具来解决在组合随机结构生成中具有应用的优化问题。

在对 sympy 进行了一些测试后,我们发现解决一些“看起来很无辜”的优化问题需要在范围1e+24内外进行中间计算(但最终它们最终提供了正确的答案)。然后我发现我误用了 sympy 的功能subs(),因为它不如evalf()替换字典精确。

这个问题在函数 subs 的手册中有描述:

If the substitution will be followed by numerical
evaluation, it is better to pass the substitution to
evalf as

>>> (1/x).evalf(subs={x: 3.0}, n=21)
0.333333333333333333333

rather than

>>> (1/x).subs({x: 3.0}).evalf(21)
0.333333333333333314830

因为前者将确保获得所需的精度水平。实际上,使用标准sympy.subs()函数替换 e+24 或symengine.subs()抛出无穷大,尽管 e+24 仍在 numpy.float64 的范围内,当我调用 built-in 时,我怀疑它是我的机器强制转换的标准类型float(...)功能。

我们知道“lambdify”,如果您进行重复替换并希望获得较高的数值精度,这是推荐的步骤,但这将是下一步。我们无法使用 python 解释器的手册,因为代码是预编译的,在互联网上也很难找到。查看源代码也没有帮助(但也许我错过了一些东西)。

4

1 回答 1

1

symengine 上还没有evalf。以下是如何实现上述目标,

In [14]: (1/x).subs({x: 3}).n(73, real=True)
Out[14]: 0.333333333333333333333

请注意,如果您执行以下操作,它将以精度 53(15 个十进制数字)进行替换

In [15]: (1/x).subs({x: 3.0}).n(73, real=True)
Out[15]: 0.333333333333333314830

您可以使用 subs withFloat(3.0, dps=21)而不仅仅是3.0以更高的精度进行计算。下面的示例将适用于 symengine 和 sympy。

In [16]: (1/x).subs({x: Float(3.0, dps=21)})
Out[16]: 0.333333333333333333333

请注意,.n()在 symengine 中更喜欢二进制数字而不是十进制数字的精度,并且real=True需要为实域给出,否则它会假设复数并给您一个带有虚部的复数,0.并且会比real=True.

于 2017-07-18T13:10:23.133 回答