associative=False,
check_field=True,
check_axioms=True,
- prefix='e'):
+ prefix='e',
+ category=None):
if check_field:
if not field.is_subring(RR):
raise ValueError("inner-product is not commutative")
- category = MagmaticAlgebras(field).FiniteDimensional()
- category = category.WithBasis().Unital()
- if associative:
- # Element subalgebras can take advantage of this.
- category = category.Associative()
+ if category is None:
+ category = MagmaticAlgebras(field).FiniteDimensional()
+ category = category.WithBasis().Unital()
+ if associative:
+ # Element subalgebras can take advantage of this.
+ category = category.Associative()
# Call the superclass constructor so that we can use its from_vector()
# method to build our multiplication table.
The ability to retrieve the original factors is implemented by our
CombinatorialFreeModule Cartesian product superclass::
- sage: J1 = HadamardEJA(2, field=QQ)
- sage: J2 = JordanSpinEJA(3, field=QQ)
- sage: J = cartesian_product([J1,J2])
- sage: J.cartesian_factors()
- (Euclidean Jordan algebra of dimension 2 over Rational Field,
- Euclidean Jordan algebra of dimension 3 over Rational Field)
+ sage: J1 = HadamardEJA(2, field=QQ)
+ sage: J2 = JordanSpinEJA(3, field=QQ)
+ sage: J = cartesian_product([J1,J2])
+ sage: J.cartesian_factors()
+ (Euclidean Jordan algebra of dimension 2 over Rational Field,
+ Euclidean Jordan algebra of dimension 3 over Rational Field)
+
+ You can provide more than two factors::
+
+ sage: J1 = HadamardEJA(2)
+ sage: J2 = JordanSpinEJA(3)
+ sage: J3 = RealSymmetricEJA(3)
+ sage: cartesian_product([J1,J2,J3])
+ Euclidean Jordan algebra of dimension 2 over Algebraic Real
+ Field (+) Euclidean Jordan algebra of dimension 3 over Algebraic
+ Real Field (+) Euclidean Jordan algebra of dimension 6 over
+ Algebraic Real Field
TESTS:
Traceback (most recent call last):
...
ValueError: all factors must share the same base field
+
"""
def __init__(self, modules, **kwargs):
- CombinatorialFreeModule_CartesianProduct.__init__(self, modules, **kwargs)
+ CombinatorialFreeModule_CartesianProduct.__init__(self,
+ modules,
+ **kwargs)
field = modules[0].base_ring()
if not all( J.base_ring() == field for J in modules ):
raise ValueError("all factors must share the same base field")
- M = cartesian_product( [J.matrix_space() for J in modules] )
-
- m = len(modules)
- W = VectorSpace(field,m)
- self._matrix_basis = []
- for k in range(m):
- for a in modules[k].matrix_basis():
- v = W.zero().list()
- v[k] = a
- self._matrix_basis.append(M(v))
-
- self._matrix_basis = tuple(self._matrix_basis)
-
- n = len(self._matrix_basis)
+ basis = tuple( b.to_vector().column() for b in self.basis() )
+
+ # Define jordan/inner products that operate on the basis.
+ def jordan_product(x_mat,y_mat):
+ x = self.from_vector(_mat2vec(x_mat))
+ y = self.from_vector(_mat2vec(y_mat))
+ return self.cartesian_jordan_product(x,y).to_vector().column()
+
+ def inner_product(x_mat, y_mat):
+ x = self.from_vector(_mat2vec(x_mat))
+ y = self.from_vector(_mat2vec(y_mat))
+ return self.cartesian_inner_product(x,y)
+
+ FiniteDimensionalEJA.__init__(self,
+ basis,
+ jordan_product,
+ inner_product,
+ field=field,
+ orthonormalize=False,
+ check_field=False,
+ check_axioms=False,
+ category=self.category())
# TODO:
#
# Initialize the FDEJA class, too. Does this override the
return FiniteDimensionalEJAOperator(Ji,self,Ei.matrix())
+ def cartesian_jordan_product(self, x, y):
+ r"""
+ The componentwise Jordan product.
+
+ We project ``x`` and ``y`` onto our factors, and add up the
+ Jordan products from the subalgebras. This may still be useful
+ after (if) the default Jordan product in the Cartesian product
+ algebra is overridden.
+
+ SETUP::
+
+ sage: from mjo.eja.eja_algebra import (HadamardEJA,
+ ....: JordanSpinEJA)
+
+ EXAMPLE::
+
+ sage: J1 = HadamardEJA(3)
+ sage: J2 = JordanSpinEJA(3)
+ sage: J = cartesian_product([J1,J2])
+ sage: x1 = J1.from_vector(vector(QQ,(1,2,1)))
+ sage: y1 = J1.from_vector(vector(QQ,(1,0,2)))
+ sage: x2 = J2.from_vector(vector(QQ,(1,2,3)))
+ sage: y2 = J2.from_vector(vector(QQ,(1,1,1)))
+ sage: z1 = J.from_vector(vector(QQ,(1,2,1,1,2,3)))
+ sage: z2 = J.from_vector(vector(QQ,(1,0,2,1,1,1)))
+ sage: (x1*y1).to_vector()
+ (1, 0, 2)
+ sage: (x2*y2).to_vector()
+ (6, 3, 4)
+ sage: J.cartesian_jordan_product(z1,z2).to_vector()
+ (1, 0, 2, 6, 3, 4)
+
+ """
+ m = len(self.cartesian_factors())
+ projections = ( self.cartesian_projection(i) for i in range(m) )
+ products = ( P(x)*P(y) for P in projections )
+ return self._cartesian_product_of_elements(tuple(products))
+
+ def cartesian_inner_product(self, x, y):
+ r"""
+ The standard componentwise Cartesian inner-product.
+
+ We project ``x`` and ``y`` onto our factors, and add up the
+ inner-products from the subalgebras. This may still be useful
+ after (if) the default inner product in the Cartesian product
+ algebra is overridden.
+
+ SETUP::
+
+ sage: from mjo.eja.eja_algebra import (HadamardEJA,
+ ....: QuaternionHermitianEJA)
+
+ EXAMPLE::
+
+ sage: J1 = HadamardEJA(3,field=QQ)
+ sage: J2 = QuaternionHermitianEJA(2,field=QQ,orthonormalize=False)
+ sage: J = cartesian_product([J1,J2])
+ sage: x1 = J1.one()
+ sage: x2 = x1
+ sage: y1 = J2.one()
+ sage: y2 = y1
+ sage: x1.inner_product(x2)
+ 3
+ sage: y1.inner_product(y2)
+ 2
+ sage: z1 = J._cartesian_product_of_elements((x1,y1))
+ sage: z2 = J._cartesian_product_of_elements((x2,y2))
+ sage: J.cartesian_inner_product(z1,z2)
+ 5
+
+ """
+ m = len(self.cartesian_factors())
+ projections = ( self.cartesian_projection(i) for i in range(m) )
+ return sum( P(x).inner_product(P(y)) for P in projections )
+
+
FiniteDimensionalEJA.CartesianProduct = CartesianProductEJA
# iota_right = FiniteDimensionalEJAOperator(J2,self,I2)
# return (iota_left, iota_right)
-# def inner_product(self, x, y):
-# r"""
-# The standard Cartesian inner-product.
-
-# We project ``x`` and ``y`` onto our factors, and add up the
-# inner-products from the subalgebras.
-
-# SETUP::
-
-
-# sage: from mjo.eja.eja_algebra import (HadamardEJA,
-# ....: QuaternionHermitianEJA,
-# ....: DirectSumEJA)
-
-# EXAMPLE::
-
-# 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
-# sage: y1 = J2.one()
-# sage: y2 = y1
-# sage: x1.inner_product(x2)
-# 3
-# sage: y1.inner_product(y2)
-# 2
-# sage: J.one().inner_product(J.one())
-# 5
-
-# """
-# (pi_left, pi_right) = self.projections()
-# x1 = pi_left(x)
-# x2 = pi_right(x)
-# y1 = pi_left(y)
-# y2 = pi_right(y)
-
-# return (x1.inner_product(y1) + x2.inner_product(y2))