1111
1212from sage .misc .cachefunc import cached_method
1313from sage .misc .lazy_attribute import lazy_attribute
14+ from sage .misc .abstract_method import abstract_method
15+ from sage .misc .constant_function import ConstantFunction
16+ from sage .misc .misc import compose
1417from sage .misc .lazy_import import LazyImport
1518from sage .categories .tensor import TensorProductsCategory , tensor
1619from sage .categories .cartesian_product import CartesianProductsCategory
@@ -193,6 +196,91 @@ def _product_from_combinatorial_algebra_multiply(self,left,right):
193196 # tester.assert_(self.product is not None)
194197 # could check that self.product is in Hom( self x self, self)
195198
199+ def _product_on_basis_tuple (self , tup ):
200+ return self .product_on_basis (* tup )
201+
202+ def _product_on_tensor_basis (self ):
203+ r"""
204+ Return the function whose sole input is an index for the tensor square of ``self``,
205+ and whose output is the product of monomials indexed by the corresponding pair of basis elements.
206+
207+ EXAMPLES::
208+
209+ sage: W=WeylGroup("A2",prefix="s")
210+ sage: A = W.algebra(ZZ)
211+ sage: AA = tensor([A,A])
212+ sage: k = AA.basis().keys().an_element(); k
213+ (s1*s2*s1, s1*s2*s1)
214+ sage: A._product_on_tensor_basis()(k)
215+ B[1]
216+ sage: AAAA = tensor([AA,AA])
217+ sage: kk = AAAA.basis().keys().an_element(); kk
218+ (s1*s2*s1, s1*s2*s1, s1*s2*s1, s1*s2*s1)
219+ sage: AA._product_on_tensor_basis()(kk)
220+ B[1] # B[1]
221+
222+ """
223+ # The algebra tensor product has functions which handle basis indices
224+ AA = tensor ([self ,self ])
225+ return compose (self ._product_on_basis_tuple , AA .index_to_indices ())
226+
227+ def _product_morphism (self ):
228+ r"""
229+ The multiplication map as a module morphism from the twofold tensor of ``self``, to ``self``.
230+
231+ EXAMPLES::
232+
233+ sage: W = WeylGroup(CartanType(['A',2]),prefix="s")
234+ sage: A = W.algebra(ZZ); A.rename("A")
235+ sage: mA = A._product_morphism(); mA
236+ Generic morphism:
237+ From: A # A
238+ To: A
239+ sage: a = A.monomial(W.from_reduced_word([1,2])); a
240+ B[s1*s2]
241+ sage: b = A.an_element(); b
242+ B[s1*s2*s1] + 3*B[s1*s2] + 3*B[s2*s1]
243+ sage: ab = tensor([a,b]); ab
244+ B[s1*s2] # B[s1*s2*s1] + 3*B[s1*s2] # B[s1*s2] + 3*B[s1*s2] # B[s2*s1]
245+ sage: mA(mA.domain()(ab))
246+ 3*B[s2*s1] + B[s2] + 3*B[1]
247+ sage: a*b
248+ 3*B[s2*s1] + B[s2] + 3*B[1]
249+ sage: AA = tensor([A,A])
250+ sage: mAA = AA._product_morphism()
251+ sage: mAA(mAA.domain()(tensor([a,b,b,b])))
252+ 27*B[s2*s1] # B[s1*s2] + 27*B[s2*s1] # B[s2*s1] + 18*B[s2*s1] # B[s1] + 18*B[s2*s1] # B[s2] + 57*B[s2*s1] # B[1] + 9*B[s2] # B[s1*s2] + 9*B[s2] # B[s2*s1] + 6*B[s2] # B[s1] + 6*B[s2] # B[s2] + 19*B[s2] # B[1] + 27*B[1] # B[s1*s2] + 27*B[1] # B[s2*s1] + 18*B[1] # B[s1] + 18*B[1] # B[s2] + 57*B[1] # B[1]
253+
254+ """
255+ from sage .categories .modules_with_basis import ModulesWithBasis
256+ module_category = ModulesWithBasis (self .base_ring ())
257+ AA = tensor ([self , self ], category = module_category )
258+ return AA .module_morphism (on_basis = self ._product_on_tensor_basis (), codomain = self , category = module_category )
259+
260+ def _unit_morphism (self ):
261+ r"""
262+ The unit map as a module morphism from the base ring to ``self``.
263+
264+ Note that the domain is the tensor unit module,
265+ the base ring viewed as a free module.
266+
267+ EXAMPLES::
268+
269+ sage: W = WeylGroup(CartanType(['A',2]),prefix="s")
270+ sage: A = W.algebra(ZZ); A.rename("A")
271+ sage: unit = A._unit_morphism(); unit
272+ Generic morphism:
273+ From: The unit object in Category of tensor products of hopf algebras with basis over Integer Ring
274+ To: A
275+ sage: unit(3*unit.domain().one())
276+ 3*B[1]
277+
278+ """
279+ from sage .categories .modules_with_basis import ModulesWithBasis
280+ U = self .tensor_unit ()
281+ one_func = ConstantFunction (self .one ())
282+ return U .module_morphism (on_basis = one_func , codomain = self , category = ModulesWithBasis (self .base_ring ()))
283+
196284 class ElementMethods :
197285
198286 def __invert__ (self ):
@@ -328,8 +416,41 @@ def extra_super_categories(self):
328416
329417 class ParentMethods :
330418 """
331- implements operations on tensor products of algebras with basis
419+ Implements operations on tensor products of algebras with basis.
332420 """
421+ @abstract_method
422+ def factors (self ):
423+ r"""
424+ The tensor factor algebras of `self`.
425+
426+ EXAMPLES::
427+
428+ sage: W = WeylGroup("A2",prefix="s")
429+ sage: A = W.algebra(ZZ); A.rename("A")
430+ sage: A2 = tensor([A,A])
431+ sage: A22 = tensor([A2,A2])
432+ sage: A22.factors()
433+ (A # A, A # A)
434+ sage: A4 = tensor([A,A,A,A])
435+ sage: A4.factors()
436+ (A, A, A, A)
437+
438+ """
439+ pass
440+
441+ @abstract_method
442+ def index_to_indices (self ):
443+ r"""
444+ The function which maps a basis index of ``self`` to a tuple of basis indices for ``self.factors()``.
445+ """
446+ pass
447+
448+ @abstract_method
449+ def indices_to_index (self ):
450+ r"""
451+ The function which maps a tuple of basis indices for ``self.factors()`` to an index of ``self.basis()``.
452+ """
453+ pass
333454
334455 @cached_method
335456 def one_basis (self ):
@@ -353,11 +474,11 @@ def one_basis(self):
353474 sage: B.one()
354475 B[word: ] # B[word: ] # B[word: ]
355476 """
356- # FIXME: this method should be conditionaly defined,
477+ # FIXME: this method should be conditionally defined,
357478 # so that B.one_basis returns NotImplemented if not
358479 # all modules provide one_basis
359- if all (hasattr (module , "one_basis" ) for module in self ._sets ):
360- return tuple (module .one_basis () for module in self ._sets )
480+ if all (hasattr (module , "one_basis" ) for module in self .factors () ):
481+ return self . indices_to_index ()( * tuple (module .one_basis () for module in self .factors ()) )
361482 else :
362483 raise NotImplementedError
363484
@@ -386,10 +507,12 @@ def product_on_basis(self, t1, t2):
386507 sage: x*y
387508 B[word: a] # B[word: c] + B[word: ac] # B[word: ca] + 2*B[word: b] # B[word: c] + 2*B[word: bc] # B[word: ca]
388509
389-
390510 TODO: optimize this implementation!
511+
512+ FIX THIS EXAMPLE!!!
513+
391514 """
392- return tensor ( (module .monomial (x1 )* module .monomial (x2 ) for (module , x1 , x2 ) in zip (self ._sets , t1 , t2 )) ) #.
515+ return tensor ( (module .monomial (x1 )* module .monomial (x2 ) for (module , x1 , x2 ) in zip (self .factors (), self . index_to_indices ()( t1 ), self . index_to_indices ()( t2 ))) ) #.
393516
394517 class ElementMethods :
395518 """
0 commit comments