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[source]¶
Bases:
AlgebraElement- coefficient_tuple()[source]¶
Return 4-tuple of coefficients of this quaternion.
EXAMPLES:
sage: K.<x> = QQ['x'] sage: Q.<i,j,k> = QuaternionAlgebra(Frac(K),-5,-2) sage: a = 1/2*x^2 + 2/3*x*i - 3/4*j + 5/7*k sage: type(a) <class 'sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_generic'> sage: a.coefficient_tuple() (1/2*x^2, 2/3*x, -3/4, 5/7)
>>> from sage.all import * >>> K = QQ['x']; (x,) = K._first_ngens(1) >>> Q = QuaternionAlgebra(Frac(K),-Integer(5),-Integer(2), names=('i', 'j', 'k',)); (i, j, k,) = Q._first_ngens(3) >>> a = Integer(1)/Integer(2)*x**Integer(2) + Integer(2)/Integer(3)*x*i - Integer(3)/Integer(4)*j + Integer(5)/Integer(7)*k >>> type(a) <class 'sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_generic'> >>> a.coefficient_tuple() (1/2*x^2, 2/3*x, -3/4, 5/7)
- conjugate()[source]¶
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) <class 'sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_rational_field'> sage: a.conjugate() 2 - 3*i + j
>>> from sage.all import * >>> A = QuaternionAlgebra(QQ,-Integer(5),-Integer(2), names=('i', 'j', 'k',)); (i, j, k,) = A._first_ngens(3) >>> a = Integer(3)*i - j + Integer(2) >>> type(a) <class 'sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_rational_field'> >>> 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
>>> from sage.all import * >>> K = QQ['x, y, z, w, a, b']; (x, y, z, w, a, b,) = K._first_ngens(6) >>> Q = QuaternionAlgebra(a,b, names=('i', 'j', 'k',)); (i, j, k,) = Q._first_ngens(3) >>> theta = x+y*i+z*j+w*k >>> theta.conjugate() x + (-y)*i + (-z)*j + (-w)*k
- is_constant()[source]¶
Return
Trueif this quaternion is constant, i.e., has no \(i\), \(j\), or \(k\) term.OUTPUT: boolean
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
>>> from sage.all import * >>> A = QuaternionAlgebra(-Integer(1),-Integer(2), names=('i', 'j', 'k',)); (i, j, k,) = A._first_ngens(3) >>> A(Integer(1)).is_constant() True >>> A(Integer(1)+i).is_constant() False >>> A(i).is_constant() False
- matrix(action='right')[source]¶
Return the matrix of right or left multiplication of
selfon the basis for the ambient quaternion algebra.In particular, if action is
'right'(the default), returns the matrix of the mapping sendingxtox*self.INPUT:
action– (default:'right')'right'or'left'
OUTPUT: a matrix
EXAMPLES:
sage: Q.<i,j,k> = QuaternionAlgebra(-3,-19) sage: a = 2/3 -1/2*i + 3/5*j - 4/3*k sage: a.matrix() [ 2/3 -1/2 3/5 -4/3] [ 3/2 2/3 4 3/5] [-57/5 -76/3 2/3 1/2] [ 76 -57/5 -3/2 2/3] sage: a.matrix() == a.matrix(action='right') True sage: a.matrix(action='left') [ 2/3 -1/2 3/5 -4/3] [ 3/2 2/3 -4 -3/5] [-57/5 76/3 2/3 -1/2] [ 76 57/5 3/2 2/3] sage: (i*a,j*a,k*a) (3/2 + 2/3*i + 4*j + 3/5*k, -57/5 - 76/3*i + 2/3*j + 1/2*k, 76 - 57/5*i - 3/2*j + 2/3*k) sage: a.matrix(action='foo') Traceback (most recent call last): ... ValueError: action must be either 'left' or 'right'
>>> from sage.all import * >>> Q = QuaternionAlgebra(-Integer(3),-Integer(19), names=('i', 'j', 'k',)); (i, j, k,) = Q._first_ngens(3) >>> a = Integer(2)/Integer(3) -Integer(1)/Integer(2)*i + Integer(3)/Integer(5)*j - Integer(4)/Integer(3)*k >>> a.matrix() [ 2/3 -1/2 3/5 -4/3] [ 3/2 2/3 4 3/5] [-57/5 -76/3 2/3 1/2] [ 76 -57/5 -3/2 2/3] >>> a.matrix() == a.matrix(action='right') True >>> a.matrix(action='left') [ 2/3 -1/2 3/5 -4/3] [ 3/2 2/3 -4 -3/5] [-57/5 76/3 2/3 -1/2] [ 76 57/5 3/2 2/3] >>> (i*a,j*a,k*a) (3/2 + 2/3*i + 4*j + 3/5*k, -57/5 - 76/3*i + 2/3*j + 1/2*k, 76 - 57/5*i - 3/2*j + 2/3*k) >>> a.matrix(action='foo') Traceback (most recent call last): ... ValueError: action must be either 'left' or 'right'
We test over a more generic base field:
sage: K.<x> = QQ['x'] sage: Q.<i,j,k> = QuaternionAlgebra(Frac(K),-5,-2) sage: a = 1/2*x^2 + 2/3*x*i - 3/4*j + 5/7*k sage: type(a) <class 'sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_generic'> sage: a.matrix() [1/2*x^2 2/3*x -3/4 5/7] [-10/3*x 1/2*x^2 -25/7 -3/4] [ 3/2 10/7 1/2*x^2 -2/3*x] [ -50/7 3/2 10/3*x 1/2*x^2]
>>> from sage.all import * >>> K = QQ['x']; (x,) = K._first_ngens(1) >>> Q = QuaternionAlgebra(Frac(K),-Integer(5),-Integer(2), names=('i', 'j', 'k',)); (i, j, k,) = Q._first_ngens(3) >>> a = Integer(1)/Integer(2)*x**Integer(2) + Integer(2)/Integer(3)*x*i - Integer(3)/Integer(4)*j + Integer(5)/Integer(7)*k >>> type(a) <class 'sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_generic'> >>> a.matrix() [1/2*x^2 2/3*x -3/4 5/7] [-10/3*x 1/2*x^2 -25/7 -3/4] [ 3/2 10/7 1/2*x^2 -2/3*x] [ -50/7 3/2 10/3*x 1/2*x^2]
- pair(right)[source]¶
Return the result of pairing
selfandright, which should both be elements of a quaternion algebra. The pairing is(x,y) = (x.conjugate()*y).reduced_trace().INPUT:
right– quaternion
EXAMPLES:
sage: A.<i,j,k>=QuaternionAlgebra(-1,-2) sage: (1+i+j-2*k).pair(2/3+5*i-3*j+k) -26/3 sage: x = 1+i+j-2*k; y = 2/3+5*i-3*j+k sage: x.pair(y) -26/3 sage: y.pair(x) -26/3 sage: (x.conjugate()*y).reduced_trace() -26/3
>>> from sage.all import * >>> A = QuaternionAlgebra(-Integer(1),-Integer(2), names=('i', 'j', 'k',)); (i, j, k,) = A._first_ngens(3) >>> (Integer(1)+i+j-Integer(2)*k).pair(Integer(2)/Integer(3)+Integer(5)*i-Integer(3)*j+k) -26/3 >>> x = Integer(1)+i+j-Integer(2)*k; y = Integer(2)/Integer(3)+Integer(5)*i-Integer(3)*j+k >>> x.pair(y) -26/3 >>> y.pair(x) -26/3 >>> (x.conjugate()*y).reduced_trace() -26/3
- reduced_characteristic_polynomial(var='x')[source]¶
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
>>> from sage.all import * >>> A = QuaternionAlgebra(-Integer(1),-Integer(2), names=('i', 'j', 'k',)); (i, j, k,) = A._first_ngens(3) >>> i.reduced_characteristic_polynomial() x^2 + 1 >>> j.reduced_characteristic_polynomial() x^2 + 2 >>> (i+j).reduced_characteristic_polynomial() x^2 + 3 >>> (Integer(2)+j+k).reduced_trace() 4 >>> (Integer(2)+j+k).reduced_characteristic_polynomial('T') T^2 - 4*T + 8
- reduced_norm()[source]¶
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
>>> from sage.all import * >>> K = QQ['x, y, z, w, a, b']; (x, y, z, w, a, b,) = K._first_ngens(6) >>> Q = QuaternionAlgebra(a,b, names=('i', 'j', 'k',)); (i, j, k,) = Q._first_ngens(3) >>> theta = x+y*i+z*j+w*k >>> theta.reduced_norm() w^2*a*b - y^2*a - z^2*b + x^2
- reduced_trace()[source]¶
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
>>> from sage.all import * >>> K = QQ['x, y, z, w, a, b']; (x, y, z, w, a, b,) = K._first_ngens(6) >>> Q = QuaternionAlgebra(a,b, names=('i', 'j', 'k',)); (i, j, k,) = Q._first_ngens(3) >>> theta = x+y*i+z*j+w*k >>> theta.reduced_trace() 2*x
- class sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_number_field[source]¶
Bases:
QuaternionAlgebraElement_abstractEXAMPLES:
sage: K.<a> = QQ[2^(1/3)]; Q.<i,j,k> = QuaternionAlgebra(K,-a,a+1) # needs sage.symbolic sage: Q([a,-2/3,a^2-1/2,a*2]) # implicit doctest # needs sage.symbolic a + (-2/3)*i + (a^2 - 1/2)*j + 2*a*k
>>> from sage.all import * >>> K = QQ[Integer(2)**(Integer(1)/Integer(3))]; (a,) = K._first_ngens(1); Q = QuaternionAlgebra(K,-a,a+Integer(1), names=('i', 'j', 'k',)); (i, j, k,) = Q._first_ngens(3)# needs sage.symbolic >>> Q([a,-Integer(2)/Integer(3),a**Integer(2)-Integer(1)/Integer(2),a*Integer(2)]) # implicit doctest # needs sage.symbolic a + (-2/3)*i + (a^2 - 1/2)*j + 2*a*k
- class sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_rational_field[source]¶
Bases:
QuaternionAlgebraElement_abstract- coefficient_tuple()[source]¶
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)
>>> from sage.all import * >>> A = QuaternionAlgebra(-Integer(1),-Integer(2), names=('i', 'j', 'k',)); (i, j, k,) = A._first_ngens(3) >>> (Integer(2)/Integer(3) + Integer(3)/Integer(5)*i + Integer(4)/Integer(3)*j - Integer(5)/Integer(7)*k).coefficient_tuple() (2/3, 3/5, 4/3, -5/7)
- conjugate()[source]¶
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) <class '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
>>> from sage.all import * >>> A = QuaternionAlgebra(QQ,-Integer(5),-Integer(2), names=('i', 'j', 'k',)); (i, j, k,) = A._first_ngens(3) >>> a = Integer(3)*i - j + Integer(2) >>> type(a) <class 'sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_rational_field'> >>> a.conjugate() 2 - 3*i + j >>> b = Integer(1) + Integer(1)/Integer(3)*i + Integer(1)/Integer(5)*j - Integer(1)/Integer(7)*k >>> b.conjugate() 1 - 1/3*i - 1/5*j + 1/7*k
- denominator()[source]¶
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
>>> from sage.all import * >>> A = QuaternionAlgebra(QQ, -Integer(1), -Integer(1)) >>> A = QuaternionAlgebra(QQ, -Integer(1), -Integer(1), names=('i', 'j', 'k',)); (i, j, k,) = A._first_ngens(3) >>> a = (Integer(1)/Integer(2)) + (Integer(1)/Integer(5))*i + (Integer(5)/Integer(12))*j + (Integer(1)/Integer(13))*k >>> a 1/2 + 1/5*i + 5/12*j + 1/13*k >>> a.denominator() 780 >>> lcm([Integer(2), Integer(5), Integer(12), Integer(13)]) 780 >>> (a * a).denominator() 608400 >>> (a + a).denominator() 390
- denominator_and_integer_coefficient_tuple()[source]¶
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)
>>> from sage.all import * >>> A = QuaternionAlgebra(-Integer(1),-Integer(2), names=('i', 'j', 'k',)); (i, j, k,) = A._first_ngens(3) >>> (Integer(2) + Integer(3)*i + Integer(4)/Integer(3)*j - Integer(5)*k).denominator_and_integer_coefficient_tuple() (3, 6, 9, 4, -15)
- integer_coefficient_tuple()[source]¶
Return the 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)
>>> from sage.all import * >>> A = QuaternionAlgebra(-Integer(1),-Integer(2), names=('i', 'j', 'k',)); (i, j, k,) = A._first_ngens(3) >>> (Integer(2) + Integer(3)*i + Integer(4)/Integer(3)*j - Integer(5)*k).integer_coefficient_tuple() (6, 9, 4, -15)
- is_constant()[source]¶
Return
Trueif this quaternion is constant, i.e., has no \(i\), \(j\), or \(k\) term.OUTPUT: boolean
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
>>> from sage.all import * >>> A = QuaternionAlgebra(-Integer(1),-Integer(2), names=('i', 'j', 'k',)); (i, j, k,) = A._first_ngens(3) >>> A(Integer(1)/Integer(3)).is_constant() True >>> A(-Integer(1)).is_constant() True >>> (Integer(1)+i).is_constant() False >>> j.is_constant() False
- reduced_norm()[source]¶
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
>>> from sage.all import * >>> K = QuaternionAlgebra(QQ, -Integer(5), -Integer(2), names=('i', 'j', 'k',)); (i, j, k,) = K._first_ngens(3) >>> i.reduced_norm() 5 >>> j.reduced_norm() 2 >>> a = Integer(1)/Integer(3) + Integer(1)/Integer(5)*i + Integer(1)/Integer(7)*j + k >>> a.reduced_norm() 22826/2205
- reduced_trace()[source]¶
Return the reduced trace of
self.This is \(2x\) if
selfis \(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
>>> from sage.all import * >>> K = QuaternionAlgebra(QQ, -Integer(5), -Integer(2), names=('i', 'j', 'k',)); (i, j, k,) = K._first_ngens(3) >>> i.reduced_trace() 0 >>> j.reduced_trace() 0 >>> a = Integer(1)/Integer(3) + Integer(1)/Integer(5)*i + Integer(1)/Integer(7)*j + k >>> a.reduced_trace() 2/3
- sage.algebras.quatalg.quaternion_algebra_element.unpickle_QuaternionAlgebraElement_generic_v0(*args)[source]¶
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
>>> from sage.all import * >>> K = QQ['X']; (X,) = K._first_ngens(1) >>> Q = QuaternionAlgebra(Frac(K), -Integer(5),-Integer(19), names=('i', 'j', 'k',)); (i, j, k,) = Q._first_ngens(3); z = Integer(2)/Integer(3) + i*X - X**Integer(2)*j + X**Integer(3)*k >>> f, t = z.__reduce__() >>> sage.algebras.quatalg.quaternion_algebra_element.unpickle_QuaternionAlgebraElement_generic_v0(*t) 2/3 + X*i + (-X^2)*j + X^3*k >>> sage.algebras.quatalg.quaternion_algebra_element.unpickle_QuaternionAlgebraElement_generic_v0(*t) == z True
- sage.algebras.quatalg.quaternion_algebra_element.unpickle_QuaternionAlgebraElement_number_field_v0(*args)[source]¶
EXAMPLES:
sage: # needs sage.symbolic 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
>>> from sage.all import * >>> # needs sage.symbolic >>> K = QQ[Integer(2)**(Integer(1)/Integer(3))]; (a,) = K._first_ngens(1); Q = QuaternionAlgebra(K, -Integer(3), a, names=('i', 'j', 'k',)); (i, j, k,) = Q._first_ngens(3); z = i + j >>> f, t = z.__reduce__() >>> sage.algebras.quatalg.quaternion_algebra_element.unpickle_QuaternionAlgebraElement_number_field_v0(*t) i + j >>> 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(*args)[source]¶
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
>>> from sage.all import * >>> Q = QuaternionAlgebra(-Integer(5),-Integer(19), names=('i', 'j', 'k',)); (i, j, k,) = Q._first_ngens(3); a = Integer(2)/Integer(3) + i*Integer(5)/Integer(7) - j*Integer(2)/Integer(5) +Integer(19)/Integer(2) >>> f, t = a.__reduce__() >>> sage.algebras.quatalg.quaternion_algebra_element.unpickle_QuaternionAlgebraElement_rational_field_v0(*t) 61/6 + 5/7*i - 2/5*j