我需要获取一些随机生成的128位数字的phi函数(Euler)。 我尝试在下面使用此代码,但是计算机考虑的太多了。
import fractions
def phi(n):
amount = 0
for k in range(1, n + 1):
if fractions.gcd(n, k) == 1:
amount += 1
return amount
有更快的东西吗?
答案 0 :(得分:7)
对于128位数字,您将要有效地计算n
的素数分解,然后使用
totient = n
for factor in prime_factors(n):
totient -= totient // factor
困难的部分是分解。对于128位数字,简单的试用划分效率将非常低。像elliptic curve factorization或quadratic sieve之类的东西会更好,但是手工编写它们很困难。最好使用一个库。
不管发现与否,我发现的最好的Python大规模分解算法的最佳实现是在codegolf.stackexchange.com上this answer的primo上。这是一个多项式二次筛。
primefac
(Python 2)和labmath
(Python 3)包含一个二次筛,但是它基于Code Golf答案的一个旧的,有点慢且有错误的版本。如果您需要固定版本,则需要转到Code Golf答案。 (还要注意,labmath.factorint
默认不使用mpqs实现。)labmath
和primefac
还包括椭圆曲线分解,以及其他一些不太可能用于此输入大小。
除此之外,还有sympy.ntheory.factorint
,但是它在我的测试中存在较大因素的问题,并且仅具有试验划分,波拉德rho和波拉德p-1分解。
无论如何,请使用这些现有分解因子选项之一,或者实施您自己的分解因子或其他方法,然后在此之上构建您的toient函数。例如,使用primefac
:
# primefac.factorint(n) returns a factor:multiplicity dict
from primefac import factorint
def totient(n):
totient = n
for factor in factorint(n):
totient -= totient // factor
return totient