Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

use parent in quaternions #37299

Merged
merged 3 commits into from
Feb 25, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -34,10 +34,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 @@ -47,8 +47,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 @@ -64,7 +62,6 @@
from sage.modules.free_module import FreeModule
from sage.modules.free_module_element import vector

from operator import itemgetter

from .quaternion_algebra_element import (
QuaternionAlgebraElement_abstract,
Expand Down Expand Up @@ -310,7 +307,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 @@ -665,7 +662,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 @@ -984,6 +981,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 @@ -144,6 +144,84 @@
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):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we move this method to AlgebrasWithBasis instead? Then we can assume it has a basis() method.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not here and now. This would require making quaternion algebras to be WithBasis (they are not) and this takes some work

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood, no problem.

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.")

Check warning on line 194 in src/sage/categories/algebras.py

View check run for this annotation

Codecov / codecov/patch

src/sage/categories/algebras.py#L193-L194

Added lines #L193 - L194 were not covered by tests
fchapoton marked this conversation as resolved.
Show resolved Hide resolved
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

Check warning on line 206 in src/sage/categories/algebras.py

View check run for this annotation

Codecov / codecov/patch

src/sage/categories/algebras.py#L206

Added line #L206 was not covered by tests
# 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

Check warning on line 220 in src/sage/categories/algebras.py

View check run for this annotation

Codecov / codecov/patch

src/sage/categories/algebras.py#L220

Added line #L220 was not covered by tests
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 @@ -2274,86 +2274,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
Loading