Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py
4108 views
1
"""
2
Hyperelliptic curves over a general ring
3
4
EXAMPLE::
5
6
sage: P.<x> = GF(5)[]
7
sage: f = x^5 - 3*x^4 - 2*x^3 + 6*x^2 + 3*x - 1
8
sage: C = HyperellipticCurve(f); C
9
Hyperelliptic Curve over Finite Field of size 5 defined by y^2 = x^5 + 2*x^4 + 3*x^3 + x^2 + 3*x + 4
10
11
EXAMPLE::
12
13
sage: P.<x> = QQ[]
14
sage: f = 4*x^5 - 30*x^3 + 45*x - 22
15
sage: C = HyperellipticCurve(f); C
16
Hyperelliptic Curve over Rational Field defined by y^2 = 4*x^5 - 30*x^3 + 45*x - 22
17
sage: C.genus()
18
2
19
20
sage: D = C.affine_patch(0)
21
sage: D.defining_polynomials()[0].parent()
22
Multivariate Polynomial Ring in x0, x1 over Rational Field
23
"""
24
25
#*****************************************************************************
26
# Copyright (C) 2006 David Kohel <[email protected]>
27
# Distributed under the terms of the GNU General Public License (GPL)
28
# http://www.gnu.org/licenses/
29
#*****************************************************************************
30
31
from sage.rings.all import PolynomialRing, RR, PowerSeriesRing, LaurentSeriesRing, O
32
from sage.functions.all import log
33
34
import sage.schemes.plane_curves.projective_curve as plane_curve
35
36
def is_HyperellipticCurve(C):
37
"""
38
EXAMPLES::
39
40
sage: R.<x> = QQ[]; C = HyperellipticCurve(x^3 + x - 1); C
41
Hyperelliptic Curve over Rational Field defined by y^2 = x^3 + x - 1
42
sage: sage.schemes.hyperelliptic_curves.hyperelliptic_generic.is_HyperellipticCurve(C)
43
True
44
"""
45
return isinstance(C,HyperellipticCurve_generic)
46
47
class HyperellipticCurve_generic(plane_curve.ProjectiveCurve_generic):
48
def __init__(self, PP, f, h=None, names=None, genus=None):
49
x, y, z = PP.gens()
50
df = f.degree()
51
F1 = sum([ f[i]*x**i*z**(df-i) for i in range(df+1) ])
52
if h is None:
53
F = y**2*z**(df-2) - F1
54
else:
55
dh = h.degree()
56
deg = max(df,dh+1)
57
F0 = sum([ h[i]*x**i*z**(dh-i) for i in range(dh+1) ])
58
F = y**2*z**(deg-2) + F0*y*z**(deg-dh-1) - F1*z**(deg-df)
59
plane_curve.ProjectiveCurve_generic.__init__(self,PP,F)
60
R = PP.base_ring()
61
if names == None:
62
names = ["x","y"]
63
elif isinstance(names,str):
64
names = names.split(",")
65
self._names = names
66
P1 = PolynomialRing(R,name=names[0])
67
P2 = PolynomialRing(P1,name=names[1])
68
self._PP = PP
69
self._printing_ring = P2
70
self._hyperelliptic_polynomials = (f,h)
71
self._genus = genus
72
73
def change_ring(self, R):
74
"""
75
Returns this HyperEllipticCurve over a new base ring R.
76
77
EXAMPLES::
78
79
sage: R.<x> = QQ['x']
80
sage: H = HyperellipticCurve(x^3-10*x+9)
81
sage: K = Qp(3,5)
82
sage: J.<a> = K.extension(x^30-3)
83
sage: HK = H.change_ring(K)
84
sage: HJ = HK.change_ring(J); HJ
85
Hyperelliptic Curve over Eisenstein Extension of 3-adic Field with capped relative precision 5 in a defined by (1 + O(3^5))*x^30 + (O(3^6))*x^29 + (O(3^6))*x^28 + (O(3^6))*x^27 + (O(3^6))*x^26 + (O(3^6))*x^25 + (O(3^6))*x^24 + (O(3^6))*x^23 + (O(3^6))*x^22 + (O(3^6))*x^21 + (O(3^6))*x^20 + (O(3^6))*x^19 + (O(3^6))*x^18 + (O(3^6))*x^17 + (O(3^6))*x^16 + (O(3^6))*x^15 + (O(3^6))*x^14 + (O(3^6))*x^13 + (O(3^6))*x^12 + (O(3^6))*x^11 + (O(3^6))*x^10 + (O(3^6))*x^9 + (O(3^6))*x^8 + (O(3^6))*x^7 + (O(3^6))*x^6 + (O(3^6))*x^5 + (O(3^6))*x^4 + (O(3^6))*x^3 + (O(3^6))*x^2 + (O(3^6))*x + (2*3 + 2*3^2 + 2*3^3 + 2*3^4 + 2*3^5 + O(3^6)) defined by (1 + O(a^150))*y^2 = (1 + O(a^150))*x^3 + (2 + 2*a^30 + a^60 + 2*a^90 + 2*a^120 + O(a^150))*x + a^60 + O(a^210)
86
"""
87
from constructor import HyperellipticCurve
88
f, h = self._hyperelliptic_polynomials
89
y = self._printing_ring.variable_name()
90
x = self._printing_ring.base_ring().variable_name()
91
return HyperellipticCurve(f.change_ring(R), h, "%s,%s"%(x,y))
92
93
def _repr_(self):
94
"""
95
String representation of hyperelliptic curves.
96
97
EXAMPLE::
98
99
sage: P.<x> = QQ[]
100
sage: f = 4*x^5 - 30*x^3 + 45*x - 22
101
sage: C = HyperellipticCurve(f); C
102
Hyperelliptic Curve over Rational Field defined by y^2 = 4*x^5 - 30*x^3 + 45*x - 22
103
sage: C = HyperellipticCurve(f,names='u,v'); C
104
Hyperelliptic Curve over Rational Field defined by v^2 = 4*u^5 - 30*u^3 + 45*u - 22
105
"""
106
107
f, h = self._hyperelliptic_polynomials
108
R = self.base_ring()
109
y = self._printing_ring.gen()
110
x = self._printing_ring.base_ring().gen()
111
if h == 0:
112
return "Hyperelliptic Curve over %s defined by %s = %s"%(R, y**2, f(x))
113
else:
114
return "Hyperelliptic Curve over %s defined by %s + %s = %s"%(R, y**2, h(x)*y, f(x))
115
116
def __cmp__(self, other):
117
if not isinstance(other, HyperellipticCurve_generic):
118
return -1
119
return cmp(self._hyperelliptic_polynomials, other._hyperelliptic_polynomials)
120
121
def hyperelliptic_polynomials(self, K=None, var='x'):
122
"""
123
EXAMPLES::
124
125
sage: R.<x> = QQ[]; C = HyperellipticCurve(x^3 + x - 1, x^3/5); C
126
Hyperelliptic Curve over Rational Field defined by y^2 + 1/5*x^3*y = x^3 + x - 1
127
sage: C.hyperelliptic_polynomials()
128
(x^3 + x - 1, 1/5*x^3)
129
"""
130
if K is None:
131
return self._hyperelliptic_polynomials
132
else:
133
f, h = self._hyperelliptic_polynomials
134
P = PolynomialRing(K, var)
135
return (P(f),P(h))
136
137
def is_singular(self):
138
r"""
139
Returns False, because hyperelliptic curves are smooth projective
140
curves, as checked on construction.
141
142
EXAMPLES::
143
144
sage: R.<x> = QQ[]
145
sage: H = HyperellipticCurve(x^5+1)
146
sage: H.is_singular()
147
False
148
149
A hyperelliptic curve with genus at least 2 always has a singularity at
150
infinity when viewed as a *plane* projective curve. This can be seen in
151
the following example.::
152
153
sage: R.<x> = QQ[]
154
sage: H = HyperellipticCurve(x^5+2)
155
sage: set_verbose(None)
156
sage: H.is_singular()
157
False
158
sage: from sage.schemes.plane_curves.projective_curve import ProjectiveCurve_generic
159
sage: ProjectiveCurve_generic.is_singular(H)
160
True
161
"""
162
return False
163
164
def is_smooth(self):
165
r"""
166
Returns True, because hyperelliptic curves are smooth projective
167
curves, as checked on construction.
168
169
EXAMPLES::
170
171
sage: R.<x> = GF(13)[]
172
sage: H = HyperellipticCurve(x^8+1)
173
sage: H.is_smooth()
174
True
175
176
A hyperelliptic curve with genus at least 2 always has a singularity at
177
infinity when viewed as a *plane* projective curve. This can be seen in
178
the following example.::
179
180
sage: R.<x> = GF(27, 'a')[]
181
sage: H = HyperellipticCurve(x^10+2)
182
sage: set_verbose(None)
183
sage: H.is_smooth()
184
True
185
sage: from sage.schemes.plane_curves.projective_curve import ProjectiveCurve_generic
186
sage: ProjectiveCurve_generic.is_smooth(H)
187
False
188
"""
189
return True
190
191
def lift_x(self, x, all=False):
192
f, h = self._hyperelliptic_polynomials
193
x += self.base_ring()(0)
194
one = x.parent()(1)
195
if h.is_zero():
196
y2 = f(x)
197
if y2.is_square():
198
if all:
199
return [self.point([x, y, one], check=False) for y in y2.sqrt(all=True)]
200
else:
201
return self.point([x, y2.sqrt(), one], check=False)
202
else:
203
b = h(x)
204
D = b*b + 4*f(x)
205
if D.is_square():
206
if all:
207
return [self.point([x, (-b+d)/2, one], check=False) for d in D.sqrt(all=True)]
208
else:
209
return self.point([x, (-b+D.sqrt())/2, one], check=False)
210
if all:
211
return []
212
else:
213
raise ValueError, "No point with x-coordinate %s on %s"%(x, self)
214
215
216
def genus(self):
217
return self._genus
218
219
def jacobian(self):
220
import jacobian_generic
221
return jacobian_generic.HyperellipticJacobian_generic(self)
222
223
def odd_degree_model(self):
224
r"""
225
Return an odd degree model of self, or raise ValueError if one does not exist over the field of definition.
226
227
EXAMPLES::
228
229
sage: x = QQ['x'].gen()
230
sage: H = HyperellipticCurve((x^2 + 2)*(x^2 + 3)*(x^2 + 5)); H
231
Hyperelliptic Curve over Rational Field defined by y^2 = x^6 + 10*x^4 + 31*x^2 + 30
232
sage: H.odd_degree_model()
233
Traceback (most recent call last):
234
...
235
ValueError: No odd degree model exists over field of definition
236
237
sage: K2 = QuadraticField(-2, 'a')
238
sage: Hp2 = H.change_ring(K2).odd_degree_model(); Hp2
239
Hyperelliptic Curve over Number Field in a with defining polynomial x^2 + 2 defined by y^2 = 6*a*x^5 - 29*x^4 - 20*x^2 + 6*a*x + 1
240
241
sage: K3 = QuadraticField(-3, 'b')
242
sage: Hp3 = H.change_ring(QuadraticField(-3, 'b')).odd_degree_model(); Hp3
243
Hyperelliptic Curve over Number Field in b with defining polynomial x^2 + 3 defined by y^2 = -4*b*x^5 - 14*x^4 - 20*b*x^3 - 35*x^2 + 6*b*x + 1
244
245
Of course, Hp2 and Hp3 are isomorphic over the composite
246
extension. One consequence of this is that odd degree models
247
reduced over "different" fields should have the same number of
248
points on their reductions. 43 and 67 split completely in the
249
compositum, so when we reduce we find:
250
251
sage: P2 = K2.factor(43)[0][0]
252
sage: P3 = K3.factor(43)[0][0]
253
sage: Hp2.change_ring(K2.residue_field(P2)).frobenius_polynomial()
254
x^4 - 16*x^3 + 134*x^2 - 688*x + 1849
255
sage: Hp3.change_ring(K3.residue_field(P3)).frobenius_polynomial()
256
x^4 - 16*x^3 + 134*x^2 - 688*x + 1849
257
sage: H.change_ring(GF(43)).odd_degree_model().frobenius_polynomial()
258
x^4 - 16*x^3 + 134*x^2 - 688*x + 1849
259
260
sage: P2 = K2.factor(67)[0][0]
261
sage: P3 = K3.factor(67)[0][0]
262
sage: Hp2.change_ring(K2.residue_field(P2)).frobenius_polynomial()
263
x^4 - 8*x^3 + 150*x^2 - 536*x + 4489
264
sage: Hp3.change_ring(K3.residue_field(P3)).frobenius_polynomial()
265
x^4 - 8*x^3 + 150*x^2 - 536*x + 4489
266
sage: H.change_ring(GF(67)).odd_degree_model().frobenius_polynomial()
267
x^4 - 8*x^3 + 150*x^2 - 536*x + 4489
268
269
TESTS::
270
sage: HyperellipticCurve(x^5 + 1, 1).odd_degree_model()
271
Traceback (most recent call last):
272
...
273
NotImplementedError: odd_degree_model only implemented for curves in Weierstrass form
274
275
sage: HyperellipticCurve(x^5 + 1, names="U, V").odd_degree_model()
276
Hyperelliptic Curve over Rational Field defined by V^2 = U^5 + 1
277
"""
278
f, h = self._hyperelliptic_polynomials
279
if h:
280
raise NotImplementedError, "odd_degree_model only implemented for curves in Weierstrass form"
281
if f.degree() % 2:
282
# already odd, so just yield self
283
return self
284
285
rts = f.roots(multiplicities=False)
286
if not rts:
287
raise ValueError, "No odd degree model exists over field of definition"
288
rt = rts[0]
289
x = f.parent().gen()
290
fnew = f((x*rt + 1)/x).numerator() # move rt to "infinity"
291
292
from constructor import HyperellipticCurve
293
return HyperellipticCurve(fnew, 0, names=self._names, PP=self._PP)
294
295
def has_odd_degree_model(self):
296
r"""
297
Return True if an odd degree model of self exists over the field of definition; False otherwise.
298
299
Use ``odd_degree_model`` to calculate an odd degree model.
300
301
EXAMPLES::
302
sage: x = QQ['x'].0
303
sage: HyperellipticCurve(x^5 + x).has_odd_degree_model()
304
True
305
sage: HyperellipticCurve(x^6 + x).has_odd_degree_model()
306
True
307
sage: HyperellipticCurve(x^6 + x + 1).has_odd_degree_model()
308
False
309
"""
310
try:
311
return bool(self.odd_degree_model())
312
except ValueError:
313
return False
314
315
def _magma_init_(self, magma):
316
"""
317
Internal function. Returns a string to initialize this elliptic
318
curve in the Magma subsystem.
319
320
EXAMPLES::
321
322
sage: R.<x> = QQ[]; C = HyperellipticCurve(x^3 + x - 1, x); C
323
Hyperelliptic Curve over Rational Field defined by y^2 + x*y = x^3 + x - 1
324
sage: magma(C) # optional - magma
325
Hyperelliptic Curve defined by y^2 + x*y = x^3 + x - 1 over Rational Field
326
sage: R.<x> = GF(9,'a')[]; C = HyperellipticCurve(x^3 + x - 1, x^10); C
327
Hyperelliptic Curve over Finite Field in a of size 3^2 defined by y^2 + x^10*y = x^3 + x + 2
328
sage: D = magma(C); D # optional - magma
329
Hyperelliptic Curve defined by y^2 + (x^10)*y = x^3 + x + 2 over GF(3^2)
330
sage: D.sage() # optional - magma
331
Hyperelliptic Curve over Finite Field in a of size 3^2 defined by y^2 + x^10*y = x^3 + x + 2
332
"""
333
f, h = self._hyperelliptic_polynomials
334
return 'HyperellipticCurve(%s, %s)'%(f._magma_init_(magma), h._magma_init_(magma))
335
336
337
def monsky_washnitzer_gens(self):
338
import sage.schemes.elliptic_curves.monsky_washnitzer as monsky_washnitzer
339
S = monsky_washnitzer.SpecialHyperellipticQuotientRing(self)
340
return S.gens()
341
342
def invariant_differential(self):
343
"""
344
Returns $dx/2y$, as an element of the Monsky-Washnitzer cohomology
345
of self
346
347
EXAMPLES::
348
349
sage: R.<x> = QQ['x']
350
sage: C = HyperellipticCurve(x^5 - 4*x + 4)
351
sage: C.invariant_differential()
352
1 dx/2y
353
354
"""
355
import sage.schemes.elliptic_curves.monsky_washnitzer as m_w
356
S = m_w.SpecialHyperellipticQuotientRing(self)
357
MW = m_w.MonskyWashnitzerDifferentialRing(S)
358
return MW.invariant_differential()
359
360
def local_coordinates_at_nonweierstrass(self, P, prec = 20, name = 't'):
361
"""
362
For a non-Weierstrass point P = (a,b) on the hyperelliptic
363
curve y^2 = f(x), returns (x(t), y(t)) such that (y(t))^2 = f(x(t)),
364
where t = x - a is the local parameter.
365
366
INPUT:
367
368
- P = (a,b) a non-Weierstrass point on self
369
- prec: desired precision of the local coordinates
370
- name: gen of the power series ring (default: 't')
371
372
OUTPUT:
373
(x(t),y(t)) such that y(t)^2 = f(x(t)) and t = x - a
374
is the local parameter at P
375
376
EXAMPLES::
377
378
sage: R.<x> = QQ['x']
379
sage: H = HyperellipticCurve(x^5-23*x^3+18*x^2+40*x)
380
sage: P = H(1,6)
381
sage: x,y = H.local_coordinates_at_nonweierstrass(P,prec=5)
382
sage: x
383
1 + t + O(t^5)
384
sage: y
385
6 + t - 7/2*t^2 - 1/2*t^3 - 25/48*t^4 + O(t^5)
386
sage: Q = H(-2,12)
387
sage: x,y = H.local_coordinates_at_nonweierstrass(Q,prec=5)
388
sage: x
389
-2 + t + O(t^5)
390
sage: y
391
12 - 19/2*t - 19/32*t^2 + 61/256*t^3 - 5965/24576*t^4 + O(t^5)
392
393
AUTHOR:
394
395
- Jennifer Balakrishnan (2007-12)
396
"""
397
d = P[1]
398
if d == 0:
399
raise TypeError, "P = %s is a Weierstrass point. Use local_coordinates_at_weierstrass instead!"%P
400
pol = self.hyperelliptic_polynomials()[0]
401
L = PowerSeriesRing(self.base_ring(), name)
402
t = L.gen()
403
L.set_default_prec(prec)
404
K = PowerSeriesRing(L, 'x')
405
pol = K(pol)
406
x = K.gen()
407
b = P[0]
408
f = pol(t+b)
409
for i in range((RR(log(prec)/log(2))).ceil()):
410
d = (d + f/d)/2
411
return t+b+O(t**(prec)), d + O(t**(prec))
412
413
def local_coordinates_at_weierstrass(self, P, prec = 20, name = 't'):
414
"""
415
For a finite Weierstrass point on the hyperelliptic
416
curve y^2 = f(x), returns (x(t), y(t)) such that
417
(y(t))^2 = f(x(t)), where t = y is the local parameter.
418
419
INPUT:
420
- P a finite Weierstrass point on self
421
- prec: desired precision of the local coordinates
422
- name: gen of the power series ring (default: 't')
423
424
OUTPUT:
425
426
(x(t),y(t)) such that y(t)^2 = f(x(t)) and t = y
427
is the local parameter at P
428
429
EXAMPLES:
430
sage: R.<x> = QQ['x']
431
sage: H = HyperellipticCurve(x^5-23*x^3+18*x^2+40*x)
432
sage: A = H(4,0)
433
sage: x,y = H.local_coordinates_at_weierstrass(A,prec =5)
434
sage: x
435
4 + 1/360*t^2 - 191/23328000*t^4 + 7579/188956800000*t^6 + O(t^7)
436
sage: y
437
t + O(t^7)
438
sage: B = H(-5,0)
439
sage: x,y = H.local_coordinates_at_weierstrass(B,prec = 5)
440
sage: x
441
-5 + 1/1260*t^2 + 887/2000376000*t^4 + 643759/1587898468800000*t^6 + O(t^7)
442
sage: y
443
t + O(t^7)
444
445
AUTHOR:
446
- Jennifer Balakrishnan (2007-12)
447
"""
448
if P[1] != 0:
449
raise TypeError, "P = %s is not a finite Weierstrass point. Use local_coordinates_at_nonweierstrass instead!"%P
450
pol = self.hyperelliptic_polynomials()[0]
451
L = PowerSeriesRing(self.base_ring(), name)
452
t = L.gen()
453
L.set_default_prec(prec+2)
454
K = PowerSeriesRing(L, 'x')
455
pol = K(pol)
456
x = K.gen()
457
b = P[0]
458
g = pol/(x-b)
459
c = b+1/g(b)*t**2
460
f = pol - t**2
461
fprime = f.derivative()
462
for i in range((RR(log(prec+2)/log(2))).ceil()):
463
c = c-f(c)/fprime(c)
464
return c + O(t**(prec+2)),t+O(t**(prec+2))
465
466
def local_coordinates_at_infinity(self, prec = 20, name = 't'):
467
"""
468
For the genus g hyperelliptic curve y^2 = f(x), returns (x(t), y(t)) such that
469
(y(t))^2 = f(x(t)), where t = x^g/y is the local parameter at infinity
470
471
INPUT:
472
- prec: desired precision of the local coordinates
473
- name: gen of the power series ring (default: 't')
474
475
OUTPUT:
476
(x(t),y(t)) such that y(t)^2 = f(x(t)) and t = x^g/y
477
is the local parameter at infinity
478
479
480
EXAMPLES:
481
sage: R.<x> = QQ['x']
482
sage: H = HyperellipticCurve(x^5-5*x^2+1)
483
sage: x,y = H.local_coordinates_at_infinity(10)
484
sage: x
485
t^-2 + 5*t^4 - t^8 - 50*t^10 + O(t^12)
486
sage: y
487
t^-5 + 10*t - 2*t^5 - 75*t^7 + 50*t^11 + O(t^12)
488
489
sage: R.<x> = QQ['x']
490
sage: H = HyperellipticCurve(x^3-x+1)
491
sage: x,y = H.local_coordinates_at_infinity(10)
492
sage: x
493
t^-2 + t^2 - t^4 - t^6 + 3*t^8 + O(t^12)
494
sage: y
495
t^-3 + t - t^3 - t^5 + 3*t^7 - 10*t^11 + O(t^12)
496
497
498
AUTHOR:
499
- Jennifer Balakrishnan (2007-12)
500
"""
501
g = self.genus()
502
pol = self.hyperelliptic_polynomials()[0]
503
K = LaurentSeriesRing(self.base_ring(), name)
504
t = K.gen()
505
K.set_default_prec(prec+2)
506
L = PolynomialRing(self.base_ring(),'x')
507
x = L.gen()
508
i = 0
509
w = (x**g/t)**2-pol
510
wprime = w.derivative(x)
511
x = t**-2
512
for i in range((RR(log(prec+2)/log(2))).ceil()):
513
x = x-w(x)/wprime(x)
514
y = x**g/t
515
return x+O(t**(prec+2)) , y+O(t**(prec+2))
516
517
518
def local_coord(self, P, prec = 20, name = 't'):
519
"""
520
Calls the appropriate local_coordinates function
521
522
INPUT:
523
- P a point on self
524
- prec: desired precision of the local coordinates
525
- name: gen of the power series ring (default: 't')
526
527
OUTPUT:
528
(x(t),y(t)) such that y(t)^2 = f(x(t)), where t
529
is the local parameter at P
530
531
EXAMPLES:
532
sage: R.<x> = QQ['x']
533
sage: H = HyperellipticCurve(x^5-23*x^3+18*x^2+40*x)
534
sage: H.local_coord(H(1,6),prec=5)
535
(1 + t + O(t^5), 6 + t - 7/2*t^2 - 1/2*t^3 - 25/48*t^4 + O(t^5))
536
sage: H.local_coord(H(4,0),prec=5)
537
(4 + 1/360*t^2 - 191/23328000*t^4 + 7579/188956800000*t^6 + O(t^7), t + O(t^7))
538
sage: H.local_coord(H(0,1,0),prec=5)
539
(t^-2 + 23*t^2 - 18*t^4 - 569*t^6 + O(t^7), t^-5 + 46*t^-1 - 36*t - 609*t^3 + 1656*t^5 + O(t^6))
540
541
AUTHOR:
542
- Jennifer Balakrishnan (2007-12)
543
544
545
"""
546
if P[1] == 0:
547
return self.local_coordinates_at_weierstrass(P, prec, name)
548
elif P[2] == 0:
549
return self.local_coordinates_at_infinity(prec, name)
550
else:
551
return self.local_coordinates_at_nonweierstrass(P, prec, name)
552
553