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

2024-05-23 15:43:37 发布

您现在位置:Python中文网/ 问答频道 /正文

在本例中,我希望能够使用Python类作为元素执行矩阵操作,这是一个简单的Galois field实现。它实现了必需的__add____mul____sub__

起初,我认为这应该可以通过numpy arrays使用dtype参数实现,但是从the ^{} documentation来看,似乎dtype不能是任意的Python类。例如,我有一个类Galois,它执行模块2的操作:

>>> from galois import Galois
>>> Galois(1) + Galois(0)
Galois(1)
>>> Galois(1) + Galois(1)
Galois(0)

我可以试着在纽比用这个:

>>> 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)

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

>>> 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)

有没有办法让这和努比一起工作?

是否有其他Python矩阵库可以对任意数类进行矩阵运算(包括反转)?

更新

谢谢你到目前为止的回答。但我还是不能像我希望的那样真正使用它。加法和乘法看起来不错,但不是矩阵求逆。例如,让我们尝试从forward S-box affine transform matrix中获取AES inverse 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把矩阵转换成浮点数,然后用纯实数进行求逆。


Tags: selfnumpyreturndefnp矩阵valmatrix
3条回答

你签过sage吗,特别是galois_group

你好像在重新发明轮子。但如果你坚持这样做,你可以考虑subclass ndarray

下面是如何使用另一个数组创建和初始化Numpy对象数组的方法:

import numpy as np

class G:
    def __init__(self, x):
        self.x = x

I = np.identity(5)
Gv = np.vectorize(G)
GG = Gv(I)

print GG[0,0].x
print GG[0,1].x

可以使用object作为dtype,这将允许任意Python对象。我不认为有任何方法可以专门化一个numpy数组来只接受一个特定的Python对象类。

相关问题 更多 >