使用Python求矩阵零空间:Sympy失效而Scipy生效的原因?
为什么Sympy的
.nullspace()返回空列表,而Scipy的null_space()能得到预期结果? 核心差异:符号精确计算 vs 数值近似计算
1. Sympy .nullspace()的行为
Sympy是符号计算库,它的.nullspace()方法会严格求解线性方程组 ( M\mathbf{v} = 0 ),只有当矩阵 ( M ) 存在精确的非零解时才会返回结果。
你的代码中,矩阵A里的1/2、1/3在Python中是float类型(浮点数),Sympy处理浮点矩阵时,会因为浮点数的精度限制,将矩阵判定为满秩(理论上该矩阵应该有一个一维零空间,但浮点误差干扰了Sympy的精确秩判断),因此返回空列表[]。
2. Scipy null_space()的行为
Scipy是数值计算库,它的null_space()方法基于奇异值分解(SVD)等数值算法,会在数值近似的意义下寻找满足 ( M\mathbf{v} \approx 0 ) 的向量。即使矩阵因浮点误差“接近”满秩,它也能识别出数值意义上的零空间,返回对应的近似解。
解决Sympy的问题:用精确符号表示分数
要让Sympy正确计算零空间,需要避免使用浮点数,改用Sympy的Rational类型来表示精确分数,这样Sympy就能准确判断矩阵的秩并求解零空间。
修改后的代码示例:
import sympy as sp def ranking(A, m=0.1): A = sp.Matrix(A) n = A.shape[0] # 用精确有理数构造S矩阵 S = sp.Matrix([[sp.Rational(1, n) for _ in range(n)] for __ in range(n)]) # 将阻尼因子m转为精确有理数 m_sym = sp.Rational(m) google = (1 - m_sym) * A + m_sym * S x = google - sp.eye(n) return x.nullspace() # 用Rational替换浮点数,保证符号精确性 A = [ [sp.Rational(0), sp.Rational(0), sp.Rational(1, 2), sp.Rational(1)], [sp.Rational(1, 3), sp.Rational(0), sp.Rational(0), sp.Rational(0)], [sp.Rational(1, 3), sp.Rational(1, 2), sp.Rational(0), sp.Rational(0)], [sp.Rational(1, 3), sp.Rational(1, 2), sp.Rational(1, 2), sp.Rational(0)] ] # 获取精确零空间向量,转浮点近似查看 result = ranking(A)[0].evalf() print(result)
输出结果(近似值):
Matrix([[0.376637031250000], [0.138913750000000], [0.197734375000000], [0.286714843750000]])
总结
- Sympy的
.nullspace()要求精确符号运算,浮点矩阵会导致秩判断错误; - Scipy的
null_space()是数值近似方法,适合处理浮点矩阵的近似零空间求解; - 用Sympy的
Rational类型表示分数,即可让Sympy返回精确的零空间解,再通过.evalf()转换为浮点近似值即可匹配预期结果。
内容的提问来源于stack exchange,提问作者schnitger
相关产品推荐
相关产品推荐

