From 33505aa83118bfda2440dc1da1f680e337ca0476 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 11 Feb 2024 17:22:51 +0100 Subject: [PATCH 1/3] use parent in quaternions --- .../algebras/quatalg/quaternion_algebra.py | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/sage/algebras/quatalg/quaternion_algebra.py b/src/sage/algebras/quatalg/quaternion_algebra.py index f45399ae288..65edd29f5ed 100644 --- a/src/sage/algebras/quatalg/quaternion_algebra.py +++ b/src/sage/algebras/quatalg/quaternion_algebra.py @@ -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, @@ -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 @@ -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, @@ -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:: @@ -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(): @@ -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. = 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. From d01b24928227d6a245fbeb76dfa2355b84a4d426 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 11 Feb 2024 18:47:03 +0100 Subject: [PATCH 2/3] move methods to category of algebras --- src/sage/categories/algebras.py | 78 ++++++++++++++++++++++++++++++++ src/sage/rings/ring.pyx | 80 --------------------------------- 2 files changed, 78 insertions(+), 80 deletions(-) diff --git a/src/sage/categories/algebras.py b/src/sage/categories/algebras.py index d93a51d28bd..39de8ca9156 100644 --- a/src/sage/categories/algebras.py +++ b/src/sage/categories/algebras.py @@ -144,6 +144,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. = PolynomialRing(QQ) + sage: K. = 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. = 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): diff --git a/src/sage/rings/ring.pyx b/src/sage/rings/ring.pyx index 650fb387fa0..132a7744f00 100644 --- a/src/sage/rings/ring.pyx +++ b/src/sage/rings/ring.pyx @@ -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: 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. = PolynomialRing(QQ) - sage: K. = 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. = 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): """ From d7c449578a4a3db3ec727d9483c4275ea93cab84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 12 Feb 2024 20:34:41 +0100 Subject: [PATCH 3/3] fix tiny detail only --- src/sage/categories/algebras.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/categories/algebras.py b/src/sage/categories/algebras.py index 39de8ca9156..87cab7bf92c 100644 --- a/src/sage/categories/algebras.py +++ b/src/sage/categories/algebras.py @@ -191,7 +191,7 @@ def has_standard_involution(self): try: basis = self.basis() except AttributeError: - raise AttributeError("Basis is not yet implemented for this algebra.") + 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