为什么SymPy的解算器只返回一个简单的解决方案?

时间:2013-11-04 13:28:07

标签: python-2.7 solver sympy

我想找到满足特定方程的所有实数。我在 Mathematica 中使用

找到这些值并没有问题
Solve[n*9^5 == 10^n-1, n]

gives both 0 and 5.51257;但是当我使用SymPy(0.7.3; Python 2.7.5)solve

n = sympy.symbols('n')
sympy.solve(n*9**5 - 10**n-1, n)

我似乎只得到一些看似0的东西,而不是第二个值,这就是我真正想要的东西。

如何让SymPy生成我正在寻找的非平凡解决方案?我应该使用不同的功能或包装吗?

1 个答案:

答案 0 :(得分:4)

solve只提供符号解决方案,因此如果找不到解决方案的封闭表单,它就不会返回它。如果你只关心数字解决方案,你想在SymPy中nsolve,或者你可以使用更加面向数字的Python库。例如

sympy.nsolve(n*9**5 - 10**n-1, n, 5)

将为您提供所需的解决方案。


使用solve的问题在于有无限多个解决方案,每个解决方案都对应于LambertW函数的一个分支。有关完整的解决方案集,请参阅WolframAlpha。不幸的是,only the principal branch of LambertW is implemented in SymPy

在修复此问题之前,另一种解决问题的方法是使用solve手动评估mpmath.lambertw在另一个分支上返回的LambertW。最简单的方法是使用lambdify

s = sympy.solve(n*9**5 - 10**n-1, n)    
import sympy.mpmath
# Replace -1 with any integer. -1 gives the other real solution, the one you want
lambdify([], s, [{'LambertW': lambda x: sympy.mpmath.lambertw(x, -1)}, "mpmath"])()

这会给[mpf('5.5125649309411875')]

字典告诉lambdify使用LambertW分支评估-1函数,使用mpmath。 "mpmath"告诉它将mpmath用于解决方案中可能存在的任何其他函数。