基于符号的Sympy与平凡解的方程组的符号解

时间:2017-03-12 14:31:48

标签: python linear-algebra sympy equation

我有一个如下的方程式系统:

enter image description here

对于这个特定的系统,我知道只有当p1 == p2时才存在一个非平凡的解决方案,这是

enter image description here

但是,如何在使用Sympy的一般情况下确定这一点?

对于此示例,我的实现如下:

from sympy import Matrix, symbols, pprint, lcm, latex
from sympy.solvers import solve_linear_system

top_matrix = Matrix.zeros(8,7)
p1 = symbols("p1")
p2 = symbols("p2")

top_matrix[0,0] = 1
top_matrix[0,1] = -1

top_matrix[1,1] = (1-p1)
top_matrix[1,2] = -1

top_matrix[2,2] = 1
top_matrix[2,4] = p2-1

top_matrix[3,1] = p1
top_matrix[3,3] = -1

top_matrix[4,3] = 1
top_matrix[4,4] = -p2

top_matrix[5,4] = 1
top_matrix[5,5] = -1

top_matrix[6,1] = -1
top_matrix[6,6] = 1

top_matrix[7,4] = -1
top_matrix[7,6] = 1

pprint(top_matrix)
vars = symbols("a1, a2, a3, a4, a5, a6, a7, a8")
print solve_linear_system(top_matrix, *vars)

结果是

None

如果我设置

p2 = p1

结果是

{a1: -1, a5: -1, a2: -1, a6: -1, a3: p1 - 1, a4: -p1}

有没有办法自动发现这个要求

2 个答案:

答案 0 :(得分:4)

似乎sympy将p1p2视为不相等,这意味着

top_matrix.nullspace()
  

[]

也就是说,具有矩阵系数top_matrix的同质系统没有非平凡的解。

这里有两个选项。第一种方法是将同类系统视为具有未知变量的向量b p2的元素,将p1视为固定参数。

b = sp.Matrix(sp.symbols('b1:8')) #import sympy as sp
sp.solve(top_matrix*b, (*b,p2))
[{b1: 0, b2: 0, b3: 0, b4: 0, b5: 0, b6: 0, b7: 0}, 
 {b1: b7, b2: b7, b3: b7*(-p1 + 1), b4: b7*p1, b5: b7, b6: b7, p2: p1}]

请注意,系统有两个解决方案。琐碎的(具有任意p2)和非平凡的p2==p1(任意b7)。

如果系统A*b=0有一个非平凡的解决方案,第二个选项是认识到系统A.T*A*b=0有一个非平凡的解决方案。如果A.T*A的行列式为零,则后者是可能的。 A.T*A的决定因素等于

(top_matrix.T * top_matrix).det().factor()
  

6*(p1 - p2)**2

立即透露它必须持有p1==p2以便有一个非平凡的解决方案。

答案 1 :(得分:3)

在您的示例代码中,solve_linear_system需要增强系统,即如果右侧为零,则矩阵应声明为Matrix.zeros(8,8)。通过此修改,您的代码将产生

{a3: 0, a1: 0, a5: 0, a7: 0, a6: 0, a2: 0, a4: 0}

这确实是一个解决方案,虽然不是有趣的......

为了解决这个问题,可以明确要求将解决方案的一个组件规范化为,例如,1。所以,如果你做了类似以下的事情:

from sympy import Matrix, symbols, pprint, lcm, latex, solve

top_matrix = Matrix.zeros(8,7)
p1,p2 = symbols("p1, p2")

top_matrix[0,0] = 1
top_matrix[0,1] = -1

top_matrix[1,1] = (1-p1)
top_matrix[1,2] = -1

top_matrix[2,2] = 1
top_matrix[2,4] = p2-1

top_matrix[3,1] = p1
top_matrix[3,3] = -1

top_matrix[4,3] = 1
top_matrix[4,4] = -p2

top_matrix[5,4] = 1
top_matrix[5,5] = -1

top_matrix[6,1] = -1
top_matrix[6,6] = -1

top_matrix[7,4] = 1
top_matrix[7,6] = 1

pprint(top_matrix)

a1,a2,a3,a4,a5,a6,a7 = list(symbols("a1, a2, a3, a4, a5, a6, a7"))

B = Matrix([[1],[a2],[a3],[a4],[a5],[a6],[a7]])

C = top_matrix * B

print(solve(C, (a2,a3,a4,a5,a6,a7,p1,p2)))

并求解剩余变量以及参数p1,p2,结果为:

[{a2: 1, a7: -1, a4: p2, a6: 1, a5: 1, p1: p2, a3: -p2 + 1}]

这确实是理想的解决方案。