运行Python高斯消元代码时出现RuntimeWarning错误,请求排查
解决高斯消元代码中的RuntimeWarning问题
我来帮你排查这个问题!你遇到的RuntimeWarning: invalid value encountered in double_scalars警告,本质是代码里出现了除以0的操作,导致产生了NaN(非数值)。咱们一步步拆解问题和修复方案:
问题根源分析
你的代码有两个核心问题导致了这个警告:
- 主元为0时的交换逻辑不完善:当前代码只交换第k行和第k+1行,如果k+1行的主元同样是0,交换后
C[k,k]还是0,后续执行m=C[j,k]/C[k,k]就会触发除以0的操作,产生NaN。 - 消元循环的索引冗余(非警告直接原因,但影响效率):消元时从第0列开始遍历,但k列之前的元素已经是0,完全不需要重复处理。
修正后的代码
from numpy import zeros def eliminasi_gauss(A, b): n = len(A) # 构建增广矩阵 C = zeros((n, n+1)) for i in range(n): for j in range(n): C[i,j] = A[i,j] C[i,n] = b[i,0] for k in range(n-1): # 寻找主元不为0的行(从k行开始往下找) pivot_row = k for i in range(k, n): if abs(C[i,k]) > 1e-10: # 用小阈值避免浮点精度问题 pivot_row = i break # 如果找不到非零主元,说明矩阵奇异 if abs(C[pivot_row,k]) < 1e-10: raise ValueError("矩阵奇异,无解或有无穷多解") # 交换当前行和找到的主元行 if pivot_row != k: C[k,:], C[pivot_row,:] = C[pivot_row,:].copy(), C[k,:].copy() # 消元操作 for j in range(k+1, n): m = C[j,k] / C[k,k] # 从k列开始处理,前面的列已经是0,无需操作 for i in range(k, n+1): C[j,i] = C[j,i] - m * C[k,i] return C
关键修改说明
- 完善主元交换逻辑:
- 遍历k行及以下的所有行,找到第一个主元绝对值大于极小阈值(
1e-10,避免浮点精度误差导致误判)的行。 - 如果找不到这样的行,直接抛出异常提示矩阵奇异,提前终止程序避免后续错误。
- 遍历k行及以下的所有行,找到第一个主元绝对值大于极小阈值(
- 优化消元循环索引:消元时从k列开始遍历,跳过已经是0的前k列,提升代码效率。
- 使用
copy()避免numpy数组赋值的引用问题:交换行时用copy()确保两行数据独立,避免后续修改互相影响。
测试示例
比如用一个简单的线性方程组测试:
A = [[1, 2, -1], [2, 1, -2], [-3, 1, 1]] b = [[3], [3], [-6]] result = eliminasi_gauss(A, b) print(result)
运行后不会出现警告,能得到正确的上三角增广矩阵。
内容的提问来源于stack exchange,提问作者yoona Kawaii
相关产品推荐
相关产品推荐

