#python #sympy
#python #симпатичный
Вопрос:
У меня есть система из пяти уравнений с пятью неизвестными. Возвращаемое решение является EmptySet() . Решение только для двух переменных, например Ta2, Tb2 возвращает правильное решение, но только в параметрической форме {(0.040093015796482*Va2*pk, 0.0240558094779889*Vb2*pk)} для других 3 переменных. Есть ли способ вернуть числовые значения всех пяти неизвестных?
Решение системы уравнений в электронной таблице дает следующие результаты: pk = 246,274, Ta2 = 223,752, Tb2 = 280,451, Vb2 = 47,339, Va2 = 22,661. Замена их в выводе sympy 0.0400930157966482 * Va2 * pk для Ta2 дает 223.752, как и ожидалось.
from sympy.core.symbol import symbols
from sympy.solvers.solveset import nonlinsolve
Va, Ta, na = symbols('Va Ta na')
Vb, Tb, nb = symbols('Vb Tb nb')
pa, pb = symbols('pa pb')
R = symbols('R')
Ta2 , Tb2 = symbols('Ta2 Tb2')
Va2 , Vb2 = symbols('Va2 Vb2')
pk = symbols('pk')
R = 8.314
Va = 30.
Vb = 40.
Ta = 200.
Tb = 300.
na = 3.
nb = 5.
pa = na*R*Ta/Va
pb = nb*R*Tb/Vb
SumV = Va Vb
eq1 = pa**5 * Va**7 - pk**5 * Va2**7
eq2 = pb**5 * Vb**7 - pk**5 * Vb2**7
eq3 = pk * Va2 - na * R * Ta2
eq4 = pk * Vb2 - nb * R * Tb2
eq5 = Va2 Vb2 - SumV
system = [eq1,eq2,eq3,eq4,eq5]
solvefor = [Ta2, Tb2, pk, Va2, Vb2]
res = nonlinsolve(system, solvefor)
res
Комментарии:
1. Вы уверены, что это разрешимо? Система из 5 некоррелированных уравнений с 5 переменными имеет либо 0, либо 1 решение. Возможно, вы нашли решение с 0
2. Решение в электронной таблице Excel дает следующие результаты: pk = 246.274, Ta2 = 223.752, Tb2 = 280.451, Vb2 = 47.339, Va2 = 22.661.
3. спасибо, вам следует обновить свой вопрос, указав, что решение существует 🙂 Я посмотрю на это
Ответ №1:
Это легко решить для линейных символов, поэтому сделайте это первым:
>>> from sympy import solve, nsolve
>>> solve(system[-3:],Va2,Vb2,Ta2,dict=True)
[{Va2: 0.01*(-4157.0*Tb2 7000.0*pk)/pk, Vb2: 41.57*Tb2/pk, Ta2: -1.66666666666667*Tb2 2.80651110576538*pk}]
>>> s3=_[0]
Подставьте это во 2-е уравнение
>>> system[1].subs(s3)
-214516237736.33*Tb2**7/pk**2 4.82643407848195e 23
И решите для pk**2
>>> solve(_,pk**2)
[4.44461136831276e-13*Tb2**7]
Обновите решение до сих пор, используя квадратный корень (который должен быть в порядке, если значения положительны)
>>> s3.update({pk:sqrt(_[0])})
Подставьте это в первое уравнение и решите с разделением пополам в интересующем диапазоне. Функция очень плоская в интересующей области, поэтому для грубой оценки мы оставляем проверку выключенной:
>>> system[0].subs(s3)
2.78002602920561e 21 - 4.82643407848195e 23*(-Tb2 1.12262552342427e-6*sqrt(Tb2**7))**7/Tb2**7
>>> nsolve(_, (270,300), solver='bisect', verify=False)
280.451434985005
Добавьте это в свое решение (и замените обратно, если вам нужны числовые значения для всего)
Добавьте это в свое решение (и замените обратно, если вам нужны числовые значения для всего)
>>> s3.update({Tb2:_})
>>> for k in reversed(s3):
... for i in s3:
... s3[i] = s3[i].subs(k,s3[k])
...
>>> s3
{Va2: 22.661, Vb2: 47.3389, Ta2: 223.7519, pk: 246.2740, Tb2: 280.4514}
[числа в решении были вручную обрезаны для отображения]