【问题标题】:Poor sympy linsolve/ solve performance可怜的 sympy linsolve/solve 性能
【发布时间】:2016-10-23 14:00:26
【问题描述】:

我正在使用 sympy 求解一个简单的线性方程组。

这是一个耦合 ODE,有变量的时间导数,我需要求解最高导数的方程组。 由于 sympy 不允许我解决像 phi_1.diff(t) 这样的语句,所以我用占位符符号替换了所有派生词。

例如:

phi.diff(t).diff(t) + phi(t) =0

变成

ddphi + phi(t) = 0

这很好用。解决方案是正确的,我可以模拟系统 - 这是一个钟摆:https://youtu.be/Gc_V2FussNk

问题在于求解方程组(使用linsolve)需要很长时间。

只需 2 个方程式,就需要 2 秒。 对于 3 个方程,它仍在计算中(超过 10 分钟后)。

编辑: @asmeurer 建议我尝试解决。 对于 n=3,linsolve 大约需要 34 分钟——我只进行了一次测量。 solve 需要 31 秒(3 次运行的平均值)。

不过,我相信线性 3x3 系统应该在几分之一秒内解决。

对于 n=4,solve 也变得非常慢(仍在计算中)

我已经格式化了代码并创建了一个 iPython 笔记本:http://nbviewer.jupyter.org/gist/lhk/bec52b222d1d8d28e0d1baf77d545ec5 如果你向下滚动一点,你可以看到方程组的格式化输出,并在其正下方调用linsolve

方程相当长,但在二阶导数中是严格线性的。 我相信这个系统是可以解决的。 我需要做的就是求解一个 3x3 线性方程组,其中系数可能是符号。

有没有更高效的方法来做到这一点?

【问题讨论】:

  • 如果您希望解决方案性能更高,您还应该将 jacobian 提供给 odeint
  • 你的微分方程在我看来不是线性的。 phi 的一些一阶导数项在您的方程组中是平方的。
  • 看起来solvelinsolve 快。
  • 问题是linsolve调用simplify,速度慢,没办法禁用。 solve 确实有一个标志,simplify=False。这有帮助吗?
  • 你可以和solve一起玩其他标志。我不是这方面的专家。

标签: python performance math simulation sympy


【解决方案1】:

solve(不是linsolve)有一些你可以设置的标志可以让它更快:

  • simplify=False:禁用简化结果。
  • rational=False:禁用浮点数到有理数的自动转换。

solve 文档字符串中有一条警告,rational=False 可能会导致某些方程由于多边形问题而无法求解,因此请注意这是一个潜在问题。

【讨论】:

  • 很好地指出理性的危险。一开始我也很警惕
  • 我相信最坏的情况是如果rational=False 失败,你会得到solve 的异常。
  • 在我的例子中(具有许多变量的简单线性方程),'simplify=False' 将速度提高了 100 倍,结果相同。太好了!
【解决方案2】:

我发现如果您在方程式之前运行 sp.init_printing(),则在 jupyter notebook 中求解可能会非常慢。我有一个“方程式”模块,我可以在其中编写方程式并求解它们。

这样更快:

import sympy as sp
import equations
sp.init_printing()

比这个:

import sympy as sp
sp.init_printing()
import equations

【讨论】:

    猜你喜欢
    • 2021-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-19
    相关资源
    最近更新 更多