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

求scipy.sparse.coo_matrix矩阵逆时触发RuntimeError:矩阵分解失败

解决scipy.sparse.coo_matrix求逆时的因式分解失败问题

可能原因及对应解决方案

1. 矩阵本身奇异(不可逆)

稀疏图邻接矩阵大概率是奇异的——比如无向图邻接矩阵通常非满秩,或存在全零行/列,直接求逆不存在。先验证矩阵可逆性:

import numpy as np
import scipy.sparse

# 转换为CSC格式方便行/列求和
adj_csc = adj.tocsc()
# 检查零行
zero_rows = (adj_csc.sum(axis=1) == 0).ravel()
print(f"零行数量: {zero_rows.sum()}")
# 检查零列
zero_cols = (adj_csc.sum(axis=0) == 0).ravel()
print(f"零列数量: {zero_cols.sum()}")

若存在零行/列,矩阵必然奇异。如果是图算法场景,你可能实际需要的是度矩阵的逆(对角矩阵,仅需对非零对角元取倒数),而非邻接矩阵的逆。

2. 矩阵格式与精度问题

scipy.sparse.linalg.inv依赖的SuperLU求解器对CSC/CSR格式兼容性更好,且float32精度可能引发数值不稳定问题,手动转换格式和精度:

from scipy.sparse.linalg import inv

# 转换为CSC格式并提升精度到float64
adj_csc = adj.tocsc().astype(np.float64)
try:
    Dinv = inv(adj_csc)
except RuntimeError as e:
    print(f"报错: {e}")

3. 调整SuperLU求解器参数

若矩阵接近奇异但理论可逆,可调整求解器参数放宽阈值:

from scipy.sparse.linalg import splu
import scipy.sparse

adj_csc = adj.tocsc().astype(np.float64)
# 配置参数:降低主元阈值,使用更优列置换策略
lu = splu(adj_csc, diag_pivot_thresh=1e-10, permc_spec='MMD_AT_PLUS_A')
# 通过求解AX=I得到逆矩阵
I = scipy.sparse.eye(adj_csc.shape[0], format='csc')
Dinv = lu.solve(I)
  • diag_pivot_thresh:值越小越易选择非对角主元,适配接近奇异的矩阵
  • permc_spec='MMD_AT_PLUS_A':优化列置换,提升因式分解稳定性

4. 替代方案:使用伪逆

若矩阵确实奇异但需类似逆的矩阵,可使用Moore-Penrose伪逆(注意:大矩阵会占用极高内存):

from scipy.sparse.linalg import pinv

Dinv_pinv = pinv(adj.tocsc().astype(np.float64))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 09:55:23