我可以将自己的Python类与numpy或其他矩阵库一起使用吗?

Cra*_*een 9 python numpy matrix

我希望能够使用Python类作为元素进行矩阵运算 - 在这种情况下,是一个简单的Galois字段实现.它实现必要的__add__,__mul__,__sub__等.

起初,我以为这应该是可能的numpy的阵列,使用dtype参数,但是从dtype文档,似乎dtype不能是任意Python类.例如,我有一个Galois以模2运算的类:

>>> from galois import Galois
>>> Galois(1) + Galois(0)
Galois(1)
>>> Galois(1) + Galois(1)
Galois(0)
Run Code Online (Sandbox Code Playgroud)

我可以尝试在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)
Run Code Online (Sandbox Code Playgroud)

但是如果我对矩阵进行操作,则元素不遵循我的类的方法:

>>> 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)
Run Code Online (Sandbox Code Playgroud)

有没有办法让这项工作与numpy?

是否有任何其他Python矩阵库可以在类似任意数字的类上进行矩阵运算(包括反转)?

更新

谢谢你到目前为止的答案.但我仍然无法像我希望的那样真正使用它.加法和乘法似乎很好,但不是矩阵求逆.例如,让我们尝试从前向S盒仿射变换矩阵中获得AES反S 盒仿射变换矩阵.

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
Run Code Online (Sandbox Code Playgroud)

结果:

[[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]]
Run Code Online (Sandbox Code Playgroud)

不是我希望的结果.似乎对于矩阵求逆,numpy只是将矩阵转换为浮点数,然后使用普通实数进行反演.

Gar*_*han 8

您可以使用objectdtype,这将允许任意的Python对象.我认为没有任何方法可以将numpy数组专门化为仅接受一个特定类的Python对象.

  • 明确使用`dtype = object`.如果你给我们一个dtype类,我们假设你的意思是'dtype = object`.对不起,我们不为您的班级制作特殊的dtype. (3认同)