diff --git a/src/sage/algebras/quatalg/quaternion_algebra.py b/src/sage/algebras/quatalg/quaternion_algebra.py index 32353a688b6..ae2c726a9dd 100644 --- a/src/sage/algebras/quatalg/quaternion_algebra.py +++ b/src/sage/algebras/quatalg/quaternion_algebra.py @@ -20,7 +20,7 @@ Pickling test:: - sage: Q. = QuaternionAlgebra(QQ,-5,-2) + sage: Q. = QuaternionAlgebra(QQ, -5, -2) sage: Q == loads(dumps(Q)) True """ @@ -62,7 +62,7 @@ from sage.matrix.constructor import diagonal_matrix, matrix from sage.structure.sequence import Sequence from sage.structure.element import RingElement -from sage.structure.factory import UniqueFactory +from sage.structure.unique_representation import UniqueRepresentation from sage.modules.free_module import FreeModule from sage.modules.free_module_element import vector from sage.quadratic_forms.quadratic_form import QuadraticForm @@ -84,14 +84,30 @@ from sage.structure.richcmp import richcmp_method -######################################################## -# Constructor -######################################################## + +def is_QuaternionAlgebra(A): + """ + Return ``True`` if ``A`` is of the QuaternionAlgebra data type. + + EXAMPLES:: + + sage: sage.algebras.quatalg.quaternion_algebra.is_QuaternionAlgebra(QuaternionAlgebra(QQ,-1,-1)) + doctest:warning... + DeprecationWarning: the function is_QuaternionAlgebra is deprecated; + use 'isinstance(..., QuaternionAlgebra)' instead + See https://github.com/sagemath/sage/issues/37896 for details. + True + sage: sage.algebras.quatalg.quaternion_algebra.is_QuaternionAlgebra(ZZ) + False + """ + from sage.misc.superseded import deprecation + deprecation(37896, "the function is_QuaternionAlgebra is deprecated; use 'isinstance(..., QuaternionAlgebra)' instead") + return isinstance(A, QuaternionAlgebra) -class QuaternionAlgebraFactory(UniqueFactory): +class QuaternionAlgebra(UniqueRepresentation, Parent): r""" - Construct a quaternion algebra. + A quaternion algebra. INPUT: @@ -143,9 +159,9 @@ class QuaternionAlgebraFactory(UniqueFactory): The following tests address the issues raised in :issue:`10601`:: - sage: QuaternionAlgebra(1r,1) + sage: QuaternionAlgebra(1r, 1) Quaternion Algebra (1, 1) with base ring Rational Field - sage: QuaternionAlgebra(1,1.0r) + sage: QuaternionAlgebra(1, 1.0r) Quaternion Algebra (1.00000000000000, 1.00000000000000) with base ring Real Field with 53 bits of precision sage: QuaternionAlgebra(0,0) @@ -153,7 +169,7 @@ class QuaternionAlgebraFactory(UniqueFactory): ... ValueError: defining elements of quaternion algebra (0, 0) are not invertible in Rational Field - sage: QuaternionAlgebra(GF(2)(1),1) + sage: QuaternionAlgebra(GF(2)(1), 1) Traceback (most recent call last): ... ValueError: 2 is not invertible in Finite Field of size 2 @@ -168,7 +184,7 @@ class QuaternionAlgebraFactory(UniqueFactory): sage: QuaternionAlgebra(QQ, -7, -21) Quaternion Algebra (-7, -21) with base ring Rational Field - sage: QuaternionAlgebra(QQ[sqrt(2)], -2,-3) # needs sage.symbolic + sage: QuaternionAlgebra(QQ[sqrt(2)], -2, -3) # needs sage.symbolic Quaternion Algebra (-2, -3) with base ring Number Field in sqrt2 with defining polynomial x^2 - 2 with sqrt2 = 1.414213562373095? @@ -188,52 +204,51 @@ class QuaternionAlgebraFactory(UniqueFactory): algebra are not integral, then a slower generic type is used for arithmetic:: - sage: type(QuaternionAlgebra(-1,-3).0) + sage: type(QuaternionAlgebra(-1, -3).0) <... 'sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_rational_field'> - sage: type(QuaternionAlgebra(-1,-3/2).0) + sage: type(QuaternionAlgebra(-1, -3/2).0) <... 'sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_generic'> - Make sure caching is sane:: - - sage: A = QuaternionAlgebra(2,3); A - Quaternion Algebra (2, 3) with base ring Rational Field - sage: B = QuaternionAlgebra(GF(5)(2),GF(5)(3)); B - Quaternion Algebra (2, 3) with base ring Finite Field of size 5 - sage: A is QuaternionAlgebra(2,3) - True - sage: B is QuaternionAlgebra(GF(5)(2),GF(5)(3)) - True - sage: Q = QuaternionAlgebra(2); Q - Quaternion Algebra (-1, -1) with base ring Rational Field - sage: Q is QuaternionAlgebra(QQ,-1,-1) - True - sage: Q is QuaternionAlgebra(-1,-1) - True - sage: Q. = QuaternionAlgebra(15); Q.variable_names() - ('ii', 'jj', 'kk') - sage: QuaternionAlgebra(15).variable_names() - ('i', 'j', 'k') - TESTS: Verify that bug found when working on :issue:`12006` involving coercing invariants into the base field is fixed:: - sage: Q = QuaternionAlgebra(-1,-1); Q + sage: Q = QuaternionAlgebra(-1, -1); Q Quaternion Algebra (-1, -1) with base ring Rational Field sage: parent(Q._a) Rational Field sage: parent(Q._b) Rational Field """ - def create_key(self, arg0, arg1=None, arg2=None, names='i,j,k'): - """ - Create a key that uniquely determines a quaternion algebra. - TESTS:: + @staticmethod + def __classcall_private__(cls, arg0, arg1=None, arg2=None, names='i,j,k'): + r""" + Normalize inputs for unique representation. - sage: QuaternionAlgebra.create_key(-1,-1) - (Rational Field, -1, -1, ('i', 'j', 'k')) + TESTS: + + Make sure caching is sane:: + + sage: A = QuaternionAlgebra(2,3); A + Quaternion Algebra (2, 3) with base ring Rational Field + sage: B = QuaternionAlgebra(GF(5)(2), GF(5)(3)); B + Quaternion Algebra (2, 3) with base ring Finite Field of size 5 + sage: A is QuaternionAlgebra(2, 3) + True + sage: B is QuaternionAlgebra(GF(5)(2), GF(5)(3)) + True + sage: Q = QuaternionAlgebra(2); Q + Quaternion Algebra (-1, -1) with base ring Rational Field + sage: Q is QuaternionAlgebra(QQ, -1, -1) + True + sage: Q is QuaternionAlgebra(-1, -1) + True + sage: Q. = QuaternionAlgebra(15); Q.variable_names() + ('ii', 'jj', 'kk') + sage: QuaternionAlgebra(15).variable_names() + ('i', 'j', 'k') """ # QuaternionAlgebra(D) if arg1 is None and arg2 is None: @@ -276,59 +291,8 @@ def create_key(self, arg0, arg1=None, arg2=None, names='i,j,k'): % (a, b, K)) names = normalize_names(3, names) - return (K, a, b, names) - - def create_object(self, version, key, **extra_args): - """ - Create the object from the key (extra arguments are ignored). This is - only called if the object was not found in the cache. - - TESTS:: - - sage: QuaternionAlgebra.create_object("6.0", (QQ, -1, -1, ('i', 'j', 'k'))) - Quaternion Algebra (-1, -1) with base ring Rational Field - """ - K, a, b, names = key return QuaternionAlgebra_ab(K, a, b, names=names) - -QuaternionAlgebra = QuaternionAlgebraFactory("QuaternionAlgebra") - -######################################################## -# Classes -######################################################## - - -def is_QuaternionAlgebra(A): - """ - Return ``True`` if ``A`` is of the QuaternionAlgebra data type. - - EXAMPLES:: - - sage: sage.algebras.quatalg.quaternion_algebra.is_QuaternionAlgebra(QuaternionAlgebra(QQ,-1,-1)) - doctest:warning... - DeprecationWarning: the function is_QuaternionAlgebra is deprecated; - use 'isinstance(..., QuaternionAlgebra_abstract)' instead - See https://github.com/sagemath/sage/issues/37896 for details. - True - sage: sage.algebras.quatalg.quaternion_algebra.is_QuaternionAlgebra(ZZ) - False - """ - from sage.misc.superseded import deprecation - deprecation(37896, "the function is_QuaternionAlgebra is deprecated; use 'isinstance(..., QuaternionAlgebra_abstract)' instead") - return isinstance(A, QuaternionAlgebra_abstract) - - -class QuaternionAlgebra_abstract(Parent): - def _repr_(self): - """ - EXAMPLES:: - - sage: sage.algebras.quatalg.quaternion_algebra.QuaternionAlgebra_abstract(QQ)._repr_() - 'Quaternion Algebra with base ring Rational Field' - """ - return "Quaternion Algebra with base ring %s" % self.base_ring() - def ngens(self): """ Return the number of generators of the quaternion algebra as a K-vector @@ -339,7 +303,7 @@ def ngens(self): EXAMPLES:: - sage: Q. = QuaternionAlgebra(QQ,-5,-2) + sage: Q. = QuaternionAlgebra(QQ, -5, -2) sage: Q.ngens() 3 sage: Q.gens() @@ -355,11 +319,11 @@ def basis(self): EXAMPLES:: - sage: Q. = QuaternionAlgebra(QQ,-5,-2) + sage: Q. = QuaternionAlgebra(QQ, -5, -2) sage: Q.basis() (1, i, j, k) - sage: Q. = QuaternionAlgebra(GF(9,'a'),-5,-2) + sage: Q. = QuaternionAlgebra(GF(9,'a'), -5, -2) sage: Q.basis() (1, xyz, abc, theta) @@ -384,7 +348,7 @@ def inner_product_matrix(self): EXAMPLES:: - sage: Q. = QuaternionAlgebra(-5,-19) + sage: Q. = QuaternionAlgebra(-5, -19) sage: Q.inner_product_matrix() [ 2 0 0 0] [ 0 10 0 0] @@ -403,27 +367,27 @@ def is_commutative(self) -> bool: EXAMPLES:: - sage: Q. = QuaternionAlgebra(QQ, -3,-7) + sage: Q. = QuaternionAlgebra(QQ, -3, -7) sage: Q.is_commutative() False """ return False def is_division_algebra(self) -> bool: - """ + r""" Return ``True`` if the quaternion algebra is a division algebra (i.e. every nonzero element in ``self`` is invertible), and ``False`` if the - quaternion algebra is isomorphic to the 2x2 matrix algebra. + quaternion algebra is isomorphic to the `2\times 2` matrix algebra. EXAMPLES:: - sage: QuaternionAlgebra(QQ,-5,-2).is_division_algebra() + sage: QuaternionAlgebra(QQ, -5, -2).is_division_algebra() True sage: QuaternionAlgebra(1).is_division_algebra() False - sage: QuaternionAlgebra(2,9).is_division_algebra() + sage: QuaternionAlgebra(2, 9).is_division_algebra() False - sage: QuaternionAlgebra(RR(2.),1).is_division_algebra() + sage: QuaternionAlgebra(RR(2.), 1).is_division_algebra() Traceback (most recent call last): ... NotImplementedError: base field must be rational numbers @@ -434,19 +398,19 @@ def is_division_algebra(self) -> bool: def is_matrix_ring(self) -> bool: """ - Return ``True`` if the quaternion algebra is isomorphic to the 2x2 + Return ``True`` if the quaternion algebra is isomorphic to the `2\times 2` matrix ring, and ``False`` if ``self`` is a division algebra (i.e. every nonzero element in ``self`` is invertible). EXAMPLES:: - sage: QuaternionAlgebra(QQ,-5,-2).is_matrix_ring() + sage: QuaternionAlgebra(QQ, -5, -2).is_matrix_ring() False sage: QuaternionAlgebra(1).is_matrix_ring() True - sage: QuaternionAlgebra(2,9).is_matrix_ring() + sage: QuaternionAlgebra(2, 9).is_matrix_ring() True - sage: QuaternionAlgebra(RR(2.),1).is_matrix_ring() + sage: QuaternionAlgebra(RR(2.), 1).is_matrix_ring() Traceback (most recent call last): ... NotImplementedError: base field must be rational numbers @@ -607,7 +571,7 @@ def vector_space(self): EXAMPLES:: - sage: QuaternionAlgebra(-3,19).vector_space() + sage: QuaternionAlgebra(-3, 19).vector_space() Ambient quadratic space of dimension 4 over Rational Field Inner product matrix: [ 2 0 0 0] @@ -618,11 +582,14 @@ def vector_space(self): return self.free_module() -class QuaternionAlgebra_ab(QuaternionAlgebra_abstract): +QuaternionAlgebra_abstract = QuaternionAlgebra # alias, deprecated in #38228 + + +class QuaternionAlgebra_ab(QuaternionAlgebra): """ A quaternion algebra of the form `(a, b)_K`. - See ``QuaternionAlgebra`` for many more examples. + See :class:`QuaternionAlgebra` for many more examples. INPUT: @@ -973,7 +940,8 @@ def order_with_level(self, level): sage: A. = QuaternionAlgebra(5) sage: level = 2 * 5 * 17 sage: O = A.order_with_level(level); O - Order of Quaternion Algebra (-2, -5) with base ring Rational Field with basis (1/2 + 1/2*j + 7/2*k, 1/2*i + 19/2*k, j + 7*k, 17*k) + Order of Quaternion Algebra (-2, -5) with base ring Rational Field + with basis (1/2 + 1/2*j + 7/2*k, 1/2*i + 19/2*k, j + 7*k, 17*k) Check that the order has the right index in the maximal order:: @@ -1052,12 +1020,12 @@ def is_definite(self): EXAMPLES:: - sage: QuaternionAlgebra(QQ,-5,-2).is_definite() + sage: QuaternionAlgebra(QQ, -5, -2).is_definite() True sage: QuaternionAlgebra(1).is_definite() False - sage: QuaternionAlgebra(RR(2.),1).is_definite() + sage: QuaternionAlgebra(RR(2.), 1).is_definite() Traceback (most recent call last): ... ValueError: base field must be rational numbers @@ -1073,9 +1041,9 @@ def __eq__(self, other): EXAMPLES:: - sage: QuaternionAlgebra(-1,-7) == QuaternionAlgebra(-1,-7) + sage: QuaternionAlgebra(-1, -7) == QuaternionAlgebra(-1, -7) True - sage: QuaternionAlgebra(-1,-7) == QuaternionAlgebra(-1,-5) + sage: QuaternionAlgebra(-1, -7) == QuaternionAlgebra(-1, -5) False """ if not isinstance(other, QuaternionAlgebra_abstract): @@ -1089,9 +1057,9 @@ def __ne__(self, other): EXAMPLES:: - sage: QuaternionAlgebra(-1,-7) != QuaternionAlgebra(-1,-7) + sage: QuaternionAlgebra(-1, -7) != QuaternionAlgebra(-1, -7) False - sage: QuaternionAlgebra(-1,-7) != QuaternionAlgebra(-1,-5) + sage: QuaternionAlgebra(-1, -7) != QuaternionAlgebra(-1, -5) True """ return not self.__eq__(other) @@ -1102,9 +1070,9 @@ def __hash__(self): EXAMPLES:: - sage: h1 = hash(QuaternionAlgebra(-1,-7)) - sage: h2 = hash(QuaternionAlgebra(-1,-7)) - sage: h3 = hash(QuaternionAlgebra(-1,-5)) + sage: h1 = hash(QuaternionAlgebra(-1, -7)) + sage: h2 = hash(QuaternionAlgebra(-1, -7)) + sage: h3 = hash(QuaternionAlgebra(-1, -5)) sage: h1 == h2 and h1 != h3 True """ @@ -1120,7 +1088,7 @@ def gen(self, i=0): EXAMPLES:: - sage: Q. = QuaternionAlgebra(QQ,-1,-2); Q + sage: Q. = QuaternionAlgebra(QQ, -1, -2); Q Quaternion Algebra (-1, -2) with base ring Rational Field sage: Q.gen(0) ii @@ -1139,7 +1107,7 @@ def gens(self) -> tuple: EXAMPLES:: - sage: Q. = QuaternionAlgebra(QQ,-1,-2); Q + sage: Q. = QuaternionAlgebra(QQ, -1, -2); Q Quaternion Algebra (-1, -2) with base ring Rational Field sage: Q.gens() (ii, jj, kk) @@ -1152,7 +1120,7 @@ def _repr_(self): TESTS:: - sage: Q. = QuaternionAlgebra(QQ,-5,-2) + sage: Q. = QuaternionAlgebra(QQ, -5, -2) sage: type(Q) sage: Q._repr_() @@ -1175,14 +1143,14 @@ def inner_product_matrix(self): EXAMPLES:: - sage: Q. = QuaternionAlgebra(-5,-19) + sage: Q. = QuaternionAlgebra(-5, -19) sage: Q.inner_product_matrix() [ 2 0 0 0] [ 0 10 0 0] [ 0 0 38 0] [ 0 0 0 190] - sage: R. = QQ[]; Q. = QuaternionAlgebra(Frac(R),a,b) + sage: R. = QQ[]; Q. = QuaternionAlgebra(Frac(R), a, b) sage: Q.inner_product_matrix() [ 2 0 0 0] [ 0 -2*a 0 0] @@ -1200,7 +1168,7 @@ def discriminant(self): EXAMPLES:: - sage: QuaternionAlgebra(210,-22).discriminant() + sage: QuaternionAlgebra(210, -22).discriminant() 210 sage: QuaternionAlgebra(19).discriminant() 19 @@ -1252,12 +1220,12 @@ def ramified_primes(self): if hilbert_symbol(self._a, self._b, p) == -1) def is_isomorphic(self, A) -> bool: - """ - Return ``True`` if (and only if) ``self`` and ``A`` are isomorphic quaternion algebras over Q. + r""" + Return ``True`` if (and only if) ``self`` and ``A`` are isomorphic quaternion algebras over `\QQ`. INPUT: - - ``A`` -- a quaternion algebra defined over the rationals Q + - ``A`` -- a quaternion algebra defined over the rationals `\QQ` EXAMPLES:: @@ -1282,7 +1250,7 @@ def _magma_init_(self, magma): EXAMPLES:: - sage: Q = QuaternionAlgebra(-1,-1); Q + sage: Q = QuaternionAlgebra(-1, -1); Q Quaternion Algebra (-1, -1) with base ring Rational Field sage: Q._magma_init_(magma) # optional - magma 'QuaternionAlgebra(_sage_[...],-1/1,-1/1)' @@ -1295,7 +1263,7 @@ def _magma_init_(self, magma): A more complicated example involving a quaternion algebra over a number field:: - sage: K. = QQ[sqrt(2)]; Q = QuaternionAlgebra(K,-1,a); Q # needs sage.symbolic + sage: K. = QQ[sqrt(2)]; Q = QuaternionAlgebra(K, -1, a); Q # needs sage.symbolic Quaternion Algebra (-1, sqrt2) with base ring Number Field in sqrt2 with defining polynomial x^2 - 2 with sqrt2 = 1.414213562373095? sage: magma(Q) # optional - magma, needs sage.symbolic @@ -1320,7 +1288,7 @@ def quaternion_order(self, basis, check=True): EXAMPLES:: - sage: Q. = QuaternionAlgebra(-11,-1) + sage: Q. = QuaternionAlgebra(-11, -1) sage: Q.quaternion_order([1,i,j,k]) Order of Quaternion Algebra (-11, -1) with base ring Rational Field with basis (1, i, j, k) @@ -1419,7 +1387,7 @@ def modp_splitting_data(self, p): The following is a good test because of the asserts in the code:: - sage: v = [Q.modp_splitting_data(p) for p in primes(20,1000)] + sage: v = [Q.modp_splitting_data(p) for p in primes(20, 1000)] Proper error handling:: @@ -1515,7 +1483,7 @@ def unpickle_QuaternionAlgebra_v0(*key): EXAMPLES:: - sage: Q = QuaternionAlgebra(-5,-19) + sage: Q = QuaternionAlgebra(-5, -19) sage: t = (QQ, -5, -19, ('i', 'j', 'k')) sage: sage.algebras.quatalg.quaternion_algebra.unpickle_QuaternionAlgebra_v0(*t) Quaternion Algebra (-5, -19) with base ring Rational Field @@ -1534,9 +1502,10 @@ class QuaternionOrder(Parent): EXAMPLES:: - sage: QuaternionAlgebra(-1,-7).maximal_order() - Order of Quaternion Algebra (-1, -7) with base ring Rational Field with basis (1/2 + 1/2*j, 1/2*i + 1/2*k, j, k) - sage: type(QuaternionAlgebra(-1,-7).maximal_order()) + sage: QuaternionAlgebra(-1, -7).maximal_order() + Order of Quaternion Algebra (-1, -7) with base ring Rational Field + with basis (1/2 + 1/2*j, 1/2*i + 1/2*k, j, k) + sage: type(QuaternionAlgebra(-1, -7).maximal_order()) """ def __init__(self, A, basis, check=True): @@ -1554,7 +1523,7 @@ def __init__(self, A, basis, check=True): EXAMPLES:: - sage: A. = QuaternionAlgebra(-3,-5) + sage: A. = QuaternionAlgebra(-3, -5) sage: sage.algebras.quatalg.quaternion_algebra.QuaternionOrder(A, [1,i,j,k]) Order of Quaternion Algebra (-3, -5) with base ring Rational Field with basis (1, i, j, k) sage: R = sage.algebras.quatalg.quaternion_algebra.QuaternionOrder(A, [1,2*i,2*j,2*k]); R @@ -1565,26 +1534,27 @@ def __init__(self, A, basis, check=True): Over QQ and number fields it is checked whether the given basis actually gives an order (as a module over the maximal order):: - sage: A. = QuaternionAlgebra(-1,-1) - sage: A.quaternion_order([1,i,j,i-j]) + sage: A. = QuaternionAlgebra(-1, -1) + sage: A.quaternion_order([1, i, j, i-j]) Traceback (most recent call last): ... ValueError: basis must have rank 4 - sage: A.quaternion_order([2,i,j,k]) + sage: A.quaternion_order([2, i, j, k]) Traceback (most recent call last): ... ValueError: lattice must contain 1 - sage: A.quaternion_order([1,i/2,j/2,k/2]) + sage: A.quaternion_order([1, i/2, j/2, k/2]) Traceback (most recent call last): ... ValueError: given lattice must be a ring sage: K = QuadraticField(10) - sage: A. = QuaternionAlgebra(K,-1,-1) - sage: A.quaternion_order([1,i,j,k]) + sage: A. = QuaternionAlgebra(K, -1, -1) + sage: A.quaternion_order([1, i, j, k]) Order of Quaternion Algebra (-1, -1) with base ring Number Field in a - with defining polynomial x^2 - 10 with a = 3.162277660168380? with basis (1, i, j, k) - sage: A.quaternion_order([1,i/2,j,k]) + with defining polynomial x^2 - 10 with a = 3.162277660168380? + with basis (1, i, j, k) + sage: A.quaternion_order([1, i/2, j, k]) Traceback (most recent call last): ... ValueError: given lattice must be a ring @@ -1659,9 +1629,9 @@ def _element_constructor_(self, x): EXAMPLES:: - sage: Q. = QuaternionAlgebra(-1,-19) - sage: O = Q.quaternion_order([1,i,j,k]) - sage: O(1+i) + sage: Q. = QuaternionAlgebra(-1, -19) + sage: O = Q.quaternion_order([1, i, j, k]) + sage: O(1 + i) 1 + i sage: O(1/2) Traceback (most recent call last): @@ -1689,7 +1659,7 @@ def one(self): EXAMPLES:: - sage: QuaternionAlgebra(-1,-7).maximal_order().one() + sage: QuaternionAlgebra(-1, -7).maximal_order().one() 1 """ return self.quaternion_algebra().one() @@ -1700,7 +1670,7 @@ def gens(self): EXAMPLES:: - sage: QuaternionAlgebra(-1,-7).maximal_order().gens() + sage: QuaternionAlgebra(-1, -7).maximal_order().gens() (1/2 + 1/2*j, 1/2*i + 1/2*k, j, k) """ return self.__basis @@ -1711,7 +1681,7 @@ def ngens(self): EXAMPLES:: - sage: QuaternionAlgebra(-1,-7).maximal_order().ngens() + sage: QuaternionAlgebra(-1, -7).maximal_order().ngens() 4 """ return 4 @@ -1726,7 +1696,7 @@ def gen(self, n): EXAMPLES:: - sage: R = QuaternionAlgebra(-11,-1).maximal_order(); R + sage: R = QuaternionAlgebra(-11, -1).maximal_order(); R Order of Quaternion Algebra (-11, -1) with base ring Rational Field with basis (1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k) sage: R.gen(0) @@ -1765,10 +1735,10 @@ def __richcmp__(self, other, op): sage: B = QuaternionAlgebra(-1, -11) sage: i,j,k = B.gens() - sage: O = B.quaternion_order([1,i,j,k]) + sage: O = B.quaternion_order([1, i, j, k]) sage: O == O True - sage: R = B.quaternion_order([1,i,(i+j)/2,(1+k)/2]) + sage: R = B.quaternion_order([1, i, (i+j)/2, (1+k)/2]) sage: O <= R # indirect doctest True sage: O >= R @@ -1799,9 +1769,9 @@ def __hash__(self): EXAMPLES:: - sage: h1 = hash(QuaternionAlgebra(-1,-7).maximal_order()) - sage: h2 = hash(QuaternionAlgebra(-1,-7).maximal_order()) - sage: h3 = hash(QuaternionAlgebra(-1,-5).maximal_order()) + sage: h1 = hash(QuaternionAlgebra(-1, -7).maximal_order()) + sage: h2 = hash(QuaternionAlgebra(-1, -7).maximal_order()) + sage: h3 = hash(QuaternionAlgebra(-1, -5).maximal_order()) sage: h1 == h2 and h1 != h3 True """ @@ -1813,7 +1783,7 @@ def basis(self): EXAMPLES:: - sage: QuaternionAlgebra(-11,-1).maximal_order().basis() + sage: QuaternionAlgebra(-11, -1).maximal_order().basis() (1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k) """ return self.__basis @@ -1835,9 +1805,9 @@ def _repr_(self): EXAMPLES:: - sage: QuaternionAlgebra(-11,-1).maximal_order()._repr_() + sage: QuaternionAlgebra(-11, -1).maximal_order()._repr_() 'Order of Quaternion Algebra (-11, -1) with base ring Rational Field with basis (1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k)' - sage: QuaternionAlgebra(-11,-1).maximal_order() + sage: QuaternionAlgebra(-11, -1).maximal_order() Order of Quaternion Algebra (-11, -1) with base ring Rational Field with basis (1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k) """ return 'Order of %s with basis %s' % (self.quaternion_algebra(), self.basis()) @@ -1858,9 +1828,9 @@ def random_element(self, *args, **kwds): EXAMPLES:: - sage: QuaternionAlgebra(-11,-1).maximal_order().random_element() # random + sage: QuaternionAlgebra(-11, -1).maximal_order().random_element() # random -4 - 4*i + j - k - sage: QuaternionAlgebra(-11,-1).maximal_order().random_element(-10,10) # random + sage: QuaternionAlgebra(-11, -1).maximal_order().random_element(-10, 10) # random -9/2 - 7/2*i - 7/2*j - 3/2*k """ return sum(ZZ.random_element(*args, **kwds) * b for b in self.basis()) @@ -1877,21 +1847,21 @@ def intersection(self, other): EXAMPLES:: - sage: R = QuaternionAlgebra(-11,-1).maximal_order() + sage: R = QuaternionAlgebra(-11, -1).maximal_order() sage: R.intersection(R) Order of Quaternion Algebra (-11, -1) with base ring Rational Field with basis (1/2 + 1/2*i, i, 1/2*j + 1/2*k, k) We intersect various orders in the quaternion algebra ramified at 11:: - sage: B = BrandtModule(11,3) + sage: B = BrandtModule(11, 3) sage: R = B.maximal_order(); S = B.order_of_level_N() sage: R.intersection(S) Order of Quaternion Algebra (-1, -11) with base ring Rational Field with basis (1/2 + 1/2*j, 1/2*i + 5/2*k, j, 3*k) sage: R.intersection(S) == S True - sage: B = BrandtModule(11,5) + sage: B = BrandtModule(11, 5) sage: T = B.order_of_level_N() sage: S.intersection(T) Order of Quaternion Algebra (-1, -11) with base ring Rational Field @@ -1923,7 +1893,7 @@ def free_module(self): EXAMPLES:: - sage: R = QuaternionAlgebra(-11,-1).maximal_order() + sage: R = QuaternionAlgebra(-11, -1).maximal_order() sage: R.basis() (1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k) sage: R.free_module() @@ -1949,9 +1919,9 @@ def discriminant(self): EXAMPLES:: - sage: QuaternionAlgebra(-11,-1).maximal_order().discriminant() + sage: QuaternionAlgebra(-11, -1).maximal_order().discriminant() 11 - sage: S = BrandtModule(11,5).order_of_level_N() + sage: S = BrandtModule(11, 5).order_of_level_N() sage: S.discriminant() 55 sage: type(S.discriminant()) @@ -2078,7 +2048,7 @@ def left_ideal(self, gens, check=True, *, is_basis=False): EXAMPLES:: - sage: Q. = QuaternionAlgebra(-11,-1) + sage: Q. = QuaternionAlgebra(-11, -1) sage: R = Q.maximal_order() sage: R.left_ideal([a*2 for a in R.basis()], is_basis=True) Fractional ideal (1 + i, 2*i, j + k, 2*k) @@ -2088,9 +2058,9 @@ def left_ideal(self, gens, check=True, *, is_basis=False): It is also possible to pass a generating set (rather than a basis), or a single generator:: - sage: R.left_ideal([i+j]) + sage: R.left_ideal([i + j]) Fractional ideal (1/2 + 1/2*i + 1/2*j + 13/2*k, i + j, 6*j + 6*k, 12*k) - sage: R.left_ideal(i+j) + sage: R.left_ideal(i + j) Fractional ideal (1/2 + 1/2*i + 1/2*j + 13/2*k, i + j, 6*j + 6*k, 12*k) sage: R.left_ideal([2, 1+j]) == R*2 + R*(1+j) True @@ -2121,7 +2091,7 @@ def right_ideal(self, gens, check=True, *, is_basis=False): EXAMPLES:: - sage: Q. = QuaternionAlgebra(-11,-1) + sage: Q. = QuaternionAlgebra(-11, -1) sage: R = Q.maximal_order() sage: R.right_ideal([2*a for a in R.basis()], is_basis=True) Fractional ideal (1 + i, 2*i, j + k, 2*k) @@ -2156,7 +2126,7 @@ def unit_ideal(self): EXAMPLES:: - sage: R = QuaternionAlgebra(-11,-1).maximal_order() + sage: R = QuaternionAlgebra(-11, -1).maximal_order() sage: I = R.unit_ideal(); I Fractional ideal (1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k) """ @@ -2173,7 +2143,7 @@ def basis_matrix(self): EXAMPLES:: - sage: O = QuaternionAlgebra(-11,-1).maximal_order() + sage: O = QuaternionAlgebra(-11, -1).maximal_order() sage: O.basis() (1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k) sage: O.basis_matrix() @@ -2185,8 +2155,8 @@ def basis_matrix(self): Note that the returned matrix is *not* necessarily the same as the basis matrix of the :meth:`unit_ideal()`:: - sage: Q. = QuaternionAlgebra(-1,-11) - sage: O = Q.quaternion_order([j,i,-1,k]) + sage: Q. = QuaternionAlgebra(-1, -11) + sage: O = Q.quaternion_order([j, i, -1, k]) sage: O.basis_matrix() [ 0 0 1 0] [ 0 1 0 0] @@ -2207,7 +2177,7 @@ def __mul__(self, other): EXAMPLES:: - sage: Q. = QuaternionAlgebra(-1,-11) + sage: Q. = QuaternionAlgebra(-1, -11) sage: O = Q.maximal_order() sage: I = O*j; I Fractional ideal (-11/2 + 1/2*j, -11/2*i + 1/2*k, -11, -11*i) @@ -2224,7 +2194,7 @@ def __add__(self, other): EXAMPLES:: - sage: Q. = QuaternionAlgebra(-1,-11) + sage: Q. = QuaternionAlgebra(-1, -11) sage: O = Q.maximal_order() sage: I = O + O*((j-3)/5); I Fractional ideal (1/10 + 3/10*j, 1/10*i + 3/10*k, j, k) @@ -2239,7 +2209,7 @@ def quadratic_form(self): EXAMPLES:: - sage: R = BrandtModule(11,13).order_of_level_N() + sage: R = BrandtModule(11, 13).order_of_level_N() sage: Q = R.quadratic_form(); Q Quadratic form in 4 variables over Rational Field with coefficients: [ 14 253 55 286 ] @@ -2257,7 +2227,7 @@ def ternary_quadratic_form(self, include_basis=False): INPUT: - - ``include_basis`` -- boolean (default: ``False``); if ``True`` also + - ``include_basis`` -- boolean (default: ``False``); if ``True``, also return a basis for the dimension 3 subspace `G` OUTPUT: QuadraticForm @@ -2282,7 +2252,7 @@ def ternary_quadratic_form(self, include_basis=False): EXAMPLES:: - sage: R = BrandtModule(11,13).order_of_level_N() + sage: R = BrandtModule(11, 13).order_of_level_N() sage: Q = R.ternary_quadratic_form(); Q Quadratic form in 3 variables over Rational Field with coefficients: [ 5820 1012 13156 ] @@ -2346,8 +2316,10 @@ def isomorphism_to(self, other, *, conjugator=False, B=10): sage: iso = O0.isomorphism_to(O1) sage: iso Ring morphism: - From: Order of Quaternion Algebra (-1, -19) with base ring Rational Field with basis (1, i, 1/2*i + 1/2*j, 1/2 + 1/2*k) - To: Order of Quaternion Algebra (-1, -19) with base ring Rational Field with basis (1, 667*i, 1/2 + 9*i + 1/2*j, 222075/1334*i + 333/667*j + 1/1334*k) + From: Order of Quaternion Algebra (-1, -19) with base ring Rational Field with + basis (1, i, 1/2*i + 1/2*j, 1/2 + 1/2*k) + To: Order of Quaternion Algebra (-1, -19) with base ring Rational Field with + basis (1, 667*i, 1/2 + 9*i + 1/2*j, 222075/1334*i + 333/667*j + 1/1334*k) Defn: i |--> 629/667*i + 36/667*j - 36/667*k j |--> 684/667*i - 648/667*j - 19/667*k k |--> -684/667*i - 19/667*j - 648/667*k @@ -2414,7 +2386,7 @@ def isomorphism_to(self, other, *, conjugator=False, B=10): Test error cases:: - sage: Quat. = QuaternionAlgebra(-1,-11) + sage: Quat. = QuaternionAlgebra(-1, -11) sage: O = Quat.maximal_order() sage: O.isomorphism_to('potato') Traceback (most recent call last): @@ -2423,8 +2395,8 @@ def isomorphism_to(self, other, *, conjugator=False, B=10): :: - sage: Quat1. = QuaternionAlgebra(-1,-11) - sage: Quat2. = QuaternionAlgebra(-3,-11) + sage: Quat1. = QuaternionAlgebra(-1, -11) + sage: Quat2. = QuaternionAlgebra(-3, -11) sage: Quat1.discriminant() == Quat2.discriminant() # isomorphic True sage: O1 = Quat1.maximal_order() @@ -2436,7 +2408,7 @@ def isomorphism_to(self, other, *, conjugator=False, B=10): :: - sage: Quat. = QuaternionAlgebra(7,11) + sage: Quat. = QuaternionAlgebra(7, 11) sage: O1 = Quat.maximal_order() sage: O2 = (O1 * (i+j)).right_order() sage: O1.isomorphism_to(O2) @@ -2446,7 +2418,7 @@ def isomorphism_to(self, other, *, conjugator=False, B=10): :: - sage: Quat. = QuaternionAlgebra(-1,-11) + sage: Quat. = QuaternionAlgebra(-1, -11) sage: O1 = Quat.quaternion_order([1, i, j, k]) sage: O2 = Quat.quaternion_order([1,-i, j,-k]) sage: O1.isomorphism_to(O2) @@ -2456,7 +2428,7 @@ def isomorphism_to(self, other, *, conjugator=False, B=10): :: - sage: Quat. = QuaternionAlgebra(-1,-11) + sage: Quat. = QuaternionAlgebra(-1, -11) sage: O1 = Quat.quaternion_order([1, i, (i+j)/2, (1+k)/2]) sage: O2 = Quat.quaternion_order([1, (2+i+k)/4, (-11*i+2*j+k)/4, (-5*i+k)/3]) sage: O1.isomorphism_to(O2) @@ -2569,7 +2541,7 @@ def __init__(self, Q, basis, left_order=None, right_order=None, check=True): """ EXAMPLES:: - sage: R = QuaternionAlgebra(-11,-1).maximal_order() + sage: R = QuaternionAlgebra(-11, -1).maximal_order() sage: R.right_ideal(R.basis()) Fractional ideal (1/2 + 1/2*i, i, 1/2*j + 1/2*k, k) sage: R.right_ideal(tuple(R.basis()), check=False, is_basis=True) @@ -2577,7 +2549,7 @@ def __init__(self, Q, basis, left_order=None, right_order=None, check=True): TESTS:: - sage: QuaternionAlgebra(-11,-1).maximal_order().unit_ideal().gens() + sage: QuaternionAlgebra(-11, -1).maximal_order().unit_ideal().gens() (1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k) Check that :issue:`31582` is fixed:: @@ -2616,7 +2588,7 @@ def scale(self, alpha, left=False): EXAMPLES:: - sage: B = BrandtModule(5,37); I = B.right_ideals()[0] + sage: B = BrandtModule(5, 37); I = B.right_ideals()[0] sage: i,j,k = B.quaternion_algebra().gens(); I Fractional ideal (2 + 2*j + 106*k, i + 2*j + 105*k, 4*j + 64*k, 148*k) sage: I.scale(i) @@ -2639,7 +2611,7 @@ def scale(self, alpha, left=False): Check that :issue:`32726` is fixed:: - sage: Q. = QuaternionAlgebra(-1,-19) + sage: Q. = QuaternionAlgebra(-1, -19) sage: I = Q.ideal([1,i,j,k]) sage: _ = I.left_order(), I.right_order() # cache sage: span = lambda L: L.basis_matrix().row_module(ZZ) @@ -2794,7 +2766,7 @@ def right_order(self): corresponding left orders, then take ideals in the left orders and from those compute the right order again:: - sage: B = BrandtModule(11,19); R = B.right_ideals() + sage: B = BrandtModule(11, 19); R = B.right_ideals() sage: O = [r.left_order() for r in R] sage: J = [O[i].left_ideal(R[i].basis()) for i in range(len(R))] sage: len(set(J)) @@ -2843,7 +2815,7 @@ def basis(self): EXAMPLES:: - sage: QuaternionAlgebra(-11,-1).maximal_order().unit_ideal().basis() + sage: QuaternionAlgebra(-11, -1).maximal_order().unit_ideal().basis() (1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k) """ return self.gens() @@ -2875,12 +2847,12 @@ def _richcmp_(self, right, op): TESTS:: - sage: B = QuaternionAlgebra(QQ,-1,-11) + sage: B = QuaternionAlgebra(QQ, -1, -11) sage: i,j,k = B.gens() - sage: I = B.ideal([1,i,j,i*j]) + sage: I = B.ideal([1, i, j, i*j]) sage: I == I True - sage: O = B.ideal([1,i,(i+j)/2,(1+i*j)/2]) + sage: O = B.ideal([1, i, (i+j)/2, (1+i*j)/2]) sage: I <= O True sage: I >= O @@ -2908,13 +2880,13 @@ def __hash__(self): EXAMPLES:: - sage: I = QuaternionAlgebra(-11,-1).maximal_order().unit_ideal() + sage: I = QuaternionAlgebra(-11, -1).maximal_order().unit_ideal() sage: hash(I) == hash(I) True TESTS:: - sage: R = QuaternionAlgebra(-11,-1).maximal_order() + sage: R = QuaternionAlgebra(-11, -1).maximal_order() sage: H = hash(R.right_ideal(R.basis())) """ return hash(self.gens()) @@ -2926,7 +2898,7 @@ def basis_matrix(self): matrix with rational entries. If `Q` is the ambient quaternion algebra, then the `\ZZ`-span of - the rows of `M` viewed as linear combinations of Q.basis() = + the rows of `M` viewed as linear combinations of ``Q.basis()`` = `[1,i,j,k]` is the fractional ideal ``self``. Also, ``M * M.denominator()`` is an integer matrix in Hermite normal form. @@ -2934,7 +2906,7 @@ def basis_matrix(self): EXAMPLES:: - sage: QuaternionAlgebra(-11,-1).maximal_order().unit_ideal().basis_matrix() + sage: QuaternionAlgebra(-11, -1).maximal_order().unit_ideal().basis_matrix() [1/2 1/2 0 0] [ 0 1 0 0] [ 0 0 1/2 1/2] @@ -2954,7 +2926,7 @@ def reduced_basis(self): EXAMPLES:: - sage: B = BrandtModule(2,37); I = B.right_ideals()[0] + sage: B = BrandtModule(2, 37); I = B.right_ideals()[0] sage: I Fractional ideal (2 + 2*i + 2*j + 2*k, 4*i + 108*k, 4*j + 44*k, 148*k) sage: I.reduced_basis() @@ -3051,9 +3023,10 @@ def minimal_element(self): EXAMPLES:: - sage: Quat. = QuaternionAlgebra(-3,-101) + sage: Quat. = QuaternionAlgebra(-3, -101) sage: O = Quat.maximal_order(); O - Order of Quaternion Algebra (-3, -101) with base ring Rational Field with basis (1/2 + 1/2*i, 1/2*j - 1/2*k, -1/3*i + 1/3*k, -k) + Order of Quaternion Algebra (-3, -101) with base ring Rational Field + with basis (1/2 + 1/2*i, 1/2*j - 1/2*k, -1/3*i + 1/3*k, -k) sage: (O * 5).minimal_element() 5/2 + 5/2*i sage: alpha = 1/2 + 1/6*i + j + 55/3*k @@ -3073,7 +3046,7 @@ def minimal_element(self): def theta_series(self, B, var='q'): r""" Return normalized theta series of ``self``, as a power series over - `\ZZ` in the variable ``var``, which is 'q' by default. + `\ZZ` in the variable ``var``, which is ``'q'`` by default. The normalized theta series is by definition @@ -3125,7 +3098,7 @@ def gram_matrix(self): EXAMPLES:: - sage: I = BrandtModule(3,5).right_ideals()[1]; I + sage: I = BrandtModule(3, 5).right_ideals()[1]; I Fractional ideal (2 + 6*j + 4*k, 2*i + 4*j + 34*k, 8*j + 32*k, 40*k) sage: I.gram_matrix() [ 640 1920 2112 1920] @@ -3161,7 +3134,7 @@ def norm(self): sage: [ magma('rideal' % str(list(I.basis()))).Norm() for I in C] [16, 32, 32] - sage: A. = QuaternionAlgebra(-1,-1) + sage: A. = QuaternionAlgebra(-1, -1) sage: R = A.ideal([i,j,k,1/2 + 1/2*i + 1/2*j + 1/2*k]) # this is actually an order, so has reduced norm 1 sage: R.norm() 1 @@ -3186,7 +3159,7 @@ def conjugate(self): EXAMPLES:: - sage: I = BrandtModule(3,5).right_ideals()[1]; I + sage: I = BrandtModule(3, 5).right_ideals()[1]; I Fractional ideal (2 + 6*j + 4*k, 2*i + 4*j + 34*k, 8*j + 32*k, 40*k) sage: I.conjugate() Fractional ideal (2 + 2*j + 28*k, 2*i + 4*j + 34*k, 8*j + 32*k, 40*k) @@ -3274,7 +3247,7 @@ def free_module(self): EXAMPLES:: - sage: X = BrandtModule(3,5).right_ideals() + sage: X = BrandtModule(3, 5).right_ideals() sage: X[0] Fractional ideal (2 + 2*j + 8*k, 2*i + 18*k, 4*j + 16*k, 20*k) sage: X[0].free_module() @@ -3292,7 +3265,7 @@ def free_module(self): [ 0 0 4/7 16/7] [ 0 0 0 20/7] - sage: QuaternionAlgebra(-11,-1).maximal_order().unit_ideal().basis_matrix() + sage: QuaternionAlgebra(-11, -1).maximal_order().unit_ideal().basis_matrix() [1/2 1/2 0 0] [ 0 1 0 0] [ 0 0 1/2 1/2] @@ -3301,7 +3274,7 @@ def free_module(self): The free module method is also useful since it allows for checking if one ideal is contained in another, computing quotients `I/J`, etc.:: - sage: X = BrandtModule(3,17).right_ideals() + sage: X = BrandtModule(3, 17).right_ideals() sage: I = X[0].intersection(X[2]); I Fractional ideal (2 + 2*j + 164*k, 2*i + 4*j + 46*k, 16*j + 224*k, 272*k) sage: I.free_module().is_submodule(X[3].free_module()) @@ -3332,7 +3305,7 @@ def intersection(self, J): EXAMPLES:: - sage: X = BrandtModule(3,5).right_ideals() + sage: X = BrandtModule(3, 5).right_ideals() sage: I = X[0].intersection(X[1]); I Fractional ideal (2 + 6*j + 4*k, 2*i + 4*j + 34*k, 8*j + 32*k, 40*k) """ @@ -3354,7 +3327,7 @@ def multiply_by_conjugate(self, J): EXAMPLES:: - sage: R = BrandtModule(3,5).right_ideals() + sage: R = BrandtModule(3, 5).right_ideals() sage: R[0].multiply_by_conjugate(R[1]) Fractional ideal (8 + 8*j + 112*k, 8*i + 16*j + 136*k, 32*j + 128*k, 160*k) sage: R[0]*R[1].conjugate() @@ -3378,7 +3351,7 @@ def pushforward(self, J, side=None): the same left order or right order as ``self`` - ``side`` -- string (default: ``None``); set to ``'left'`` or ``'right'`` to - perform pushforward of left or right ideals respectively. If ``None`` the side + perform pushforward of left or right ideals, respectively. If ``None``, the side is determined by the matching left or right orders OUTPUT: a fractional quaternion ideal @@ -3472,7 +3445,7 @@ def pullback(self, J, side=None): left order equal to the right order of ``self``, or vice versa - ``side`` -- string (default: ``None``); set to ``'left'`` or ``'right'`` to - perform pullback of left or right ideals respectively. If ``None`` the side + perform pullback of left or right ideals, respectively. If ``None``, the side is determined by the matching left and right orders OUTPUT: a fractional quaternion ideal @@ -3571,8 +3544,8 @@ def is_equivalent(self, J, B=10, certificate=False, side=None): - ``certificate`` -- if ``True`` returns an element alpha such that alpha*J = I or J*alpha = I for right and left ideals respectively - - ``side`` -- if ``'left'`` performs left equivalence test. If ``'right' - ``or ``None`` performs right ideal equivalence test + - ``side`` -- if ``'left'`` performs left equivalence test. If ``'right'`` + or ``None``, performs right ideal equivalence test OUTPUT: boolean, or (boolean, alpha) if ``certificate`` is ``True`` @@ -4021,12 +3994,12 @@ def basis_for_quaternion_lattice(gens, reverse=None): EXAMPLES:: sage: from sage.algebras.quatalg.quaternion_algebra import basis_for_quaternion_lattice - sage: A. = QuaternionAlgebra(-1,-7) + sage: A. = QuaternionAlgebra(-1, -7) sage: basis_for_quaternion_lattice([i+j, i-j, 2*k, A(1/3)]) doctest:warning ... DeprecationWarning: ... [1/3, i + j, 2*j, 2*k] - sage: basis_for_quaternion_lattice([A(1),i,j,k]) + sage: basis_for_quaternion_lattice([A(1), i, j, k]) [1, i, j, k] """ if reverse is None: