微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

数组的三个参数 pow

如何解决数组的三个参数 pow

pow 接受模 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 实现了 __pow__,但直接调用不会做任何事情:

>>> A.__pow__(23,13)
NotImplemented

在两步中使用求幂和取模会产生不正确的结果(猜测它溢出了 dtype)

>>> print(*(A ** 23 % 13))  # wrong result!
0 1 7 9 10 8 11 12 0 6
>>> print(*[pow(int(a),13) for a in A])  # correct result
0 1 7 9 10 8 11 2 5 3

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

如何计算 numpy 数组的 3-arg pow?

解决方法

找到最大的 n,使得 2^n 不大于您的指数。然后通过重复平方取模数 n 步计算 A^{2^n}。然后将此矩阵与您通过递归调用 value0 value 1/5 x value2 的相同算法获得的矩阵相乘。

我知道这会进行很多调用,但由于大多数操作都在 Numpy 中运行,因此它可能很快。您可以记录矩阵 (your exponent - 2^n) 以使其更快。观察到递归调用的次数最多为 A^{2^n} (mod k)

,

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

((A ** 13 % 13) * (A ** 10 % 13)) % 13

输出:

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
,

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

result_iter = map(lambda x: pow(int(x),23,13),A))

results = list(result_iter)
print(results)

输出:

[0,3]

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。