问题描述
我希望能够使用Python类作为元素来进行矩阵运算-在这种情况下,一个简单的 Galois字段实施.它实现了必需的__add__
,__mul__
,__sub__
等.
I'd like to be able to do matrix operations using a Python class as the elements—in this case, a simple Galois field implementation. It implements the necessary __add__
, __mul__
, __sub__
etc.
起初,我认为可以使用 numpy数组,使用dtype
参数,但来自 dtype
文档,看来dtype
不能是任意的Python类.例如,我有一个类Galois
可以对模2进行运算:
At first, I thought this should be possible with numpy arrays, using the dtype
parameter, but from the dtype
documentation, it seems that dtype
can't be an arbitrary Python class. For example, I have a class Galois
which does operations modulo 2:
>>> from galois import Galois
>>> Galois(1) + Galois(0)
Galois(1)
>>> Galois(1) + Galois(1)
Galois(0)
我可以尝试在numpy中使用它:
I can try to use this in numpy:
>>> import numpy as np
>>> a = np.identity(4, Galois)
>>> a
array([[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1]], dtype=object)
但是,如果我对矩阵进行运算,则元素将不遵循类的方法:
But if I do operations on the matrices, the elements aren't following the methods of my class:
>>> b = np.identity(4, Galois)
>>> a+b
array([[2, 0, 0, 0],
[0, 2, 0, 0],
[0, 0, 2, 0],
[0, 0, 0, 2]], dtype=object)
有什么办法可以使numpy正常工作吗?
Is there any way to make this work with numpy?
是否还有其他Python矩阵库可以对任意数字类进行矩阵运算(包括求逆)?
Is there any other Python matrix library that can do matrix operations (including inversion) on an arbitrary number-like class?
感谢您到目前为止的回答.但是我仍然无法如我所愿地真正使用它.加法和乘法看起来不错,但矩阵求逆却不好.例如,让我们尝试获取 AES逆S盒仿射变换矩阵从转发S-box仿射变换矩阵.
Thanks for the answers so far. But I'm still not able to really use it as I hoped. Adds and multiplies seem good, but not matrix inversion. For example, let's try to get the AES inverse S-box affine transform matrix from the forward S-box affine transform matrix.
class Galois(object):
MODULO = 2
def __init__(self, val):
self.val = int(val) % self.MODULO
def __add__(self, val):
return self.__class__((self.val + int(val)) % self.MODULO)
def __sub__(self, val):
return self.__class__((self.val - int(val)) % self.MODULO)
def __mul__(self, val):
return self.__class__((self.val * int(val)) % self.MODULO)
def __int__(self):
return self.val
def __repr__(self):
return "%s(%d)" % (self.__class__.__name__, self.val)
def __float__(self):
return float(self.val)
if __name__ == "__main__":
import numpy as np
Gv = np.vectorize(Galois)
a = Gv(np.identity(8)) + Gv(np.eye(8,8,-1)) + Gv(np.eye(8,8,-2)) + Gv(np.eye(8,8,-3)) + Gv(np.eye(8,8,-4)) + Gv(np.eye(8,8,4)) + Gv(np.eye(8,8,5)) + Gv(np.eye(8,8,6)) + Gv(np.eye(8,8,7))
print np.matrix(a)
print np.matrix(a).I
结果:
[[Galois(1) Galois(0) Galois(0) Galois(0) Galois(1) Galois(1) Galois(1)
Galois(1)]
[Galois(1) Galois(1) Galois(0) Galois(0) Galois(0) Galois(1) Galois(1)
Galois(1)]
[Galois(1) Galois(1) Galois(1) Galois(0) Galois(0) Galois(0) Galois(1)
Galois(1)]
[Galois(1) Galois(1) Galois(1) Galois(1) Galois(0) Galois(0) Galois(0)
Galois(1)]
[Galois(1) Galois(1) Galois(1) Galois(1) Galois(1) Galois(0) Galois(0)
Galois(0)]
[Galois(0) Galois(1) Galois(1) Galois(1) Galois(1) Galois(1) Galois(0)
Galois(0)]
[Galois(0) Galois(0) Galois(1) Galois(1) Galois(1) Galois(1) Galois(1)
Galois(0)]
[Galois(0) Galois(0) Galois(0) Galois(1) Galois(1) Galois(1) Galois(1)
Galois(1)]]
[[ 0.4 0.4 -0.6 0.4 0.4 -0.6 0.4 -0.6]
[-0.6 0.4 0.4 -0.6 0.4 0.4 -0.6 0.4]
[ 0.4 -0.6 0.4 0.4 -0.6 0.4 0.4 -0.6]
[-0.6 0.4 -0.6 0.4 0.4 -0.6 0.4 0.4]
[ 0.4 -0.6 0.4 -0.6 0.4 0.4 -0.6 0.4]
[ 0.4 0.4 -0.6 0.4 -0.6 0.4 0.4 -0.6]
[-0.6 0.4 0.4 -0.6 0.4 -0.6 0.4 0.4]
[ 0.4 -0.6 0.4 0.4 -0.6 0.4 -0.6 0.4]]
不是我希望的结果.似乎对于矩阵求逆,numpy只是将矩阵转换为浮点数,然后使用纯实数进行求逆.
Not the result I hoped for. It seems that for the matrix inversion, numpy just converts the matrix to floats, then does the inversion with plain real numbers.
推荐答案
您可以将object
用作dtype
,这将允许任意Python对象.我认为没有什么办法可以专门化一个numpy数组,使其仅接受一个特定类的Python对象.
You can use object
as the dtype
, which will allow arbitrary Python objects. I don't think there's any way of specializing a numpy array to accept only one particular class of Python object.
这篇关于我可以将自己的Python类与numpy或其他矩阵库一起使用吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!