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, QuadraticField
+from sage.rings.number_field.number_field import 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
z = R.gen()
p = z**2 - 2
if p.is_irreducible():
- field = NumberField(p, 'sqrt2', embedding=RLF(2).sqrt())
+ field = field.extension(p, 'sqrt2', embedding=RLF(2).sqrt())
basis = tuple( s.change_ring(field) for s in basis )
self._basis_normalizers = tuple(
~(self.natural_inner_product(s,s).sqrt()) for s in basis )
else:
basis = ( (b/n) for (b,n) in izip(self.natural_basis(),
self._basis_normalizers) )
- field = self.base_ring().base_ring() # yeeeaahhhhhhh
- J = MatrixEuclideanJordanAlgebra(field,
+
+ # Do this over the rationals and convert back at the end.
+ J = MatrixEuclideanJordanAlgebra(QQ,
basis,
self.rank(),
normalize_basis=False)
# p might be missing some vars, have to substitute "optionally"
pairs = izip(x.base_ring().gens(), self._basis_normalizers)
substitutions = { v: v*c for (v,c) in pairs }
- return p.subs(substitutions)
+ result = p.subs(substitutions)
+
+ # The result of "subs" can be either a coefficient-ring
+ # element or a polynomial. Gotta handle both cases.
+ if result in QQ:
+ return self.base_ring()(result)
+ else:
+ return result.change_ring(self.base_ring())
@staticmethod
Xu = cls.real_unembed(X)
Yu = cls.real_unembed(Y)
tr = (Xu*Yu).trace()
+
if tr in RLF:
# It's real already.
return tr
sage: e2*e2
e2
+ In theory, our "field" can be any subfield of the reals::
+
+ sage: RealSymmetricEJA(2, AA)
+ Euclidean Jordan algebra of dimension 3 over Algebraic Real Field
+ sage: RealSymmetricEJA(2, RR)
+ Euclidean Jordan algebra of dimension 3 over Real Field with
+ 53 bits of precision
+
TESTS:
The dimension of this algebra is `(n^2 + n) / 2`::
n = M.nrows()
if M.ncols() != n:
raise ValueError("the matrix 'M' must be square")
- field = M.base_ring()
+
+ # We don't need any adjoined elements...
+ field = M.base_ring().base_ring()
+
blocks = []
for z in M.list():
- a = z.vector()[0] # real part, I guess
- b = z.vector()[1] # imag part, I guess
+ a = z.list()[0] # real part, I guess
+ b = z.list()[1] # imag part, I guess
blocks.append(matrix(field, 2, [[a,b],[-b,a]]))
- # We can drop the imaginaries here.
- return matrix.block(field.base_ring(), n, blocks)
+ return matrix.block(field, n, blocks)
@staticmethod
if not n.mod(2).is_zero():
raise ValueError("the matrix 'M' must be a complex embedding")
- field = QQ
+ # If "M" was normalized, its base ring might have roots
+ # adjoined and they can stick around after unembedding.
+ field = M.base_ring()
R = PolynomialRing(field, 'z')
z = R.gen()
- F = NumberField(z**2 + 1,'i', embedding=CLF(-1).sqrt())
+ F = field.extension(z**2 + 1, 'i', embedding=CLF(-1).sqrt())
i = F.gen()
# Go top-left to bottom-right (reading order), converting every
sage: from mjo.eja.eja_algebra import ComplexHermitianEJA
+ EXAMPLES:
+
+ In theory, our "field" can be any subfield of the reals::
+
+ sage: ComplexHermitianEJA(2,AA)
+ Euclidean Jordan algebra of dimension 4 over Algebraic Real Field
+ sage: ComplexHermitianEJA(2,RR)
+ Euclidean Jordan algebra of dimension 4 over Real Field with
+ 53 bits of precision
+
TESTS:
The dimension of this algebra is `n^2`::
True
"""
- R = PolynomialRing(QQ, 'z')
+ R = PolynomialRing(field, 'z')
z = R.gen()
- F = NumberField(z**2 + 1, 'I', embedding=CLF(-1).sqrt())
+ F = field.extension(z**2 + 1, 'I')
I = F.gen()
# This is like the symmetric case, but we need to be careful:
if M.ncols() != n:
raise ValueError("the matrix 'M' must be square")
if not n.mod(4).is_zero():
- raise ValueError("the matrix 'M' must be a complex embedding")
+ raise ValueError("the matrix 'M' must be a quaternion embedding")
# Use the base ring of the matrix to ensure that its entries can be
# multiplied by elements of the quaternion algebra.