| 1 | The method image_of_hecke_algebra computes the image by starting with the zero subspace and adding hecke operators until the sturm bound. |
| 2 | |
| 3 | This patch speeds up this method significantly by checking at each step whether the current module is the full endomorphism ring by checking to see if it is of maximal rank and is saturated. This method is already referenced in the current code but was never actually implemented. |
| 4 | |
| 5 | The speedup should be evident in most modular abelian varieties of dimension greater than 1. |
| 6 | |
| 7 | Without the break condition: |
| 8 | {{{ |
| 9 | sage: %time J1(18).endomorphism_ring().image_of_hecke_algebra(check_every=0) |
| 10 | CPU times: user 1.12 s, sys: 60 ms, total: 1.18 s |
| 11 | Wall time: 1.17 s |
| 12 | Subring of endomorphism ring of Abelian variety J1(18) of dimension 2 |
| 13 | sage: %time J0(23).endomorphism_ring().image_of_hecke_algebra(check_every=0) |
| 14 | CPU times: user 164 ms, sys: 8 ms, total: 172 ms |
| 15 | Wall time: 161 ms |
| 16 | Subring of endomorphism ring of Abelian variety J0(23) of dimension 2 |
| 17 | sage: %time J1(23).endomorphism_ring().image_of_hecke_algebra(check_every=0) |
| 18 | CPU times: user 3min 42s, sys: 8.91 s, total: 3min 51s |
| 19 | Wall time: 3min 51s |
| 20 | Subring of endomorphism ring of Abelian variety J1(23) of dimension 12 |
| 21 | }}} |
| 22 | |
| 23 | With the break condition: |
| 24 | {{{ |
| 25 | sage: %time J1(18).endomorphism_ring().image_of_hecke_algebra(check_every=1) |
| 26 | CPU times: user 204 ms, sys: 40 ms, total: 244 ms |
| 27 | Wall time: 236 ms |
| 28 | Subring of endomorphism ring of Abelian variety J1(18) of dimension 2 |
| 29 | sage: %time J0(23).endomorphism_ring().image_of_hecke_algebra(check_every=1) |
| 30 | CPU times: user 92 ms, sys: 16 ms, total: 108 ms |
| 31 | Wall time: 99.1 ms |
| 32 | Subring of endomorphism ring of Abelian variety J0(23) of dimension 2 |
| 33 | sage: %time J1(23).endomorphism_ring().image_of_hecke_algebra(check_every=1) |
| 34 | CPU times: user 28.5 s, sys: 1.26 s, total: 29.8 s |
| 35 | Wall time: 29.8 s |
| 36 | Subring of endomorphism ring of Abelian variety J1(23) of dimension 12 |
| 37 | }}} |
| 38 | |
| 39 | |
| 40 | I also checked this is against the old code. I broke the caching by commenting out lines 956-959 and then ran this code on a big computer. |
| 41 | {{{ |
| 42 | from sage.all import * |
| 43 | from itertools import product |
| 44 | |
| 45 | |
| 46 | @parallel(40) |
| 47 | def test_at_level(N, j): |
| 48 | if j == 0: |
| 49 | J = J0(N) |
| 50 | else: |
| 51 | J = J1(N) |
| 52 | |
| 53 | R = J.endomorphism_ring() |
| 54 | A = R.image_of_hecke_algebra(check_every=0) |
| 55 | B = R.image_of_hecke_algebra(check_every=1) |
| 56 | |
| 57 | return [x.matrix() for x in A.gens()] == \ |
| 58 | [x.matrix() for x in B.gens()] |
| 59 | |
| 60 | Ns = range(1,26) |
| 61 | js = [0,1] |
| 62 | tests = list(product(Ns,js)) |
| 63 | |
| 64 | test_results = list(test_at_level(tests)) |
| 65 | print("Number of tests: {}".format(len(test_results))) |
| 66 | if all([x[1] for x in test_results]): |
| 67 | print("Passed") |
| 68 | else: |
| 69 | print("Failed") |
| 70 | }}} |