我需要解下面的非线性方程组:

enter image description here

我正在使用渐近的solve()函数来获得该方程组的解.通常,solve()会生成所有的解决方案.我已经指定了常量a、b、c、d、g、h的值,并期望得到所有的解.

但是solve()只产生一个解决方案,这太不正确了.我的问题是:

如何使用一个单一的python实用程序获得所有符号解决方案?我不想要数值解.

下面是实现solve()的代码部分:

from sympy import  solve

from sympy import symbols
x,y,a,b,c,d,g,h = symbols('x y a b c d g h')
a = 0.12
b = -2.031529100521498e-30
c = b
d = 1
g = 11
h = 0
F = (y + a/2)*x*(2*x**2 - 2*y*a + 2*d**2 + b + c) - (x*y*g**2)
G = (x**2 - y*a + b + d**2)*(x**2 - y*a + c+d**2) - 4*((y+a/2)**2)*x**2 - (h**2 + (x**2)*(g**2))
sol = solve([F,G],(x,y),dict=True,simplify=False)
print(sol)

推荐答案

以下是你的方程式:

In [45]: from sympy import  solve
    ...: 
    ...: from sympy import symbols
    ...: x,y,a,b,c,d,g,h = symbols('x y a b c d g h')
    ...: a = 0.12
    ...: b = -2.031529100521498e-30
    ...: c = b
    ...: d = 1
    ...: g = 11
    ...: h = 0
    ...: F = (y + a/2)*x*(2*x**2 - 2*y*a + 2*d**2 + b + c) - (x*y*g**2)
    ...: G = (x**2 - y*a + b + d**2)*(x**2 - y*a + c+d**2) - 4*((y+a/2)**2)*x**2 - (h**2 + (x**2)*(g*
    ...: *2))

我要把浮点数转换成有理数,因为浮点数和多项式一般不能很好地混合.我只想在这里指出,您的值b非常小,以至于实际上是零(在标准的64位浮点中).如果希望b为非零,则需要从一开始就避免浮点数,因为在执行上面所示的代码后,浮点数已经消失了.

In [46]: F, G = nsimplify(F), nsimplify(G) # don't use floats with polynomials

In [47]: F
Out[47]: 
                        ⎛   2   6⋅y    ⎞
-121⋅x⋅y + x⋅(y + 3/50)⋅⎜2⋅x  - ─── + 2⎟
                        ⎝        25    ⎠

In [48]: G
Out[48]: 
                                            2
     2           2        2   ⎛ 2   3⋅y    ⎞ 
- 4⋅x ⋅(y + 3/50)  - 121⋅x  + ⎜x  - ─── + 1⎟ 
                              ⎝      25    ⎠ 

方程式F分解,所以让我们依次取这两个因子:

In [56]: F.factor()
Out[56]: 
  ⎛      2         2        2               ⎞
x⋅⎝1250⋅x ⋅y + 75⋅x  - 150⋅y  - 74384⋅y + 75⎠
─────────────────────────────────────────────
                     625                     

In [57]: _, F1, F2 = F.factor().args

In [58]: F1
Out[58]: x

In [59]: solve([F1, G], [x, y])
Out[59]: [(0, 25/3)]

我相信这就是你提到的解决方案.您认为这是不正确的,但对于代码中所示的方程式来说,这绝对是正确的.

这是最简单的一个.现在,对于F2,我们计算Groebner基数:

In [61]: gb = groebner([F2, G], [x, y], method='f5b')

In [62]: print(gb[0])
x**2 + 16*y**4/121 + 595216*y**3/9075 + 892608*y**2/75625 + 1844017554*y/1890625 - 75643/75625

In [63]: print(gb[1])
y**5 + 74411*y**4/150 + 148777*y**3/1250 + 1845583341*y**2/250000 + 691424307*y/781250 - 113451/125000

我们可以看到,gb[1]y中的一个五次数.这个五次曲线是不可约的,并且可能没有根的公式(Abel-Ruffini),但当系数是显式有理数时,SymPy可以将根表示为RootOf:

In [66]: r1, r2, r3, r4, r5 = Poly(gb[-1]).all_roots()

In [67]: r1
Out[67]: 
       ⎛          5               4               3                 2                              
CRootOf⎝18750000⋅x  + 9301375000⋅x  + 2231655000⋅x  + 138418750575⋅x  + 16594183368⋅x - 17017650, 0

⎞
⎠

这些根中的每一个都可以在第一个方程中用来求解x,例如:

In [69]: print(solve([gb[0],y-r1], [x, y]))
[(-sqrt(-2250000*CRootOf(18750000*x**5 + 9301375000*x**4 + 2231655000*x**3 + 138418750575*x**2 + 16594183368*x - 17017650, 0)**4 - 200836800*CRootOf(18750000*x**5 + 9301375000*x**4 + 2231655000*x**3 + 138418750575*x**2 + 16594183368*x - 17017650, 0)**2 + 17019675 - 16596157986*CRootOf(18750000*x**5 + 9301375000*x**4 + 2231655000*x**3 + 138418750575*x**2 + 16594183368*x - 17017650, 0) - 1116030000*CRootOf(18750000*x**5 + 9301375000*x**4 + 2231655000*x**3 + 138418750575*x**2 + 16594183368*x - 17017650, 0)**3)/4125, CRootOf(18750000*x**5 + 9301375000*x**4 + 2231655000*x**3 + 138418750575*x**2 + 16594183368*x - 17017650, 0)), (sqrt(-2250000*CRootOf(18750000*x**5 + 9301375000*x**4 + 2231655000*x**3 + 138418750575*x**2 + 16594183368*x - 17017650, 0)**4 - 200836800*CRootOf(18750000*x**5 + 9301375000*x**4 + 2231655000*x**3 + 138418750575*x**2 + 16594183368*x - 17017650, 0)**2 + 17019675 - 16596157986*CRootOf(18750000*x**5 + 9301375000*x**4 + 2231655000*x**3 + 138418750575*x**2 + 16594183368*x - 17017650, 0) - 1116030000*CRootOf(18750000*x**5 + 9301375000*x**4 + 2231655000*x**3 + 138418750575*x**2 + 16594183368*x - 17017650, 0)**3)/4125, CRootOf(18750000*x**5 + 9301375000*x**4 + 2231655000*x**3 + 138418750575*x**2 + 16594183368*x - 17017650, 0))]

还有其他方法可以做到这一点,但这就给出了RootOf方面的所有解决方案.我不知道这是不是您想要的,但您可能希望SymPy返回一些不可能返回的东西.以下是全套解决方案:

In [71]: sx1, sx2 = solve(gb[0], x)

In [72]: sols = solve([F1, G], [x, y], dict=True)

In [73]: sols.extend([{x:sx1.subs(y, r), y:r} for r in [r1,r2,r3,r4,r5]])

In [74]: sols.extend([{x:sx2.subs(y, r), y:r} for r in [r1,r2,r3,r4,r5]])

这是它们在数字上的样子:

In [76]: for s in sols:
    ...:     print(s[x].n(3), s[y].n(3))
    ...: 
0 8.33
-0.0610 -496.
-10.9 -0.121
-0.0917 0.00102
-7.71 + 0.091*I -0.045 - 3.86*I
-7.71 - 0.091*I -0.045 + 3.86*I
0.0610 -496.
10.9 -0.121
0.0917 0.00102
7.71 - 0.091*I -0.045 - 3.86*I
7.71 + 0.091*I -0.045 + 3.86*I

这个问题很模糊,你是否有兴趣得到a,b等符号形式的解决方案,而不是明确的数字.gb[-1]是一个不可约的五次曲线,这一事实使得符号系数的情况不太可能存在任何有意义的显式解:

https://en.wikipedia.org/wiki/Abel%E2%80%93Ruffini_theorem

一般来说,当面对这类问题时,最好考虑不同的方法.显式解可能是不可能的(就像这里),或者太复杂而没有多大用处(例如,当使用Cardano的四次公式时).当我给出这个建议时,似乎很少人注意到它,但实际上,在这样的情况下,寻求explicit个解决方案要好得多.原始的多项式方程已经是解的更好的表示,而不是任何基本公式所能提供的:对于符号工作,使用这些多项式作为系统解的implicit表示通常更好.我不能建议如何做到这一点,因为我不知道你下一步打算做什么(如果你想要答案,请问一个新的问题).

Python相关问答推荐

具有多个选项的计数_匹配

根据不同列的值在收件箱中移动数据

如何使用Python将工作表从一个Excel工作簿复制粘贴到另一个工作簿?

numba jitClass,记录类型为字符串

Python上的Instagram API:缺少client_id参数"

2D空间中的反旋算法

当独立的网络调用不应该互相阻塞时,'

Python解析整数格式说明符的规则?

如果条件不满足,我如何获得掩码的第一个索引并获得None?

把一个pandas文件夹从juyter笔记本放到堆栈溢出问题中的最快方法?

NumPy中条件嵌套for循环的向量化

Python+线程\TrocessPoolExecutor

mypy无法推断类型参数.List和Iterable的区别

使用特定值作为引用替换数据框行上的值

ConversationalRetrivalChain引发键错误

在代码执行后关闭ChromeDriver窗口

什么是一种快速而优雅的方式来转换一个包含一串重复的列,而不对同一个值多次运行转换,

浏览超过10k页获取数据,解析:欧洲搜索服务:从欧盟站点收集机会的微小刮刀&

TypeError:';Locator';对象无法在PlayWriter中使用.first()调用

大型稀疏CSR二进制矩阵乘法结果中的错误