SageMath 10.7二次型求解时的Pari整数转换错误
SageMath二次型solve方法PARI整数转换错误的原因与解决方法
错误场景复现
使用SageMath 10.7处理二次型时,调用QuadraticForm.solve()触发PARI整数转换错误:
sage: version() 'SageMath version 10.7, Release Date: 2025-08-09' sage: t = 8 sage: B = matrix(ZZ, [(1, 0, 0),(1, 2, 4),(1, 16, 256),(1, 32, 1024),(1, 18, 324),(1, 34, 1156),(1, 48, 2304),(1, 50, 2500)]) sage: K = B.T.right_kernel_matrix() sage: G = K.T * K sage: P = PolynomialRing(QQ, names=['x1', 'x2', 'x3', 'x4', 'x5', 'x6', 'x7', 'x8']) sage: P.inject_variables() sage: x = vector([x1, x2, x3, x4, x5, x6, x7, x8]) sage: f = x * G * x sage: QF = QuadraticForm(f) sage: sol = QF.solve(c=2^t) TypeError: Unable to coerce PARI [75, -425, 51; 69, -384, 46; 34, -153, 18; 9, -9, 1; 30, -128, 15; 7, 0, 0; 0, 7, 0; 0, 0, 1; 0, 0, 0] to an Integer
手动构造二次型时,仅使用G的上三角部分可正常运行(但非目标二次型):
sage: QF = QuadraticForm(QQ, G.nrows(), [G[i, j] for i in range(G.nrows()) for j in range(i, G.ncols())]) sage: QF.solve(c=2^t)
而手动将非对角元乘2构造目标二次型时,同样触发错误:
sage: QF = QuadraticForm(QQ, G.nrows(), [G[i, j] if i == j else 2 * G[i, j] for i in range(G.nrows()) for j in range(i, G.ncols())]) sage: QF.solve(c=2^t)
错误原因
SageMath的QuadraticForm.solve()底层依赖PARI库的二次型求解函数,PARI对二次型的系数存储有严格规范:
- 对角元对应二次型中平方项的系数
- 非对角元对应交叉项系数的一半
当手动将非对角元乘以2时,传入的系数违反了PARI的存储规范:PARI期望非对角元是交叉项的一半,但实际传入的是完整的交叉项系数,导致底层函数解析时试图将不符合预期的矩阵元素转换为整数,最终触发类型错误。
直接使用G的上三角元素构造时,QuadraticForm默认将非对角元视为交叉项的一半,刚好符合PARI要求,因此可以正常运行,但此时构造的二次型并非目标的x*G*x(因为x*G*x的交叉项系数是2*G[i,j],i≠j)。
解决方法
由于G = K.T * K是天然的对称矩阵,直接使用该对称矩阵构造QuadraticForm即可,SageMath会自动处理系数的存储格式,适配PARI的要求:
sage: t = 8 sage: B = matrix(ZZ, [(1, 0, 0),(1, 2, 4),(1, 16, 256),(1, 32, 1024),(1, 18, 324),(1, 34, 1156),(1, 48, 2304),(1, 50, 2500)]) sage: K = B.T.right_kernel_matrix() sage: G = K.T * K # 直接用对称矩阵G构造目标二次型 sage: QF = QuadraticForm(QQ, G) sage: sol = QF.solve(c=2^t)
这种方式构造的二次型与x*G*x完全一致,同时符合PARI的系数规范,可正常调用solve()方法。
内容的提问来源于stack exchange,提问作者grnx
相关产品推荐
相关产品推荐

