Python 数组的三参数pow

Python 数组的三参数pow,python,numpy,math,pow,modular-arithmetic,Python,Numpy,Math,Pow,Modular Arithmetic,接受模pow(x,y,z)的第三个参数,该参数的计算效率高于x**y%z。如何使用数组实现这一点?我所尝试的: >>> import numpy as np >>> A = np.array(range(10)) >>> pow(A, 23, 13) TypeError: unsupported operand type(s) for pow(): 'numpy.ndarray', 'int', 'int' 尽管ndarray实现了\uuu

接受模
pow(x,y,z)
的第三个参数,该参数的计算效率高于
x**y%z
。如何使用数组实现这一点?我所尝试的:

>>> import numpy as np
>>> A = np.array(range(10))
>>> pow(A, 23, 13)
TypeError: unsupported operand type(s) for pow(): 'numpy.ndarray', 'int', 'int'
尽管ndarray实现了
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

>>> A.__pow__(23, 13)
NotImplemented
在两个步骤中使用求幂和模运算会给出错误的结果(猜测它溢出了数据类型)

实际的数组很大,所以我不能使用dtype“object”,也不能直接在Python中进行循环

如何计算numpy阵列的3-arg功率?

您可以使用
map()
和lambda来完成此操作。然后,您可以一次使用一个结果。尝试:

result_iter=map(λx:pow(int(x),23,13,A))
结果=列表(结果)
打印(结果)
输出:

[0, 1, 7, 9, 10, 8, 11, 2, 5, 3]

求最大的n,使2^n不大于你的指数。然后通过重复平方和取n步的模来计算A^{2^n}。然后将该矩阵与通过递归调用
(指数-2^n)
的相同算法得到的矩阵相乘


我知道这会打很多电话,但因为大多数操作都是在Numpy中运行的,所以速度可能很快。您可以记录矩阵
A^{2^n}(mod k)
,使其更快。请注意,递归调用的数量最多为
log_2(exponent)+1

如果没有找到更好的答案,请尝试。原始解决方案的问题是numpy中的np.int64/np.float64溢出,这与python中的int不同(它可以扩展尽可能多的可用内存)

输出:

array([ 0,  1,  7,  9, 10,  8, 11,  2,  5,  3])
如果您的阵列溢出,您需要将电源分解到较小的元素,以便它不会溢出。例如,您可以像这样分解成更小的碎片:

n = 1
B = A % 13
while 2*n < 23:
    B = B * B % 13
    n *= 2
B = B * (A ** (23-n) % 13) % 13
B
n=1
B=A%13
而2*n<23:
B=B*B%13
n*=2
B=B*(A**(23-n)%13)%13
B

这是否回答了您的问题?它似乎还没有得到Numpy的支持。然而,要求在Numpy中添加此函数可能是一个好主意。@JérômeRichard:不,这是一个矩阵幂,而这个问题要求的是元素幂。这是可行的,但相对于Numpy中的矢量化解决方案,速度会慢得多。这基本上是在数组上循环(甚至可能比普通循环慢)我只使用了
A=np.array(范围(10))
作为一个简单的例子。这仍然会溢出
A=np.array(范围(40))
@诺斯特彭斯尼克也使用同样的方法将能量分解成更小的数字,这样它就不会溢出。我为一个示例添加了一个编辑。我不明白,即使是一个平方运算也会导致溢出,这不是真的吗?@nosteponnek是的,如果数组中的值足够大,它会。但是,您可以通过增加正在使用的数据类型的精度和范围来避免这种情况(例如,使用双精度而不是浮点)。然而,这里真正的问题是,即使值很小,指数运算也会很快导致溢出。该方法通过在每次平方运算后重复获取模量来确保不会发生这种情况。
array([ 0,  1,  7,  9, 10,  8, 11,  2,  5,  3])
n = 1
B = A % 13
while 2*n < 23:
    B = B * B % 13
    n *= 2
B = B * (A ** (23-n) % 13) % 13
B