Original post: https://math.stackexchange.com/questions/316376/how-to-calculate-these-totient-summation-sums-efficiently
Background:
- Totient summatory function: Wolfram
Python code snippet:
class TotientSummatoryFunction(): """Totient summatory function class.""" def __init__(self, bound, mod): """Initialize. Args: bound: An integer. mod: An integer. """ self.mod = mod self.small_values = None self.small_value_bound = None self.big_values = {} self.InitSmallValues(bound) def InitSmallValues(self, bound): """Initialize small values for totient summatory function. Args: bound: An integer. """ n = 3 * int(math.pow(bound, 2 / 3)) assert(n**3 >= bound**2) print('InitSmallValues({n})'.format(n=n)) phi = [i for i in range(n + 1)] for i in range(2, n + 1): if phi[i] != i: continue for j in range(i, n + 1, i): phi[j] = phi[j] // i * (i - 1) self.small_values = [0 for i in range(n + 1)] self.small_values[1] = phi[1] % self.mod for i in range(2, n + 1): self.small_values[i] = (self.small_values[i - 1] + phi[i]) % self.mod self.small_value_bound = n def Get(self, n): """Get totient summatory function value. Args: n: An integer. Returns: An integer. """ if n <= self.small_value_bound: return self.small_values[n] if n not in self.big_values: result = n * (n + 1) // 2 m = self.IntegerSqrt(n) for d in range(1, m + 1): result -= self.Get(d) * (n // d - n // (d + 1)) for k in range(2, n // (m + 1) + 1): result -= self.Get(n // k) self.big_values[n] = result % self.mod return self.big_values[n] def IntegerSqrt(self, n): """ Get the integer part of Sqrt[n]. Args: n: An integer. Returns: An integer. """ guess = (n >> n.bit_length() // 2) + 1 result = (guess + n // guess) // 2 while abs(result - guess) > 1: guess = result result = (guess + n // guess) // 2 while result * result > n: result -= 1 return result