python - 使用solve 来表达变量时出现 Sympy TypeError

标签 python sympy

以下一些example我在网上找到了,我可以这样做:

from sympy import var
from sympy import solve

Ldy, Ldz = var('Ldy Ldz')
g, x, y, z = var('g x y z')
xZ, yZ, zZ = var('xZ yZ zZ')
xdd, ydd, zdd = var('xdd ydd zdd')

E1 = z * xdd + (xZ - x) * (g + zdd)
E2 = z * ydd + (yZ - y) * (g + zdd) - Ldy
E3 = -y * xdd + x * ydd - zZ * (g + zdd) + Ldz

out = solve([E1, E2, E3], [xdd, ydd, Ldy])

print(type(xdd))
print("xdd = ", (out[xdd]).factor())

得出xdd = (g + zdd)*(x - xZ)/z

现在,为我自己的方程做这个:

from sympy import symbols, solve

x, y, z, k12, k26, x0 = symbols("x, y, z, k12, k26, x0")
symbols = x, y, z, k12, k26, x0

eq1 = k12 * x**2 -y
eq2 = k26 * y**3 - z
eq3 = x * 2*y + 6*z - x0

out = solve([eq1, eq2, eq3], [x,y,z])
print("x = ", (out[x]).factor())

给出类型错误:列表索引必须是整数或切片,而不是符号

我做错了什么?

最佳答案

问题是 solve 有多种返回类型:有时它返回一个列表,有时返回一个字典,有时返回一个字典列表。输出形式取决于所求解方程的细节:变量的数量、解的数量。这意味着应该使用 list=Truedict=True 来强制 solve 输出一致。请注意,dict=True 表示输出是字典的列表,因为可能存在多个解决方案——这里就是这种情况。在您的示例中:

out = solve([eq1, eq2, eq3], [x,y,z], dict=True)
for sol in out:
    print("x = ", sol[x].factor())

打印

x =  18**(1/3)*((3*x0 - sqrt(6*k12*k26*x0 + 1)/(k12*k26) + 1/(k12*k26))/k26)**(2/3)*(sqrt(6*k12*k26*x0 + 1) + 1)/(18*k12*x0)
x =  -18**(1/3)*((3*x0 + sqrt(6*k12*k26*x0 + 1)/(k12*k26) + 1/(k12*k26))/k26)**(2/3)*(sqrt(6*k12*k26*x0 + 1) - 1)/(18*k12*x0)
x =  -2**(1/3)*((3*x0 - sqrt(6*k12*k26*x0 + 1)/(k12*k26) + 1/(k12*k26))/k26)**(2/3)*(3**(2/3) - 3*3**(1/6)*I)*(sqrt(6*k12*k26*x0 +1) + 1)/(36*k12*x0)
x =  -2**(1/3)*((3*x0 - sqrt(6*k12*k26*x0 + 1)/(k12*k26) + 1/(k12*k26))/k26)**(2/3)*(3**(2/3) + 3*3**(1/6)*I)*(sqrt(6*k12*k26*x0 +1) + 1)/(36*k12*x0)
x =  2**(1/3)*((3*x0 + sqrt(6*k12*k26*x0 + 1)/(k12*k26) + 1/(k12*k26))/k26)**(2/3)*(3**(2/3) - 3*3**(1/6)*I)*(sqrt(6*k12*k26*x0 + 1) - 1)/(36*k12*x0)
x =  2**(1/3)*((3*x0 + sqrt(6*k12*k26*x0 + 1)/(k12*k26) + 1/(k12*k26))/k26)**(2/3)*(3**(2/3) + 3*3**(1/6)*I)*(sqrt(6*k12*k26*x0 + 1) - 1)/(36*k12*x0)

出于这个原因和其他原因,SymPy 开发人员建议使用 solveset and its relatives而不是解决。具体来说,可以在此处使用 nonlinsolve:

out = nonlinsolve([eq1, eq2, eq3], [x,y,z])
for sol in out:
    print("x = ", sol[x].factor())

打印

x =  -18**(1/3)*((3*x0 + sqrt(6*k12*k26*x0 + 1)/(k12*k26) + 1/(k12*k26))/k26)**(2/3)*(sqrt(6*k12*k26*x0 + 1) - 1)/(18*k12*x0)
x =  18**(1/3)*((3*x0 - sqrt(6*k12*k26*x0 + 1)/(k12*k26) + 1/(k12*k26))/k26)**(2/3)*(sqrt(6*k12*k26*x0 + 1) + 1)/(18*k12*x0)
x =  2**(1/3)*((3*x0 + sqrt(6*k12*k26*x0 + 1)/(k12*k26) + 1/(k12*k26))/k26)**(2/3)*(3**(2/3) - 3*3**(1/6)*I)*(sqrt(6*k12*k26*x0 + 1) - 1)/(36*k12*x0)
x =  2**(1/3)*((3*x0 + sqrt(6*k12*k26*x0 + 1)/(k12*k26) + 1/(k12*k26))/k26)**(2/3)*(3**(2/3) + 3*3**(1/6)*I)*(sqrt(6*k12*k26*x0 + 1) - 1)/(36*k12*x0)
x =  -2**(1/3)*((3*x0 - sqrt(6*k12*k26*x0 + 1)/(k12*k26) + 1/(k12*k26))/k26)**(2/3)*(3**(2/3) + 3*3**(1/6)*I)*(sqrt(6*k12*k26*x0 +1) + 1)/(36*k12*x0)
x =  -2**(1/3)*((3*x0 - sqrt(6*k12*k26*x0 + 1)/(k12*k26) + 1/(k12*k26))/k26)**(2/3)*(3**(2/3) - 3*3**(1/6)*I)*(sqrt(6*k12*k26*x0 +1) + 1)/(36*k12*x0)

求解集及其亲属的返回类型始终是 SymPy 集。

关于python - 使用solve 来表达变量时出现 Sympy TypeError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52534507/

相关文章:

python-3.x - 如何用 sympy 声明自然符号?

python - 使用 sympy 集成指数函数

python - 如何实现最大似然估计类型 2?

python - state.sls 和 state.apply 之间有什么区别?

python - 比较 Mathematica 和 Python 中的卷积

python - 如何将多个列表划分在一起同时保持顺序?

python - Series 的真值在数据框中不明确

python - 在 sympy 中设置输出为 2**3 * 2**4 = 2**7 而不是 128

python - django:如果 QueryDict 中不存在,则分配 None 值

python - 如何修复 Python 数独求解器错误?