私のプロジェクトでは、行列 Y と K を指定して行列 X を解く必要があります。(XY=K) 各行列の要素は、ランダムな 256 ビット素数を法とする整数でなければなりません。この問題を解決するための最初の試みは、SymPy のmod_inv(n)
関数を使用しました。これに関する問題は、約 30 のサイズの行列でメモリが不足していることです。次に考えたのは、行列の因数分解を実行することでした。ただし、SymPy には、数を法とする行列を見つけることができるソルバーが含まれていないようです。使用できる回避策や自作のコードはありますか?
3825 次
1 に答える
15
sympy
のMatrix
クラスはモジュラー逆数をサポートします。モジュロ 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
ます。私は確信が持てませんが、意図された用途は数値安定性(小さな数をゼロとして扱う)のためだと思います。モジュール削減に使用しました。
モジュロ 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 を取り、分数を剰余逆数として解釈することで、これに対処します。
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]
于 2016-05-03T22:13:02.700 に答える