Skip to content

Commit a1f9934

Browse files
author
Release Manager
committed
gh-40221: Fix caching in Khuri-Makdisi Jacobian implementation This PR fixes a bug with caching of some expensive parts of the Khuri- Makdisi Jacobian implementation. This speeds up constructing the Jacobian group by approximately 95% on the example below. The speedup was significant enough that I was able to remove `long test` from all but one test in the Khuri-Makdisi implementation. Testing the entire Khuri-Makdisi implementation takes slightly longer now that we are including more tests, but all the tests I've included finish in under 5 seconds (at least on my machine, if the CI complains we can put back some of the `long test` markers). ``` K = GF(5) Kx.<x> = FunctionField(K) t = polygen(Kx) F.<y> = Kx.extension(t^3 + (2*x^2 + 3*x + 3)*t^2 + (3*x^2 + x)*t + x^5 + 3*x^4 + 4*x^3 + 4*x^2 + x + 4) J = F.jacobian(model='km_small') %time J.group() # Before: About 1 minute. After: about 3 seconds. ``` The performance increase is similar for `km_medium` and `km_large`. ### 📝 Checklist <!-- Put an `x` in all the boxes that apply. --> - [x] The title is concise and informative. - [x] The description explains in detail what this PR is about. - [ ] I have linked a relevant issue or discussion. - [ ] I have created tests covering the changes. - [ ] I have updated the documentation and checked the documentation preview. ### ⌛ Dependencies None URL: #40221 Reported by: Vincent Macri Reviewer(s): Kwankyu Lee
2 parents 7179e53 + d85d786 commit a1f9934

File tree

3 files changed

+5
-63
lines changed

3 files changed

+5
-63
lines changed

src/sage/rings/function_field/jacobian_base.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@
5252
5353
We can get the corresponding point in the Jacobian in a different model. ::
5454
55-
sage: # long time
5655
sage: p1km = J_km(p1)
5756
sage: p1km.order()
5857
5
@@ -112,7 +111,6 @@ def order(self):
112111
113112
EXAMPLES::
114113
115-
sage: # long time
116114
sage: P2.<x,y,z> = ProjectiveSpace(GF(29), 2)
117115
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
118116
sage: F = C.function_field()
@@ -642,7 +640,6 @@ def __call__(self, x):
642640
643641
TESTS::
644642
645-
sage: # long time
646643
sage: K.<x> = FunctionField(GF(2)); _.<Y> = K[]
647644
sage: F.<y> = K.extension(Y^2 + Y + x + 1/x)
648645
sage: J_hess = F.jacobian(model='hess')

src/sage/rings/function_field/jacobian_khuri_makdisi.py

Lines changed: 5 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@
6868
6969
EXAMPLES::
7070
71-
sage: # long time
7271
sage: P2.<x,y,z> = ProjectiveSpace(GF(17), 2)
7372
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
7473
sage: F = C.function_field()
@@ -155,7 +154,6 @@ class JacobianPoint(JacobianPoint_base):
155154
156155
EXAMPLES::
157156
158-
sage: # long time
159157
sage: P2.<x,y,z> = ProjectiveSpace(GF(7), 2)
160158
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
161159
sage: b = C([0,1,0]).place()
@@ -178,7 +176,6 @@ def __init__(self, parent, w):
178176
179177
TESTS::
180178
181-
sage: # long time
182179
sage: P2.<x,y,z> = ProjectiveSpace(GF(7), 2)
183180
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
184181
sage: b = C([0,1,0]).place()
@@ -199,7 +196,6 @@ def _repr_(self):
199196
200197
EXAMPLES::
201198
202-
sage: # long time
203199
sage: P2.<x,y,z> = ProjectiveSpace(GF(7), 2)
204200
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
205201
sage: h = C.function(y/x).divisor_of_poles()
@@ -222,7 +218,6 @@ def __hash__(self):
222218
223219
EXAMPLES::
224220
225-
sage: # long time
226221
sage: P2.<x,y,z> = ProjectiveSpace(GF(7), 2)
227222
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
228223
sage: F = C.function_field()
@@ -247,7 +242,6 @@ def _richcmp_(self, other, op):
247242
248243
EXAMPLES::
249244
250-
sage: # long time
251245
sage: P2.<x,y,z> = ProjectiveSpace(GF(7), 2)
252246
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
253247
sage: h = C.function(y/x).divisor_of_poles()
@@ -281,7 +275,6 @@ def _add_(self, other):
281275
282276
EXAMPLES::
283277
284-
sage: # long time
285278
sage: P2.<x,y,z> = ProjectiveSpace(GF(7), 2)
286279
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
287280
sage: h = C.function(y/x).divisor_of_poles()
@@ -313,7 +306,6 @@ def _neg_(self):
313306
314307
EXAMPLES::
315308
316-
sage: # long time
317309
sage: P2.<x,y,z> = ProjectiveSpace(GF(7), 2)
318310
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
319311
sage: F = C.function_field()
@@ -348,7 +340,6 @@ def _rmul_(self, n):
348340
349341
EXAMPLES::
350342
351-
sage: # long time
352343
sage: P2.<x,y,z> = ProjectiveSpace(GF(7), 2)
353344
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
354345
sage: h = C.function(y/x).divisor_of_poles()
@@ -372,7 +363,6 @@ def multiple(self, n):
372363
373364
EXAMPLES::
374365
375-
sage: # long time
376366
sage: P2.<x,y,z> = ProjectiveSpace(GF(7), 2)
377367
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
378368
sage: h = C.function(y/x).divisor_of_poles()
@@ -404,7 +394,6 @@ def addflip(self, other):
404394
405395
EXAMPLES::
406396
407-
sage: # long time
408397
sage: P2.<x,y,z> = ProjectiveSpace(GF(7), 2)
409398
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
410399
sage: h = C.function(y/x).divisor_of_poles()
@@ -437,7 +426,6 @@ def defining_matrix(self):
437426
438427
EXAMPLES::
439428
440-
sage: # long time
441429
sage: P2.<x,y,z> = ProjectiveSpace(GF(7), 2)
442430
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
443431
sage: h = C.function(y/x).divisor_of_poles()
@@ -462,7 +450,6 @@ def divisor(self):
462450
463451
EXAMPLES::
464452
465-
sage: # long time
466453
sage: P2.<x,y,z> = ProjectiveSpace(GF(7), 2)
467454
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
468455
sage: F = C.function_field()
@@ -506,7 +493,6 @@ class JacobianGroupEmbedding(Map):
506493
507494
EXAMPLES::
508495
509-
sage: # long time
510496
sage: k = GF(5)
511497
sage: P2.<x,y,z> = ProjectiveSpace(k, 2)
512498
sage: C = Curve(x^3 + z^3 - y^2*z, P2)
@@ -528,7 +514,6 @@ def __init__(self, base_group, extension_group):
528514
529515
TESTS::
530516
531-
sage: # long time
532517
sage: k = GF(5)
533518
sage: P2.<x,y,z> = ProjectiveSpace(k, 2)
534519
sage: C = Curve(x^3 + z^3 - y^2*z, P2)
@@ -553,7 +538,6 @@ def _repr_type(self):
553538
554539
TESTS::
555540
556-
sage: # long time
557541
sage: k = GF(5)
558542
sage: P2.<x,y,z> = ProjectiveSpace(k, 2)
559543
sage: C = Curve(x^3 + z^3 - y^2*z, P2)
@@ -577,7 +561,6 @@ def _call_(self, x):
577561
578562
TESTS::
579563
580-
sage: # long time
581564
sage: k = GF(5)
582565
sage: P2.<x,y,z> = ProjectiveSpace(k, 2)
583566
sage: C = Curve(x^3 + z^3 - y^2*z, P2)
@@ -609,7 +592,6 @@ class JacobianGroup(UniqueRepresentation, JacobianGroup_base):
609592
610593
EXAMPLES::
611594
612-
sage: # long time
613595
sage: P2.<x,y,z> = ProjectiveSpace(GF(7), 2)
614596
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
615597
sage: h = C.function(y/x).divisor_of_poles()
@@ -627,7 +609,6 @@ def __init__(self, parent, function_field, base_div):
627609
628610
TESTS::
629611
630-
sage: # long time
631612
sage: P2.<x,y,z> = ProjectiveSpace(GF(7), 2)
632613
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
633614
sage: h = C.function(y/x).divisor_of_poles()
@@ -639,18 +620,14 @@ def __init__(self, parent, function_field, base_div):
639620
D0 = base_div
640621

641622
self._base_div_degree = base_div.degree()
642-
self._V_cache = 10*[None]
643-
644-
V_cache = self._V_cache
623+
self._V_cache = dict()
645624

646625
def V(n):
647-
if n in V_cache:
648-
return V_cache[n]
649-
650-
Vn, from_Vn, to_Vn = (n * D0).function_space()
651-
V_cache[n] = (Vn, from_Vn, to_Vn)
626+
if n in self._V_cache:
627+
return self._V_cache[n]
652628

653-
return Vn, from_Vn, to_Vn
629+
self._V_cache[n] = (n * D0).function_space()
630+
return self._V_cache[n]
654631

655632
def mu(n, m, i, j):
656633
Vn, from_Vn, to_Vn = V(n)
@@ -692,7 +669,6 @@ def _repr_(self):
692669
693670
EXAMPLES::
694671
695-
sage: # long time
696672
sage: P2.<x,y,z> = ProjectiveSpace(GF(7), 2)
697673
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
698674
sage: h = C.function(y/x).divisor_of_poles()
@@ -714,7 +690,6 @@ def _wd_from_divisor(self, x):
714690
715691
TESTS:
716692
717-
sage: # long time
718693
sage: P2.<x,y,z> = ProjectiveSpace(GF(7), 2)
719694
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
720695
sage: h = C.function(y/x).divisor_of_poles()
@@ -741,7 +716,6 @@ def _element_constructor_(self, x):
741716
742717
TESTS::
743718
744-
sage: # long time
745719
sage: P2.<x,y,z> = ProjectiveSpace(GF(7), 2)
746720
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
747721
sage: h = C.function(y/x).divisor_of_poles()
@@ -800,7 +774,6 @@ def point(self, divisor):
800774
801775
EXAMPLES::
802776
803-
sage: # long time
804777
sage: P2.<x,y,z> = ProjectiveSpace(GF(7), 2)
805778
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
806779
sage: h = C.function(y/x).divisor_of_poles()
@@ -834,7 +807,6 @@ def zero(self):
834807
835808
EXAMPLES::
836809
837-
sage: # long time
838810
sage: P2.<x,y,z> = ProjectiveSpace(GF(7), 2)
839811
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
840812
sage: h = C.function(y/x).divisor_of_poles()
@@ -866,7 +838,6 @@ class JacobianGroup_finite_field(JacobianGroup, JacobianGroup_finite_field_base)
866838
867839
EXAMPLES::
868840
869-
sage: # long time
870841
sage: k = GF(7)
871842
sage: P2.<x,y,z> = ProjectiveSpace(k, 2)
872843
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
@@ -890,7 +861,6 @@ def __init__(self, parent, function_field, base_div):
890861
891862
TESTS::
892863
893-
sage: # long time
894864
sage: k = GF(7)
895865
sage: P2.<x,y,z> = ProjectiveSpace(k, 2)
896866
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
@@ -981,7 +951,6 @@ def _frobenius_on(self, pt):
981951
982952
TESTS::
983953
984-
sage: # long time
985954
sage: k = GF(7)
986955
sage: A.<x,y> = AffineSpace(k,2)
987956
sage: C = Curve(y^2 + x^3 + 2*x + 1).projective_closure()
@@ -1016,15 +985,13 @@ def __init__(self, function_field, base_div, model, **kwds):
1016985
1017986
TESTS::
1018987
1019-
sage: # long time
1020988
sage: P2.<x,y,z> = ProjectiveSpace(GF(7), 2)
1021989
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
1022990
sage: J = C.jacobian(model='km_large')
1023991
sage: TestSuite(J).run(skip=['_test_elements', '_test_pickling'])
1024992
1025993
::
1026994
1027-
sage: # long time
1028995
sage: J = C.jacobian(model='km_unknown')
1029996
Traceback (most recent call last):
1030997
...

0 commit comments

Comments
 (0)