numpy可以完全消除浮点产生的误差吗?

来源:6-4 实现高斯-约旦消元法

code_bean

2022-04-26

老师,按照您的思路,用numpy重新实现了一遍 高斯约旦消元法,
发现,这样的话,居然没有浮点误差?是numpy可以完全消除浮点产生的误差吗?


import numpy as np


class LinearSystem:
    def __init__(self, aa: np.array, b: np.array):
        assert aa.shape[0] == b.size, "row number of A must be equal to the length of b"
        self._m = aa.shape[0]
        self._n = aa.shape[1]
        assert self._m == self._n  # TODO: no this restriction
        # 插入到最后一列,构成增广数组
        self.aab = np.insert(aa, self._n, values=b, axis=1)
        # print(self.aab)

    def _max_row(self, i, n):
        best, index = self.aab[i, i], i
        for j in range(i+1, n):  # j始终比i大一个
            if self.aab[j, i] > best:
                best, index = self.aab[j, i], j
        return index

    def _forward(self):
        for i in range(self._n):
            max_row_num = self._max_row(i, self._n)
            # 注意,这里必须加上np.copy,否则无法交换成功
            self.aab[i], self.aab[max_row_num] = np.copy(self.aab[max_row_num]), np.copy(self.aab[i])
            # 该列的主元化1
            self.aab[i] = self.aab[i] / self.aab[i, i]
            # 该列的主元的下面的所有行清零
            for j in range(i+1, self._n):
                self.aab[j] = self.aab[j] - self.aab[j, i] * self.aab[i]

    def _backward(self):
        for i in range(self._n-1, -1, -1):
            for j in range(i-1, -1, -1):
                self.aab[j] = self.aab[j] - self.aab[j, i]*self.aab[i]

    def gauss_jordan_elimination(self):
        self._forward()
        self._backward()
        print("---------------")
        print(self.aab)


if __name__ == '__main__':
    aa = np.array([[1, 2, 4],
                   [3, 7, 2],
                   [2, 3, 3]], np.float64)  # 需要指定为浮点,不然默认是int

    b = np.array([7, -11, 1])
    ls = LinearSystem(aa, b)
    ls.gauss_jordan_elimination()
    print("************************************")
    aa = np.array([[1, -3, 5], [2, -1, -3], [3, 1, 4]], np.float64)  # 需要指定为浮点,不然默认是int
    b = np.array([-9, 19, -13])
    ls = LinearSystem(aa, b)
    ls.gauss_jordan_elimination()
    print("************************************")
    aa = np.array([[1, 2, -2], [2, -3, 1], [3, -1, 3]], np.float64)  # 需要指定为浮点,不然默认是int
    b = np.array([6, -10, -16])
    ls = LinearSystem(aa, b)
    ls.gauss_jordan_elimination()
    print("************************************")

图片描述

写回答

1回答

liuyubobobo

2022-04-27

不可以。只要使用计算机做数值计算,就一定有浮点误差。只不过较新版本的 numpy 会自动做一些 round 处理,使得打印出来的结果看起来没有浮点误差。但是做复杂的数值计算,一定也还会有浮点误差问题。


继续加油!:) 

1
1
code_bean
原来是这样,谢谢老师
2022-04-27
共1条回复

结合编程学数学 专为程序员设计的线性代数

创新设计,通俗易懂。编程结合数学,bobo带你彻底征服线性代数

3404 学习 · 375 问题

查看课程