通过sympy逆Python查找不工作的数组的逆



有人能解释为什么逆不与这个矩阵工作,但它是与注释部分?

from sympy import Matrix
list = []
print(self.get_key_secret())
key = np.array([7, 23, 21, 9, 19, 3, 15, 15, 12]).reshape(3, 3)
# key = np.array(
#     [[3, 10, 20],
#     [20, 9, 17],
#     [9, 4, 17]])
print(self.get_message_secret().shape)
encr = np.matmul(self.get_message_secret(), key)
encr = encr % 26
inverse_keyArray = Matrix(key).inv_mod(26)
print(inverse_keyArray)
inverse_keyArray = np.array(inverse_keyArray).astype(float)
print(inverse_keyArray)
decryption = np.matmul(encr, inverse_keyArray)
res = np.remainder(decryption, 26)
print(res)

我得到错误

ValueError: inverse of -3318 (mod 26) does not exist
sympy.matrices.common.NonInvertibleMatrixError: Matrix is not invertible (mod 26)

我本来想抱怨缺少self.get_key_secret()之类的项目,但意识到inv只涉及key数组:

In [1]: key = np.array([7, 23, 21, 9, 19, 3, 15, 15, 12]).reshape(3, 3)
In [2]: key
Out[2]: 
array([[ 7, 23, 21],
[ 9, 19,  3],
[15, 15, 12]])

我从那得到一个sympy.Matrix:

In [3]: Matrix(key)
Out[3]: 
⎡7   23  21⎤
⎢          ⎥
⎢9   19  3 ⎥
⎢          ⎥
⎣15  15  12⎦

完整的错误,带回溯。诚然,它并没有增加多少。部分原因是我不熟悉这个mod逆。

In [4]: Matrix(key).inv_mod(26)
-----------------------------------------------------------------------
ValueError                            Traceback (most recent call last)
File /usr/local/lib/python3.8/dist-packages/sympy/matrices/inverse.py:176, in _inv_mod(M, m)
175 try:
--> 176     det_inv = mod_inverse(det_K, m)
177 except ValueError:
File /usr/local/lib/python3.8/dist-packages/sympy/core/numbers.py:551, in mod_inverse(a, m)
550 if c is None:
--> 551     raise ValueError('inverse of %s (mod %s) does not exist' % (a, m))
552 return c
ValueError: inverse of -3318 (mod 26) does not exist
During handling of the above exception, another exception occurred:
NonInvertibleMatrixError              Traceback (most recent call last)
Input In [4], in <cell line: 1>()
----> 1 Matrix(key).inv_mod(26)
File /usr/local/lib/python3.8/dist-packages/sympy/matrices/matrices.py:2199, in MatrixBase.inv_mod(self, m)
2198 def inv_mod(self, m):
-> 2199     return _inv_mod(self, m)
File /usr/local/lib/python3.8/dist-packages/sympy/matrices/inverse.py:178, in _inv_mod(M, m)
176     det_inv = mod_inverse(det_K, m)
177 except ValueError:
--> 178     raise NonInvertibleMatrixError('Matrix is not invertible (mod %d)' % m)
180 K_adj = M.adjugate()
181 K_inv = M.__class__(N, N,
182         [det_inv * K_adj[i, j] % m for i in range(N) for j in range(N)])
NonInvertibleMatrixError: Matrix is not invertible (mod 26)

所以这个错误与numpysympy的混合无关,因为它使用的是sympy矩阵。

常见的数值矩阵逆工作:

In [6]: np.linalg.inv(key)
Out[6]: 
array([[-0.05515371, -0.01175407,  0.0994575 ],
[ 0.01898734,  0.06962025, -0.05063291],
[ 0.04520796, -0.07233273,  0.02230259]])

和等效分数版本

In [9]: Matrix(key).inv()
Out[9]: 
⎡-61    -13     55 ⎤
⎢────   ────   ─── ⎥
⎢1106   1106   553 ⎥
⎢                  ⎥
⎢        11        ⎥
⎢3/158  ───   -4/79⎥
⎢       158        ⎥
⎢                  ⎥
⎢  25   -40    37  ⎥
⎢ ───   ────  ──── ⎥
⎣ 553   553   1659 ⎦

尝试其他mod:

In [15]: Matrix(key).inv_mod(5)
Out[15]: 
⎡4  2  0⎤
⎢       ⎥
⎢1  2  4⎥
⎢       ⎥
⎣0  0  3⎦

也适用于5的其他幂

我认为你不需要将sympy矩阵对象转换为numpy,因为sympy处理矩阵乘法(使用相同的@运算符),并且你只使用2d矩阵-你不需要numpymatmul的"批处理"功能。

例如:

In [32]: M = Matrix(key)
In [33]: M1= M.inv_mod(5)
In [34]: M@M1
Out[34]: 
⎡51  60  155⎤
⎢           ⎥
⎢55  56  85 ⎥
⎢           ⎥
⎣75  60  96 ⎦

使用sympy可以避免浮点数逆运算的问题。

In [38]: M@M.inv()
Out[38]: 
⎡1  0  0⎤
⎢       ⎥
⎢0  1  0⎥
⎢       ⎥
⎣0  0  1⎦
In [39]: key@np.linalg.inv(key)
Out[39]: 
array([[1.00000000e+00, 2.22044605e-16, 0.00000000e+00],
[0.00000000e+00, 1.00000000e+00, 1.24900090e-16],
[1.11022302e-16, 0.00000000e+00, 1.00000000e+00]])

最新更新