Numpy 矩阵幂/指数与模?
是否可以将 numpy 的 linalg.matrix_power 与模一起使用,以便元素不会增长到大于某个值?
Is it possible to use numpy's linalg.matrix_power with a modulo so the elements don't grow larger than a certain value?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
使用 Numpy 的实现:
https://github.com /numpy/numpy/blob/master/numpy/matrixlib/defmatrix.py#L98
我通过添加模项来对其进行调整。 但是,存在一个错误,即如果发生溢出,则不会引发
OverflowError
或任何其他类型的异常。从那时起,解决方案将是错误的。 此处有一个错误报告。这是代码。小心使用:
Using the implementation from Numpy:
https://github.com/numpy/numpy/blob/master/numpy/matrixlib/defmatrix.py#L98
I adapted it by adding a modulo term. HOWEVER, there is a bug, in that if an overflow occurs, no
OverflowError
or any other sort of exception is raised. From that point on, the solution will be wrong. There is a bug report here.Here is the code. Use with care:
这种显而易见的方法有什么问题吗?
例如
What's wrong with the obvious approach?
E.g.
我之前的所有解决方案都存在溢出问题,因此我必须编写一个算法来解决每次整数乘法后的溢出问题。我就是这样做的:
I had overflow issues with all the previous solutions, so I had to write an algorithm that accounts for overflows after every single integer multiplication. This is how I did it:
对我有用的是在一行中更改 Tamas Hegedus 代码,以指定 dtype=object。这是必需的,因为 Numpy 不像 python 那样支持大整数。使用 dtype=object 强制 numpy 支持大整数并避免无提示溢出错误。
使用指数 10^(15) 和模数约 10^(12) 进行测试。
What worked for me was changing Tamas Hegedus code in a single line, to specify dtype=object. This is needed, since Numpy does not support large integers as python does. Using dtype=object forces numpy to support large integers and avoid silent overflow errors.
Tested with exponent 10^(15) and modulus about 10^(12).
为了防止溢出,您可以利用以下事实:如果您首先对每个输入数字取模,则会得到相同的结果;事实上:
对于一个矩阵
M
。这来自以下两个基本恒等式,它们对于整数x
和y
(以及正幂 p)有效:相同的恒等式也适用于矩阵,因为矩阵加法和乘法可以通过标量加法和乘法来表达。这样,您只需对小数求幂(n mod p 通常比 n 小得多),并且发生溢出的可能性要小得多。因此,在 NumPy 中,您只需执行以下操作
即可获得
(arr**k) mod p
。如果这仍然不够(即,如果尽管
n mod p
很小,但仍存在[n mod p]**k
导致溢出的风险),您可以中断将幂分解为多次幂。上述基本恒等式产生and
因此,您可以将幂
k
分解为a+b+…
或a*b*…
或其任意组合。上述恒等式允许您仅执行小数乘小数的幂运算,这大大降低了整数溢出的风险。In order to prevent overflow, you can use the fact that you get the same result if you first take the modulo of each of your input numbers; in fact:
for a matrix
M
. This comes from the following two fundamental identities, which are valid for integersx
andy
(and a positive power p):The same identities hold for matrices as well, since matrix addition and multiplication can be expressed through scalar addition and multiplication. With this, you only exponentiate small numbers (n mod p is generally much smaller than n) and are much less likely to get overflows. In NumPy, you would therefore simply do
in order to get
(arr**k) mod p
.If this is still not enough (i.e., if there is a risk that
[n mod p]**k
causes overflow despiten mod p
being small), you can break up the exponentiation into multiple exponentiations. The fundamental identities above yieldand
Thus, you can break up power
k
asa+b+…
ora*b*…
or any combination thereof. The identities above allow you to perform only exponentiations of small numbers by small numbers, which greatly lowers the risk of integer overflows.