Floating point Sympy使用int参数,但使用浮点旋转
我正在mac上使用Sympy1.0和Python2.7.10。问题是,如果我对参数使用浮点数而不是整数,solve()似乎会永远旋转 这是我的脚本,其中a、b和c指定为int,如图所示。无论是否对a、b和c进行smpfify,它都会给出以下输出:Floating point Sympy使用int参数,但使用浮点旋转,floating-point,sympy,Floating Point,Sympy,我正在mac上使用Sympy1.0和Python2.7.10。问题是,如果我对参数使用浮点数而不是整数,solve()似乎会永远旋转 这是我的脚本,其中a、b和c指定为int,如图所示。无论是否对a、b和c进行smpfify,它都会给出以下输出: from sympy import * x = symbols('x') a = 500 b = 10 c = 333 y = a + b * (x - c) - (a * (x / c) + x * b * log(x / c)) print
from sympy import *
x = symbols('x')
a = 500
b = 10
c = 333
y = a + b * (x - c) - (a * (x / c) + x * b * log(x / c))
print 'y=', y
solution = solve(y, x)
print 'solve() gives:', solution
这张照片是:
y= -10*x*log(x/333) + 2830*x/333 - 2830
solve() gives: [333*exp(LambertW(-283*exp(-283/333)/333) + 283/333)]
这是正确的,正如我使用nsolve()数值求解并与独立计算的解进行比较所验证的那样
现在,我将a、b和c的定义更改为:
a = 500.0
b = 10.0
c = 333.0
然后输出如下:
y= -10.0*x*log(0.003003003003003*x) + 8.4984984984985*x - 2830.0
有了这个,solve()开始旋转,似乎永远不会停止。请注意,此表达式在数字上是正确的
因此,问题是:如何在Symphy方程中使用浮点参数?无法解释Symphy为什么会有问题,但是,我怀疑这与浮点表示不精确有关 一种解决方法是在不明确指定参数
a
、b
和c
的情况下求解,然后使用.subs()
附言:@asmeuer向我介绍了LambertW
的分支选择选项,我认为问题在于solve默认情况下会将浮动转换为理性,这会导致日志反转时产生巨大的权力solve(rational=False)
应该关闭此功能,但对我来说,这会导致solve
失败,出现NotImplementedError
。我打开了它 我在写完之前不小心发了帖子。我想说的是:首先,我看到了你所看到的,使用浮动。第二,当我使用int而不是float时,我得到了我之前看到的涉及LambertW的解,而不是数值解。奇怪。第三,solve()返回一个表达式;但有两个根源。另一个接近242.259。难道我不希望solve()也能找到这个吗?叹气。2.当我使用int而不是float时,我看到了一个涉及LambertW的解决方案(但它与我之前看到的解决方案不同——可能只是这个根的特例解决方案。)@wchlm实际上,y
有两个根。不幸的是,我无法找到一种方法让solve
(或solveset
)同时提供这两种方法(尽管我不是专家)。@wchlm我已经根据@asmeuer关于如何获得LambertW
的各个分支的建议更新了答案,谢谢。我明白你在做什么,尤其是在读了兰伯特的W(最近我把Abramowitz和Stegun的副本给了别人,以为我再也不需要它了;-)上的维基百科页面之后。但是,如图所示的确切代码在尝试的replace()上给了我一个Python语法错误:文件“stelios.py”,第8行sol_two_分支=[sol[0],sol[0]。replace(sp.LambertW,lambda*args:sp.LambertW(*args,-1))]SyntaxError:只有命名的参数可以跟在*表达式后面,您能帮我解决这个问题吗?(这可能是因为我仍在使用Python 2吗?)。提供两个rootsye,这是solve的一个已知问题。具有LambertW的解应该有无限多个复解,每个分支对应一个复解。您可以通过设置第二个参数获得其他分支,如LambertW(-283*exp(-283/333)/333,-1)
。
import sympy as sp
x, a, b, c = sp.symbols('x, a, b, c')
y = a + b * (x - c) - (a * (x / c) + x * b * sp.log(x / c))
sol = sp.solve(y, x)
# find the second root manually by considering the k=-1 branch
# (solve provides only the k=0 branch)
sol_two_branches = [sol[0], sol[0].replace(sp.LambertW, lambda *args: sp.LambertW(*args,-1))]
print([s.subs({a:500,b:10,c:333}).n() for s in sol_two_branches])
[333.000000000000, 242.528588686908]