Skip to content

Commit

Permalink
sagemathgh-37299: use parent in quaternions
Browse files Browse the repository at this point in the history
    
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: sagemath#37299
Reported by: Frédéric Chapoton
Reviewer(s): Frédéric Chapoton, Travis Scrimshaw
  • Loading branch information
Release Manager committed Feb 17, 2024
2 parents ea91293 + d7c4495 commit 86321b9
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 86 deletions.
22 changes: 16 additions & 6 deletions src/sage/algebras/quatalg/quaternion_algebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@
# (at your option) any later version.
# https://www.gnu.org/licenses/
# ****************************************************************************
from operator import itemgetter

from sage.arith.misc import (hilbert_conductor_inverse,
hilbert_symbol,
factor,
gcd,
kronecker as kronecker_symbol,
prime_divisors,
Expand All @@ -50,8 +50,6 @@
from sage.rings.integer_ring import ZZ
from sage.rings.rational import Rational
from sage.rings.finite_rings.finite_field_constructor import GF

from sage.rings.ring import Algebra
from sage.rings.ideal import Ideal_fractional
from sage.rings.rational_field import is_RationalField, QQ
from sage.rings.infinity import infinity
Expand All @@ -68,7 +66,6 @@
from sage.modules.free_module_element import vector
from sage.quadratic_forms.quadratic_form import QuadraticForm

from operator import itemgetter

from .quaternion_algebra_element import (
QuaternionAlgebraElement_abstract,
Expand Down Expand Up @@ -314,7 +311,7 @@ def is_QuaternionAlgebra(A):
return isinstance(A, QuaternionAlgebra_abstract)


class QuaternionAlgebra_abstract(Algebra):
class QuaternionAlgebra_abstract(Parent):
def _repr_(self):
"""
EXAMPLES::
Expand Down Expand Up @@ -669,7 +666,7 @@ def __init__(self, base_ring, a, b, names='i,j,k'):
ValueError: 2 is not invertible in Integer Ring
"""
cat = Algebras(base_ring).Division().FiniteDimensional()
Algebra.__init__(self, base_ring, names, category=cat)
Parent.__init__(self, base=base_ring, names=names, category=cat)
self._a = a
self._b = b
if is_RationalField(base_ring) and a.denominator() == 1 == b.denominator():
Expand Down Expand Up @@ -988,6 +985,19 @@ def gen(self, i=0):
"""
return self._gens[i]

def gens(self) -> tuple:
"""
Return the generators of ``self``.
EXAMPLES::
sage: Q.<ii,jj,kk> = QuaternionAlgebra(QQ,-1,-2); Q
Quaternion Algebra (-1, -2) with base ring Rational Field
sage: Q.gens()
(ii, jj, kk)
"""
return self._gens

def _repr_(self):
"""
Print representation.
Expand Down
78 changes: 78 additions & 0 deletions src/sage/categories/algebras.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,84 @@ def Supercommutative(self):
Semisimple = LazyImport('sage.categories.semisimple_algebras',
'SemisimpleAlgebras')

class ParentMethods:
def characteristic(self):
r"""
Return the characteristic of this algebra, which is the same
as the characteristic of its base ring.
EXAMPLES::
sage: # needs sage.modules
sage: ZZ.characteristic()
0
sage: A = GF(7^3, 'a') # needs sage.rings.finite_rings
sage: A.characteristic() # needs sage.rings.finite_rings
7
"""
return self.base_ring().characteristic()

def has_standard_involution(self):
r"""
Return ``True`` if the algebra has a standard involution and ``False`` otherwise.
This algorithm follows Algorithm 2.10 from John Voight's *Identifying the Matrix Ring*.
Currently the only type of algebra this will work for is a quaternion algebra.
Though this function seems redundant, once algebras have more functionality, in particular
have a method to construct a basis, this algorithm will have more general purpose.
EXAMPLES::
sage: # needs sage.combinat sage.modules
sage: B = QuaternionAlgebra(2)
sage: B.has_standard_involution()
True
sage: R.<x> = PolynomialRing(QQ)
sage: K.<u> = NumberField(x**2 - 2) # needs sage.rings.number_field
sage: A = QuaternionAlgebra(K, -2, 5) # needs sage.rings.number_field
sage: A.has_standard_involution() # needs sage.rings.number_field
True
sage: L.<a,b> = FreeAlgebra(QQ, 2)
sage: L.has_standard_involution()
Traceback (most recent call last):
...
NotImplementedError: has_standard_involution is not implemented for this algebra
"""
field = self.base_ring()
try:
basis = self.basis()
except AttributeError:
raise AttributeError("basis is not yet implemented for this algebra")
try:
# TODO: The following code is specific to the quaternion algebra
# and should belong there
# step 1
for i in range(1, 4):
ei = basis[i]
a = ei**2
coef = a.coefficient_tuple()
ti = coef[i]
ni = a - ti * ei
if ni not in field:
return False
# step 2
for i in range(1, 4):
for j in range(2, 4):
ei = basis[i]
ej = basis[j]
a = ei**2
coef = a.coefficient_tuple()
ti = coef[i]
b = ej**2
coef = b.coefficient_tuple()
tj = coef[j]
nij = (ei + ej)**2 - (ti + tj) * (ei + ej)
if nij not in field:
return False
except AttributeError:
raise NotImplementedError("has_standard_involution is not implemented for this algebra")
return True

class ElementMethods:
# TODO: move the content of AlgebraElement here or higher in the category hierarchy
def _div_(self, y):
Expand Down
80 changes: 0 additions & 80 deletions src/sage/rings/ring.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -2166,86 +2166,6 @@ cdef class Algebra(Ring):
Ring.__init__(self,base_ring, names=names, normalize=normalize,
category=category)

def characteristic(self):
r"""
Return the characteristic of this algebra, which is the same
as the characteristic of its base ring.
See objects with the ``base_ring`` attribute for additional examples.
Here are some examples that explicitly use the :class:`Algebra` class.
EXAMPLES::
sage: # needs sage.modules
sage: A = Algebra(ZZ); A
<sage.rings.ring.Algebra object at ...>
sage: A.characteristic()
0
sage: A = Algebra(GF(7^3, 'a')) # needs sage.rings.finite_rings
sage: A.characteristic() # needs sage.rings.finite_rings
7
"""
return self.base_ring().characteristic()

def has_standard_involution(self):
r"""
Return ``True`` if the algebra has a standard involution and ``False`` otherwise.
This algorithm follows Algorithm 2.10 from John Voight's *Identifying the Matrix Ring*.
Currently the only type of algebra this will work for is a quaternion algebra.
Though this function seems redundant, once algebras have more functionality, in particular
have a method to construct a basis, this algorithm will have more general purpose.
EXAMPLES::
sage: # needs sage.combinat sage.modules
sage: B = QuaternionAlgebra(2)
sage: B.has_standard_involution()
True
sage: R.<x> = PolynomialRing(QQ)
sage: K.<u> = NumberField(x**2 - 2) # needs sage.rings.number_field
sage: A = QuaternionAlgebra(K, -2, 5) # needs sage.rings.number_field
sage: A.has_standard_involution() # needs sage.rings.number_field
True
sage: L.<a,b> = FreeAlgebra(QQ, 2)
sage: L.has_standard_involution()
Traceback (most recent call last):
...
NotImplementedError: has_standard_involution is not implemented for this algebra
"""
field = self.base_ring()
try:
basis = self.basis()
except AttributeError:
raise AttributeError("Basis is not yet implemented for this algebra.")
try:
# TODO: The following code is specific to the quaternion algebra
# and should belong there
#step 1
for i in range(1,4):
ei = basis[i]
a = ei**2
coef = a.coefficient_tuple()
ti = coef[i]
ni = a - ti*ei
if ni not in field:
return False
#step 2
for i in range(1,4):
for j in range(2,4):
ei = basis[i]
ej = basis[j]
a = ei**2
coef = a.coefficient_tuple()
ti = coef[i]
b = ej**2
coef = b.coefficient_tuple()
tj = coef[j]
nij = (ei + ej)**2 - (ti + tj)*(ei + ej)
if nij not in field:
return False
except AttributeError:
raise NotImplementedError("has_standard_involution is not implemented for this algebra")
return True

cdef class CommutativeAlgebra(CommutativeRing):
"""
Expand Down

0 comments on commit 86321b9

Please sign in to comment.