Reputation: 17497
I have the following Python code which computes the first n
Euler Totient function values:
import numpy as np
def euler_totients(n):
phi = np.arange(n+1)
it = np.nditer(phi, flags=['f_index'])
for i in it:
if i == it.index and it.index > 1:
for j in range(it.index, n+1, it.index):
phi[j] -= phi[j] / it.index
return phi
I would like to use numpy.nditer
for the inner loop but it doesn't appear to allow specification of the starting point or the step size as I need for the inner loop. The official documentation for numpy.nditer
includes a brief description of the itershape
parameter (which sounds promising), but it's a bit vague and doesn't include an example.
So, is there a way I can specify the starting point and step size of an numpy.nditer
and if so, how?
Upvotes: 1
Views: 375
Reputation: 231500
Plain python version is faster:
In [166]: def foo(n):
...: phi = list(range(n+1))
...: for index,i in enumerate(phi):
...: if i==index and index>1:
...: for j in range(index, n+1, index):
...: phi[j] -= int(phi[j]/index)
...: return phi
...:
In [167]: foo(10)
Out[167]: [0, 1, 1, 2, 2, 4, 2, 6, 4, 6, 4]
In [168]: timeit euler_totients(1000)
15.7 ms ± 63.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [169]: timeit foo(1000)
637 µs ± 24.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Upvotes: 1