我正在尝试使用以下python代码解决一组方程式(当然使用SymPy):
def Solve(kp1, kp2):
a, b, d, e, f = S('a b d e f'.split())
equations = [
Eq(a+b, 2.6),
Eq(2*a + b + d + 2*f, 7),
Eq(d + e, 2),
Eq(a*e,kp2*b*d),
Eq( ((b * (f**0.5))/a)*((a+b+d+e+f+13.16)**-0.5), kp1)
]
return solve(equations)
代码在大约35秒后成功解决了方程式。 Solve()
函数在另一个文件中的迭代块(大约2000次迭代)中使用,因此速度对我来说非常重要。
有没有办法加速求解器?如果没有,你能推荐另一种方法来解决使用python的方程组吗?
答案 0 :(得分:5)
你只需要解决一次方程式。之后,您将获得以下形式的等式:
所以你可以简单地计算a,...,e依赖于kp1和kp2。例如,求解第一,第三和第四个方程给出:
在我的电脑上解决所有五个方程式太慢了,但是如果它给你一个表达式,你只需要插入(替换)kp1和kp2的值,你就不必再次求解方程式了。如需替换,请查看sympy documentation。
所以你的循环应该是这样的:
solutions = sympy.solve(eqs, exclude=[kp1, kp2])
for data_kp1, data_kp2 in data:
for key, eq in solutions:
solution = eq.subs([(kp1, data_kp1), (kp2, data_kp2)])
final_solutions.append("{key}={solution}".format(key=key, solution=solution))
答案 1 :(得分:2)
求解a,b,d,e的前4个线性方程。这产生两种解决方案。将这些中的每一个替换为第5个等式(以这种形式:Eq(b**2*f, d**2*kp1**2*(a + b + 2*d + f + 13.16)))
给出两个等式(e51和e52)。这两个等式在f中是非线性的,如果你在它们上使用unrad,你将最终得到2 f中的有序多项式 - 这可能就是为什么你没有得到解,因为一般只有四次方是可以解的。调用这两个方程e51u和e52u。
如果你对真正的根感兴趣,你可以使用real_roots给这些多项式赋予根,然后代入kp1和kp2的所需值,只留下f作为未知。例如,
>>> ans = solve(equations[:-1],a,b,d,e)
>>> l=equations[-1] # modified as suggested
>>> l=l.lhs-l.rhs
>>> l
b**2*f - d**2*kp1**2*(a + b + 2*d + f + 13.16)
>>> e51=l.subs(ans[0]); e51u=unrad(e51)[0]
>>> e52=l.subs(ans[1]); e52u=unrad(e52)[0]
>>> import random
>>> for r1,r2 in [[random.random() for i in range(2)] for j in range(3)]:
... print [i.n(2) for i in real_roots(e51u.subs(dict(kp1=r1,kp2=r2)))]
... print [i.n(2) for i in real_roots(e52u.subs(dict(kp1=r1,kp2=r2)))]
... print '^_r1,r2=',r1,r2
...
[1.7, 2.9, 3.0, 8.2]
[1.7, 2.9, 3.0, 8.2]
^_r1,r2= 0.937748743197 0.134640776315
[1.3, 2.3, 4.7, 7.4]
[1.3, 2.3, 4.7, 7.4]
^_r1,r2= 0.490002815309 0.324553144174
[1.1, 2.1]
[1.1, 2.1]
^_r1,r2= 0.308803300429 0.595356213169
看来e51u和e52u都给出了相同的解决方案,所以也许你只需要使用其中一个。你应该检查原始方程中的答案,看看哪个是真正的解决方案:
>>> r1,r2
(0.30880330042869408, 0.59535621316941589)
>>> [e51.subs(dict(kp1=r1,kp2=r2,f=i)).n(2) for i in real_roots(e51u.subs(dict(kp1=r1,kp2=r2)))]
[1.0e-12, 13.]
所以在这里你看到只有第一个解决方案(从上面看来是1.1)实际上是一个解决方案; 2.1是一个虚假的解决方案。