@@ -539,7 +539,9 @@ class :class:`~sage.modules.free_module.FreeModule_generic`
539539from typing import Generator , Optional
540540
541541from sage .categories .fields import Fields
542+ from sage .categories .homset import Hom
542543from sage .categories .modules import Modules
544+ from sage .categories .morphism import SetIsomorphism
543545from sage .categories .rings import Rings
544546from sage .misc .cachefunc import cached_method
545547from sage .rings .integer import Integer
@@ -755,15 +757,15 @@ def isomorphism_with_fixed_basis(self, basis=None, codomain=None):
755757 - ``codomain`` -- (default: ``None``) the codomain of the
756758 isomorphism represented by a free module within the category
757759 :class:`~sage.categories.modules_with_basis.ModulesWithBasis` with
758- the same rank and base ring as ``self``; if ``None`` a free module
760+ the same rank and base ring as ``self``; if ``None``, a free module
759761 represented by
760762 :class:`~sage.combinat.free_module.CombinatorialFreeModule` is
761763 constructed
762764
763765 OUTPUT:
764766
765- - a module morphism represented by
766- :class:`~sage.modules.with_basis. morphism.ModuleMorphismFromFunction `
767+ - a module isomorphism represented by
768+ :class:`~sage.categories. morphism.SetIsomorphism `
767769
768770 EXAMPLES::
769771
@@ -800,6 +802,12 @@ def isomorphism_with_fixed_basis(self, basis=None, codomain=None):
800802 To: Free module generated by {'a', 'b', 'c'} over Rational Field
801803 sage: phi_eW(e[1] + 2 * e[2])
802804 B['a'] + 2*B['b']
805+ sage: ~phi_eW
806+ Generic morphism:
807+ From: Free module generated by {'a', 'b', 'c'} over Rational Field
808+ To: 3-dimensional vector space over the Rational Field
809+ sage: (~phi_eW)(W.basis()['b']).display()
810+ e_2
803811
804812 Providing a :class:`~sage.modules.free_module.Module_free_ambient` as the codomain::
805813
@@ -814,44 +822,60 @@ def isomorphism_with_fixed_basis(self, basis=None, codomain=None):
814822 Sending (1,1)-tensors to matrices::
815823
816824 sage: T11 = V.tensor_module(1, 1); T11
817- Free module of type-(1,1) tensors on the 3-dimensional vector space over the Rational Field
825+ Free module of type-(1,1) tensors on the
826+ 3-dimensional vector space over the Rational Field
818827 sage: e_T11 = T11.basis("e"); e_T11
819828 Standard basis on the
820829 Free module of type-(1,1) tensors on the 3-dimensional vector space over the Rational Field
821830 induced by Basis (e_1,e_2,e_3) on the 3-dimensional vector space over the Rational Field
822831 sage: W = MatrixSpace(QQ, 3)
823832 sage: phi_e_T11 = T11.isomorphism_with_fixed_basis(e_T11, codomain=W); phi_e_T11
824833 Generic morphism:
825- From: Free module of type-(1,1) tensors on the 3-dimensional vector space over the Rational Field
834+ From: Free module of type-(1,1) tensors on the
835+ 3-dimensional vector space over the Rational Field
826836 To: Full MatrixSpace of 3 by 3 dense matrices over Rational Field
827837 sage: t = T11.an_element(); t.display()
828838 1/2 e_1⊗e^1
829839 sage: phi_e_T11(t)
830840 [1/2 0 0]
831841 [ 0 0 0]
832842 [ 0 0 0]
843+ sage: ~phi_e_T11
844+ Generic morphism:
845+ From: Full MatrixSpace of 3 by 3 dense matrices over Rational Field
846+ To: Free module of type-(1,1) tensors on the
847+ 3-dimensional vector space over the Rational Field
848+ sage: (~phi_e_T11)(W([[0, 1/2, 1/3],
849+ ....: [-1/2, 0, 0],
850+ ....: [-1/3, 0, 0]])).display()
851+ 1/2 e_1⊗e^2 + 1/3 e_1⊗e^3 - 1/2 e_2⊗e^1 - 1/3 e_3⊗e^1
833852
834853 Sending symmetric bilinear forms to matrices (note that they are currently elements
835854 of `T^{(0,2)}(M)`, not the symmetric power of `M`)::
836855
837856 sage: T02 = V.tensor_module(0, 2); T02
838- Free module of type-(0,2) tensors on the 3-dimensional vector space over the Rational Field
857+ Free module of type-(0,2) tensors on the
858+ 3-dimensional vector space over the Rational Field
839859 sage: e_T02 = T02.basis("e"); e_T02
840860 Standard basis on the
841- Free module of type-(0,2) tensors on the 3-dimensional vector space over the Rational Field
842- induced by Basis (e_1,e_2,e_3) on the 3-dimensional vector space over the Rational Field
861+ Free module of type-(0,2) tensors on the
862+ 3-dimensional vector space over the Rational Field
863+ induced by Basis (e_1,e_2,e_3) on the
864+ 3-dimensional vector space over the Rational Field
843865 sage: W = MatrixSpace(QQ, 3)
844866 sage: phi_e_T02 = T02.isomorphism_with_fixed_basis(e_T02, codomain=W); phi_e_T02
845867 Generic morphism:
846- From: Free module of type-(0,2) tensors on the 3-dimensional vector space over the Rational Field
868+ From: Free module of type-(0,2) tensors on the
869+ 3-dimensional vector space over the Rational Field
847870 To: Full MatrixSpace of 3 by 3 dense matrices over Rational Field
848871
849872 sage: a = V.sym_bilinear_form()
850873 sage: a[1,1], a[1,2], a[1,3] = 1, 2, 3
851874 sage: a[2,2], a[2,3] = 4, 5
852875 sage: a[3,3] = 6
853876 sage: a.display()
854- e^1⊗e^1 + 2 e^1⊗e^2 + 3 e^1⊗e^3 + 2 e^2⊗e^1 + 4 e^2⊗e^2 + 5 e^2⊗e^3 + 3 e^3⊗e^1 + 5 e^3⊗e^2 + 6 e^3⊗e^3
877+ e^1⊗e^1 + 2 e^1⊗e^2 + 3 e^1⊗e^3 + 2 e^2⊗e^1 + 4 e^2⊗e^2 + 5 e^2⊗e^3
878+ + 3 e^3⊗e^1 + 5 e^3⊗e^2 + 6 e^3⊗e^3
855879 sage: phi_e_T02(a)
856880 [1 2 3]
857881 [2 4 5]
@@ -860,15 +884,18 @@ def isomorphism_with_fixed_basis(self, basis=None, codomain=None):
860884 Same but explicitly in the subspace of symmetric bilinear forms::
861885
862886 sage: Sym2Vdual = V.dual_symmetric_power(2); Sym2Vdual
863- Free module of fully symmetric type-(0,2) tensors on the 3-dimensional vector space over the Rational Field
887+ Free module of fully symmetric type-(0,2) tensors on the
888+ 3-dimensional vector space over the Rational Field
864889 sage: Sym2Vdual.is_submodule(T02)
865890 True
866891 sage: Sym2Vdual.rank()
867892 6
868893 sage: e_Sym2Vdual = Sym2Vdual.basis("e"); e_Sym2Vdual
869894 Standard basis on the
870- Free module of fully symmetric type-(0,2) tensors on the 3-dimensional vector space over the Rational Field
871- induced by Basis (e_1,e_2,e_3) on the 3-dimensional vector space over the Rational Field
895+ Free module of fully symmetric type-(0,2) tensors on the
896+ 3-dimensional vector space over the Rational Field
897+ induced by Basis (e_1,e_2,e_3) on the
898+ 3-dimensional vector space over the Rational Field
872899 sage: W_basis = [phi_e_T02(b) for b in e_Sym2Vdual]; W_basis
873900 [
874901 [1 0 0] [0 1 0] [0 0 1] [0 0 0] [0 0 0] [0 0 0]
@@ -877,25 +904,34 @@ def isomorphism_with_fixed_basis(self, basis=None, codomain=None):
877904 ]
878905 sage: W = MatrixSpace(QQ, 3).submodule(W_basis); W
879906 Free module generated by {0, 1, 2, 3, 4, 5} over Rational Field
880- sage: phi_e_Sym2Vdual = Sym2Vdual.isomorphism_with_fixed_basis(e_Sym2Vdual, codomain=W); phi_e_Sym2Vdual
907+ sage: phi_e_Sym2Vdual = Sym2Vdual.isomorphism_with_fixed_basis(e_Sym2Vdual,
908+ ....: codomain=W)
909+ sage: phi_e_Sym2Vdual
881910 Generic morphism:
882- From: Free module of fully symmetric type-(0,2) tensors on the 3-dimensional vector space over the Rational Field
911+ From: Free module of fully symmetric type-(0,2) tensors on the
912+ 3-dimensional vector space over the Rational Field
883913 To: Free module generated by {0, 1, 2, 3, 4, 5} over Rational Field
884914
885915 Sending tensors to elements of the tensor square of :class:`CombinatorialFreeModule`::
886916
887917 sage: T20 = V.tensor_module(2, 0); T20
888- Free module of type-(2,0) tensors on the 3-dimensional vector space over the Rational Field
918+ Free module of type-(2,0) tensors on the
919+ 3-dimensional vector space over the Rational Field
889920 sage: e_T20 = T02.basis("e"); e_T20
890921 Standard basis on the
891- Free module of type-(0,2) tensors on the 3-dimensional vector space over the Rational Field
892- induced by Basis (e_1,e_2,e_3) on the 3-dimensional vector space over the Rational Field
922+ Free module of type-(0,2) tensors on the
923+ 3-dimensional vector space over the Rational Field
924+ induced by Basis (e_1,e_2,e_3) on the
925+ 3-dimensional vector space over the Rational Field
893926 sage: W = CombinatorialFreeModule(QQ, [1, 2, 3]).tensor_square(); W
894- Free module generated by {1, 2, 3} over Rational Field # Free module generated by {1, 2, 3} over Rational Field
927+ Free module generated by {1, 2, 3} over Rational Field
928+ # Free module generated by {1, 2, 3} over Rational Field
895929 sage: phi_e_T20 = T20.isomorphism_with_fixed_basis(e_T20, codomain=W); phi_e_T20
896930 Generic morphism:
897- From: Free module of type-(2,0) tensors on the 3-dimensional vector space over the Rational Field
898- To: Free module generated by {1, 2, 3} over Rational Field # Free module generated by {1, 2, 3} over Rational Field
931+ From: Free module of type-(2,0) tensors on the
932+ 3-dimensional vector space over the Rational Field
933+ To: Free module generated by {1, 2, 3} over Rational Field
934+ # Free module generated by {1, 2, 3} over Rational Field
899935 sage: t = T20.an_element(); t.display()
900936 1/2 e_1⊗e_1
901937 sage: phi_e_T20(t)
@@ -940,13 +976,17 @@ def isomorphism_with_fixed_basis(self, basis=None, codomain=None):
940976
941977 codomain_basis = Family (codomain .basis ())
942978 if isinstance (codomain_basis , TrivialFamily ):
943- # assume that codomain basis keys are to be ignored
944- key_pairs = enumerate (basis .keys ())
979+ # assume that codomain basis keys are to be ignored;
980+ # need them several times, can't keep as generators
981+ key_pairs = tuple (enumerate (basis .keys ()))
982+ basis_by_codomain_key = basis
945983 else :
946984 # assume that the keys of the codomain should be used
947- key_pairs = zip (codomain_basis .keys (), basis .keys ())
948- # Need them several times, can't keep as generators
949- key_pairs = tuple (key_pairs )
985+ # need them several times, can't keep as generators
986+ key_pairs = tuple (zip (codomain_basis .keys (), basis .keys ()))
987+ basis_by_codomain_key = {}
988+ for codomain_key , domain_key in key_pairs :
989+ basis_by_codomain_key [codomain_key ] = basis [domain_key ]
950990
951991 def _isomorphism (x ):
952992 r"""
@@ -955,7 +995,21 @@ def _isomorphism(x):
955995 return codomain .sum (x [basis , domain_key ] * codomain_basis [codomain_key ]
956996 for codomain_key , domain_key in key_pairs )
957997
958- return self .module_morphism (function = _isomorphism , codomain = codomain )
998+ def _inverse (y ):
999+ r"""
1000+ Concrete isomorphism from ``codomain`` to ``self``.
1001+ """
1002+ return self .linear_combination (
1003+ (basis_by_codomain_key [codomain_key ], coefficient )
1004+ for codomain_key , coefficient in y .monomial_coefficients ().items ())
1005+
1006+ category = Modules (self .base_ring ())
1007+ homset = Hom (self , codomain , category )
1008+ isomorphism = SetIsomorphism (homset , _isomorphism )
1009+ inverse = SetIsomorphism (homset .reversed (), _inverse )
1010+ isomorphism ._set_inverse (inverse )
1011+ inverse ._set_inverse (isomorphism )
1012+ return isomorphism
9591013
9601014 def _test_isomorphism_with_fixed_basis (self , ** options ):
9611015 r"""
@@ -3160,7 +3214,6 @@ def hom(self, codomain, matrix_rep, bases=None, name=None,
31603214 for more documentation.
31613215
31623216 """
3163- from sage .categories .homset import Hom
31643217 homset = Hom (self , codomain )
31653218 return homset (matrix_rep , bases = bases , name = name ,
31663219 latex_name = latex_name )
0 commit comments