如何为python准备一个方程组

时间:2016-11-06 08:53:24

标签: python linear-algebra

这个VIDEO非常适合在简化的情况下进行演示 - 如果有三个方程式和三个变量。

假设我要解决以下系统

enter image description here

表示变量f1,x1和x2。由于这是一个相当小的系统,我可以轻松地手动完成。但这是一个简化的例子 - 实际上我的系统由100个变量和100个方程组成。

所以我的问题是如何分离变量以解决这个问题?如何在一个向量中收集所有变量并重写系统以便我可以解决它? 最后我想要的是f1,x1和x2的数值。

ps:我刚刚通过插入随机数制作了这个系统。我不确定系统是否可以解决,但是......你明白了。 (在这种情况下调整数值​​)。

2 个答案:

答案 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