Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/schemes/toric/weierstrass_higher.py
8820 views
1
r"""
2
Weierstrass for Elliptic Curves in Higher Codimension
3
4
The :mod:`~sage.schemes.toric.weierstrass` module lets you transform a
5
genus-one curve, given as a hypersurface in a toric surface, into
6
Weierstrass form. The purpose of this module is to extend this to
7
higher codimension subschemes of toric varieties. In general, this is
8
an unsolved problem. However, for certain special cases this is known.
9
10
The simplest codimension-two case is the complete intersection of two
11
quadratic equations in `\mathbb{P}^3` ::
12
13
sage: R.<w,x,y,z> = QQ[]
14
sage: quadratic1 = w^2+x^2+y^2
15
sage: quadratic2 = z^2 + w*x
16
sage: WeierstrassForm([quadratic1, quadratic2])
17
(-1/4, 0)
18
19
Hence, the Weierstrass form of this complete intersection is $Y^2 =
20
X^3 - \frac{1}{4} X Z^4$.
21
"""
22
23
#*****************************************************************************
24
# Copyright (C) 2012 Volker Braun <[email protected]>
25
#
26
# Distributed under the terms of the GNU General Public License (GPL)
27
# as published by the Free Software Foundation; either version 2 of
28
# the License, or (at your option) any later version.
29
# http://www.gnu.org/licenses/
30
#*****************************************************************************
31
32
from sage.rings.all import PolynomialRing
33
from sage.rings.invariant_theory import invariant_theory
34
from sage.schemes.toric.weierstrass import (
35
_check_homogeneity, _extract_coefficients )
36
37
38
######################################################################
39
def WeierstrassForm2(polynomial, variables=None, transformation=False):
40
r"""
41
Helper function for :func:`~sage.schemes.toric.weierstrass.WeierstrassForm`
42
43
Currently, only the case of the complete intersection of two
44
quadratic equations in `\mathbb{P}^3` is supported.
45
46
INPUT / OUTPUT:
47
48
See :func:`~sage.schemes.toric.weierstrass.WeierstrassForm`
49
50
TESTS::
51
52
sage: from sage.schemes.toric.weierstrass_higher import WeierstrassForm2
53
sage: R.<w,x,y,z> = QQ[]
54
sage: quadratic1 = w^2+x^2+y^2
55
sage: quadratic2 = z^2 + w*x
56
sage: WeierstrassForm2([quadratic1, quadratic2])
57
(-1/4, 0)
58
"""
59
if transformation:
60
return WeierstrassMap_P3(*polynomial, variables=variables)
61
else:
62
return WeierstrassForm_P3(*polynomial, variables=variables)
63
64
65
######################################################################
66
#
67
# Weierstrass form of complete intersection of two quadratics in P^3
68
#
69
######################################################################
70
def _check_polynomials_P3(quadratic1, quadratic2, variables):
71
"""
72
Check that the polynomial is weighted homogeneous in standard variables.
73
74
INPUT:
75
76
- ``quadratic1``, ``quadratic2`` -- two quadratic polynomials in 4
77
homogeneous or 3 inhomogeneous variables.
78
79
- ``variables`` -- the variables or ``None`` (default).
80
81
OUTPUT:
82
83
This function returns ``variables``, potentially guessed from the
84
polynomial ring. A ``ValueError`` is raised if the polynomial is
85
not homogeneous.
86
87
EXAMPLES:
88
89
sage: from sage.schemes.toric.weierstrass_higher import _check_polynomials_P3
90
sage: R.<w,x,y,z> = QQ[]
91
sage: quadratic = w^2+x^2+y^2+z^2
92
sage: _check_polynomials_P3(w^2, quadratic, [w,x,y,z])
93
(w, x, y, z)
94
sage: _check_polynomials_P3(w^2, quadratic, None)
95
(w, x, y, z)
96
sage: _check_polynomials_P3(z^2, quadratic.subs(w=0), None)
97
(x, y, z, None)
98
sage: R.<w,x,y,z,t> = QQ[]
99
sage: quadratic = w^2+x^2+y^2+z^2 + t*(x*y+y*z+z*w+w*x)
100
sage: _check_polynomials_P3(w^2, quadratic, [w,x,y,z])
101
(w, x, y, z)
102
sage: _check_polynomials_P3(w^2, quadratic, [w,x,y,t])
103
Traceback (most recent call last):
104
...
105
ValueError: The polynomial is not homogeneous with weights (1, 1, 1, 1)
106
"""
107
if quadratic1.parent() is not quadratic2.parent():
108
raise ValueError('The two quadratics must be in the same polynomial ring.')
109
if variables is None:
110
from sage.misc.misc import uniq
111
variables = uniq(quadratic1.variables() + quadratic2.variables())
112
variables.reverse()
113
if len(variables) == 4:
114
w, x, y, z = variables
115
_check_homogeneity(quadratic1, [w, x, y, z], (1, 1, 1, 1), 2)
116
_check_homogeneity(quadratic2, [w, x, y, z], (1, 1, 1, 1), 2)
117
elif len(variables) == 3:
118
w, x, y = variables
119
z = None
120
else:
121
raise ValueError('Need three or four variables, got '+str(variables))
122
return (w, x, y, z)
123
124
125
126
######################################################################
127
def _biquadratic_syzygy_quartic(quadratic1, quadratic2, variables=None):
128
r"""
129
Helper function for the Weierstrass form of a biquadratic in $`\mathbb{P}^3$
130
131
The invariants and covariants of a quaternary biquadratic satisfy
132
the relation
133
:meth:`sage.rings.invariant_theory.TwoQuaternaryQuadratics.syzygy`,
134
which is (modulo the two quadratic equations) of the form $J^2 =
135
p_4(T, T')$ where
136
137
* $J$, $T$, $T'$ are the covariants of the biquadratic.
138
139
* $p_4$ is some quartic polynomial whose coefficients are
140
invariants of the biquadratic.
141
142
INPUT:
143
144
See :func:`WeierstrassForm_P3`
145
146
OUTPUT:
147
148
A triple consisting of
149
150
- The quaternary biquadratic as an algebraic form
151
:class:`~sage.rings.invariant_theory.TwoQuaternaryQuadratics`
152
153
- The binary quartic $p_4$ as a
154
:class:`~sage.rings.invariant_theory.BinaryQuartic`
155
156
- The dictionary of variable substitutions from the variables of
157
the quartic to the variables of the biquadratic.
158
159
EXAMPLES::
160
161
sage: from sage.schemes.toric.weierstrass_higher import _biquadratic_syzygy_quartic
162
sage: R.<w,x,y,z> = QQ[]
163
sage: _biquadratic_syzygy_quartic(w^2+x^2+y^2, z^2)
164
(Joint quaternary quadratic with coefficients (1, 1, 1, 0, 0, 0, 0, 0, 0, 0)
165
and quaternary quadratic with coefficients (0, 0, 0, 1, 0, 0, 0, 0, 0, 0),
166
Binary quartic with coefficients (0, 0, 0, -1, 0), {aux...})
167
"""
168
w, x, y, z = _check_polynomials_P3(quadratic1, quadratic2, variables)
169
biquadratic = invariant_theory.quaternary_biquadratic(quadratic1, quadratic2, [w, x, y, z])
170
171
# construct auxiliary polynomial ring to work with the rhs of the syzygy
172
R = biquadratic.ring()
173
n = R.ngens()
174
R_aux = PolynomialRing(R.base_ring(), n+2, 'aux')
175
to_aux = dict()
176
from_aux = dict()
177
for var, var_aux in zip(R.gens(), R_aux.gens()[0:n]):
178
to_aux[var] = var_aux
179
from_aux[var_aux] = var
180
T, T_prime = R_aux.gens()[n:]
181
from_aux[T] = biquadratic.T_covariant()
182
from_aux[T_prime] = biquadratic.T_prime_covariant()
183
184
# Syzygy is J^2 = syz_rhs + (terms that vanish on the biquadratic) with
185
# J = biquadratic.J_covariant()
186
syz_rhs = T**4 * biquadratic.Delta_invariant().subs(to_aux) \
187
- T**3*T_prime * biquadratic.Theta_invariant().subs(to_aux) \
188
+ T**2*T_prime**2 * biquadratic.Phi_invariant().subs(to_aux) \
189
- T*T_prime**3 * biquadratic.Theta_prime_invariant().subs(to_aux) \
190
+ T_prime**4 * biquadratic.Delta_prime_invariant().subs(to_aux)
191
quartic = invariant_theory.binary_quartic(syz_rhs, [T, T_prime])
192
return (biquadratic, quartic, from_aux)
193
194
195
######################################################################
196
def WeierstrassForm_P3(quadratic1, quadratic2, variables=None):
197
r"""
198
Bring a complete intersection of two quadratics into Weierstrass form.
199
200
Input/output is the same as
201
:func:`sage.schemes.toric.weierstrass.WeierstrassForm`, except
202
that the two input polynomials must be quadratic polynomials in
203
`\mathbb{P}^3`.
204
205
EXAMPLES::
206
207
sage: from sage.schemes.toric.weierstrass_higher import WeierstrassForm_P3
208
sage: R.<w,x,y,z> = QQ[]
209
sage: quadratic1 = w^2+x^2+y^2
210
sage: quadratic2 = z^2 + w*x
211
sage: WeierstrassForm_P3(quadratic1, quadratic2)
212
(-1/4, 0)
213
214
TESTS::
215
216
sage: R.<w,x,y,z,a0,a1,a2,a3,b0,b1,b2,b3,b4,b5> = QQ[]
217
sage: p1 = w^2 + x^2 + y^2 + z^2
218
sage: p2 = a0*w^2 + a1*x^2 + a2*y^2 + a3*z^2
219
sage: p2 += b0*x*y + b1*x*z + b2*x*w + b3*y*z + b4*y*w + b5*z*w
220
sage: a, b = WeierstrassForm_P3(p1, p2, [w,x,y,z])
221
sage: a.total_degree(), len(a.coefficients())
222
(4, 107)
223
sage: b.total_degree(), len(b.coefficients())
224
(6, 648)
225
"""
226
biquadratic, quartic, from_aux = \
227
_biquadratic_syzygy_quartic(quadratic1, quadratic2, variables=variables)
228
a = quartic.EisensteinD().subs(from_aux)
229
b = quartic.EisensteinE().subs(from_aux)
230
return (-4*a, 16*b)
231
232
233
######################################################################
234
def WeierstrassMap_P3(quadratic1, quadratic2, variables=None):
235
r"""
236
Bring a complete intersection of two quadratics into Weierstrass form.
237
238
Input/output is the same as
239
:func:`sage.schemes.toric.weierstrass.WeierstrassForm`, except
240
that the two input polynomials must be quadratic polynomials in
241
`\mathbb{P}^3`.
242
243
EXAMPLES::
244
245
sage: from sage.schemes.toric.weierstrass_higher import \
246
....: WeierstrassMap_P3, WeierstrassForm_P3
247
sage: R.<w,x,y,z> = QQ[]
248
sage: quadratic1 = w^2+x^2+y^2
249
sage: quadratic2 = z^2 + w*x
250
sage: X, Y, Z = WeierstrassMap_P3(quadratic1, quadratic2)
251
sage: X
252
1/1024*w^8 + 3/256*w^6*x^2 + 19/512*w^4*x^4 + 3/256*w^2*x^6 + 1/1024*x^8
253
sage: Y
254
1/32768*w^12 - 7/16384*w^10*x^2 - 145/32768*w^8*x^4 - 49/8192*w^6*x^6
255
- 145/32768*w^4*x^8 - 7/16384*w^2*x^10 + 1/32768*x^12
256
sage: Z
257
-1/8*w^2*y*z + 1/8*x^2*y*z
258
259
sage: a, b = WeierstrassForm_P3(quadratic1, quadratic2); a, b
260
(-1/4, 0)
261
262
sage: ideal = R.ideal(quadratic1, quadratic2)
263
sage: (-Y^2 + X^3 + a*X*Z^4 + b*Z^6).reduce(ideal)
264
0
265
266
TESTS::
267
268
sage: R.<w,x,y,z,a0,a1,a2,a3> = GF(101)[]
269
sage: p1 = w^2 + x^2 + y^2 + z^2
270
sage: p2 = a0*w^2 + a1*x^2 + a2*y^2 + a3*z^2
271
sage: X, Y, Z = WeierstrassMap_P3(p1, p2, [w,x,y,z])
272
sage: X.total_degree(), len(X.coefficients())
273
(22, 4164)
274
sage: Y.total_degree(), len(Y.coefficients())
275
(33, 26912)
276
sage: Z.total_degree(), len(Z.coefficients())
277
(10, 24)
278
sage: Z
279
w*x*y*z*a0^3*a1^2*a2 - w*x*y*z*a0^2*a1^3*a2 - w*x*y*z*a0^3*a1*a2^2
280
+ w*x*y*z*a0*a1^3*a2^2 + w*x*y*z*a0^2*a1*a2^3 - w*x*y*z*a0*a1^2*a2^3
281
- w*x*y*z*a0^3*a1^2*a3 + w*x*y*z*a0^2*a1^3*a3 + w*x*y*z*a0^3*a2^2*a3
282
- w*x*y*z*a1^3*a2^2*a3 - w*x*y*z*a0^2*a2^3*a3 + w*x*y*z*a1^2*a2^3*a3
283
+ w*x*y*z*a0^3*a1*a3^2 - w*x*y*z*a0*a1^3*a3^2 - w*x*y*z*a0^3*a2*a3^2
284
+ w*x*y*z*a1^3*a2*a3^2 + w*x*y*z*a0*a2^3*a3^2 - w*x*y*z*a1*a2^3*a3^2
285
- w*x*y*z*a0^2*a1*a3^3 + w*x*y*z*a0*a1^2*a3^3 + w*x*y*z*a0^2*a2*a3^3
286
- w*x*y*z*a1^2*a2*a3^3 - w*x*y*z*a0*a2^2*a3^3 + w*x*y*z*a1*a2^2*a3^3
287
"""
288
biquadratic, quartic, from_aux = \
289
_biquadratic_syzygy_quartic(quadratic1, quadratic2, variables=variables)
290
J = biquadratic.J_covariant()
291
g = quartic.g_covariant().subs(from_aux)
292
h = quartic.h_covariant().subs(from_aux)
293
return (4*g, 4*h, J)
294
295
296