6.8 这个实现,有点问题。
来源:6-8 实现更一般化的高斯-约旦消元法
jandy_chen
2020-03-17
如题针对:
A9 = Matrix([[2,0,1],
[-1,-1,-2],
[-3,0,1]])
b9 = Vector([1, 0, 0])
ls9 = LinearSystem(A9, b9)
if not ls9.gauss_jordan_elimination():
print("No Solution!")
ls9.fancy_print()
---------
会得出这样得结果:
No Solution!
1.0 0.0 0.0 | 0.19999999999999996
0.0 0.0 1.0 | 0.6000000000000001
0.0 -1.0 0.0 | 1.4000000000000001
=====
经调试,发现判断主元时,没有考虑是负数情况,缺少变负为正考虑;
试着优化代码如下:
## 完成前向高斯消元
def _forward(self):
i,k =0,0
while i<self._m and k<self._n:
if self.Ab[i][k] < 0: ##增加判断
self.Ab[i] = self.Ab[i]*(-1)
但是打印结果发现会对:0.0也有-号了
1.0 0.0 0.0 | 0.19999999999999996
-0.0 1.0 0.0 | -1.4000000000000001
0.0 0.0 1.0 | 0.6000000000000001
请问老师,针对这类情况,您会怎么优化,改进代码??
写回答
1回答
-
赞!
这里确实有问题。我看了一下。其实在判断哪一个是主元行的时候,应该比较绝对值。可以这么修改:
def _max_row(self, index_i, index_j, n): best, ret = abs(self.Ab[index_i][index_j]), index_i for i in range(index_i + 1, n): if abs(self.Ab[i][index_j]) > best: best, ret = abs(self.Ab[i][index_j]), i return ret
当然,对于你的方法,对负数主元行做一下翻转,也是没问题的。
至于打印的结果,有 -0.0,是浮点误差的原因。换句话说,计算的结果,按照浮点数的方式解析,符号位是负的。使用计算机做浮点运算,浮点误差是不可避免的。如果你一定要避免,只能在打印输出的时候再做特殊判断,比如我们实现了 is_zero,我们可以在打印前,判断这个数 is_zero(x) 是否为 True,如果是 True,就统一打印 0,而不是将打印方式全盘交给 Python。
继续加油!:)
212020-04-05
相似问题