| 1 | """ |
|---|
| 2 | Jacobian of a General Hyperelliptic Curve |
|---|
| 3 | """ |
|---|
| 4 | |
|---|
| 5 | #***************************************************************************** |
|---|
| 6 | # Copyright (C) 2006 David Kohel <kohel@maths.usyd.edu> |
|---|
| 7 | # Distributed under the terms of the GNU General Public License (GPL) |
|---|
| 8 | # http://www.gnu.org/licenses/ |
|---|
| 9 | #***************************************************************************** |
|---|
| 10 | |
|---|
| 11 | from sage.rings.all import is_Ring |
|---|
| 12 | from sage.schemes.jacobians.abstract_jacobian import Jacobian_generic |
|---|
| 13 | import sage.schemes.generic.homset as homset |
|---|
| 14 | import sage.schemes.generic.morphism as morphism |
|---|
| 15 | from hyperelliptic_generic import is_HyperellipticCurve |
|---|
| 16 | import jacobian_homset |
|---|
| 17 | import jacobian_morphism |
|---|
| 18 | |
|---|
| 19 | class HyperellipticJacobian_generic(Jacobian_generic): |
|---|
| 20 | """ |
|---|
| 21 | EXAMPLES: |
|---|
| 22 | sage: FF = FiniteField(2003) |
|---|
| 23 | sage: R.<x> = PolynomialRing(FF) |
|---|
| 24 | sage: f = x**5 + 1184*x**3 + 1846*x**2 + 956*x + 560 |
|---|
| 25 | sage: C = HyperellipticCurve(f) |
|---|
| 26 | sage: J = C.jacobian() |
|---|
| 27 | sage: a = x**2 + 376*x + 245; b = 1015*x + 1368 |
|---|
| 28 | sage: X = J(FF) |
|---|
| 29 | sage: D = X([a,b]) |
|---|
| 30 | sage: D |
|---|
| 31 | (x^2 + 376*x + 245, y + 988*x + 635) |
|---|
| 32 | sage: J(0) |
|---|
| 33 | (1) |
|---|
| 34 | sage: D == J([a,b]) |
|---|
| 35 | True |
|---|
| 36 | sage: D == D + J(0) |
|---|
| 37 | True |
|---|
| 38 | |
|---|
| 39 | An more extended example, demonstrating arithmetic in J(QQ) and J(K) |
|---|
| 40 | for a number field K/QQ. |
|---|
| 41 | |
|---|
| 42 | sage: P.<x> = PolynomialRing(QQ) |
|---|
| 43 | sage: f = x^5 - x + 1; h = x |
|---|
| 44 | sage: C = HyperellipticCurve(f,h,'u,v') |
|---|
| 45 | sage: C |
|---|
| 46 | Hyperelliptic Curve over Rational Field defined by v^2 + u*v = u^5 - u + 1 |
|---|
| 47 | sage: PP = C.ambient_space() |
|---|
| 48 | sage: PP |
|---|
| 49 | Projective Space of dimension 2 over Rational Field |
|---|
| 50 | sage: C.defining_polynomial() |
|---|
| 51 | -x0^5 + x0*x1*x2^3 + x1^2*x2^3 + x0*x2^4 - x2^5 |
|---|
| 52 | sage: C(QQ) |
|---|
| 53 | Set of Rational Points of Hyperelliptic Curve over Rational Field defined by v^2 + u*v = u^5 - u + 1 |
|---|
| 54 | sage: K.<t> = NumberField(x^2-2) |
|---|
| 55 | sage: C(K) |
|---|
| 56 | Set of Rational Points over Number Field in t with defining polynomial x^2 - 2 of Hyperelliptic Curve over Rational Field defined by v^2 + u*v = u^5 - u + 1 |
|---|
| 57 | sage: P = C(QQ)(0,1,1); P |
|---|
| 58 | (0 : 1 : 1) |
|---|
| 59 | sage: P == C(0,1,1) |
|---|
| 60 | True |
|---|
| 61 | sage: C(0,1,1).parent() |
|---|
| 62 | Set of Rational Points of Hyperelliptic Curve over Rational Field defined by v^2 + u*v = u^5 - u + 1 |
|---|
| 63 | sage: P1 = C(K)(P) |
|---|
| 64 | sage: P2 = C(K)([2,4*t-1,1]) |
|---|
| 65 | sage: P3 = C(K)([-1/2,1/8*(7*t+2),1]) |
|---|
| 66 | sage: P1, P2, P3 |
|---|
| 67 | ((0 : 1 : 1), (2 : 4*t - 1 : 1), (-1/2 : 7/8*t + 1/4 : 1)) |
|---|
| 68 | sage: J = C.jacobian() |
|---|
| 69 | sage: J |
|---|
| 70 | Jacobian of Hyperelliptic Curve over Rational Field defined by v^2 + u*v = u^5 - u + 1 |
|---|
| 71 | sage: Q = J(QQ)(P); Q |
|---|
| 72 | (u, v + -1) |
|---|
| 73 | sage: for i in range(6): Q*i |
|---|
| 74 | (1) |
|---|
| 75 | (u, v + -1) |
|---|
| 76 | (u^2, v + u - 1) |
|---|
| 77 | (u^2, v + 1) |
|---|
| 78 | (u, v + 1) |
|---|
| 79 | (1) |
|---|
| 80 | sage: Q1 = J(K)(P1); print "%s -> %s"%( P1, Q1 ) |
|---|
| 81 | (0 : 1 : 1) -> (u, v + -1) |
|---|
| 82 | sage: Q2 = J(K)(P2); print "%s -> %s"%( P2, Q2 ) |
|---|
| 83 | (2 : 4*t - 1 : 1) -> (u + -2, v + -4*t + 1) |
|---|
| 84 | sage: Q3 = J(K)(P3); print "%s -> %s"%( P3, Q3 ) |
|---|
| 85 | (-1/2 : 7/8*t + 1/4 : 1) -> (u + 1/2, v + -7/8*t - 1/4) |
|---|
| 86 | sage: R.<x> = PolynomialRing(K) |
|---|
| 87 | sage: Q4 = J(K)([x^2-t,R(1)]) |
|---|
| 88 | sage: for i in range(4): Q4*i |
|---|
| 89 | (1) |
|---|
| 90 | (u^2 + -t, v + -1) |
|---|
| 91 | (u^2 + (-3/4*t - 9/16)*u + 1/2*t + 1/4, v + (-1/32*t - 57/64)*u + 1/2*t + 9/16) |
|---|
| 92 | (u^2 + (1352416/247009*t - 1636930/247009)*u + -1156544/247009*t + 1900544/247009, v + (-2326345442/122763473*t + 3233153137/122763473)*u + 2439343104/122763473*t - 3350862929/122763473) |
|---|
| 93 | sage: R2 = Q2*5; R2 |
|---|
| 94 | (u^2 + (-3789465233/116983808)*u + -267915823/58491904, v + (-233827256513849/1789384327168*t + 1/2)*u + -15782925357447/894692163584*t) |
|---|
| 95 | sage: R3 = Q3*5; R3 |
|---|
| 96 | (u^2 + 5663300808399913890623/14426454798950909645952*u + -26531814176395676231273/28852909597901819291904, v + (253155440321645614070860868199103/2450498420175733688903836378159104*t + 1/2)*u + 2427708505064902611513563431764311/4900996840351467377807672756318208*t) |
|---|
| 97 | sage: R4 = Q4*5; R4 |
|---|
| 98 | (u^2 + (-3789465233/116983808)*u + -267915823/58491904, v + (233827256513849/1789384327168*t + 1/2)*u + 15782925357447/894692163584*t) |
|---|
| 99 | sage: # Thus we find the following identity: |
|---|
| 100 | sage: 5*Q2 + 5*Q4 |
|---|
| 101 | (1) |
|---|
| 102 | sage: # Moreover the following relation holds in the 5-torsion subgroup: |
|---|
| 103 | sage: Q2 + Q4 == 2*Q1 |
|---|
| 104 | True |
|---|
| 105 | """ |
|---|
| 106 | |
|---|
| 107 | def dimension(self): |
|---|
| 108 | return self.__curve.genus() |
|---|
| 109 | |
|---|
| 110 | def point(self, mumford, check=True): |
|---|
| 111 | try: |
|---|
| 112 | return jacobian_homset.JacobianHomset_divisor_classes(self, self.base_ring())(mumford) |
|---|
| 113 | except AttributeError: |
|---|
| 114 | raise ValueError, "Arguments must determine a valid Mumford divisor." |
|---|
| 115 | |
|---|
| 116 | def _homset_class(self, *args, **kwds): |
|---|
| 117 | return jacobian_homset.JacobianHomset_divisor_classes(*args, **kwds) |
|---|
| 118 | |
|---|
| 119 | def _point_class(self, *args, **kwds): |
|---|
| 120 | return jacobian_morphism.JacobianMorphism_divisor_class_field(*args, **kwds) |
|---|
| 121 | |
|---|
| 122 | def _cmp_(self,other): |
|---|
| 123 | if self.curve() == other.curve(): |
|---|
| 124 | return 0 |
|---|
| 125 | else: |
|---|
| 126 | return -1 |
|---|