You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Numpy linalg.det对同一矩阵返回不同计算结果?

Rayleigh迭代中行列式计算异常现象的原因分析

问题代码

import numpy as np

def rayleigh_quot(A,X):
    D = X.T @ A @ X
    Q = norme_euclid(X)**2
    return D/Q

def norme_euclid(M):
    M = np.array(M)
    return np.sqrt(np.max(np.linalg.eig(M@M.T)[0]))

def X_iter(A,X):
    D = A @ X
    Q = norme_euclid(A @ X)
    return (D/Q).reshape(3,1)

def is_invert(M):
    print(M)
    print(f"\ndeterminant : {np.linalg.det(M)}")
    if np.linalg.det(M) == 0: 
        return False
    return True

def rayleigh_iter(A,B):
    X = B
    n = 0
    while(True):
        n += 1;
        print(n)
        v = rayleigh_quot(A,X)[0]
        Y = A-v*np.identity(A.shape[0])
        if not is_invert(Y):
            return v, Y
        M = np.linalg.inv(Y)
        X = X_iter(M,X)

A = np.array([[1,2,3],[1,2,1],[3,2,1]])
B = np.array([[1],[1],[1]])
v,Y = rayleigh_iter(A,B)

问题描述

程序执行到第7、8次迭代时,输出的矩阵看似完全一致,但np.linalg.det(M)分别返回-8.997687189537842e-14和0.0,请问这一现象的原因是什么?是否是因为输出未显示全部小数位?


原因分析

1. 浮点数精度的固有误差

计算机采用二进制浮点数存储数值,无法精确表示所有十进制小数,迭代过程中误差会不断累积。第7次迭代得到的行列式-8.997e-14是一个接近0的极小值,属于浮点计算的舍入误差,并非矩阵真的奇异。到第8次迭代时,累积的浮点误差导致行列式被直接计算为0.0,这是数值精度限制下的近似结果,而非严格意义上的行列式为0。

2. 打印输出的小数截断

Numpy默认打印矩阵时只显示有限位数的小数(通常为6位),这会掩盖矩阵间的微小差异。实际上第7、8次迭代的矩阵在浮点精度层面存在细微差别,只是打印时被截断了。你可以通过设置np.set_printoptions(precision=15)来强制显示更多小数位,就能看到两者的具体差异。

3. 直接用行列式判断可逆性的弊端

用np.linalg.det(M) == 0判断矩阵是否可逆是极不可靠的。对于接近奇异的矩阵,浮点计算出的行列式可能因为精度问题直接返回0,但矩阵并非严格奇异。正确的判断方式应该是:

  • 计算矩阵的条件数(np.linalg.cond(M)),当条件数远大于1时,说明矩阵接近奇异;
  • 尝试求逆时捕获LinAlgError异常;
  • 使用LU分解等数值稳定性更好的方法判断可逆性。

内容的提问来源于stack exchange,提问作者Rafik Bouloudene

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 14:15:27