Skip to content

Commit

Permalink
Add quaternion algebra constructor from ramification.
Browse files Browse the repository at this point in the history
  • Loading branch information
Eloitor committed Jan 29, 2024
1 parent 3dd953c commit 8b4220c
Showing 1 changed file with 46 additions and 4 deletions.
50 changes: 46 additions & 4 deletions src/sage/algebras/quatalg/quaternion_algebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
- Peter Bruin (2021): do not require the base ring to be a field
- Eloi Torrents (2024): construct quaternion algebras over number fields from ramification
This code is partly based on Sage code by David Kohel from 2005.
TESTS:
Expand Down Expand Up @@ -78,6 +80,8 @@

from sage.categories.algebras import Algebras

from sage.libs.pari.all import pari

########################################################
# Constructor
########################################################
Expand All @@ -89,7 +93,7 @@ class QuaternionAlgebraFactory(UniqueFactory):
INPUT:
There are three input formats:
There are four input formats:
- ``QuaternionAlgebra(a, b)``, where `a` and `b` can be coerced to
units in a common field `K` of characteristic different from 2.
Expand All @@ -102,6 +106,12 @@ class QuaternionAlgebraFactory(UniqueFactory):
`D` over `K = \QQ`. Suitable nonzero rational numbers `a`, `b`
as above are deduced from `D`.
- ``QuaternionAlgebra(K, L_finite, L_archimedean)``, where `L_finite`
is a list of prime ideals and `L_archimedean` is a list local
invariants (0 or 1/2) specifying the ramification at the real places.
This constructs a quaternion algebra ramified exacly at the
specified places.
OUTPUT:
The quaternion algebra `(a, b)_K` over `K` generated by `i`, `j`
Expand Down Expand Up @@ -178,6 +188,21 @@ class QuaternionAlgebraFactory(UniqueFactory):
sage: QuaternionAlgebra(2*3*5*7)
Quaternion Algebra (-22, 210) with base ring Rational Field
``QuaternionAlgebra(K, L_finite, L_archimedean)`` -- return the quaternion
algebra over `K` with the specified ramification::
sage: K.<w> = NumberField(x^2-x-1)
sage: P = K.prime_above(2)
sage: Q = K.prime_above(3)
sage: A = QuaternionAlgebra(K, [P,Q], [0,0])
sage: A.discriminant()
Fractional ideal (6)
sage: A = QuaternionAlgebra(K, [P,Q], [1/2,0])
Traceback (most recent call last):
...
PariError: domain error in checkhasse: sum(Hasse invariants) != 0
sage: QuaternionAlgebra(QQ.number_field(), [ZZ.ideal(2),ZZ.ideal(3)], [0])
Quaternion Algebra (-1, 3) with base ring Rational Field
If the coefficients `a` and `b` in the definition of the quaternion
algebra are not integral, then a slower generic type is used for
arithmetic::
Expand Down Expand Up @@ -257,11 +282,28 @@ def create_key(self, arg0, arg1=None, arg2=None, names='i,j,k'):
a = K(v[0])
b = K(v[1])

# QuaternionAlgebra(K, a, b)
else:
# QuaternionAlgebra(K, finite_places, archimedian_places)
K = arg0
a = K(arg1)
b = K(arg2)
if isinstance(arg1, list) and isinstance(arg2, list):
if K == QQ:
D = ZZ.ideal_monoid().prod(arg1).gen()
a, b = hilbert_conductor_inverse(D)
a = Rational(a)
b = Rational(b)
else:
if len(arg2) != len(K.real_places()):
raise ValueError("must specify ramification at the real places of %s" % K)
K_pari = pari(K)
fin_places_pari = [I.pari_prime() for I in arg1]
A = K_pari.alginit([2, [fin_places_pari, [QQ(1/2)] * len(fin_places_pari)], arg2])
L_pari = A.algsplittingfield()
a = K(L_pari.disc()[1])
b = K(A.algb())
else:
# QuaternionAlgebra(K, a, b)
a = K(arg1)
b = K(arg2)

if not K(2).is_unit():
raise ValueError("2 is not invertible in %s" % K)
Expand Down

0 comments on commit 8b4220c

Please sign in to comment.