Sympy:在有限域中求解矩阵
Sympy: Solving Matrices in a finite field
对于我的项目,我需要在给定矩阵 Y 和 K 的情况下求解矩阵 X。(XY=K) 每个矩阵的元素必须是对随机 256 位素数取模的整数。我第一次尝试使用 SymPy 的 mod_inv(n)
函数来解决这个问题。这个问题是我 运行 内存不足,矩阵大小约为 30。我的下一个想法是执行矩阵分解,因为这可能不会占用太多内存。但是,SymPy 似乎不包含可以找到模数矩阵的求解器。我可以使用任何解决方法或自制代码吗?
sympy
的 Matrix
class 支持 mod 逆元。这是一个示例 modulo 5:
from sympy import Matrix, pprint
A = Matrix([
[5,6],
[7,9]
])
#Find inverse of A modulo 26
A_inv = A.inv_mod(5)
pprint(A_inv)
#Prints the inverse of A modulo 5:
#[3 3]
#[ ]
#[1 0]
用于查找行简化阶梯形式的 rref
方法支持关键字 iszerofunction
,该关键字指示矩阵中的哪些条目应被视为零。尽管我不确定,但我相信预期用途是为了数值稳定性(将小数视为零)。我用它来 mod 缩小角。
这是一个例子 modulo 5:
from sympy import Matrix, Rational, mod_inverse, pprint
B = Matrix([
[2,2,3,2,2],
[2,3,1,1,4],
[0,0,0,1,0],
[4,1,2,2,3]
])
#Find row-reduced echolon form of B modulo 5:
B_rref = B.rref(iszerofunc=lambda x: x % 5==0)
pprint(B_rref)
# Returns row-reduced echelon form of B modulo 5, along with pivot columns:
# ([1 0 7/2 0 -1], [0, 1, 3])
# [ ]
# [0 1 -2 0 2 ]
# [ ]
# [0 0 0 1 0 ]
# [ ]
# [0 0 -10 0 5 ]
这有点正确,除了 rref[0]
返回的矩阵中仍然有 5 和分数。通过采用 mod 并将分数解释为 mod 倒数来处理此问题:
def mod(x,modulus):
numer, denom = x.as_numer_denom()
return numer*mod_inverse(denom,modulus) % modulus
pprint(B_rref[0].applyfunc(lambda x: mod(x,5)))
#returns
#[1 0 1 0 4]
#[ ]
#[0 1 3 0 2]
#[ ]
#[0 0 0 1 0]
#[ ]
#[0 0 0 0 0]
对于我的项目,我需要在给定矩阵 Y 和 K 的情况下求解矩阵 X。(XY=K) 每个矩阵的元素必须是对随机 256 位素数取模的整数。我第一次尝试使用 SymPy 的 mod_inv(n)
函数来解决这个问题。这个问题是我 运行 内存不足,矩阵大小约为 30。我的下一个想法是执行矩阵分解,因为这可能不会占用太多内存。但是,SymPy 似乎不包含可以找到模数矩阵的求解器。我可以使用任何解决方法或自制代码吗?
sympy
的 Matrix
class 支持 mod 逆元。这是一个示例 modulo 5:
from sympy import Matrix, pprint
A = Matrix([
[5,6],
[7,9]
])
#Find inverse of A modulo 26
A_inv = A.inv_mod(5)
pprint(A_inv)
#Prints the inverse of A modulo 5:
#[3 3]
#[ ]
#[1 0]
用于查找行简化阶梯形式的 rref
方法支持关键字 iszerofunction
,该关键字指示矩阵中的哪些条目应被视为零。尽管我不确定,但我相信预期用途是为了数值稳定性(将小数视为零)。我用它来 mod 缩小角。
这是一个例子 modulo 5:
from sympy import Matrix, Rational, mod_inverse, pprint
B = Matrix([
[2,2,3,2,2],
[2,3,1,1,4],
[0,0,0,1,0],
[4,1,2,2,3]
])
#Find row-reduced echolon form of B modulo 5:
B_rref = B.rref(iszerofunc=lambda x: x % 5==0)
pprint(B_rref)
# Returns row-reduced echelon form of B modulo 5, along with pivot columns:
# ([1 0 7/2 0 -1], [0, 1, 3])
# [ ]
# [0 1 -2 0 2 ]
# [ ]
# [0 0 0 1 0 ]
# [ ]
# [0 0 -10 0 5 ]
这有点正确,除了 rref[0]
返回的矩阵中仍然有 5 和分数。通过采用 mod 并将分数解释为 mod 倒数来处理此问题:
def mod(x,modulus):
numer, denom = x.as_numer_denom()
return numer*mod_inverse(denom,modulus) % modulus
pprint(B_rref[0].applyfunc(lambda x: mod(x,5)))
#returns
#[1 0 1 0 4]
#[ ]
#[0 1 3 0 2]
#[ ]
#[0 0 0 1 0]
#[ ]
#[0 0 0 0 0]