Sympy TypeError при использовании решает, чтобы выразить переменную в терминах других - PullRequest
0 голосов
/ 27 сентября 2018

Следуя некоторому примеру Я нашел в Интернете, я могу сделать это:

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())

Даёт TypeError: list indices must be integers or slices, not Symbol.

Что я делаю не так?

1 Ответ

0 голосов
/ 27 сентября 2018

Проблема в том, что solve имеет несколько типов возврата: иногда он возвращает список, иногда диктат, иногда список диктов.Форма вывода зависит от особенностей решаемых уравнений: количество переменных, количество решений.Это означает, что нужно использовать либо list=True, либо dict=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 и его родственников вместо solve.В частности, здесь можно использовать 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...