Skip to content

Commit 8adab0f

Browse files
committed
change how construction is done
1 parent be07520 commit 8adab0f

File tree

1 file changed

+49
-38
lines changed

1 file changed

+49
-38
lines changed

src/sage/schemes/hyperelliptic_curves/constructor.py

Lines changed: 49 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,11 @@ def HyperellipticCurve(f, h=0, names=None, PP=None, check_squarefree=True):
9292
sage: HyperellipticCurve(x^8 + 1, x)
9393
Traceback (most recent call last):
9494
...
95-
ValueError: Not a hyperelliptic curve: highly singular at infinity.
95+
ValueError: not a hyperelliptic curve: highly singular at infinity
9696
sage: HyperellipticCurve(x^8 + x^7 + 1, x^4)
9797
Traceback (most recent call last):
9898
...
99-
ValueError: Not a hyperelliptic curve: singularity in the provided affine patch.
99+
ValueError: not a hyperelliptic curve: singularity in the provided affine patch
100100
101101
sage: F.<t> = PowerSeriesRing(FiniteField(2))
102102
sage: P.<x> = PolynomialRing(FractionField(F))
@@ -128,7 +128,7 @@ def HyperellipticCurve(f, h=0, names=None, PP=None, check_squarefree=True):
128128
sage: HyperellipticCurve((x^3-x+2)^2*(x^6-1))
129129
Traceback (most recent call last):
130130
...
131-
ValueError: Not a hyperelliptic curve: singularity in the provided affine patch.
131+
ValueError: not a hyperelliptic curve: singularity in the provided affine patch
132132
133133
sage: HyperellipticCurve((x^3-x+2)^2*(x^6-1), check_squarefree=False)
134134
Hyperelliptic Curve over Finite Field of size 7 defined by
@@ -147,7 +147,7 @@ def HyperellipticCurve(f, h=0, names=None, PP=None, check_squarefree=True):
147147
sage: HyperellipticCurve(f, h)
148148
Traceback (most recent call last):
149149
...
150-
ValueError: Not a hyperelliptic curve: highly singular at infinity.
150+
ValueError: not a hyperelliptic curve: highly singular at infinity
151151
152152
sage: HyperellipticCurve(F)
153153
Hyperelliptic Curve over Rational Field defined by y^2 = x^6 + 1
@@ -160,7 +160,7 @@ def HyperellipticCurve(f, h=0, names=None, PP=None, check_squarefree=True):
160160
sage: HyperellipticCurve(x^5 + t)
161161
Traceback (most recent call last):
162162
...
163-
ValueError: Not a hyperelliptic curve: singularity in the provided affine patch.
163+
ValueError: not a hyperelliptic curve: singularity in the provided affine patch
164164
165165
Input with integer coefficients creates objects with the integers
166166
as base ring, but only checks smoothness over `\QQ`, not over Spec(`\ZZ`).
@@ -203,59 +203,73 @@ def HyperellipticCurve(f, h=0, names=None, PP=None, check_squarefree=True):
203203
"""
204204
# F is the discriminant; use this for the type check
205205
# rather than f and h, one of which might be constant.
206-
F = h**2 + 4*f
206+
F = h**2 + 4 * f
207207
if not isinstance(F, Polynomial):
208-
raise TypeError("Arguments f (= %s) and h (= %s) must be polynomials" % (f, h))
208+
raise TypeError(f"Arguments {f = } and {h = } must be polynomials")
209209
P = F.parent()
210210
f = P(f)
211211
h = P(h)
212212
df = f.degree()
213-
dh_2 = 2*h.degree()
213+
dh_2 = 2 * h.degree()
214214
if dh_2 < df:
215-
g = (df-1)//2
215+
g = (df - 1) // 2
216216
else:
217-
g = (dh_2-1)//2
217+
g = (dh_2 - 1) // 2
218218
if check_squarefree:
219219
# Assuming we are working over a field, this checks that after
220220
# resolving the singularity at infinity, we get a smooth double cover
221221
# of P^1.
222222
if P(2) == 0:
223223
# characteristic 2
224224
if h == 0:
225-
raise ValueError("In characteristic 2, argument h (= %s) must be non-zero." % h)
226-
if h[g+1] == 0 and f[2*g+1]**2 == f[2*g+2]*h[g]**2:
227-
raise ValueError("Not a hyperelliptic curve: "
228-
"highly singular at infinity.")
229-
should_be_coprime = [h, f*h.derivative()**2+f.derivative()**2]
225+
raise ValueError(
226+
f"for characteristic 2, argument {h = } must be non-zero"
227+
)
228+
if h[g + 1] == 0 and f[2 * g + 1] ** 2 == f[2 * g + 2] * h[g] ** 2:
229+
raise ValueError(
230+
"not a hyperelliptic curve: highly singular at infinity"
231+
)
232+
should_be_coprime = [h, f * h.derivative() ** 2 + f.derivative() ** 2]
230233
else:
231234
# characteristic not 2
232-
if F.degree() not in [2*g+1, 2*g+2]:
233-
raise ValueError("Not a hyperelliptic curve: "
234-
"highly singular at infinity.")
235+
if F.degree() not in [2 * g + 1, 2 * g + 2]:
236+
raise ValueError(
237+
"not a hyperelliptic curve: highly singular at infinity"
238+
)
235239
should_be_coprime = [F, F.derivative()]
236240
try:
237241
smooth = should_be_coprime[0].gcd(should_be_coprime[1]).degree() == 0
238242
except (AttributeError, NotImplementedError, TypeError):
239243
try:
240244
smooth = should_be_coprime[0].resultant(should_be_coprime[1]) != 0
241245
except (AttributeError, NotImplementedError, TypeError):
242-
raise NotImplementedError("Cannot determine whether "
243-
"polynomials %s have a common root. Use "
244-
"check_squarefree=False to skip this check." %
245-
should_be_coprime)
246+
raise NotImplementedError(
247+
"cannot determine whether "
248+
f"polynomials {should_be_coprime} have a common root, use "
249+
"check_squarefree=False to skip this check"
250+
)
246251
if not smooth:
247-
raise ValueError("Not a hyperelliptic curve: "
248-
"singularity in the provided affine patch.")
252+
raise ValueError(
253+
"not a hyperelliptic curve: "
254+
"singularity in the provided affine patch"
255+
)
249256
R = P.base_ring()
250257
PP = ProjectiveSpace(2, R)
251258
if names is None:
252259
names = ["x", "y"]
253260

254-
superclass = []
261+
bases = []
255262
cls_name = ["HyperellipticCurve"]
256263

264+
# For certain genus we specialise to child classes with
265+
# optimised methods
257266
genus_classes = {2: HyperellipticCurve_g2}
267+
if g in genus_classes:
268+
bases.append(genus_classes[g])
269+
cls_name.append("g%s" % g)
258270

271+
# For certain base fields, we specialise to child classes
272+
# with special case methods
259273
def is_FiniteField(x):
260274
return isinstance(x, FiniteField)
261275

@@ -265,25 +279,22 @@ def is_pAdicField(x):
265279
fields = [
266280
("FiniteField", is_FiniteField, HyperellipticCurve_finite_field),
267281
("RationalField", is_RationalField, HyperellipticCurve_rational_field),
268-
("pAdicField", is_pAdicField, HyperellipticCurve_padic_field)]
269-
270-
if g in genus_classes:
271-
superclass.append(genus_classes[g])
272-
cls_name.append("g%s" % g)
282+
("pAdicField", is_pAdicField, HyperellipticCurve_padic_field),
283+
]
273284

274285
for name, test, cls in fields:
275286
if test(R):
276-
superclass.append(cls)
287+
bases.append(cls)
277288
cls_name.append(name)
278289
break
279290

280-
base_cls = None
281-
if len(superclass) == 0:
282-
base_cls = HyperellipticCurve_generic
291+
# If no specialised child class was found, we simply use the
292+
# generic class in the class construction
293+
if not bases:
294+
bases = [HyperellipticCurve_generic]
283295

296+
# Dynamically build a class from multiple inheritance. Note that
297+
# all classes we slect from are children of HyperellipticCurve_generic
284298
class_name = "_".join(cls_name)
285-
cls = dynamic_class(class_name,
286-
tuple(superclass),
287-
cls=base_cls,
288-
doccls=HyperellipticCurve)
299+
cls = dynamic_class(class_name, tuple(bases), doccls=HyperellipticCurve)
289300
return cls(PP, f, h, names=names, genus=g)

0 commit comments

Comments
 (0)