Skip to content

Commit 2e9c575

Browse files
author
Release Manager
committed
gh-37299: use parent in quaternions replace the auld-style class by `Parent` and categories for quaternion algebras. ### 📝 Checklist - [x] The title is concise, informative, and self-explanatory. - [x] The description explains in detail what this PR is about. - [ ] I have linked a relevant issue or discussion. - [x] I have created tests covering the changes. - [x] I have updated the documentation accordingly. URL: #37299 Reported by: Frédéric Chapoton Reviewer(s): Frédéric Chapoton, Travis Scrimshaw
2 parents 4988157 + d7c4495 commit 2e9c575

File tree

3 files changed

+94
-86
lines changed

3 files changed

+94
-86
lines changed

src/sage/algebras/quatalg/quaternion_algebra.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@
3737
# (at your option) any later version.
3838
# https://www.gnu.org/licenses/
3939
# ****************************************************************************
40+
from operator import itemgetter
4041

4142
from sage.arith.misc import (hilbert_conductor_inverse,
4243
hilbert_symbol,
43-
factor,
4444
gcd,
4545
kronecker as kronecker_symbol,
4646
prime_divisors,
@@ -50,8 +50,6 @@
5050
from sage.rings.integer_ring import ZZ
5151
from sage.rings.rational import Rational
5252
from sage.rings.finite_rings.finite_field_constructor import GF
53-
54-
from sage.rings.ring import Algebra
5553
from sage.rings.ideal import Ideal_fractional
5654
from sage.rings.rational_field import is_RationalField, QQ
5755
from sage.rings.infinity import infinity
@@ -68,7 +66,6 @@
6866
from sage.modules.free_module_element import vector
6967
from sage.quadratic_forms.quadratic_form import QuadraticForm
7068

71-
from operator import itemgetter
7269

7370
from .quaternion_algebra_element import (
7471
QuaternionAlgebraElement_abstract,
@@ -314,7 +311,7 @@ def is_QuaternionAlgebra(A):
314311
return isinstance(A, QuaternionAlgebra_abstract)
315312

316313

317-
class QuaternionAlgebra_abstract(Algebra):
314+
class QuaternionAlgebra_abstract(Parent):
318315
def _repr_(self):
319316
"""
320317
EXAMPLES::
@@ -669,7 +666,7 @@ def __init__(self, base_ring, a, b, names='i,j,k'):
669666
ValueError: 2 is not invertible in Integer Ring
670667
"""
671668
cat = Algebras(base_ring).Division().FiniteDimensional()
672-
Algebra.__init__(self, base_ring, names, category=cat)
669+
Parent.__init__(self, base=base_ring, names=names, category=cat)
673670
self._a = a
674671
self._b = b
675672
if is_RationalField(base_ring) and a.denominator() == 1 == b.denominator():
@@ -988,6 +985,19 @@ def gen(self, i=0):
988985
"""
989986
return self._gens[i]
990987

988+
def gens(self) -> tuple:
989+
"""
990+
Return the generators of ``self``.
991+
992+
EXAMPLES::
993+
994+
sage: Q.<ii,jj,kk> = QuaternionAlgebra(QQ,-1,-2); Q
995+
Quaternion Algebra (-1, -2) with base ring Rational Field
996+
sage: Q.gens()
997+
(ii, jj, kk)
998+
"""
999+
return self._gens
1000+
9911001
def _repr_(self):
9921002
"""
9931003
Print representation.

src/sage/categories/algebras.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,84 @@ def Supercommutative(self):
141141
Semisimple = LazyImport('sage.categories.semisimple_algebras',
142142
'SemisimpleAlgebras')
143143

144+
class ParentMethods:
145+
def characteristic(self):
146+
r"""
147+
Return the characteristic of this algebra, which is the same
148+
as the characteristic of its base ring.
149+
150+
EXAMPLES::
151+
152+
sage: # needs sage.modules
153+
sage: ZZ.characteristic()
154+
0
155+
sage: A = GF(7^3, 'a') # needs sage.rings.finite_rings
156+
sage: A.characteristic() # needs sage.rings.finite_rings
157+
7
158+
"""
159+
return self.base_ring().characteristic()
160+
161+
def has_standard_involution(self):
162+
r"""
163+
Return ``True`` if the algebra has a standard involution and ``False`` otherwise.
164+
165+
This algorithm follows Algorithm 2.10 from John Voight's *Identifying the Matrix Ring*.
166+
Currently the only type of algebra this will work for is a quaternion algebra.
167+
Though this function seems redundant, once algebras have more functionality, in particular
168+
have a method to construct a basis, this algorithm will have more general purpose.
169+
170+
EXAMPLES::
171+
172+
sage: # needs sage.combinat sage.modules
173+
sage: B = QuaternionAlgebra(2)
174+
sage: B.has_standard_involution()
175+
True
176+
sage: R.<x> = PolynomialRing(QQ)
177+
sage: K.<u> = NumberField(x**2 - 2) # needs sage.rings.number_field
178+
sage: A = QuaternionAlgebra(K, -2, 5) # needs sage.rings.number_field
179+
sage: A.has_standard_involution() # needs sage.rings.number_field
180+
True
181+
sage: L.<a,b> = FreeAlgebra(QQ, 2)
182+
sage: L.has_standard_involution()
183+
Traceback (most recent call last):
184+
...
185+
NotImplementedError: has_standard_involution is not implemented for this algebra
186+
"""
187+
field = self.base_ring()
188+
try:
189+
basis = self.basis()
190+
except AttributeError:
191+
raise AttributeError("basis is not yet implemented for this algebra")
192+
try:
193+
# TODO: The following code is specific to the quaternion algebra
194+
# and should belong there
195+
# step 1
196+
for i in range(1, 4):
197+
ei = basis[i]
198+
a = ei**2
199+
coef = a.coefficient_tuple()
200+
ti = coef[i]
201+
ni = a - ti * ei
202+
if ni not in field:
203+
return False
204+
# step 2
205+
for i in range(1, 4):
206+
for j in range(2, 4):
207+
ei = basis[i]
208+
ej = basis[j]
209+
a = ei**2
210+
coef = a.coefficient_tuple()
211+
ti = coef[i]
212+
b = ej**2
213+
coef = b.coefficient_tuple()
214+
tj = coef[j]
215+
nij = (ei + ej)**2 - (ti + tj) * (ei + ej)
216+
if nij not in field:
217+
return False
218+
except AttributeError:
219+
raise NotImplementedError("has_standard_involution is not implemented for this algebra")
220+
return True
221+
144222
class ElementMethods:
145223
# TODO: move the content of AlgebraElement here or higher in the category hierarchy
146224
def _div_(self, y):

src/sage/rings/ring.pyx

Lines changed: 0 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -2166,86 +2166,6 @@ cdef class Algebra(Ring):
21662166
Ring.__init__(self,base_ring, names=names, normalize=normalize,
21672167
category=category)
21682168

2169-
def characteristic(self):
2170-
r"""
2171-
Return the characteristic of this algebra, which is the same
2172-
as the characteristic of its base ring.
2173-
2174-
See objects with the ``base_ring`` attribute for additional examples.
2175-
Here are some examples that explicitly use the :class:`Algebra` class.
2176-
2177-
EXAMPLES::
2178-
2179-
sage: # needs sage.modules
2180-
sage: A = Algebra(ZZ); A
2181-
<sage.rings.ring.Algebra object at ...>
2182-
sage: A.characteristic()
2183-
0
2184-
sage: A = Algebra(GF(7^3, 'a')) # needs sage.rings.finite_rings
2185-
sage: A.characteristic() # needs sage.rings.finite_rings
2186-
7
2187-
"""
2188-
return self.base_ring().characteristic()
2189-
2190-
def has_standard_involution(self):
2191-
r"""
2192-
Return ``True`` if the algebra has a standard involution and ``False`` otherwise.
2193-
This algorithm follows Algorithm 2.10 from John Voight's *Identifying the Matrix Ring*.
2194-
Currently the only type of algebra this will work for is a quaternion algebra.
2195-
Though this function seems redundant, once algebras have more functionality, in particular
2196-
have a method to construct a basis, this algorithm will have more general purpose.
2197-
2198-
EXAMPLES::
2199-
2200-
sage: # needs sage.combinat sage.modules
2201-
sage: B = QuaternionAlgebra(2)
2202-
sage: B.has_standard_involution()
2203-
True
2204-
sage: R.<x> = PolynomialRing(QQ)
2205-
sage: K.<u> = NumberField(x**2 - 2) # needs sage.rings.number_field
2206-
sage: A = QuaternionAlgebra(K, -2, 5) # needs sage.rings.number_field
2207-
sage: A.has_standard_involution() # needs sage.rings.number_field
2208-
True
2209-
sage: L.<a,b> = FreeAlgebra(QQ, 2)
2210-
sage: L.has_standard_involution()
2211-
Traceback (most recent call last):
2212-
...
2213-
NotImplementedError: has_standard_involution is not implemented for this algebra
2214-
"""
2215-
field = self.base_ring()
2216-
try:
2217-
basis = self.basis()
2218-
except AttributeError:
2219-
raise AttributeError("Basis is not yet implemented for this algebra.")
2220-
try:
2221-
# TODO: The following code is specific to the quaternion algebra
2222-
# and should belong there
2223-
#step 1
2224-
for i in range(1,4):
2225-
ei = basis[i]
2226-
a = ei**2
2227-
coef = a.coefficient_tuple()
2228-
ti = coef[i]
2229-
ni = a - ti*ei
2230-
if ni not in field:
2231-
return False
2232-
#step 2
2233-
for i in range(1,4):
2234-
for j in range(2,4):
2235-
ei = basis[i]
2236-
ej = basis[j]
2237-
a = ei**2
2238-
coef = a.coefficient_tuple()
2239-
ti = coef[i]
2240-
b = ej**2
2241-
coef = b.coefficient_tuple()
2242-
tj = coef[j]
2243-
nij = (ei + ej)**2 - (ti + tj)*(ei + ej)
2244-
if nij not in field:
2245-
return False
2246-
except AttributeError:
2247-
raise NotImplementedError("has_standard_involution is not implemented for this algebra")
2248-
return True
22492169

22502170
cdef class CommutativeAlgebra(CommutativeRing):
22512171
"""

0 commit comments

Comments
 (0)