简体   繁体   English

Numpy 矩阵求逆与对象

[英]Numpy matrix inversion with objects

I'm using the gf256 library to do galois field math, and I have it in a numpy matrix.我正在使用 gf256 库进行伽罗瓦域数学,并将它放在一个 numpy 矩阵中。 Though when calling np.linalg.inv() with it, it throws an error.虽然当用它调用np.linalg.inv()时,它会抛出一个错误。

That's the summary, here's the details:总结就是这样,下面是详细信息:

import numpy as np
from gf256 import GF256 as gf
npgf = np.vectorize(gf)

arr = np.identity(4, np.uint8) * 10
gfarr = npgf(arr)

After all this, gfarr looks like this毕竟, gfarr看起来像这样

array([[GF256(0b00001010), GF256(0b00000000), GF256(0b00000000),
        GF256(0b00000000)],
       [GF256(0b00000000), GF256(0b00001010), GF256(0b00000000),
        GF256(0b00000000)],
       [GF256(0b00000000), GF256(0b00000000), GF256(0b00001010),
        GF256(0b00000000)],
       [GF256(0b00000000), GF256(0b00000000), GF256(0b00000000),
        GF256(0b00001010)]], dtype=object)

And np.linalg.inv(gfarr) throws this error并且np.linalg.inv(gfarr)抛出这个错误

Traceback (most recent call last):
  File "<pyshell#152>", line 1, in <module>
    np.linalg.inv(gfarr)
  File "[python3.6]\lib\site-packages\numpy\linalg\linalg.py", line 528, in inv
    ainv = _umath_linalg.inv(a, signature=signature, extobj=extobj)
TypeError: No loop matching the specified signature and casting
was found for ufunc inv

The matrix is definitely invertable, and the GF256 class supports all the usual operators.矩阵肯定是可逆的,GF256 类支持所有常用运算符。 Is it possible to make this work with numpy?是否可以使用 numpy 进行这项工作?

np.linalg.inv will invoke a BLAS/LAPACK implementation of matrix inversion using floats, but you need to use Galois field arithmetic in the matrix inversion process. np.linalg.inv将使用浮点数调用矩阵求逆的 BLAS/LAPACK 实现,但您需要在矩阵求逆过程中使用伽罗瓦域算法。 To do this, the NumPy array will need to intercept or override the call to np.linalg.inv in __array_function__() .为此,NumPy 数组需要在np.linalg.inv __array_function__()拦截或覆盖对np.linalg.inv的调用。 The matrix inversion of A can be accomplished using Gaussian elimination on [A | I] A的矩阵求逆可以使用[A | I]上的高斯消元法来完成[A | I] [A | I] over the Galois field, which yields [I | A^-1] [A | I]在伽罗瓦域上,产生[I | A^-1] [I | A^-1] . [I | A^-1]

I had a similar use case, so I created a Python package called galois that extends NumPy arrays over Galois fields.我有一个类似的用例,所以我创建了一个名为galois的 Python 包,它在 Galois 字段上扩展了 NumPy 数组。 It replaces the NumPy ufuncs with JIT compiled ufuncs using Numba.它使用 Numba 将 NumPy ufunc 替换为 JIT 编译的 ufunc。 This means the array arithmetic is as fast, or nearly as fast, as normal NumPy arithmetic.这意味着数组算术与普通 NumPy 算术一样快或几乎一样快。 See this performance comparison .请参阅此性能比较

It also supports linear algebra and overrides the relevant np.linalg functions.它还支持线性代数并覆盖相关的np.linalg函数。 So the matrix inversion you're looking for works out of the box.因此,您正在寻找的矩阵求逆是开箱即用的。 Here's an example using your matrix.这是使用矩阵的示例。

In [1]: import numpy as np                                                                                                                                                                     

In [2]: import galois                                                                                                                                                                          

In [3]: GF = galois.GF(2**8)                                                                                                                                                                   

In [4]: print(GF.properties)                                                                                                                                                                   
GF(2^8):
  characteristic: 2
  degree: 8
  order: 256
  irreducible_poly: x^8 + x^4 + x^3 + x^2 + 1
  is_primitive_poly: True
  primitive_element: x

In [5]: A = GF.Identity(4) * GF(10); A                                                                                                                                                         
Out[5]: 
GF([[10,  0,  0,  0],
    [ 0, 10,  0,  0],
    [ 0,  0, 10,  0],
    [ 0,  0,  0, 10]], order=2^8)

In [6]: A_inv = np.linalg.inv(A); A_inv                                                                                                                                                        
Out[6]: 
GF([[221,   0,   0,   0],
    [  0, 221,   0,   0],
    [  0,   0, 221,   0],
    [  0,   0,   0, 221]], order=2^8)

In [7]: A @ A_inv                                                                                                                                                                              
Out[7]: 
GF([[1, 0, 0, 0],
    [0, 1, 0, 0],
    [0, 0, 1, 0],
    [0, 0, 0, 1]], order=2^8)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM