Elements of Quaternion Algebras

Sage allows for computation with elements of quaternion algebras over a nearly arbitrary base field of characteristic not 2. Sage also has very highly optimized implementation of arithmetic in rational quaternion algebras and quaternion algebras over number fields.

class sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_abstract
__float__()

Try to coerce this quaternion to a Python float.

EXAMPLES:

sage: A.<i,j,k>=QuaternionAlgebra(-1,-2)
sage: float(A(-3/2))
-1.5
sage: float(A(-3))
-3.0
sage: float(-3 + i)
...
TypeError
__int__()

Try to coerce this quaternion to a Python int.

EXAMPLES::
sage: A.<i,j,k>=QuaternionAlgebra(-1,-2) sage: int(A(-3)) -3 sage: int(A(-3/2)) -2 sage: int(-3 + i) Traceback (most recent call last): ... TypeError
__invert__()

Return inverse of self.

EXAMPLES:

sage: Q.<i,j,k> = QuaternionAlgebra(QQ,-7,-13)
sage: theta = 1/3 - 2/3*i + 4/19*j - 17/3*k
sage: (1/theta) * theta
1
sage: type(theta)
<type 'sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_rational_field'>
sage: 1/Q(0)
...
ZeroDivisionError: rational division by zero

Note that the quaternion algebra need not be a division algebra, in which case we can get a ZeroDivisionException:

sage: Q.<i,j,k> = QuaternionAlgebra(QQ,4,9)
sage: theta = 2-i
sage: theta.reduced_norm()
0
sage: 1/theta
...
ZeroDivisionError: rational division by zero

The universal test:

sage: K.<x,y,z,w,a,b> = QQ[] sage: Q.<i,j,k> = QuaternionAlgebra(a,b) sage: theta = x+y*i+z*j+w*k sage: 1/theta == theta.conjugate()/theta.reduced_norm() True
__long__()

Try to coerce this quaternion to a Python long.

EXAMPLES:

sage: A.<i,j,k>=QuaternionAlgebra(-1,-2)
sage: long(A(-3))
-3L
sage: long(A(-3/2))
-2L
sage: long(-3 + i)
...
TypeError
static __new__()
T.__new__(S, ...) -> a new object with type S, a subtype of T
__nonzero__()
x.__nonzero__() <==> x != 0
_div_()

Return quotient of self by right.

EXAMPLES:

sage: K.<x> = QQ[]; Q.<i,j,k> = QuaternionAlgebra(x, 2*x); 
sage: theta = x + 2*x*i + 3*j + (x-2)*k
sage: type(theta)
<type 'sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_generic'>
sage: theta._div_(theta)   # funny reduced form of Frac(QQ['x'])...
64/64
sage: theta._div_(theta) == 1
True
_integer_()

Try to coerce this quaternion to an Integer.

EXAMPLES::
sage: A.<i,j,k>=QuaternionAlgebra(-1,-2) sage: Integer(A(-3)) # indirect doctest -3 sage: type(Integer(A(-3))) <type ‘sage.rings.integer.Integer’> sage: Integer(A(-3/2)) Traceback (most recent call last): ... TypeError: no conversion of this rational to integer sage: Integer(-3 + i) Traceback (most recent call last): ... TypeError
_rational_()

Try to coerce this quaternion to a Rational.

EXAMPLES:

sage: Q.<i,j,k> = QuaternionAlgebra(Frac(QQ['x']),-5,-2)
sage: Rational(Q(2/3))                                # indirect doctest
2/3
sage: Rational(2/3 + i)
...
TypeError
_repr_()

Return string representation of this quaternion:

EXAMPLES:

sage: R.<x> = Frac(QQ['x']); Q.<i,j,k> = QuaternionAlgebra(R,-5*x,-2)
sage: a = x + i*x^3 + j*x^2 + k*x
sage: a._repr_()
'x + x^3*i + x^2*j + x*k'
sage: a = x+2/3 + i*x^3 + j*(x^2-5/2) + k*x
sage: a._repr_()
'x + 2/3 + x^3*i + (x^2 - 5/2)*j + x*k'
sage: type(a)
<type 'sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_generic'>
sage: Q(0)._repr_()
'0'
conjugate()

Return the conjugate of the quaternion: if \theta = x + yi + zj + wk, return x - yi - zj - wk; that is, return theta.reduced_trace() - theta.

EXAMPLES:

sage: A.<i,j,k> = QuaternionAlgebra(QQ,-5,-2)
sage: a = 3*i - j + 2
sage: type(a)
<type 'sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_rational_field'>
sage: a.conjugate()
2 - 3*i + j

The “universal” test:

sage: K.<x,y,z,w,a,b> = QQ[]
sage: Q.<i,j,k> = QuaternionAlgebra(a,b)
sage: theta = x+y*i+z*j+w*k
sage: theta.conjugate()
x + (-y)*i + (-z)*j + (-w)*k
is_constant()

Return True if this quaternion is constant, i.e., has no i, j, or k term.

OUTPUT:
bool

EXAMPLES:

sage: A.<i,j,k>=QuaternionAlgebra(-1,-2)
sage: A(1).is_constant()
True
sage: A(1+i).is_constant()
False
sage: A(i).is_constant()
False
reduced_characteristic_polynomial()

Return the reduced characteristic polynomial of this quaternion algebra element, which is X^2 - tX + n, where t is the reduced trace and n is the reduced norm.

INPUT:
  • var – string (default: ‘x’); indeterminate of characteristic polynomial

EXAMPLES:

sage: A.<i,j,k>=QuaternionAlgebra(-1,-2)
sage: i.reduced_characteristic_polynomial()
x^2 + 1
sage: j.reduced_characteristic_polynomial()
x^2 + 2
sage: (i+j).reduced_characteristic_polynomial()
x^2 + 3
sage: (2+j+k).reduced_trace()
4
sage: (2+j+k).reduced_characteristic_polynomial('T')
T^2 - 4*T + 8
reduced_norm()

Return the reduced norm of self: if \theta = x + yi + zj +
wk, then \theta has reduced norm x^2 - ay^2 - bz^2 +
abw^2.

EXAMPLES:

sage: K.<x,y,z,w,a,b> = QQ[]
sage: Q.<i,j,k> = QuaternionAlgebra(a,b)
sage: theta = x+y*i+z*j+w*k
sage: theta.reduced_norm()
w^2*a*b - y^2*a - z^2*b + x^2
reduced_trace()

Return the reduced trace of self: if \theta = x + yi + zj +
wk, then \theta has reduced trace 2x.

EXAMPLES:

sage: K.<x,y,z,w,a,b> = QQ[]
sage: Q.<i,j,k> = QuaternionAlgebra(a,b)
sage: theta = x+y*i+z*j+w*k
sage: theta.reduced_trace()
2*x
class sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_generic

TESTS:

We test pickling:

sage: R.<x> = Frac(QQ['x']); Q.<i,j,k> = QuaternionAlgebra(R,-5*x,-2)
sage: theta = x + i*x^3 + j*x^2 + k*x
sage: theta == loads(dumps(theta))
True
__getitem__()

EXAMPLES:

sage: Q.<i,j,k> = QuaternionAlgebra(Frac(QQ['x']),-5,-2)
sage: theta = 1/2 + 2/3*i - 3/4*j + 5/7*k
sage: type(theta)
<type 'sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_generic'>
sage: list(theta)
[1/2, 2/3, -3/4, 5/7]
__init__()
x.__init__(...) initializes x; see x.__class__.__doc__ for signature
static __new__()
T.__new__(S, ...) -> a new object with type S, a subtype of T
__reduce__()

Used for pickling.

TESTS::
sage: K.<x> = Frac(QQ[‘x’]); Q.<i,j,k> = QuaternionAlgebra(K,-5,-2) sage: theta = 1/x + x*i - (x+1)*j + 2/(3*x^3+5)*k sage: loads(dumps(theta)) == theta True sage: type(theta) <type ‘sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_generic’>
_add_()

Return the sum of self and _right.

EXAMPLES:

sage: K.<x> = Frac(QQ['x']); Q.<i,j,k> = QuaternionAlgebra(K,-5,-2)
sage: (x+i+j+x^3*k) + (x-i-j+ (2/3*x^3+x)*k)              # indirect doctest
2*x + (5/3*x^3 + x)*k
sage: type(i)
<type 'sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_generic'>
_mul_()

Return the product of self and _right.

EXAMPLES::
sage: K.<x> = Frac(QQ[‘x’]); Q.<i,j,k> = QuaternionAlgebra(K,-5,-2) sage: type(i) <type ‘sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_generic’> sage: (x+i+j+x^3*k)._mul_(x-i-j+ (2/3*x^3+x)*k) -20/3*x^6 - 10*x^4 + x^2 + 7 + (10/3*x^3 + 2*x)*i + (-25/3*x^3 - 5*x)*j + (5/3*x^4 + x^2)*k
_repr_()

Print representation of self.

EXAMPLES:

sage: K.<x> = Frac(QQ['x']); Q.<i,j,k> = QuaternionAlgebra(K,-5,-2)
sage: theta = 1/x + x*i - (x+1)*j + 2/(3*x^3+5)*k
sage: type(theta)
<type 'sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_generic'>
sage: theta._repr_()
'1/x + x*i + (-x - 1)*j + (2/(3*x^3 + 5))*k'
_sub_()

Return the difference of self and _right.

EXAMPLES:

sage: K.<x> = Frac(QQ['x']); Q.<i,j,k> = QuaternionAlgebra(K,-5,-2)
sage: type(i)
<type 'sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_generic'>
sage: (x+i+j+x^3*k)._sub_(x-i-j+ (2/3*x^3+x)*k)
2*i + 2*j + (1/3*x^3 - x)*k
class sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_number_field
__getitem__()

EXAMPLES:

sage: K.<a> = QQ[2^(1/3)]; Q.<i,j,k> = QuaternionAlgebra(K,-a,a+1)
sage: Q([a,-2/3,a^2-1/2,a*2])
a + (-2/3)*i + (a^2 - 1/2)*j + 2*a*k
sage: x = Q([a,-2/3,a^2-1/2,a*2])
sage: type(x)
<type 'sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_number_field'>
sage: x[0]
a
sage: x[1]
-2/3
sage: x[2]
a^2 - 1/2
sage: x[3]
2*a
sage: list(x)
[a, -2/3, a^2 - 1/2, 2*a]
__init__()
x.__init__(...) initializes x; see x.__class__.__doc__ for signature
static __new__()
T.__new__(S, ...) -> a new object with type S, a subtype of T
__reduce__()

EXAMPLES:

sage: K.<a> = QQ[2^(1/3)]; Q.<i,j,k> = QuaternionAlgebra(K, -3, a)
sage: z = (i+j+k+a)^2; z
a^2 + 4*a - 3 + 2*a*i + 2*a*j + 2*a*k
sage: f, t = z.__reduce__()
sage: f(*t)
a^2 + 4*a - 3 + 2*a*i + 2*a*j + 2*a*k
sage: loads(dumps(z)) == z
True
_add_()

Add self and _right:

EXAMPLES::
sage: K.<a> = QQ[2^(1/3)]; Q.<i,j,k> = QuaternionAlgebra(K, -3, a) sage: z = a + i + (2/3)*a^3*j + (1+a)*k; w = a - i - (2/3)*a^3*j + (1/3+a)*k sage: type(z) <type ‘sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_number_field’> sage: z._add_(w) 2*a + (2*a + 4/3)*k
_mul_()

Multiply self and _right.

EXAMPLES:

sage: K.<a> = QQ[2^(1/3)]; Q.<i,j,k> = QuaternionAlgebra(K, -3, a)
sage: z = a + i + (2/3)*a^3*j + (1+a)*k; w = a - i - (2/3)*a^3*j + (1/3+a)*k
sage: type(z)
<type 'sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_number_field'>
sage: z._mul_(w)
5*a^2 - 7/9*a + 9 + (-8/3*a^2 - 16/9*a)*i + (-6*a - 4)*j + (2*a^2 + 4/3*a)*k
_sub_()

Subtract _right from self.

EXAMPLES:

sage: K.<a> = QQ[2^(1/3)]; Q.<i,j,k> = QuaternionAlgebra(K, -3, a)
sage: z = a + i + (2/3)*a^3*j + (1+a)*k; w = a - i - (2/3)*a^3*j + (1/3+a)*k
sage: type(z)
<type 'sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_number_field'>
sage: z._sub_(w)
2*i + 8/3*j + 2/3*k
class sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_rational_field

TESTS:

We test pickling:

sage: Q.<i,j,k> = QuaternionAlgebra(QQ,-5,-2)
sage: i + j + k == loads(dumps(i+j+k))
True
__getitem__()

TESTS:

sage: Q.<i,j,k> = QuaternionAlgebra(QQ,-5,-2)
sage: theta = 1/2 + 2/3*i - 3/4*j + 5/7*k
sage: type(theta)
<type 'sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_rational_field'>
sage: list(theta)
[1/2, 2/3, -3/4, 5/7]
__init__()
x.__init__(...) initializes x; see x.__class__.__doc__ for signature
static __new__()
T.__new__(S, ...) -> a new object with type S, a subtype of T
__nonzero__()
x.__nonzero__() <==> x != 0
__reduce__()

Used for pickling.

TESTS:

sage: K.<x> = QQ[]
sage: Q.<i,j,k> = QuaternionAlgebra(Frac(K),-5,-19)
sage: theta = 1/2 + 2/3*i - 3/4*j + 5/7*k
sage: type(theta)
<type 'sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_generic'>
sage: loads(dumps(theta)) == theta
True
_add_()

EXAMPLES:

sage: Q.<i,j,k> = QuaternionAlgebra(15)
sage: type(i)
<type 'sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_rational_field'>
sage: (2/3 + 3/4*i + 5/6*j + 7/8*k)._add_(-2/3 - 3/4*i + 5/6*j + 7/8*k)
5/3*j + 7/4*k
_divide_by_integer()

Return the quotient of self by the integer n.

EXAMPLES::
sage: A = QuaternionAlgebra(7) sage: a = A.random_element() sage: a/5 == a._divide_by_integer(5) True sage: a._divide_by_integer(0) Traceback (most recent call last): ... ZeroDivisionError
_mul_()

EXAMPLES:

sage: Q.<i,j,k> = QuaternionAlgebra(15)
sage: type(i)
<type 'sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_rational_field'>
sage: (2/3 + 3/4*i + 5/6*j + 7/8*k)._mul_(-2/3 - 3/4*i + 5/6*j + 7/8*k)
9331/576 - i - 63/16*j + 5/4*k        
_multiply_by_integer()

Return the product of self times the integer n.

EXAMPLES::
sage: A = QuaternionAlgebra(7) sage: a = A.random_element() sage: 5*a == a._multiply_by_integer(5) True
_rational_()

Try to coerce this quaternion to a Rational.

EXAMPLES:

sage: A.<i,j,k> = QuaternionAlgebra(-1,-2)
sage: Rational(A(-2/3))                             # indirect doctest
-2/3
sage: Rational(i)
...
TypeError
_sub_()

EXAMPLES:

sage: Q.<i,j,k> = QuaternionAlgebra(15)
sage: type(i)
<type 'sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_rational_field'>
sage: (2/3 + 3/4*i + 5/6*j + 7/8*k)._sub_(-2/3 - 3/4*i + 5/6*j + 7/8*k)
4/3 + 3/2*i
coefficient_tuple()

Return 4-tuple of rational numbers which are the coefficients of this quaternion.

EXAMPLES:

sage: A.<i,j,k>=QuaternionAlgebra(-1,-2)
sage: (2/3 + 3/5*i + 4/3*j - 5/7*k).coefficient_tuple()
(2/3, 3/5, 4/3, -5/7)
conjugate()

Return the conjugate of this quaternion.

EXAMPLES:

sage: A.<i,j,k> = QuaternionAlgebra(QQ,-5,-2)
sage: a = 3*i - j + 2
sage: type(a)
<type 'sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_rational_field'>
sage: a.conjugate()
2 - 3*i + j
sage: b = 1 + 1/3*i + 1/5*j - 1/7*k
sage: b.conjugate()
1 - 1/3*i - 1/5*j + 1/7*k
denominator()

Return the lowest common multiple of the denominators of the coefficients of i, j and k for this quaternion.

EXAMPLES:

sage: A = QuaternionAlgebra(QQ, -1, -1)
sage: A.<i,j,k> = QuaternionAlgebra(QQ, -1, -1)
sage: a = (1/2) + (1/5)*i + (5/12)*j + (1/13)*k
sage: a
1/2 + 1/5*i + 5/12*j + 1/13*k
sage: a.denominator()
780
sage: lcm([2, 5, 12, 13])
780
sage: (a * a).denominator()
608400
sage: (a + a).denominator()
390
denominator_and_integer_coefficient_tuple()

Return 5-tuple d, x, y, z, w, where this rational quaternion is equal to (x + yi + zj + wk)/d and x, y, z, w do not share a common factor with d.

OUTPUT:
5-tuple of Integers

EXAMPLES:

sage: A.<i,j,k>=QuaternionAlgebra(-1,-2)
sage: (2 + 3*i + 4/3*j - 5*k).denominator_and_integer_coefficient_tuple()
(3, 6, 9, 4, -15)
integer_coefficient_tuple()

Returns integer part of this quaternion, ignoring the common denominator.

OUTPUT:
4-tuple of Integers

EXAMPLES:

sage: A.<i,j,k>=QuaternionAlgebra(-1,-2)
sage: (2 + 3*i + 4/3*j - 5*k).integer_coefficient_tuple()
(6, 9, 4, -15)
is_constant()

Return True if this quaternion is constant, i.e., has no i, j, or k term.

OUTPUT:
bool

EXAMPLES:

sage: A.<i,j,k>=QuaternionAlgebra(-1,-2)
sage: A(1/3).is_constant()
True
sage: A(-1).is_constant()
True
sage: (1+i).is_constant()
False
sage: j.is_constant()
False
reduced_norm()

Return the reduced norm of self. Given a quaternion x+yi+zj+wk, this is x^2 - ay^2 - bz^2 + abw^2.

EXAMPLES:

sage: K.<i,j,k> = QuaternionAlgebra(QQ, -5, -2)
sage: i.reduced_norm()
5
sage: j.reduced_norm()
2
sage: a = 1/3 + 1/5*i + 1/7*j + k
sage: a.reduced_norm()
22826/2205
reduced_trace()

Return the reduced trace of self, which is 2x if self is x+iy+zj+wk.

EXAMPLES:

sage: K.<i,j,k> = QuaternionAlgebra(QQ, -5, -2)
sage: i.reduced_trace()
0
sage: j.reduced_trace()
0
sage: a = 1/3 + 1/5*i + 1/7*j + k
sage: a.reduced_trace()
2/3
sage.algebras.quatalg.quaternion_algebra_element._clear_globals()

Clear all global variables allocated for optimization of quaternion algebra arithmetic.

Do not call this except on exit of Sage, unless you want to see segfaults.

This is called in the function quit_sage(), which is defined in all.py.

EXAMPLES:

sage: sage.algebras.quatalg.quaternion_algebra_element._clear_globals()
sage: sage.algebras.quatalg.quaternion_algebra_element._init_globals()
sage.algebras.quatalg.quaternion_algebra_element._init_globals()

Clear all global variables allocated for optimization of quaternion algebra arithmetic.

Do not call this unless you want to leak memory.

EXAMPLES:

sage: sage.algebras.quatalg.quaternion_algebra_element._clear_globals()
sage: sage.algebras.quatalg.quaternion_algebra_element._init_globals()
sage.algebras.quatalg.quaternion_algebra_element.clear_mpz_globals()
sage.algebras.quatalg.quaternion_algebra_element.gmp_randrange()
sage.algebras.quatalg.quaternion_algebra_element.init_mpz_globals()
sage.algebras.quatalg.quaternion_algebra_element.unpickle_QuaternionAlgebraElement_generic_v0()

EXAMPLES:

sage: K.<X> = QQ[]
sage: Q.<i,j,k> = QuaternionAlgebra(Frac(K), -5,-19); z = 2/3 + i*X - X^2*j + X^3*k
sage: f, t = z.__reduce__()
sage: sage.algebras.quatalg.quaternion_algebra_element.unpickle_QuaternionAlgebraElement_generic_v0(*t)
2/3 + X*i + (-X^2)*j + X^3*k
sage: sage.algebras.quatalg.quaternion_algebra_element.unpickle_QuaternionAlgebraElement_generic_v0(*t) == z
True
sage.algebras.quatalg.quaternion_algebra_element.unpickle_QuaternionAlgebraElement_number_field_v0()

EXAMPLES:

sage: K.<a> = QQ[2^(1/3)]; Q.<i,j,k> = QuaternionAlgebra(K, -3, a); z = i + j
sage: f, t = z.__reduce__()
sage: sage.algebras.quatalg.quaternion_algebra_element.unpickle_QuaternionAlgebraElement_number_field_v0(*t)
i + j
sage: sage.algebras.quatalg.quaternion_algebra_element.unpickle_QuaternionAlgebraElement_number_field_v0(*t) == z
True
sage.algebras.quatalg.quaternion_algebra_element.unpickle_QuaternionAlgebraElement_rational_field_v0()

EXAMPLES:

sage: Q.<i,j,k> = QuaternionAlgebra(-5,-19); a = 2/3 + i*5/7 - j*2/5 +19/2
sage: f, t = a.__reduce__()
sage: sage.algebras.quatalg.quaternion_algebra_element.unpickle_QuaternionAlgebraElement_rational_field_v0(*t)
61/6 + 5/7*i - 2/5*j

Previous topic

Quaternion Algebras

Next topic

Matrices and Spaces of Matrices

This Page