This function just directly iterates a given function at a point.

{{{id=1| def iteratedir(f,n,a): Q=a for i in range(n): Q=f(Q) return Q /// }}}

This function uses the division algorithm to speed up the iteration: If we want the nth iterate, we can choose to look at n=km+r, iterate f k times and then iterate that with itself m times, and evaluate at f^r(a). This involves less operations. The question is, which is the optimal k? clearly there are some time savings, but these are lost when we are iterateing f with itself too many times.

{{{id=2| def iterate_modk(f, n, a, k): F=f v=divmod(n,k) for i in range(k-1): F=f(F) Q=iteratedir(f,v[1],a) R=iteratedir(F,v[0],Q) return R /// }}}

Here is an example of the function. Below is the set-up (function, finite field, iterate we want).

To see the optimal iteration, we computed a few examples (with the times included). We still don't know how to decide, but for the few examples below we have seen that the optimal point is when k=4 or 5. What does this have to do with anything?

{{{id=4| G.=GF(3^19) R.=PolynomialRing(G) f=x^2+2 n=floor(sqrt(len(G))) for i in range(1,10): i time iterate_modk(f,n,c,i) /// 1 c^18 + c^16 + 2*c^14 + c^13 + 2*c^12 + 2*c^10 + c^9 + c^8 + 2*c^6 + c^5 + c^2 + 1 Time: CPU 51.19 s, Wall: 53.07 s 2 c^18 + c^16 + 2*c^14 + c^13 + 2*c^12 + 2*c^10 + c^9 + c^8 + 2*c^6 + c^5 + c^2 + 1 Time: CPU 26.12 s, Wall: 26.66 s 3 c^18 + c^16 + 2*c^14 + c^13 + 2*c^12 + 2*c^10 + c^9 + c^8 + 2*c^6 + c^5 + c^2 + 1 Time: CPU 19.39 s, Wall: 20.80 s 4 c^18 + c^16 + 2*c^14 + c^13 + 2*c^12 + 2*c^10 + c^9 + c^8 + 2*c^6 + c^5 + c^2 + 1 Time: CPU 16.61 s, Wall: 17.04 s 5 c^18 + c^16 + 2*c^14 + c^13 + 2*c^12 + 2*c^10 + c^9 + c^8 + 2*c^6 + c^5 + c^2 + 1 Time: CPU 16.41 s, Wall: 16.88 s 6 c^18 + c^16 + 2*c^14 + c^13 + 2*c^12 + 2*c^10 + c^9 + c^8 + 2*c^6 + c^5 + c^2 + 1 Time: CPU 18.49 s, Wall: 19.13 s 7 c^18 + c^16 + 2*c^14 + c^13 + 2*c^12 + 2*c^10 + c^9 + c^8 + 2*c^6 + c^5 + c^2 + 1 Time: CPU 25.34 s, Wall: 26.02 s 8 c^18 + c^16 + 2*c^14 + c^13 + 2*c^12 + 2*c^10 + c^9 + c^8 + 2*c^6 + c^5 + c^2 + 1 Time: CPU 37.68 s, Wall: 39.22 s 9 c^18 + c^16 + 2*c^14 + c^13 + 2*c^12 + 2*c^10 + c^9 + c^8 + 2*c^6 + c^5 + c^2 + 1 Time: CPU 61.25 s, Wall: 62.92 s }}} {{{id=5| G.=GF(5^13) R.=PolynomialRing(G) f=x^2+2 n=floor(sqrt(len(G))) for i in range(1,10): i time iterate_modk(f,n,c,i) /// 1 4*c^12 + c^10 + 4*c^9 + 3*c^8 + c^7 + 4*c^6 + 4*c^4 + 2*c^3 + 3*c^2 + 3*c + 2 Time: CPU 40.02 s, Wall: 41.83 s 2 4*c^12 + c^10 + 4*c^9 + 3*c^8 + c^7 + 4*c^6 + 4*c^4 + 2*c^3 + 3*c^2 + 3*c + 2 Time: CPU 20.95 s, Wall: 21.74 s 3 4*c^12 + c^10 + 4*c^9 + 3*c^8 + c^7 + 4*c^6 + 4*c^4 + 2*c^3 + 3*c^2 + 3*c + 2 Time: CPU 14.05 s, Wall: 14.20 s 4 4*c^12 + c^10 + 4*c^9 + 3*c^8 + c^7 + 4*c^6 + 4*c^4 + 2*c^3 + 3*c^2 + 3*c + 2 Time: CPU 11.80 s, Wall: 12.06 s 5 4*c^12 + c^10 + 4*c^9 + 3*c^8 + c^7 + 4*c^6 + 4*c^4 + 2*c^3 + 3*c^2 + 3*c + 2 Time: CPU 11.35 s, Wall: 11.55 s 6 4*c^12 + c^10 + 4*c^9 + 3*c^8 + c^7 + 4*c^6 + 4*c^4 + 2*c^3 + 3*c^2 + 3*c + 2 Time: CPU 12.71 s, Wall: 12.91 s 7 4*c^12 + c^10 + 4*c^9 + 3*c^8 + c^7 + 4*c^6 + 4*c^4 + 2*c^3 + 3*c^2 + 3*c + 2 Time: CPU 16.72 s, Wall: 17.32 s 8 4*c^12 + c^10 + 4*c^9 + 3*c^8 + c^7 + 4*c^6 + 4*c^4 + 2*c^3 + 3*c^2 + 3*c + 2 Time: CPU 24.17 s, Wall: 25.30 s 9 4*c^12 + c^10 + 4*c^9 + 3*c^8 + c^7 + 4*c^6 + 4*c^4 + 2*c^3 + 3*c^2 + 3*c + 2 Time: CPU 37.73 s, Wall: 38.39 s }}}

The following polynomial is not irreducible, and notice that the time dip happens at 2... Is there something to this?

{{{id=12| G.=GF(3^19) R.=PolynomialRing(G) f=x^4+2 n=floor(sqrt(len(G))) for i in range(1,10): i time iterate_modk(f,n,c,i) /// 1 2*c^18 + 2*c^17 + c^13 + c^11 + c^10 + 2*c^9 + c^8 + 2*c^7 + c^6 + 2*c^5 + c^4 + 2*c + 2 Time: CPU 52.77 s, Wall: 54.40 s 2 2*c^18 + 2*c^17 + c^13 + c^11 + c^10 + 2*c^9 + c^8 + 2*c^7 + c^6 + 2*c^5 + c^4 + 2*c + 2 Time: CPU 32.36 s, Wall: 33.96 s 3 2*c^18 + 2*c^17 + c^13 + c^11 + c^10 + 2*c^9 + c^8 + 2*c^7 + c^6 + 2*c^5 + c^4 + 2*c + 2 Time: CPU 37.83 s, Wall: 39.16 s 4 2*c^18 + 2*c^17 + c^13 + c^11 + c^10 + 2*c^9 + c^8 + 2*c^7 + c^6 + 2*c^5 + c^4 + 2*c + 2 Time: CPU 74.94 s, Wall: 77.39 s 5 2*c^18 + 2*c^17 + c^13 + c^11 + c^10 + 2*c^9 + c^8 + 2*c^7 + c^6 + 2*c^5 + c^4 + 2*c + 2 Time: CPU 208.04 s, Wall: 213.04 s 6 ^CTraceback (most recent call last): time iterate_modk(f,n,c,i) File "", line 1, in File "/private/var/folders/of/of1uAoZoGDOU7RzXM1esKJ8kyXA/-Tmp-/tmpB_PLL3/___code___.py", line 7, in exec compile(u'for i in range(_sage_const_1 ,_sage_const_10 ):\n i\n __time__=misc.cputime(); __wall__=misc.walltime(); iterate_modk(f,n,c,i); print "Time: CPU %.2f s, Wall: %.2f s"%(misc.cputime(__time__), misc.walltime(__wall__))' + '\n', '', 'single') File "", line 3, in File "/private/var/folders/of/of1uAoZoGDOU7RzXM1esKJ8kyXA/-Tmp-/tmpOhPZKg/___code___.py", line 9, in iterate_modk R=iteratedir(F,v[_sage_const_0 ],Q) File "/private/var/folders/of/of1uAoZoGDOU7RzXM1esKJ8kyXA/-Tmp-/tmpHkjbNd/___code___.py", line 5, in iteratedir Q=f(Q) File "polynomial_zz_pex.pyx", line 283, in sage.rings.polynomial.polynomial_zz_pex.Polynomial_ZZ_pEX.__call__ (sage/rings/polynomial/polynomial_zz_pex.cpp:12684) File "polynomial_zz_pex.pyx", line 55, in sage.rings.polynomial.polynomial_zz_pex.ZZ_pE_c_to_list (sage/rings/polynomial/polynomial_zz_pex.cpp:10741) File "integer_ring.pyx", line 429, in sage.rings.integer_ring.IntegerRing_class._coerce_ZZ (sage/rings/integer_ring.c:6448) ^C __SAGE__ Traceback (most recent call last): File "/Applications/sage/local/lib/python/encodings/utf_8.py", line 15, in decode def decode(input, errors='strict'): KeyboardInterrupt }}} {{{id=13| /// }}}