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

两种方法计算矩阵奇异值结果不一致,求技术协助

两种奇异值计算方法结果不一致的原因与修正方案

你遇到的问题核心有两个:

  • np.linalg.svd返回的奇异值是降序排列的,而np.linalg.eigvals返回的特征值是无序的
  • 由于数值计算误差,R.T @ R的特征值可能带有极小的虚部,直接开平方会得到复数

修正步骤:

  1. 对R.T @ R的特征值取实部(半正定矩阵的特征值理论上是实数)
  2. 过滤掉极小的非正值(数值误差导致的负数或零)
  3. 对特征值的平方根进行降序排序,和SVD的结果对齐

修正后的代码:

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np

A = mpimg.imread('sunflower.jpeg')
R = A[:,:,0]

# 方法1:SVD计算奇异值
U, S_svd, V = np.linalg.svd(R)
# 方法2:特征值法修正版
rW = np.linalg.eigvals(np.dot(R.T, R))
# 处理数值误差:取实部,过滤极小负值,开平方后降序排序
singvals_eig = np.sqrt(np.maximum(np.real(rW), 0))
singvals_eig = np.sort(singvals_eig)[::-1]
# 截断到和SVD结果一致的长度(取矩阵行列数的较小值)
singvals_eig = singvals_eig[:len(S_svd)]

# 验证结果一致性(允许浮点计算的微小误差)
print(np.allclose(S_svd, singvals_eig))  # 正常会输出True

补充说明:

  • 半正定矩阵的特征值理论上非负,但浮点计算中可能出现极小的负数,用np.maximum(..., 0)可以避免开平方时出现NaN
  • SVD返回的奇异值数量是矩阵行数和列数的较小值,而R.T @ R的特征值数量等于列数,所以要截断到和SVD一致的长度
  • 用np.allclose对比结果,允许浮点计算的微小误差,而非直接判断数值完全相等

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 18:03:18