我正在尝试使用Sympy和Python解决一个非线性方程组。
结果几乎是正确的,但始终只有极小的假想部分,并且此过程非常耗时。
我还尝试在Matlab下进行相同的计算,结果非常好且快速。
我知道虚构的小部分可以忽略。但是我认为我的代码中肯定有错误,导致缓慢而虚构的部分。有人可以帮我吗?
Python:3.6
Sympy:1.1.1
import sympy
A1, B1, C1, D1, E1, F1 = (0.0019047619047619048,
-1.7494954273533616e-19,
0.0004761904761904762,
-8.747477136766808e-18,
0.047619047619047616,
1.0)
A2, B2, C2, D2, E2, F2 = (8.264462809917356e-05,
-0.0,
0.00033057851239669424,
-0.008264462809917356,
-0.03305785123966942,
1.0)
k, b = sympy.symbols('k b')
eq1 = B1 ** 2 * b ** 2 + 2 * B1 * D1 * b - 2 * B1 * E1 * b * k - 4 * F1 * B1 * k + D1 ** 2 + 2 * D1 * E1 * k + \
4 * C1 * D1 * b * k + E1 ** 2 * k ** 2 - 4 * A1 * E1 * b - 4 * A1 * C1 * b ** 2 - 4 * C1 * F1 * k ** 2 - 4 * A1 * F1
eq2 = B2 ** 2 * b ** 2 + 2 * B2 * D2 * b - 2 * B2 * E2 * b * k - 4 * F2 * B2 * k + D2 ** 2 + 2 * D2 * E2 * k + \
4 * C2 * D2 * b * k + E2 ** 2 * k ** 2 - 4 * A2 * E2 * b - 4 * A2 * C2 * b ** 2 - 4 * C2 * F2 * k ** 2 - 4 * A2 * F2
s=sympy.solve([eq1,eq2],[k,b])
print(s)
这就是我在Python和Sympy下获得的东西,其中的虚构部分很小。而且几乎要花10秒。这对于我的整个项目都是不可接受的。
[(1.07269682322063 + 2.8315655624133e-28*I, -27.3048937553762 + 0.e-27*I),
(1.79271658724978 - 2.83156477591471e-28*I, -76.8585791921325 - 0.e-27*I),
(2.34194482854222 + 2.83156702952074e-28*I, -19.2027508047623 - 0.e-26*I),
(5.20930842765403 - 2.83156580622397e-28*I, -105.800442914396 - 7.59430998293648e-28*I)]
这就是我在MATLAB下使用“ solve”获得的结果。非常快。那就是我想要的。
k =
5.2093
1.7927
1.0727
2.3419
b =
-105.8
-76.859
-27.305
-19.203
答案 0 :(得分:0)
SymPy打算是一个符号包,而不是数字包,因此应该可以预期结果。但是,有函数**
可用于查找数值解。在SymPy / mpmath中,没有专用的方法(我知道)可以计算多项式的所有根(在这种情况下为一对二次)。您将必须一一找到根:
nsolve
但是人们可以使用现有的工具来构建此类方程的求解器。以下是一个示例(在极端情况下可能会出现许多数字问题):
>>> list(nsolve((eq1, eq2), (k,b), (1, 1)))
[1.07269682322063, -27.3048937553762]
这为问题中的方程式提供了以下解决方案:
def n2solve(eq1, eq2, x, y, n):
"""Return numerical solutions for 2 equations in
x and y where each is polynomial of order 2 or less
as would be true for equations describing geometrical
objects.
Examples
========
>>> n2solve(x**2 + y, y**2 - 3*x*y + 4, x, y, 3)
(-2.82, -7.96)
(-1.34, -1.80)
"""
from sympy.core.containers import Tuple
from sympy.solvers.solvers import unrad, solve
eqs = Tuple(eq1, eq2)
sym = set([x, y])
assert all(i.free_symbols == sym for i in eqs)
anx = solve(eq1, x)[0]
yeq = eq2.subs(x, anx)
z = unrad(yeq)
z = z[0] if z else yeq
yy = real_roots(z)
def norm(x,y):
return abs((x**2+y**2).n(2))
got=[]
for yi in yy:
yi = yi.n(n)
ty = eqs.subs(y, yi)
for xi in real_roots(ty[0]):
xi = xi.n(n)
got.append((norm(*ty.subs(x, xi)), xi, yi))
return sorted([(x,y) for e,x,y in sorted(got)[:len(got)//2]])