from sage.misc.table import table
from sage.modules.free_module import FreeModule, VectorSpace
from sage.rings.integer_ring import ZZ
-from sage.rings.number_field.number_field import NumberField
+from sage.rings.number_field.number_field import NumberField, QuadraticField
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
from sage.rings.rational_field import QQ
from sage.rings.real_lazy import CLF, RLF
-def _real_symmetric_basis(n, field):
+def _real_symmetric_basis(n, field, normalize):
"""
Return a basis for the space of real symmetric n-by-n matrices.
sage: set_random_seed()
sage: n = ZZ.random_element(1,5)
- sage: B = _real_symmetric_basis(n, QQbar)
+ sage: B = _real_symmetric_basis(n, QQbar, False)
sage: all( M.is_symmetric() for M in B)
True
Sij = Eij
else:
Sij = Eij + Eij.transpose()
- # Now normalize it.
- Sij = Sij / _real_symmetric_matrix_ip(Sij,Sij).sqrt()
+ if normalize:
+ Sij = Sij / _real_symmetric_matrix_ip(Sij,Sij).sqrt()
S.append(Sij)
return tuple(S)
-def _complex_hermitian_basis(n, field):
+def _complex_hermitian_basis(n, field, normalize):
"""
Returns a basis for the space of complex Hermitian n-by-n matrices.
sage: set_random_seed()
sage: n = ZZ.random_element(1,5)
- sage: R = PolynomialRing(QQ, 'z')
- sage: z = R.gen()
- sage: field = NumberField(z**2 - 2, 'sqrt2', embedding=RLF(2).sqrt())
- sage: B = _complex_hermitian_basis(n, field)
+ sage: field = QuadraticField(2, 'sqrt2')
+ sage: B = _complex_hermitian_basis(n, field, False)
sage: all( M.is_symmetric() for M in B)
True
Sij_imag = _embed_complex_matrix(I*Eij - I*Eij.transpose())
S.append(Sij_imag)
- # Normalize these with our inner product before handing them back.
- # And since we embedded them, we can drop back to the "field" that
- # we started with instead of the complex extension "F".
- return tuple( (s / _complex_hermitian_matrix_ip(s,s).sqrt()).change_ring(field)
- for s in S )
+ # Since we embedded these, we can drop back to the "field" that we
+ # started with instead of the complex extension "F".
+ S = [ s.change_ring(field) for s in S ]
+ if normalize:
+ S = [ s / _complex_hermitian_matrix_ip(s,s).sqrt() for s in S ]
+
+ return tuple(S)
-def _quaternion_hermitian_basis(n, field):
+def _quaternion_hermitian_basis(n, field, normalize):
"""
Returns a basis for the space of quaternion Hermitian n-by-n matrices.
sage: set_random_seed()
sage: n = ZZ.random_element(1,5)
- sage: B = _quaternion_hermitian_basis(n, QQ)
+ sage: B = _quaternion_hermitian_basis(n, QQ, False)
sage: all( M.is_symmetric() for M in B )
True
EXAMPLES::
- sage: R = PolynomialRing(QQ, 'z')
- sage: z = R.gen()
- sage: F = NumberField(z**2 + 1, 'i', embedding=CLF(-1).sqrt())
+ sage: F = QuadraticField(-1, 'i')
sage: x1 = F(4 - 2*i)
sage: x2 = F(1 + 2*i)
sage: x3 = F(-i)
sage: set_random_seed()
sage: n = ZZ.random_element(5)
- sage: R = PolynomialRing(QQ, 'z')
- sage: z = R.gen()
- sage: F = NumberField(z**2 + 1, 'i', embedding=CLF(-1).sqrt())
+ sage: F = QuadraticField(-1, 'i')
sage: X = random_matrix(F, n)
sage: Y = random_matrix(F, n)
sage: actual = _embed_complex_matrix(X) * _embed_complex_matrix(Y)
Unembedding is the inverse of embedding::
sage: set_random_seed()
- sage: R = PolynomialRing(QQ, 'z')
- sage: z = R.gen()
- sage: F = NumberField(z**2 + 1, 'i', embedding=CLF(-1).sqrt())
+ sage: F = QuadraticField(-1, 'i')
sage: M = random_matrix(F, 3)
sage: _unembed_complex_matrix(_embed_complex_matrix(M)) == M
True
if M.ncols() != n:
raise ValueError("the matrix 'M' must be square")
- R = PolynomialRing(QQ, 'z')
- z = R.gen()
- F = NumberField(z**2 + 1, 'i', embedding=CLF(-1).sqrt())
+ F = QuadraticField(-1, 'i')
i = F.gen()
blocks = []
True
"""
- def __init__(self, n, field=QQ, **kwargs):
- if n > 1:
+ def __init__(self, n, field=QQ, normalize_basis=True, **kwargs):
+ if n > 1 and normalize_basis:
# We'll need sqrt(2) to normalize the basis, and this
# winds up in the multiplication table, so the whole
# algebra needs to be over the field extension.
R = PolynomialRing(field, 'z')
z = R.gen()
- field = NumberField(z**2 - 2, 'sqrt2', embedding=RLF(2).sqrt())
+ p = z**2 - 2
+ if p.is_irreducible():
+ field = NumberField(p, 'sqrt2', embedding=RLF(2).sqrt())
- S = _real_symmetric_basis(n, field)
+ S = _real_symmetric_basis(n, field, normalize_basis)
Qs = _multiplication_table_from_matrix_basis(S)
fdeja = super(RealSymmetricEJA, self)
True
"""
- def __init__(self, n, field=QQ, **kwargs):
- if n > 1:
+ def __init__(self, n, field=QQ, normalize_basis=True, **kwargs):
+ if n > 1 and normalize_basis:
# We'll need sqrt(2) to normalize the basis, and this
# winds up in the multiplication table, so the whole
# algebra needs to be over the field extension.
R = PolynomialRing(field, 'z')
z = R.gen()
- field = NumberField(z**2 - 2, 'sqrt2', embedding=RLF(2).sqrt())
- S = _complex_hermitian_basis(n, field)
+ p = z**2 - 2
+ if p.is_irreducible():
+ field = NumberField(p, 'sqrt2', embedding=RLF(2).sqrt())
+
+ S = _complex_hermitian_basis(n, field, normalize_basis)
Qs = _multiplication_table_from_matrix_basis(S)
fdeja = super(ComplexHermitianEJA, self)
True
"""
- def __init__(self, n, field=QQ, **kwargs):
- S = _quaternion_hermitian_basis(n, field)
+ def __init__(self, n, field=QQ, normalize_basis=True, **kwargs):
+ S = _quaternion_hermitian_basis(n, field, normalize_basis)
Qs = _multiplication_table_from_matrix_basis(S)
fdeja = super(QuaternionHermitianEJA, self)