1481 | | sage: a = tensor((s[5],s[5])) |
1482 | | sage: pp(a) # used to yield p[[5]] # p[[5]] |
1483 | | Traceback (most recent call last): |
1484 | | ... |
1485 | | NotImplementedError |
| 1481 | sage: a = tensor((s[2],s[2])) |
| 1482 | |
| 1483 | The following originally used to yield ``p[[2]] # p[[2]]``, and if |
| 1484 | there was no natural coercion between ``s`` and ``p``, this would |
| 1485 | raise a ``NotImplementedError``. Since :trac:`15305`, this takes the |
| 1486 | coercion between ``s`` and ``p`` and lifts it to the tensor product. :: |
| 1487 | |
| 1488 | sage: pp(a) |
| 1489 | 1/4*p[1, 1] # p[1, 1] + 1/4*p[1, 1] # p[2] + 1/4*p[2] # p[1, 1] + 1/4*p[2] # p[2] |
| 2650 | def _coerce_map_from_(self, R): |
| 2651 | """ |
| 2652 | Return ``True`` if there is a coercion from ``R`` into ``self`` and |
| 2653 | ``False`` otherwise. The things that coerce into ``self`` are: |
| 2654 | |
| 2655 | - Anything with a coercion into ``self.base_ring()``. |
| 2656 | |
| 2657 | - A tensor algebra whose factors have a coercion into the |
| 2658 | corresponding factors of ``self``. |
| 2659 | |
| 2660 | TESTS:: |
| 2661 | |
| 2662 | sage: C = CombinatorialFreeModule(ZZ, ZZ) |
| 2663 | sage: C2 = CombinatorialFreeModule(ZZ, NN) |
| 2664 | sage: M = C.module_morphism(lambda x: C2.monomial(abs(x)), codomain=C2) |
| 2665 | sage: M.register_as_coercion() |
| 2666 | sage: C2(C.basis()[3]) |
| 2667 | B[3] |
| 2668 | sage: C2(C.basis()[3] + C.basis()[-3]) |
| 2669 | 2*B[3] |
| 2670 | sage: S = C.tensor(C) |
| 2671 | sage: S2 = C2.tensor(C2) |
| 2672 | sage: S2.has_coerce_map_from(S) |
| 2673 | True |
| 2674 | sage: S.has_coerce_map_from(S2) |
| 2675 | False |
| 2676 | sage: S.an_element() |
| 2677 | 3*B[0] # B[-1] + 2*B[0] # B[0] + 2*B[0] # B[1] |
| 2678 | sage: S2(S.an_element()) |
| 2679 | 2*B[0] # B[0] + 5*B[0] # B[1] |
| 2680 | |
| 2681 | :: |
| 2682 | |
| 2683 | sage: C = CombinatorialFreeModule(ZZ, Set([1,2])) |
| 2684 | sage: D = CombinatorialFreeModule(ZZ, Set([2,4])) |
| 2685 | sage: f = C.module_morphism(on_basis=lambda x: D.monomial(2*x), codomain=D) |
| 2686 | sage: f.register_as_coercion() |
| 2687 | sage: T = tensor((C,C)) |
| 2688 | sage: p = D.an_element() |
| 2689 | sage: T(tensor((p,p))) |
| 2690 | Traceback (most recent call last): |
| 2691 | ... |
| 2692 | NotImplementedError |
| 2693 | sage: T = tensor((D,D)) |
| 2694 | sage: p = C.an_element() |
| 2695 | sage: T(tensor((p,p))) |
| 2696 | 4*B[2] # B[2] + 4*B[2] # B[4] + 4*B[4] # B[2] + 4*B[4] # B[4] |
| 2697 | """ |
| 2698 | if R in ModulesWithBasis(self.base_ring()).TensorProducts() \ |
| 2699 | and isinstance(R, CombinatorialFreeModule_Tensor) \ |
| 2700 | and len(R._sets) == len(self._sets) \ |
| 2701 | and all(self._sets[i].has_coerce_map_from(M) |
| 2702 | for i,M in enumerate(R._sets)): |
| 2703 | modules = R._sets |
| 2704 | vector_map = [self._sets[i].coerce_map_from(M) |
| 2705 | for i,M in enumerate(modules)] |
| 2706 | return R.module_morphism(lambda x: self._tensor_of_elements( |
| 2707 | [vector_map[i](M.monomial(x[i])) |
| 2708 | for i,M in enumerate(modules)]), |
| 2709 | codomain=self) |
| 2710 | |
| 2711 | return super(CombinatorialFreeModule_Tensor, self)._coerce_map_from_(R) |
| 2712 | |