提问人:desert_ranger 提问时间:7/5/2023 最后编辑:desert_ranger 更新时间:7/5/2023 访问量:138
为什么我的高斯消元算法失败了?
Why is my gaussian elimination algorithm failing?
问:
在高斯消元法中,我们取矩阵 A 和另一个矩阵 I。
我们继续将矩阵 A 转换为单位矩阵。完成后,我们将对单位矩阵的 A 执行相同的步骤。然后 A 成为单位矩阵,I 成为逆矩阵。
但是,在我的代码中,A 变成了恒等式,但逆的前几行是不正确的
我花了几个多小时进行调试。我意识到,只要我的矩阵相对稀疏,我的方法就会起作用。例如,这有效 -
A = [[10., 3, 10.], [0., 9., 0.], [10.,12.,1.]]
是的,我的矩阵最终总是变成单位矩阵。问题是这不会成为A
I
A^{-1}
关于我的方法的快速解释。我首先致力于将我的矩阵转换为上三角形矩阵。然后我努力将其转换为单位矩阵。代码是用Python 2.7
这是我的代码 -
from fractions import Fraction
A = [[10., 3, 10.], [0., 9., 0.], [10.,12.,1.]]
for i in range(len(A)):
for j in range(len(A)):
A[i][j] = Fraction(A[i][j])
row = len(A)
print "row = ", row
I = [[0 for i in range(len(A))] for j in range(len(A))]
for i in range(len(I)):
for j in range(len(I)):
if i == j:
I[i][j] = 1
I[i][j] = Fraction(I[i][j])
print I
foo = {}
for i in range(len(A)):
for j in range(len(A)):
if i==j:
foo[i] = A[i][j]
print "A before = ", A
print "I before = ", I
i = 0
for k in range(len(A)):
normalize = A[k][k]
if normalize != Fraction(0,1):
for l in range(len(A)):
A[k][l] = A[k][l]/normalize
for l in range(len(I)):
I[k][l] = I[k][l]/normalize
i = k+1
while i<len(A):
coeff = A[i][k]
for j in range(len(A)):
A[i][j] = A[k][j]*coeff - A[i][j]
I[i][j] = I[k][j]*coeff - I[i][j]
i = i + 1
print "A intermediate = ", A
print "I intermediate = ", I
for i in range(len(A)):
for j in range(len(A)):
k = i
while k+1<len(A):
coeff = A[i][k+1]
A[i][j] = A[i][j] - A[k+1][j]*coeff
print "A[i][j] final = ", A[i][j]
I[i][j] = I[i][j] - I[k+1][j]*coeff
k = k+1
print "A final = ", A
print "I final = ", I
这是输出 -
A final = [[Fraction(1, 1), Fraction(0, 1), Fraction(0, 1)], [Fraction(0, 1), Fraction(1, 1), Fraction(0, 1)], [Fraction(0, 1), Fraction(0, 1), Fraction(1, 1)]]
I final = [[Fraction(-1, 90), Fraction(-13, 90), Fraction(1, 9)], [Fraction(0, 1), Fraction(1, 9), Fraction(0, 1)], [Fraction(1, 9), Fraction(1, 9), Fraction(-1, 9)]]
编辑 1 - 我只需要使用标准的 Python 库来解决这个问题。
编辑 2 - 例如,如果我给出这个输入 -
A = [[5,10,20], [2, 8, 12], [4, 8, 8]]
我得到以下错误的输出 -
A final = [[Fraction(1, 1), Fraction(0, 1), Fraction(0, 1)], [Fraction(0, 1), Fraction(1, 1), Fraction(0, 1)], [Fraction(0, 1), Fraction(0, 1), Fraction(1, 1)]]
I final = [[Fraction(0, 1), Fraction(-1, 2), Fraction(1, 2)], [Fraction(-1, 5), Fraction(1, 4), Fraction(1, 8)], [Fraction(1, 10), Fraction(0, 1), Fraction(-1, 8)]]
这是正确的答案——
答:
1赞
GabeDoubleU
7/5/2023
#1
嘿,我重写了代码,以便可以更好地突出显示计算机所执行的过程,我认为问题可能在于在行乘法之前在单位矩阵中添加行。下面是编写的代码:
from fractions import Fraction
def p_frac(x):
if x.denominator == 0: return "NaN"
if x.numerator == 0: return "0"
if x.denominator == 1: return str(x.numerator)
return str(x.numerator)+"/"+str(x.denominator)
A = [[10., 3, 10.], [0., 9., 0.], [10.,12.,1.]]
for i in range(len(A)):
for j in range(len(A)):
A[i][j] = Fraction(A[i][j])
row = len(A)
print ("row = ", row)
I = [[0 for i in range(len(A))] for j in range(len(A))]
for i in range(len(I)):
for j in range(len(I)):
if i == j:
I[i][j] = 1
I[i][j] = Fraction(I[i][j])
print (I)
foo = {}
for i in range(len(A)):
for j in range(len(A)):
if i==j:
foo[i] = A[i][j]
print ("A before = ")
print('\n'.join(['\t'.join([p_frac(cell) for cell in row]) for row in A]))
print ("I before = ")
print('\n'.join(['\t'.join([p_frac(cell) for cell in row]) for row in I]))
i = 0
for k in range(len(A)):
normalize = A[k][k]
if normalize != Fraction(0,1):
for l in range(len(A)):
A[k][l] = A[k][l]/normalize
for l in range(len(I)):
I[k][l] = I[k][l]/normalize
i = k+1
while i<len(A):
coeff = A[i][k]
for j in range(len(A)):
A[i][j] = A[k][j]*coeff - A[i][j]
I[i][j] = I[k][j]*coeff - I[i][j]
i = i + 1
print("A step", str(k+1))
print('\n'.join(['\t'.join([p_frac(cell) for cell in row]) for row in A]))
print("I step", str(k + 1))
print('\n'.join(['\t'.join([p_frac(cell) for cell in row]) for row in I]))
for i in range(len(A)):
for j in range(len(A)):
k = i
while k+1<len(A):
coeff = A[i][k+1]
A[i][j] = A[i][j] - A[k+1][j]*coeff
# print ("A[i][j] final = ", A[i][j])
I[i][j] = I[i][j] - I[k+1][j]*coeff
k = k+1
print ("A final = ")
print('\n'.join(['\t'.join([p_frac(cell) for cell in row]) for row in A]))
print ("I final = ")
print('\n'.join(['\t'.join([p_frac(cell) for cell in row]) for row in I]))
这是我注意到算法差异的地方:
你在 k=0 之后有了这个
A step 1
1 3/10 1
0 -9 0
0 -9 9
I step 1
1/10 0 0
0 -1 0
1 0 -1
但是在 k=1 之后,你有
A step 2
1 3/10 1
0 1 0
0 0 -9
I step 2
1/10 0 0
0 1/9 0
-1 -1 1
如果我没记错的话,我第 2 步第三行和第二列的条目应该是 +1,对吧?
评论
0赞
desert_ranger
7/5/2023
非常感谢。但对不起,我不承认我的错误。你能详细说明一下吗?
上一个:矩阵乘法后恢复矩阵
评论