The ``field`` we're given must be real with ``check_field=True``::
- sage: JordanSpinEJA(2, QQbar)
+ sage: JordanSpinEJA(2, field=QQbar)
Traceback (most recent call last):
...
ValueError: scalar field is not real
- sage: JordanSpinEJA(2, QQbar, check_field=False)
+ sage: JordanSpinEJA(2, field=QQbar, check_field=False)
Euclidean Jordan algebra of dimension 2 over Algebraic Field
The multiplication table must be square with ``check_axioms=True``::
sage: x = J.random_element()
sage: J(x.to_vector().column()) == x
True
+
"""
msg = "not an element of this algebra"
if elt == 0:
# Used to check whether or not something is zero in an inexact
# ring. This number is sufficient to allow the construction of
- # QuaternionHermitianEJA(2, RDF) with check_axioms=True.
+ # QuaternionHermitianEJA(2, field=RDF) with check_axioms=True.
epsilon = 1e-16
for i in range(self.dimension()):
sage: J = HadamardEJA(2)
sage: J.coordinate_polynomial_ring()
Multivariate Polynomial Ring in X1, X2...
- sage: J = RealSymmetricEJA(3,QQ,orthonormalize=False)
+ sage: J = RealSymmetricEJA(3,field=QQ,orthonormalize=False)
sage: J.coordinate_polynomial_ring()
Multivariate Polynomial Ring in X1, X2, X3, X4, X5, X6...
"""
def __init__(self,
- field,
basis,
jordan_product,
inner_product,
+ field=AA,
orthonormalize=True,
prefix='e',
category=None,
if not all( all(b_i in QQ for b_i in b.list()) for b in basis ):
raise TypeError("basis not rational")
+ # Temporary(?) hack to ensure that the matrix and vector bases
+ # are over the same ring.
+ basis = tuple( b.change_ring(field) for b in basis )
+
n = len(basis)
vector_basis = basis
# because they are necessarily defined with respect to
# ambient coordinates and not any particular basis.
self._rational_algebra = RationalBasisEuclideanJordanAlgebra(
- QQ,
basis,
jordan_product,
inner_product,
+ field=QQ,
orthonormalize=False,
prefix=prefix,
category=category,
In theory, our "field" can be any subfield of the reals::
- sage: RealSymmetricEJA(2, RDF)
+ sage: RealSymmetricEJA(2, field=RDF)
Euclidean Jordan algebra of dimension 3 over Real Double Field
- sage: RealSymmetricEJA(2, RR)
+ sage: RealSymmetricEJA(2, field=RR)
Euclidean Jordan algebra of dimension 3 over Real Field with
53 bits of precision
"""
@classmethod
- def _denormalized_basis(cls, n, field):
+ def _denormalized_basis(cls, n):
"""
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 = RealSymmetricEJA._denormalized_basis(n,QQ)
+ sage: B = RealSymmetricEJA._denormalized_basis(n)
sage: all( M.is_symmetric() for M in B)
True
S = []
for i in range(n):
for j in range(i+1):
- Eij = matrix(field, n, lambda k,l: k==i and l==j)
+ Eij = matrix(ZZ, n, lambda k,l: k==i and l==j)
if i == j:
Sij = Eij
else:
return 4 # Dimension 10
@classmethod
- def random_instance(cls, field=AA, **kwargs):
+ def random_instance(cls, **kwargs):
"""
Return a random instance of this type of algebra.
"""
n = ZZ.random_element(cls._max_random_instance_size() + 1)
- return cls(n, field, **kwargs)
+ return cls(n, **kwargs)
- def __init__(self, n, field=AA, **kwargs):
- basis = self._denormalized_basis(n, field)
- super(RealSymmetricEJA, self).__init__(field,
- basis,
+ def __init__(self, n, **kwargs):
+ super(RealSymmetricEJA, self).__init__(self._denormalized_basis(n),
self.jordan_product,
self.trace_inner_product,
**kwargs)
self.rank.set_cache(n)
- self.one.set_cache(self(matrix.identity(field,n)))
+ self.one.set_cache(self(matrix.identity(ZZ,n)))
class ComplexMatrixEuclideanJordanAlgebra(MatrixEuclideanJordanAlgebra):
In theory, our "field" can be any subfield of the reals::
- sage: ComplexHermitianEJA(2, RDF)
+ sage: ComplexHermitianEJA(2, field=RDF)
Euclidean Jordan algebra of dimension 4 over Real Double Field
- sage: ComplexHermitianEJA(2, RR)
+ sage: ComplexHermitianEJA(2, field=RR)
Euclidean Jordan algebra of dimension 4 over Real Field with
53 bits of precision
"""
@classmethod
- def _denormalized_basis(cls, n, field):
+ def _denormalized_basis(cls, n):
"""
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: field = QuadraticField(2, 'sqrt2')
- sage: B = ComplexHermitianEJA._denormalized_basis(n, field)
+ sage: B = ComplexHermitianEJA._denormalized_basis(n)
sage: all( M.is_symmetric() for M in B)
True
"""
+ field = ZZ
R = PolynomialRing(field, 'z')
z = R.gen()
F = field.extension(z**2 + 1, 'I')
- I = F.gen()
+ I = F.gen(1)
# This is like the symmetric case, but we need to be careful:
#
return tuple( s.change_ring(field) for s in S )
- def __init__(self, n, field=AA, **kwargs):
- basis = self._denormalized_basis(n,field)
- super(ComplexHermitianEJA, self).__init__(field,
- basis,
- self.jordan_product,
- self.trace_inner_product,
- **kwargs)
+ def __init__(self, n, **kwargs):
+ super(ComplexHermitianEJA, self).__init__(self._denormalized_basis(n),
+ self.jordan_product,
+ self.trace_inner_product,
+ **kwargs)
self.rank.set_cache(n)
# TODO: pre-cache the identity!
return 3 # Dimension 9
@classmethod
- def random_instance(cls, field=AA, **kwargs):
+ def random_instance(cls, **kwargs):
"""
Return a random instance of this type of algebra.
"""
n = ZZ.random_element(cls._max_random_instance_size() + 1)
- return cls(n, field, **kwargs)
+ return cls(n, **kwargs)
class QuaternionMatrixEuclideanJordanAlgebra(MatrixEuclideanJordanAlgebra):
@staticmethod
In theory, our "field" can be any subfield of the reals::
- sage: QuaternionHermitianEJA(2, RDF)
+ sage: QuaternionHermitianEJA(2, field=RDF)
Euclidean Jordan algebra of dimension 6 over Real Double Field
- sage: QuaternionHermitianEJA(2, RR)
+ sage: QuaternionHermitianEJA(2, field=RR)
Euclidean Jordan algebra of dimension 6 over Real Field with
53 bits of precision
"""
@classmethod
- def _denormalized_basis(cls, n, field):
+ def _denormalized_basis(cls, n):
"""
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 = QuaternionHermitianEJA._denormalized_basis(n,QQ)
+ sage: B = QuaternionHermitianEJA._denormalized_basis(n)
sage: all( M.is_symmetric() for M in B )
True
"""
+ field = ZZ
Q = QuaternionAlgebra(QQ,-1,-1)
I,J,K = Q.gens()
return tuple( s.change_ring(field) for s in S )
- def __init__(self, n, field=AA, **kwargs):
- basis = self._denormalized_basis(n,field)
- super(QuaternionHermitianEJA, self).__init__(field,
- basis,
+ def __init__(self, n, **kwargs):
+ super(QuaternionHermitianEJA, self).__init__(self._denormalized_basis(n),
self.jordan_product,
self.trace_inner_product,
**kwargs)
return 2 # Dimension 6
@classmethod
- def random_instance(cls, field=AA, **kwargs):
+ def random_instance(cls, **kwargs):
"""
Return a random instance of this type of algebra.
"""
n = ZZ.random_element(cls._max_random_instance_size() + 1)
- return cls(n, field, **kwargs)
+ return cls(n, **kwargs)
class HadamardEJA(ConcreteEuclideanJordanAlgebra):
(r0, r1, r2)
"""
- def __init__(self, n, field=AA, **kwargs):
- V = VectorSpace(field, n)
- basis = V.basis()
-
+ def __init__(self, n, **kwargs):
def jordan_product(x,y):
- return V([ xi*yi for (xi,yi) in zip(x,y) ])
+ P = x.parent()
+ return P(tuple( xi*yi for (xi,yi) in zip(x,y) ))
def inner_product(x,y):
return x.inner_product(y)
# Don't orthonormalize because our basis is already
- # orthonormal with respect to our inner-product. But also
- # don't pass check_field=False here, because the user can pass
- # in a field!
- super(HadamardEJA, self).__init__(field,
- basis,
+ # orthonormal with respect to our inner-product.
+ if not 'orthonormalize' in kwargs:
+ kwargs['orthonormalize'] = False
+
+ # But also don't pass check_field=False here, because the user
+ # can pass in a field!
+ standard_basis = FreeModule(ZZ, n).basis()
+ super(HadamardEJA, self).__init__(standard_basis,
jordan_product,
inner_product,
- orthonormalize=False,
check_axioms=False,
**kwargs)
self.rank.set_cache(n)
return 5
@classmethod
- def random_instance(cls, field=AA, **kwargs):
+ def random_instance(cls, **kwargs):
"""
Return a random instance of this type of algebra.
"""
n = ZZ.random_element(cls._max_random_instance_size() + 1)
- return cls(n, field, **kwargs)
+ return cls(n, **kwargs)
class BilinearFormEJA(ConcreteEuclideanJordanAlgebra):
sage: actual == expected
True
"""
- def __init__(self, B, field=AA, **kwargs):
+ def __init__(self, B, **kwargs):
if not B.is_positive_definite():
raise ValueError("bilinear form is not positive-definite")
- n = B.nrows()
- V = VectorSpace(field, n)
-
def inner_product(x,y):
return (B*x).inner_product(y)
def jordan_product(x,y):
+ P = x.parent()
x0 = x[0]
xbar = x[1:]
y0 = y[0]
ybar = y[1:]
z0 = inner_product(x,y)
zbar = y0*xbar + x0*ybar
- return V([z0] + zbar.list())
+ return P((z0,) + tuple(zbar))
- super(BilinearFormEJA, self).__init__(field,
- V.basis(),
+ n = B.nrows()
+ standard_basis = FreeModule(ZZ, n).basis()
+ super(BilinearFormEJA, self).__init__(standard_basis,
jordan_product,
inner_product,
**kwargs)
return 5
@classmethod
- def random_instance(cls, field=AA, **kwargs):
+ def random_instance(cls, **kwargs):
"""
Return a random instance of this algebra.
"""
n = ZZ.random_element(cls._max_random_instance_size() + 1)
if n.is_zero():
- B = matrix.identity(field, n)
- return cls(B, field, **kwargs)
+ B = matrix.identity(ZZ, n)
+ return cls(B, **kwargs)
- B11 = matrix.identity(field,1)
- M = matrix.random(field, n-1)
- I = matrix.identity(field, n-1)
- alpha = field.zero()
+ B11 = matrix.identity(ZZ, 1)
+ M = matrix.random(ZZ, n-1)
+ I = matrix.identity(ZZ, n-1)
+ alpha = ZZ.zero()
while alpha.is_zero():
- alpha = field.random_element().abs()
+ alpha = ZZ.random_element().abs()
B22 = M.transpose()*M + alpha*I
from sage.matrix.special import block_matrix
B = block_matrix(2,2, [ [B11, ZZ(0) ],
[ZZ(0), B22 ] ])
- return cls(B, field, **kwargs)
+ return cls(B, **kwargs)
class JordanSpinEJA(BilinearFormEJA):
True
"""
- def __init__(self, n, field=AA, **kwargs):
+ def __init__(self, n, **kwargs):
# This is a special case of the BilinearFormEJA with the
# identity matrix as its bilinear form.
- B = matrix.identity(field, n)
+ B = matrix.identity(ZZ, n)
# Don't orthonormalize because our basis is already
- # orthonormal with respect to our inner-product. But
- # also don't pass check_field=False here, because the
- # user can pass in a field!
+ # orthonormal with respect to our inner-product.
+ if not 'orthonormalize' in kwargs:
+ kwargs['orthonormalize'] = False
+
+ # But also don't pass check_field=False here, because the user
+ # can pass in a field!
super(JordanSpinEJA, self).__init__(B,
- field,
- orthonormalize=False,
check_axioms=False,
**kwargs)
return 5
@classmethod
- def random_instance(cls, field=AA, **kwargs):
+ def random_instance(cls, **kwargs):
"""
Return a random instance of this type of algebra.
Needed here to override the implementation for ``BilinearFormEJA``.
"""
n = ZZ.random_element(cls._max_random_instance_size() + 1)
- return cls(n, field, **kwargs)
+ return cls(n, **kwargs)
class TrivialEJA(ConcreteEuclideanJordanAlgebra):
0
"""
- def __init__(self, field=AA, **kwargs):
+ def __init__(self, **kwargs):
jordan_product = lambda x,y: x
- inner_product = lambda x,y: field(0)
+ inner_product = lambda x,y: 0
basis = ()
- super(TrivialEJA, self).__init__(field,
- basis,
+ super(TrivialEJA, self).__init__(basis,
jordan_product,
inner_product,
**kwargs)
self.one.set_cache( self.zero() )
@classmethod
- def random_instance(cls, field=AA, **kwargs):
+ def random_instance(cls, **kwargs):
# We don't take a "size" argument so the superclass method is
# inappropriate for us.
- return cls(field, **kwargs)
+ return cls(**kwargs)
class DirectSumEJA(FiniteDimensionalEuclideanJordanAlgebra):
r"""
have the same base ring; an error is raised otherwise::
sage: set_random_seed()
- sage: J1 = random_eja(AA)
- sage: J2 = random_eja(QQ,orthonormalize=False)
+ sage: J1 = random_eja(field=AA)
+ sage: J2 = random_eja(field=QQ,orthonormalize=False)
sage: J = DirectSumEJA(J1,J2)
Traceback (most recent call last):
...
EXAMPLES::
- sage: J1 = HadamardEJA(2,QQ)
- sage: J2 = JordanSpinEJA(3,QQ)
+ sage: J1 = HadamardEJA(2, field=QQ)
+ sage: J2 = JordanSpinEJA(3, field=QQ)
sage: J = DirectSumEJA(J1,J2)
sage: J.factors()
(Euclidean Jordan algebra of dimension 2 over Rational Field,
EXAMPLE::
- sage: J1 = HadamardEJA(3,QQ)
- sage: J2 = QuaternionHermitianEJA(2,QQ,orthonormalize=False)
+ sage: J1 = HadamardEJA(3,field=QQ)
+ sage: J2 = QuaternionHermitianEJA(2,field=QQ,orthonormalize=False)
sage: J = DirectSumEJA(J1,J2)
sage: x1 = J1.one()
sage: x2 = x1