Sympy1.10调用GramSchmidt误判正交向量非线性独立问题
Sympy版本差异导致GramSchmidt正交化误报线性无关性校验失败问题
问题现象
在固定点位对矩阵函数应用Gram-Schmidt正交化流程,测试输入为已验证两两正交的非零向量集:
sympy 1.7版本下所有测试用例运行正常,正交化结果符合预期sympy 1.10版本下直接抛出如下报错,中断运行:
ValueError: GramSchmidt: vector set not linearly independent
该报错不符合数学逻辑:两两正交的非零向量必然线性无关,即便使用sympy原生接口计算向量两两之间的点积,化简后结果均为0,可验证向量集的正交性与线性无关性。同时简单的标准正交基输入(如三维单位坐标向量组)可在1.10版本下正常运行,进一步说明报错属于异常行为。
复现代码
from sympy import * x,y,a,b = symbols("x y a b", real=True) Q = Matrix([[-2*x/a**2, -a**2*y/(b**2*x), a**2*b**4*x/(2*a**4*y**2+2*b**4*x**2)], [-2*y/b**2, 1, a**4*b**2*y/(2*a**4*y**2+2*b**4*x**2)], [1, 0, 1]]) print(Q) print("Checking orthogonality:") print(Q[:,0].dot(Q[:,1])) print(simplify(Q[:,0].dot(Q[:,2]))) print(simplify(Q[:,1].dot(Q[:,2]))) print("Correct expected behavior for simple example:") print(GramSchmidt([Matrix([1,0,0]), Matrix([0,1,0]), Matrix([0,0,1])])) print("ValueError for my example:") gs = GramSchmidt([Q[:,0], Q[:, 1], Q[:, 2]])
问题成因
该差异来自sympy 1.8版本后对GramSchmidt函数的逻辑修改:
- 1.7版本无前置线性相关性校验,直接执行正交化投影流程,投影过程中自动做的项化简足以识别零残差,因此不会误报
- 1.10版本新增了前置线性相关性检测步骤,该步骤默认不对符号表达式做充分化简,直接判断线性组合系数是否为零。测试用例中的向量包含分式、多项式组合,未化简状态下无法被识别出点积为零的正交关系,因此被误判为线性相关,抛出错误。
可行解决方案
由于必须使用1.10版本调用奇异值分解接口,可通过以下方式规避问题,无需降级版本:
- 调用
GramSchmidt时显式传入simplify=True参数,即把报错行修改为:
该参数会让正交化全流程(含前置线性检测、每一步投影计算)自动对符号表达式做化简,既可以正确识别线性无关的向量集,计算效率也远高于传入未化简行向量的方案。gs = GramSchmidt([Q[:,0], Q[:, 1], Q[:, 2]], simplify=True) - 若上述方式仍偶发误判,可提前对传入的每个列向量做一次化简处理再传入函数:
vec_list = [simplify(Q[:,0]), simplify(Q[:,1]), simplify(Q[:,2])] gs = GramSchmidt(vec_list, simplify=True)
内容的提问来源于stack exchange,提问作者Nap D. Lover
相关产品推荐
相关产品推荐

