@@ -70,7 +70,8 @@ class TernaryQF(SageObject):
70
70
sage: TestSuite(TernaryQF).run()
71
71
"""
72
72
73
- __slots__ = ['_a' , '_b' , '_c' , '_r' , '_s' , '_t' , '_automorphisms' , '_number_of_automorphisms' ]
73
+ __slots__ = ['_a' , '_b' , '_c' , '_r' , '_s' , '_t' ,
74
+ '_automorphisms' , '_number_of_automorphisms' ]
74
75
75
76
possible_automorphisms = None
76
77
@@ -90,17 +91,16 @@ def __init__(self, v):
90
91
[1 2 3]
91
92
[4 5 6]
92
93
"""
93
-
94
94
if len (v ) != 6 :
95
95
# Check we have six coefficients
96
96
raise ValueError ("Ternary quadratic form must be given by a list of six coefficients" )
97
97
self ._a , self ._b , self ._c , self ._r , self ._s , self ._t = (ZZ (x ) for x in v )
98
98
self ._automorphisms = None
99
99
self ._number_of_automorphisms = None
100
100
101
- def coefficients (self ):
101
+ def coefficients (self ) -> tuple :
102
102
r"""
103
- Return the list of coefficients of the ternary quadratic form.
103
+ Return the tuple of coefficients of the ternary quadratic form.
104
104
105
105
EXAMPLES::
106
106
@@ -113,7 +113,7 @@ def coefficients(self):
113
113
"""
114
114
return self ._a , self ._b , self ._c , self ._r , self ._s , self ._t
115
115
116
- def __hash__ (self ):
116
+ def __hash__ (self ) -> int :
117
117
"""
118
118
Return a hash for ``self``.
119
119
@@ -124,7 +124,6 @@ def __hash__(self):
124
124
5881802312257552497 # 64-bit
125
125
1770036893 # 32-bit
126
126
"""
127
-
128
127
return hash (self .coefficients ())
129
128
130
129
def coefficient (self , n ):
@@ -166,7 +165,7 @@ def polynomial(self, names='x,y,z'):
166
165
x , y , z = polygens (ZZ , names )
167
166
return self ._a * x ** 2 + self ._b * y ** 2 + self ._c * z ** 2 + self ._t * x * y + self ._s * x * z + self ._r * y * z
168
167
169
- def _repr_ (self ):
168
+ def _repr_ (self ) -> str :
170
169
r"""
171
170
Display the quadratic form.
172
171
@@ -230,19 +229,19 @@ def __call__(self, v):
230
229
# Check if v has 3 cols
231
230
if v .ncols () == 3 :
232
231
M = v .transpose () * self .matrix () * v
233
- return TernaryQF ([M [0 , 0 ]// 2 , M [1 , 1 ]// 2 , M [2 , 2 ]// 2 ,
232
+ return TernaryQF ([M [0 , 0 ] // 2 , M [1 , 1 ] // 2 , M [2 , 2 ] // 2 ,
234
233
M [1 , 2 ], M [0 , 2 ], M [0 , 1 ]])
235
- else :
236
- return QuadraticForm (ZZ , v .transpose () * self .matrix () * v )
237
- elif isinstance (v , (Vector , list , tuple )):
234
+
235
+ return QuadraticForm (ZZ , v .transpose () * self .matrix () * v )
236
+ if isinstance (v , (Vector , list , tuple )):
238
237
# Check that v has length 3
239
238
if len (v ) != 3 :
240
239
raise TypeError ("your vector needs to have length 3" )
241
240
v0 , v1 , v2 = v
242
241
a , b , c , r , s , t = self .coefficients ()
243
242
return a * v0 ** 2 + b * v1 ** 2 + c * v2 ** 2 + r * v1 * v2 + s * v0 * v2 + t * v0 * v1
244
- else :
245
- raise TypeError ("presently we can only evaluate a quadratic form on a list, tuple, vector or matrix" )
243
+
244
+ raise TypeError ("presently we can only evaluate a quadratic form on a list, tuple, vector or matrix" )
246
245
247
246
def quadratic_form (self ):
248
247
r"""
@@ -260,11 +259,13 @@ def quadratic_form(self):
260
259
sage: bool(QF1 == QF2)
261
260
True
262
261
"""
263
- return QuadraticForm (ZZ , 3 , [self ._a , self ._t , self ._s , self ._b , self ._r , self ._c ])
262
+ return QuadraticForm (ZZ , 3 , [self ._a , self ._t , self ._s ,
263
+ self ._b , self ._r , self ._c ])
264
264
265
265
def matrix (self ):
266
266
r"""
267
267
Return the Hessian matrix associated to the ternary quadratic form.
268
+
268
269
That is, if `Q` is a ternary quadratic form, `Q(x,y,z) = a\cdot x^2 + b\cdot y^2 + c\cdot z^2 + r\cdot y\cdot z + s\cdot x\cdot z + t\cdot x\cdot y`,
269
270
then the Hessian matrix associated to `Q` is
270
271
::
@@ -289,12 +290,15 @@ def matrix(self):
289
290
sage: (v*M*v.column())[0]//2
290
291
28
291
292
"""
292
- M = matrix (ZZ , 3 , [2 * self ._a , self ._t , self ._s , self ._t , 2 * self ._b , self ._r , self ._s , self ._r , 2 * self ._c ])
293
- return M
293
+ return matrix (ZZ , 3 , 3 , [2 * self ._a , self ._t , self ._s ,
294
+ self ._t , 2 * self ._b , self ._r ,
295
+ self ._s , self ._r , 2 * self ._c ])
294
296
295
297
def disc (self ):
296
298
r"""
297
- Return the discriminant of the ternary quadratic form, this is the determinant of the matrix divided by 2.
299
+ Return the discriminant of the ternary quadratic form.
300
+
301
+ This is the determinant of the matrix divided by 2.
298
302
299
303
EXAMPLES::
300
304
@@ -324,28 +328,19 @@ def is_definite(self) -> bool:
324
328
d1 = self ._a
325
329
if d1 == 0 :
326
330
return False
327
- d2 = 4 * self ._a * self ._b - self ._t ** 2
331
+ d2 = 4 * self ._a * self ._b - self ._t ** 2
328
332
if d2 == 0 :
329
333
return False
330
334
d3 = self .disc ()
331
335
if d3 == 0 :
332
336
return False
333
337
if d1 > 0 :
334
338
if d2 > 0 :
335
- if d3 > 0 :
336
- return True
337
- else :
338
- return False
339
- else :
340
- return False
341
- else :
342
- if d2 > 0 :
343
- if d3 < 0 :
344
- return True
345
- else :
346
- return False
347
- else :
348
- return False
339
+ return d3 > 0
340
+ return False
341
+ if d2 > 0 :
342
+ return d3 < 0
343
+ return False
349
344
350
345
def is_positive_definite (self ) -> bool :
351
346
"""
@@ -370,22 +365,13 @@ def is_positive_definite(self) -> bool:
370
365
d1 = self ._a
371
366
if d1 == 0 :
372
367
return False
373
- d2 = 4 * self ._a * self ._b - self ._t ** 2
368
+ d2 = 4 * self ._a * self ._b - self ._t ** 2
374
369
if d2 == 0 :
375
370
return False
376
371
d3 = self .disc ()
377
372
if d3 == 0 :
378
373
return False
379
- if d1 > 0 :
380
- if d2 > 0 :
381
- if d3 > 0 :
382
- return True
383
- else :
384
- return False
385
- else :
386
- return False
387
- else :
388
- return False
374
+ return d1 > 0 and d2 > 0 and d3 > 0
389
375
390
376
def is_negative_definite (self ) -> bool :
391
377
"""
@@ -405,22 +391,13 @@ def is_negative_definite(self) -> bool:
405
391
d1 = self ._a
406
392
if d1 == 0 :
407
393
return False
408
- d2 = 4 * self ._a * self ._b - self ._t ** 2
394
+ d2 = 4 * self ._a * self ._b - self ._t ** 2
409
395
if d2 == 0 :
410
396
return False
411
397
d3 = self .disc ()
412
398
if d3 == 0 :
413
399
return False
414
- if d1 < 0 :
415
- if d2 > 0 :
416
- if d3 < 0 :
417
- return True
418
- else :
419
- return False
420
- else :
421
- return False
422
- else :
423
- return False
400
+ return d1 < 0 and d2 > 0 and d3 < 0
424
401
425
402
def __neg__ (self ):
426
403
"""
@@ -487,7 +464,7 @@ def primitive(self):
487
464
"""
488
465
l = self .coefficients ()
489
466
g = gcd (l )
490
- return TernaryQF ([a // g for a in l ])
467
+ return TernaryQF ([a // g for a in l ])
491
468
492
469
def scale_by_factor (self , k ):
493
470
"""
@@ -950,7 +927,6 @@ def find_p_neighbors(self, p, mat=False):
950
927
sage: neig.count(Q2)
951
928
3
952
929
"""
953
-
954
930
z = self .find_zeros_mod_p (p )
955
931
return [self .find_p_neighbor_from_vec (p , v , mat ) for v in z ]
956
932
@@ -964,7 +940,6 @@ def basic_lemma(self, p):
964
940
sage: Q.basic_lemma(3)
965
941
4
966
942
"""
967
-
968
943
return _basic_lemma (self ._a , self ._b , self ._c , self ._r , self ._s , self ._t , p )
969
944
970
945
def xi (self , p ):
@@ -1085,20 +1060,15 @@ def automorphism_symmetries(self, A):
1085
1060
sage: Q.automorphism_symmetries(identity_matrix(ZZ,3))
1086
1061
[]
1087
1062
"""
1088
-
1089
1063
if A == identity_matrix (3 ):
1090
1064
return []
1091
- else :
1092
- bs = (A - 1 ).columns ()
1093
- for b1 in bs :
1094
- if b1 != 0 :
1095
- break
1096
- A1 = self .symmetry (b1 )* A
1097
- bs = (A1 - 1 ).columns ()
1098
- for b2 in bs :
1099
- if b2 != 0 :
1100
- break
1101
- return [b1 , b2 ]
1065
+
1066
+ bs = (A - 1 ).columns ()
1067
+ b1 = next (v for v in bs if v )
1068
+ A1 = self .symmetry (b1 ) * A
1069
+ bs = (A1 - 1 ).columns ()
1070
+ b2 = next (v for v in bs if v )
1071
+ return [b1 , b2 ]
1102
1072
1103
1073
def automorphism_spin_norm (self , A ):
1104
1074
"""
@@ -1117,14 +1087,15 @@ def automorphism_spin_norm(self, A):
1117
1087
"""
1118
1088
if A == identity_matrix (ZZ , 3 ):
1119
1089
return 1
1120
- bs = self .automorphism_symmetries (A )
1121
- s = self (bs [ 0 ] ) * self (bs [ 1 ] )
1090
+ b1 , b2 = self .automorphism_symmetries (A )
1091
+ s = self (b1 ) * self (b2 )
1122
1092
return s .squarefree_part ()
1123
1093
1124
1094
def _border (self , n ):
1125
1095
"""
1126
1096
Auxiliary function to find the automorphisms of a positive definite ternary quadratic form.
1127
- It return a boolean whether the n-condition is true. If Q = TernaryQF([a,b,c,r,s,t]), the conditions are:
1097
+
1098
+ It returns a boolean whether the n-condition is true. If Q = TernaryQF([a,b,c,r,s,t]), the conditions are:
1128
1099
1129
1100
1. a = t, s = 2r.
1130
1101
2. a = s, t = 2r.
@@ -1194,7 +1165,6 @@ def _border(self, n):
1194
1165
sage: Q16._border(16)
1195
1166
True
1196
1167
"""
1197
-
1198
1168
a , b , c , r , s , t = self .coefficients ()
1199
1169
if n == 1 :
1200
1170
return (a == t ) and (s == 2 * r )
@@ -1307,7 +1277,6 @@ def _automorphisms_reduced_fast(self):
1307
1277
sage: Q._automorphisms_reduced_fast()
1308
1278
[(1, 0, 0, 0, 1, 0, 0, 0, 1)]
1309
1279
"""
1310
-
1311
1280
if self ._border (1 ):
1312
1281
if self ._border (2 ):
1313
1282
if self ._border (14 ):
@@ -1672,6 +1641,7 @@ def _automorphisms_reduced_fast(self):
1672
1641
def _automorphisms_reduced_slow (self ):
1673
1642
"""
1674
1643
Return the automorphisms of the reduced ternary quadratic form.
1644
+
1675
1645
It searches over all 3x3 matrices with coefficients -1, 0, 1,
1676
1646
determinant 1 and finite order, because Eisenstein reduced forms
1677
1647
are Minkowski reduced. See Cassels.
@@ -2023,7 +1993,7 @@ def find_all_ternary_qf_by_level_disc(N, d):
2023
1993
...
2024
1994
ValueError: There are no ternary forms of this level and discriminant
2025
1995
"""
2026
- return [TernaryQF (_ ) for _ in _find_all_ternary_qf_by_level_disc (N , d )]
1996
+ return [TernaryQF (qf ) for qf in _find_all_ternary_qf_by_level_disc (N , d )]
2027
1997
2028
1998
2029
1999
def find_a_ternary_qf_by_level_disc (N , d ):
0 commit comments