Python线性方程组-高斯消去法

Python线性方程组-高斯消去法,python,numpy,matrix,scipy,linear-algebra,Python,Numpy,Matrix,Scipy,Linear Algebra,目标 给定一组点,我试图找到满足所有点的线性方程的系数 例如,如果我想找到线性方程(ax+by+c=z): 我需要至少三个三维点: (2, 2, 12) (3, 4, 19) (4, 5, 24) 给定足够多的坐标点(x,y,z),我应该能够使用高斯消去法找到(a,b,c)。 然而,我认为在特殊情况下,我在解决矩阵时遇到了问题。您可以在此处查看我对python实现的第一次尝试: 让我们看几个例子 数据集1 使用以下“手工制作”点(x、y、z): 对以下矩阵执行LU分解: [[ 2. 2.

目标

给定一组点,我试图找到满足所有点的线性方程的系数

例如,如果我想找到线性方程(ax+by+c=z):

我需要至少三个三维点:

(2, 2, 12)
(3, 4, 19)
(4, 5, 24)
给定足够多的坐标点(x,y,z),我应该能够使用高斯消去法找到(a,b,c)。

然而,我认为在特殊情况下,我在解决矩阵时遇到了问题。您可以在此处查看我对python实现的第一次尝试:

让我们看几个例子

数据集1

使用以下“手工制作”点(x、y、z):

对以下矩阵执行LU分解:

[[  2.   2.   1.  12.]
 [  3.   4.   1.  19.]
 [  4.   5.   1.  24.]]
[[  3.   4.   1.  19.]
 [  4.   5.   1.  24.]
 [  5.   6.   1.  29.]]
[[  5.   6.   1.  29.]
 [  6.   7.   1.  34.]
 [  7.   8.   1.  39.]]
反求U矩阵:

[[  4.    5.    1.   24. ]
 [  0.   -0.5   0.5   0. ]
 [  0.    0.    0.5   1. ]]
[[  5.00000000e+00   6.00000000e+00   1.00000000e+00   2.90000000e+01]
 [  0.00000000e+00   4.00000000e-01   4.00000000e-01   1.60000000e+00]
 [  0.00000000e+00   0.00000000e+00   4.44089210e-16   0.00000000e+00]]
[[  7.00000000e+00   8.00000000e+00   1.00000000e+00   3.90000000e+01]
 [  0.00000000e+00   2.85714286e-01   2.85714286e-01   1.14285714e+00]
 [  0.00000000e+00   0.00000000e+00   0.00000000e+00   3.55271368e-15]]
返回的结果(a、b、c):

对!一切似乎都很好

数据集2

使用以下“手工制作”点(x、y、z):

对以下矩阵执行LU分解:

[[  2.   2.   1.  12.]
 [  3.   4.   1.  19.]
 [  4.   5.   1.  24.]]
[[  3.   4.   1.  19.]
 [  4.   5.   1.  24.]
 [  5.   6.   1.  29.]]
[[  5.   6.   1.  29.]
 [  6.   7.   1.  34.]
 [  7.   8.   1.  39.]]
反求U矩阵:

[[  4.    5.    1.   24. ]
 [  0.   -0.5   0.5   0. ]
 [  0.    0.    0.5   1. ]]
[[  5.00000000e+00   6.00000000e+00   1.00000000e+00   2.90000000e+01]
 [  0.00000000e+00   4.00000000e-01   4.00000000e-01   1.60000000e+00]
 [  0.00000000e+00   0.00000000e+00   4.44089210e-16   0.00000000e+00]]
[[  7.00000000e+00   8.00000000e+00   1.00000000e+00   3.90000000e+01]
 [  0.00000000e+00   2.85714286e-01   2.85714286e-01   1.14285714e+00]
 [  0.00000000e+00   0.00000000e+00   0.00000000e+00   3.55271368e-15]]
返回的结果(a、b、c):

虽然从技术上讲,这是一个解决方案,而不是我一直在寻找的

数据集3

使用以下“手工制作”点(x、y、z):

对以下矩阵执行LU分解:

[[  2.   2.   1.  12.]
 [  3.   4.   1.  19.]
 [  4.   5.   1.  24.]]
[[  3.   4.   1.  19.]
 [  4.   5.   1.  24.]
 [  5.   6.   1.  29.]]
[[  5.   6.   1.  29.]
 [  6.   7.   1.  34.]
 [  7.   8.   1.  39.]]
反求U矩阵:

[[  4.    5.    1.   24. ]
 [  0.   -0.5   0.5   0. ]
 [  0.    0.    0.5   1. ]]
[[  5.00000000e+00   6.00000000e+00   1.00000000e+00   2.90000000e+01]
 [  0.00000000e+00   4.00000000e-01   4.00000000e-01   1.60000000e+00]
 [  0.00000000e+00   0.00000000e+00   4.44089210e-16   0.00000000e+00]]
[[  7.00000000e+00   8.00000000e+00   1.00000000e+00   3.90000000e+01]
 [  0.00000000e+00   2.85714286e-01   2.85714286e-01   1.14285714e+00]
 [  0.00000000e+00   0.00000000e+00   0.00000000e+00   3.55271368e-15]]
实现崩溃

思想

在数据集2和3中,最后一行和倒数第二行为“特殊”。倒数第二行的“b”和“c”的值相同(在我的特殊示例中也是如此!)。不幸的是,我缺乏数学知识,无法从中得出正面或反面的结论

当最后一行都是零并且上面一行的值相等时,我需要处理一些特殊情况吗

提前谢谢

退房,然后

例如,使用数据集1 对于
3x+2y+2=z
使用

例如,使用数据集2 我得到

>>> a = np.array([[3, 4, 1], [4, 5, 1], [5, 6, 1]])
>>> b = np.array([19, 24, 29])
>>> np.linalg.solve(a, b)
array([ 0.73333333,  4.26666667, -0.26666667])
这就是你想要的答案吗?这是一个有效的答案,但由于
a
排名第二,
[2,3,1.]
也是一个有效的答案。见下文

例如,使用数据集3 重复这个过程

>>> a = np.array([[5, 6, 1], [6, 7, 1], [7, 8, 1]])
>>> b = np.array([29, 34, 39])
>>> np.linalg.solve(a, b)
LinAlgError: Singular matrix
这意味着系数的值为零,因此矩阵的值是无限的,或者一般来说,有无穷多个解或者没有解

>>> np.linalg.det(a)
0.0
>>> 1. / np.linalg.det(a)
inf
>>> np.linalg.lstsq(a,b)
(array([ 2.,  3.,  1.]),       # solution "x"
 array([], dtype=float64),     # residuals, empty if rank > a.shape[0] or < a.shape[1]
 2,                            # rank
 array([  1.61842911e+01,   2.62145599e-01,   2.17200830e-16]))    # singular values of "a"
记住,通过假设
x=inv(a)b
求解系统
ax=b
,因此
inv(a)
必须存在且是有限的。如果
a
是单数,则
inv(a)
是无限的

>>> np.linalg.inv(a)
LinAlgError: Singular matrix
那么,试着寻找一个最好的解决方案怎么样

>>> np.linalg.det(a)
0.0
>>> 1. / np.linalg.det(a)
inf
>>> np.linalg.lstsq(a,b)
(array([ 2.,  3.,  1.]),       # solution "x"
 array([], dtype=float64),     # residuals, empty if rank > a.shape[0] or < a.shape[1]
 2,                            # rank
 array([  1.61842911e+01,   2.62145599e-01,   2.17200830e-16]))    # singular values of "a"
np.linalg.lstsq(a,b) (数组([2,3,1.]),#解“x” 数组([],dtype=float64),#残差,如果秩>a.shape[0]或
因此,它找到了最好的解决方案,如
[2,3,1.]
,幸运的是,它实际上是针对您的条件的解决方案!残差返回为空,因为as@wim说,
a
秩不足,例如:不等于方阵
a
的维数或满秩。

您要寻找的是包含所有3个点的平面。对于数据集2和3,您的解决方案似乎表现得很奇怪,原因是这三个点是共线的,因此不存在唯一的解决方案(即,存在无限多个包含任何给定直线的平面)。这反映在LU分解中,显示为“零”行,因为矩阵是秩2

假设您坚持寻找包含所有3个点的平面,您需要确保您的矩阵实际上是秩3。如果是,那么你有一个解决方案。如果它是秩2,则包含公共线的任何平面都是有效解

>>> np.linalg.det(a)
0.0
>>> 1. / np.linalg.det(a)
inf
>>> np.linalg.lstsq(a,b)
(array([ 2.,  3.,  1.]),       # solution "x"
 array([], dtype=float64),     # residuals, empty if rank > a.shape[0] or < a.shape[1]
 2,                            # rank
 array([  1.61842911e+01,   2.62145599e-01,   2.17200830e-16]))    # singular values of "a"

注意:如果您试图为4个点找到一个公共平面,则可能会发现不存在此类解决方案。

是的,这是一种特殊情况,您需要以不同方式处理。在案例2和案例3中,您有一个。一般来说,它可能意味着有无穷多个解,或者没有解

您可以通过检查通过叠加这3个向量生成的矩阵的大小来确定这些情况是否会发生

>>> import numpy as np
>>> from scipy.linalg import det
>>> data1 = np.array([(2, 2, 12), (3, 4, 19), (4, 5, 24)])
>>> data2 = np.array([(3, 4, 19), (4, 5, 24), (5, 6, 29)])
>>> data3 = np.array([(5, 6, 29), (6, 7, 34), (7, 8, 39)])
>>> det(data1)
-1.9999999999999982
>>> det(data2)
5.551115123125788e-17
>>> det(data3)
8.881784197001213e-16
示例1是一个满秩矩阵,它从几何角度告诉您这3个点是


例子2和3生成零行列式的矩阵,它告诉你点是线性相关的。

我认为这可能是一个数学问题,考虑把它移到你的是肯定正确的,但是我怀疑OP是否理解“满秩矩阵”是什么。甚至不确定行列式会不会响。重要的术语已经联系起来了