这个VIDEO非常适合在简化的情况下进行演示 - 如果有三个方程式和三个变量。
假设我要解决以下系统
表示变量f1,x1和x2。由于这是一个相当小的系统,我可以轻松地手动完成。但这是一个简化的例子 - 实际上我的系统由100个变量和100个方程组成。
所以我的问题是如何分离变量以解决这个问题?如何在一个向量中收集所有变量并重写系统以便我可以解决它? 最后我想要的是f1,x1和x2的数值。
ps:我刚刚通过插入随机数制作了这个系统。我不确定系统是否可以解决,但是......你明白了。 (在这种情况下调整数值)。
答案 0 :(得分:2)
据我了解,您必须调整系统矩阵以处理RyA
和当前右侧的其他变量。您可以手动执行此操作(在这种情况下,此问题超出了本网站的范围,纯粹是数学练习)或使用例如sympy而不是np.linalg.solve()
,它可以为您解决问题的代数部分:
from sympy import Matrix, symbols, solve
x1, x2, f1 = symbols('x1 x2 f1')
X = Matrix([0, x1, x2])
B = Matrix([f1, 50, 60])
M = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
solve(M * X - B, [x1, x2, f1])
# {f1: 40, x2: 100/3, x1: -30}
请注意,sympy
在求解数字线性系统时可能比numpy.linalg
慢,因此您可能希望使用sympy
来完成工作的代数部分,计算矩阵和右边手边,然后使用numpy.linalg.solve
来解决它。
import numpy as np
from sympy import expand
def symbolic_to_matrix(F, variables):
"""
F is a symbolic vector function that is a left hand side of equation F = 0
variables is a list of variables (sympy.Symbol's) which F depends on.
Assuming that there exists numeric matrix A such that equation F = 0
is equivalent to linear equation Ax = b, this function returns
tuple (A, b)
"""
A = []
b = []
for row in F:
coeffs = expand(row).as_coefficients_dict()
A.append([float(coeffs[x]) for x in variables])
b.append(-float(coeffs[1]))
return np.array(A), np.array(b)
A, b = symbolic_to_matrix(M * X - B, [x1, x2, f1])
# A
# array([[ 2., 3., -1.],
# [ 5., 6., 0.],
# [ 8., 9., 0.]])
# b
# array([ -0., 50., 60.])
np.linalg.solve(A, b)
# array([-30. , 33.33333333, 40. ])
# the same answer
答案 1 :(得分:0)
您可以在列表列表中表示线性方程组,然后定义一个非常简单的函数来求解它,如下所示:
def solve(equations):
"""
the constants of a system of linear equations are stored in a list for each equation in the system
for example the system below:
2x+9y-3z+7w+8=0
7x-2y+6z-1w-10=0
-8x-3y+2z+5w+4=0
0x+2y+z+w+0=0
is expressed as the list:
[[2,9,-3,7,8],[7,-2,6,-1,-10],[-8,-3,2,5,4],[0,2,1,1,0]]
"""
for i in equations:
if len(i)<>(len(equations)+1):
raise ValueError("your equation system has not a valid format")
lists=[] # I failed to name it meaningfully
for eq in range(len(equations)):
#print "equations 1", equations
#find an equation whose first element is not zero and call it index
index=-1
for i in range(len(equations)):
if equations[i][0]<>0:
index=i;
break;
if index==-1:
raise ValueError("your equation system can not be solved")
#print "index "+str(eq)+": ",index
#for the equation[index] calc the lists next item as follows
lists.append([-1.0*i/equations[index][0] for i in equations[index][1:]])
#print "list"+str(eq)+": ", lists[-1]
#remove equation[index] and modify the others
equations.pop(index)
for i in equations:
for j in range(len(lists[-1])):
i[j+1]+=i[0]*lists[-1][j]
i.pop(0)
lists.reverse()
answers=[lists[0][0]]
for i in range(1,len(lists)):
tmpans=lists[i][-1]
for j in range(len(lists[i])-1):
tmpans+=lists[i][j]*answers[-1-j]
answers.append(tmpans)
answers.reverse()
return answers