# we've specified a real embedding.
raise ValueError("scalar field is not real")
- from mjo.eja.eja_utils import _change_ring
- # If the basis given to us wasn't over the field that it's
- # supposed to be over, fix that. Or, you know, crash.
- basis = tuple( _change_ring(b, field) for b in basis )
-
if check_axioms:
# Check commutativity of the Jordan and inner-products.
# This has to be done before we build the multiplication
"""
@classmethod
- def _denormalized_basis(cls, n):
+ def _denormalized_basis(cls, n, field):
"""
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)
+ sage: B = RealSymmetricEJA._denormalized_basis(n,ZZ)
sage: all( M.is_symmetric() for M in B)
True
S = []
for i in range(n):
for j in range(i+1):
- Eij = matrix(ZZ, n, lambda k,l: k==i and l==j)
+ Eij = matrix(field, n, lambda k,l: k==i and l==j)
if i == j:
Sij = Eij
else:
n = ZZ.random_element(cls._max_random_instance_size() + 1)
return cls(n, **kwargs)
- def __init__(self, n, **kwargs):
+ def __init__(self, n, field=AA, **kwargs):
# We know this is a valid EJA, but will double-check
# if the user passes check_axioms=True.
if "check_axioms" not in kwargs: kwargs["check_axioms"] = False
if n <= 1:
associative = True
- super().__init__(self._denormalized_basis(n),
+ super().__init__(self._denormalized_basis(n,field),
self.jordan_product,
self.trace_inner_product,
+ field=field,
associative=associative,
**kwargs)
"""
@classmethod
- def _denormalized_basis(cls, n):
+ def _denormalized_basis(cls, n, field):
"""
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: B = ComplexHermitianEJA._denormalized_basis(n)
+ sage: B = ComplexHermitianEJA._denormalized_basis(n,ZZ)
sage: all( M.is_symmetric() for M in B)
True
"""
- field = ZZ
- R = PolynomialRing(field, 'z')
+ R = PolynomialRing(ZZ, 'z')
z = R.gen()
- F = field.extension(z**2 + 1, 'I')
+ F = ZZ.extension(z**2 + 1, 'I')
I = F.gen(1)
# This is like the symmetric case, but we need to be careful:
# "erase" E_ij
Eij[i,j] = 0
- # Since we embedded these, we can drop back to the "field" that we
- # started with instead of the complex extension "F".
+ # Since we embedded the entries, we can drop back to the
+ # desired real "field" instead of the extension "F".
return tuple( s.change_ring(field) for s in S )
- def __init__(self, n, **kwargs):
+ def __init__(self, n, field=AA, **kwargs):
# We know this is a valid EJA, but will double-check
# if the user passes check_axioms=True.
if "check_axioms" not in kwargs: kwargs["check_axioms"] = False
if n <= 1:
associative = True
- super().__init__(self._denormalized_basis(n),
+ super().__init__(self._denormalized_basis(n,field),
self.jordan_product,
self.trace_inner_product,
+ field=field,
associative=associative,
**kwargs)
# TODO: this could be factored out somehow, but is left here
"""
@classmethod
- def _denormalized_basis(cls, n):
+ def _denormalized_basis(cls, n, field):
"""
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)
+ sage: B = QuaternionHermitianEJA._denormalized_basis(n,ZZ)
sage: all( M.is_symmetric() for M in B )
True
"""
- field = ZZ
Q = QuaternionAlgebra(QQ,-1,-1)
I,J,K = Q.gens()
# "erase" E_ij
Eij[i,j] = 0
- # Since we embedded these, we can drop back to the "field" that we
- # started with instead of the quaternion algebra "Q".
+ # Since we embedded the entries, we can drop back to the
+ # desired real "field" instead of the quaternion algebra "Q".
return tuple( s.change_ring(field) for s in S )
- def __init__(self, n, **kwargs):
+ def __init__(self, n, field=AA, **kwargs):
# We know this is a valid EJA, but will double-check
# if the user passes check_axioms=True.
if "check_axioms" not in kwargs: kwargs["check_axioms"] = False
if n <= 1:
associative = True
- super().__init__(self._denormalized_basis(n),
+ super().__init__(self._denormalized_basis(n,field),
self.jordan_product,
self.trace_inner_product,
+ field=field,
associative=associative,
**kwargs)
(r0, r1, r2)
"""
- def __init__(self, n, **kwargs):
+ def __init__(self, n, field=AA, **kwargs):
if n == 0:
jordan_product = lambda x,y: x
inner_product = lambda x,y: x
if "orthonormalize" not in kwargs: kwargs["orthonormalize"] = False
if "check_axioms" not in kwargs: kwargs["check_axioms"] = False
- column_basis = tuple( b.column() for b in FreeModule(ZZ, n).basis() )
+ column_basis = tuple( b.column()
+ for b in FreeModule(field, n).basis() )
super().__init__(column_basis,
jordan_product,
inner_product,
+ field=field,
associative=True,
**kwargs)
self.rank.set_cache(n)
True
"""
- def __init__(self, B, **kwargs):
+ def __init__(self, B, field=AA, **kwargs):
# The matrix "B" is supplied by the user in most cases,
# so it makes sense to check whether or not its positive-
# definite unless we are specifically asked not to...
return P([z0] + zbar.list())
n = B.nrows()
- column_basis = tuple( b.column() for b in FreeModule(ZZ, n).basis() )
+ column_basis = tuple( b.column()
+ for b in FreeModule(field, n).basis() )
# TODO: I haven't actually checked this, but it seems legit.
associative = False
super().__init__(column_basis,
jordan_product,
inner_product,
+ field=field,
associative=associative,
**kwargs)
True
"""
- def __init__(self, n, **kwargs):
+ def __init__(self, n, *args, **kwargs):
# This is a special case of the BilinearFormEJA with the
# identity matrix as its bilinear form.
B = matrix.identity(ZZ, n)
# But also don't pass check_field=False here, because the user
# can pass in a field!
- super().__init__(B, **kwargs)
+ super().__init__(B, *args, **kwargs)
@staticmethod
def _max_random_instance_size():
from sage.matrix.constructor import matrix
from sage.modules.free_module_element import vector
-def _change_ring(x, R):
- r"""
- Change the ring of a vector, matrix, or a cartesian product of
- those things.
-
- SETUP::
-
- sage: from mjo.eja.eja_utils import _change_ring
-
- EXAMPLES::
-
- sage: v = vector(QQ, (1,2,3))
- sage: m = matrix(QQ, [[1,2],[3,4]])
- sage: _change_ring(v, RDF)
- (1.0, 2.0, 3.0)
- sage: _change_ring(m, RDF)
- [1.0 2.0]
- [3.0 4.0]
- sage: _change_ring((v,m), RDF)
- (
- [1.0 2.0]
- (1.0, 2.0, 3.0), [3.0 4.0]
- )
- sage: V1 = cartesian_product([v.parent(), v.parent()])
- sage: V = cartesian_product([v.parent(), V1])
- sage: V((v, (v, v)))
- ((1, 2, 3), ((1, 2, 3), (1, 2, 3)))
- sage: _change_ring(V((v, (v, v))), RDF)
- ((1.0, 2.0, 3.0), ((1.0, 2.0, 3.0), (1.0, 2.0, 3.0)))
-
- """
- try:
- return x.change_ring(R)
- except AttributeError:
- try:
- from sage.categories.sets_cat import cartesian_product
- if hasattr(x, 'element_class'):
- # x is a parent and we're in a recursive call.
- return cartesian_product( [_change_ring(x_i, R)
- for x_i in x.cartesian_factors()] )
- else:
- # x is an element, and we want to change the ring
- # of its parent.
- P = x.parent()
- Q = cartesian_product( [_change_ring(P_i, R)
- for P_i in P.cartesian_factors()] )
- return Q(x)
- except AttributeError:
- # No parent for x
- return x.__class__( _change_ring(x_i, R) for x_i in x )
-
def _scale(x, alpha):
r"""
Scale the vector, matrix, or cartesian-product-of-those-things