numpy 二进制矩阵乘法

kiayqfof  于 2022-12-13  发布在  其他
关注(0)|答案(1)|浏览(164)

我得到了一个矩阵 A,以下列字节为行:

11111110  (0xfe)
11111000  (0xf8)
10000100  (0x84)
10010010  (0x92)

我的程序用函数sys.stdin.read(1)从stdin中读取一个字节。假设我收到字节 x10101010 (0xaa)。有没有一种方法可以用numpy来执行乘法:

>>> A.dot(x)
0x06 (00000110)

由于A是一个4x8矩阵,由4个字节作为行组成,而x是一个8位数组,我希望收到(半字节0110)字节0000 0110作为A * x相乘的结果,将位视为矩阵的元素。
如果将矩阵的元素视为二进制字节,则结果为:

>>> A = np.array([[1,1,1,1,1,1,1,0],[1,1,1,1,1,0,0,0],[1,0,0,0,0,1,0,0],[1,0,0,1,0,0,1,0]])
>>> x = np.array([1,0,1,0,1,0,1,0])
>>> A.dot(x)%2
array([0, 1, 1, 0])
guicsvcw

guicsvcw1#

1.未使用dot

您不需要完全展开矩阵来执行比特“乘法”。您要将A视为4x 8的比特矩阵,将x视为8元素的比特向量。如果Ax中的比特都为on,则列乘法会产生1,如果其中一个比特为0,则会产生0。这相当于套用比特和(&):

>>> [hex(n) for n in (A & x)]
['0xaa', '0xa8', '0x80', '0x82']
10101010
10101000
10000000
10000000

Here是一个关于计算字节中位数的帖子。bin(n).count("1")可能是最容易使用的,因此

>>> [bin(n).count("1") % 2 for n in (A & x)]
[0, 1, 1, 0]

如果只需要一个数字,可以执行以下操作

>>> int(''.join(str(bin(n).count("1") % 2) for n in (A & x)), 2)
6

2.使用dot

要使用dot,可以很容易地将Ax扩展为它们的numpy等价物:

>>> list(list(int(n) for n in list(bin(r)[2:])) for r in A)
[['1', '1', '1', '1', '1', '1', '1', '0'],
 ['1', '1', '1', '1', '1', '0', '0', '0'],
 ['1', '0', '0', '0', '0', '1', '0', '0'],
 ['1', '0', '0', '1', '0', '0', '1', '0']]
>>> list(int(n) for n in bin(x)[2:])
[1, 0, 1, 0, 1, 0, 1, 0]

您可以将dot套用至结果:

>>> np.dot(list(list(int(n) for n in list(bin(r)[2:])) for r in A),
           list(int(n) for n in bin(x)[2:])) % 2
array([0, 1, 1, 0])

相关问题