"""
self._rank = rank
self._natural_basis = natural_basis
- self._multiplication_table = mult_table
+
if category is None:
category = FiniteDimensionalAlgebrasWithBasis(field).Unital()
fda = super(FiniteDimensionalEuclideanJordanAlgebra, self)
category=category)
self.print_options(bracket='')
+ # The multiplication table we're given is necessarily in terms
+ # of vectors, because we don't have an algebra yet for
+ # anything to be an element of. However, it's faster in the
+ # long run to have the multiplication table be in terms of
+ # algebra elements. We do this after calling the superclass
+ # constructor so that from_vector() knows what to do.
+ self._multiplication_table = [ map(lambda x: self.from_vector(x), ls)
+ for ls in mult_table ]
+
def _element_constructor_(self, elt):
"""
return fmt.format(self.dimension(), self.base_ring())
def product_on_basis(self, i, j):
- ei = self.basis()[i]
- ej = self.basis()[j]
- Lei = self._multiplication_table[i]
- return self.from_vector(Lei*ej.to_vector())
+ return self._multiplication_table[i][j]
def _a_regular_element(self):
"""
# Construct a new algebra over a multivariate polynomial ring...
names = tuple('X' + str(i) for i in range(1,n+1))
R = PolynomialRing(self.base_ring(), names)
- J = FiniteDimensionalEuclideanJordanAlgebra(
- R,
- tuple(self._multiplication_table),
- r)
+ # Hack around the fact that our multiplication table is in terms of
+ # algebra elements but the constructor wants it in terms of vectors.
+ vmt = [ tuple(map(lambda x: x.to_vector(), ls))
+ for ls in self._multiplication_table ]
+ J = FiniteDimensionalEuclideanJordanAlgebra(R, tuple(vmt), r)
idmat = matrix.identity(J.base_ring(), n)
"""
def __init__(self, n, field=QQ):
- # The superclass constructor takes a list of matrices, the ith
- # representing right multiplication by the ith basis element
- # in the vector space. So if e_1 = (1,0,0), then right
- # (Hadamard) multiplication of x by e_1 picks out the first
- # component of x; and likewise for the ith basis element e_i.
- Qs = [ matrix(field, n, n, lambda k,j: 1*(k == j == i))
- for i in xrange(n) ]
+ V = VectorSpace(field, n)
+ mult_table = [ [ V.basis()[i]*(i == j) for i in range(n) ]
+ for j in range(n) ]
fdeja = super(RealCartesianProductEJA, self)
- return fdeja.__init__(field, Qs, rank=n)
+ return fdeja.__init__(field, mult_table, rank=n)
def inner_product(self, x, y):
return _usual_ip(x,y)
multiplication on the right is matrix multiplication. Given a basis
for the underlying matrix space, this function returns a
multiplication table (obtained by looping through the basis
- elements) for an algebra of those matrices. A reordered copy
- of the basis is also returned to work around the fact that
- the ``span()`` in this function will change the order of the basis
- from what we think it is, to... something else.
+ elements) for an algebra of those matrices.
"""
# In S^2, for example, we nominally have four coordinates even
# though the space is of dimension three only. The vector space V
V = VectorSpace(field, dimension**2)
W = V.span_of_basis( _mat2vec(s) for s in basis )
+ n = len(basis)
+ mult_table = [[W.zero() for i in range(n)] for j in range(n)]
+ for i in range(n):
+ for j in range(n):
+ mat_entry = (basis[i]*basis[j] + basis[j]*basis[i])/2
+ mult_table[i][j] = W.coordinate_vector(_mat2vec(mat_entry))
- Qs = []
- for s in basis:
- # Brute force the multiplication-by-s matrix by looping
- # through all elements of the basis and doing the computation
- # to find out what the corresponding row should be.
- Q_cols = []
- for t in basis:
- this_col = _mat2vec((s*t + t*s)/2)
- Q_cols.append(W.coordinates(this_col))
- Q = matrix.column(field, W.dimension(), Q_cols)
- Qs.append(Q)
-
- return Qs
+ return mult_table
def _embed_complex_matrix(M):
"""
def __init__(self, n, field=QQ):
- Qs = []
- id_matrix = matrix.identity(field, n)
- for i in xrange(n):
- ei = id_matrix.column(i)
- Qi = matrix.zero(field, n)
- Qi.set_row(0, ei)
- Qi.set_column(0, ei)
- Qi += matrix.diagonal(n, [ei[0]]*n)
- # The addition of the diagonal matrix adds an extra ei[0] in the
- # upper-left corner of the matrix.
- Qi[0,0] = Qi[0,0] * ~field(2)
- Qs.append(Qi)
+ V = VectorSpace(field, n)
+ mult_table = [[V.zero() for i in range(n)] for j in range(n)]
+ for i in range(n):
+ for j in range(n):
+ x = V.basis()[i]
+ y = V.basis()[j]
+ x0 = x[0]
+ xbar = x[1:]
+ y0 = y[0]
+ ybar = y[1:]
+ # z = x*y
+ z0 = x.inner_product(y)
+ zbar = y0*xbar + x0*ybar
+ z = V([z0] + zbar.list())
+ mult_table[i][j] = z
# The rank of the spin algebra is two, unless we're in a
# one-dimensional ambient space (because the rank is bounded by
# the ambient dimension).
fdeja = super(JordanSpinEJA, self)
- return fdeja.__init__(field, Qs, rank=min(n,2))
+ return fdeja.__init__(field, mult_table, rank=min(n,2))
def inner_product(self, x, y):
return _usual_ip(x,y)
# matrix for the successive basis elements b0, b1,... of
# that subspace.
field = superalgebra.base_ring()
- mult_table = []
- for b_right in superalgebra_basis:
- b_right_cols = []
- # The first column of the left-multiplication matrix by
- # b1 is what we get if we apply that matrix to b1. The
- # second column of the left-multiplication matrix by b1
- # is what we get when we apply that matrix to b2...
- for b_left in superalgebra_basis:
- # Multiply in the original EJA, but then get the
- # coordinates from the subalgebra in terms of its
- # basis.
- this_col = W.coordinates((b_left*b_right).to_vector())
- b_right_cols.append(this_col)
- b_right_matrix = matrix.column(field, b_right_cols)
- mult_table.append(b_right_matrix)
-
- for m in mult_table:
- m.set_immutable()
- mult_table = tuple(mult_table)
+ n = len(superalgebra_basis)
+ mult_table = [[W.zero() for i in range(n)] for j in range(n)]
+ for i in range(n):
+ for j in range(n):
+ product = superalgebra_basis[i]*superalgebra_basis[j]
+ mult_table[i][j] = W.coordinate_vector(product.to_vector())
# TODO: We'll have to redo this and make it unique again...
prefix = 'f'