【问题标题】:Can it be that `sympy` is much, much slower than Mathematica?'sympy' 会比 Mathematica 慢很多吗?
【发布时间】:2015-12-12 17:14:54
【问题描述】:

我正在使用 Sympy 复制 Mathematica 结果,而我对后者不熟悉,所以我可能做错了。但是,我注意到一些使用 Mathematica 最多花费一分钟的东西在 sympy 中只会持续很长时间(阅读:在一小时前开始后没有完成)。这适用于Simplify()solve()。是我做错了什么,还是真的是这样?

我会附上我的solve() 案例:

import sympy as sp
from sympy import init_printing
init_printing()

p, r, c, p, y, Lambda = sp.symbols('p r c p y Lambda')

F = sp.Symbol('F')
eta1 = lambda p: 1/(1-sp.exp(-Lambda) * sp.exp(-Lambda)*(sp.exp(Lambda) - 1 - Lambda))
eta2 = lambda p: 1/(1-sp.exp(-Lambda)) * sp.exp(-Lambda)/(1-F) * (sp.exp(Lambda*(1- F)) - 1 - Lambda*(1-F))

eta = lambda p: 1 - eta1(p) + eta2(p)
etaOfR = sp.limit(eta(p), F,  1)

S = lambda p: eta(p)*y/p*(p-c)
SOfR = etaOfR*y/r*(r-c)
sp.solve(S(p)-SOfR, F)

对应的 Mathematica 代码

ClearAll[r, p, lambda, a, A, c, eta, f, y, constant1, constant2, eta, \
etaOfR]
constant1[lambda_] := Exp[-lambda]/(1 - Exp[-lambda]);
constant2[lambda_] := constant1[lambda]*(Exp[lambda] - 1 - lambda);
eta[lambda_, f_] := 
  1 - constant2[lambda] + 
   constant1[lambda]*(Exp[lambda*(1 - f)] - 1 - lambda*(1 - f)) ;
etaOfR[lambda_] := Limit[eta[lambda, f], f -> 1];
expression1[lambda_, f_] := 
  y/p (p - c) eta[lambda, f] == y/r (r - c) etaOfR[lambda];

Solve[expression1[lambda, f], f] // FullSimplify

输出:

{{f -> (-(1 + lambda) p r + 
    c (lambda p + r) + (c - 
       p) r ProductLog[-E^(((-c lambda p + (c (-1 + lambda) + 
           p) r)/((c - p) r)))])/(lambda (c - p) r)}}

【问题讨论】:

  • 我最初的感觉是,Mathematica 目前可能比 Sympy 好很多,因为它拥有巨大的领先优势。
  • 为什么要用lambda定义函数?
  • @MaxNoe 因为教程没有提到如何定义函数,所以我搜索了一下,看到网上有人这样做。
  • 据我了解,sympy 不需要这些功能。只需使用您的符号。
  • 关于Simplify:简化并不是一个定义明确的东西,所以性能上的巨大差异以及结果的巨大差异完全可以预料。想想FullSimplifySimplify 之间的区别。前者可能会慢得多,即使它给出与后者相同的结果。 (这不适用于方程求解。)

标签: python wolfram-mathematica sympy


【解决方案1】:

正确的做法是:

from sympy import *
init_printing()
p, r, c, p, y, lam, f = symbols('p r c p y lambda f')
constant1 = exp(-lam) / (1 - exp(-lam))
constant2 = constant1 * (exp(lam) -  1 - lam)
eta = 1 - constant2 + constant1 * (exp(lam * (1-f)) - 1 - lam * (1 - f))
etaOfR = limit(eta, f,  1)
expression1 = Eq(y / p * (p - c) * eta, 
             y / r * (r - c) * etaOfR)
solve(expression1, f)

您也可以在此处查看笔记本: http://nbviewer.ipython.org/gist/jankoslavic/0ad7d5c2731d425dabb3

结果与 Mathematica 的结果相同(见最后一行),Sympy 的性能相当。

【讨论】:

  • sympy 中的 30 秒和 Mathematica 中的 1 秒不是我所说的可比性。 Certik 将 sympy 移植到 C++ 是有原因的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
  • 2013-09-24
  • 2010-11-06
  • 1970-01-01
相关资源
最近更新 更多