BIG数(128位)的Euler上位函数有快速算法吗?

时间:2018-09-10 17:09:35

标签: python math bignum

我需要获取一些随机生成的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

有更快的东西吗?

1 个答案:

答案 0 :(得分:7)

对于128位数字,您将要有效地计算n的素数分解,然后使用

totient = n
for factor in prime_factors(n):
    totient -= totient // factor

困难的部分是分解。对于128位数字,简单的试用划分效率将非常低。像elliptic curve factorizationquadratic sieve之类的东西会更好,但是手工编写它们很困难。最好使用一个库。

不管发现与否,我发现的最好的Python大规模分解算法的最佳实现是在codegolf.stackexchange.com上this answerprimo上。这是一个多项式二次筛。

primefac(Python 2)和labmath(Python 3)包含一个二次筛,但是它基于Code Golf答案的一个旧的,有点慢且有错误的版本。如果您需要固定版本,则需要转到Code Golf答案。 (还要注意,labmath.factorint默认不使用mpqs实现。)labmathprimefac还包括椭圆曲线分解,以及其他一些不太可能用于此输入大小。

除此之外,还有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