K iUdZddlmZmZmZmZmZddlmZGddZ Gdde Z Gdd e Z Gd d e Z d Z y )a  Computations with homomorphisms of modules and rings. This module implements classes for representing homomorphisms of rings and their modules. Instead of instantiating the classes directly, you should use the function ``homomorphism(from, to, matrix)`` to create homomorphism objects. )Module FreeModuleQuotientModule SubModuleSubQuotientModule)CoercionFailedceZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZdZdZeZdZdZdZdZdZdZdZdZ dZ!y) ModuleHomomorphisma" Abstract base class for module homomoprhisms. Do not instantiate. Instead, use the ``homomorphism`` function: >>> from sympy import QQ >>> from sympy.abc import x >>> from sympy.polys.agca import homomorphism >>> F = QQ.old_poly_ring(x).free_module(2) >>> homomorphism(F, F, [[1, 0], [0, 1]]) Matrix([ [1, 0], : QQ[x]**2 -> QQ[x]**2 [0, 1]]) Attributes: - ring - the ring over which we are considering modules - domain - the domain module - codomain - the codomain module - _ker - cached kernel - _img - cached image Non-implemented methods: - _kernel - _image - _restrict_domain - _restrict_codomain - _quotient_domain - _quotient_codomain - _apply - _mul_scalar - _compose - _add c*t|tstd|zt|tstd|z|j|jk7rt d|d|||_||_|j|_d|_d|_y)NzSource must be a module, got %szTarget must be a module, got %sz0Source and codomain must be over same ring, got z != ) isinstancer TypeErrorring ValueErrordomaincodomain_ker_img)selfrrs d/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/sympy/polys/agca/homomorphisms.py__init__zModuleHomomorphism.__init__8s&&)=FG G(F+=HI I ;;(-- '/5xAB B   KK   c\|j|j|_|jS)a Compute the kernel of ``self``. That is, if ``self`` is the homomorphism `\phi: M \to N`, then compute `ker(\phi) = \{x \in M | \phi(x) = 0\}`. This is a submodule of `M`. Examples ======== >>> from sympy import QQ >>> from sympy.abc import x >>> from sympy.polys.agca import homomorphism >>> F = QQ.old_poly_ring(x).free_module(2) >>> homomorphism(F, F, [[1, 0], [x, 0]]).kernel() <[x, -1]> )r_kernelrs rkernelzModuleHomomorphism.kernelFs%$ 99  DIyyrc\|j|j|_|jS)a Compute the image of ``self``. That is, if ``self`` is the homomorphism `\phi: M \to N`, then compute `im(\phi) = \{\phi(x) | x \in M \}`. This is a submodule of `N`. Examples ======== >>> from sympy import QQ >>> from sympy.abc import x >>> from sympy.polys.agca import homomorphism >>> F = QQ.old_poly_ring(x).free_module(2) >>> homomorphism(F, F, [[1, 0], [x, 0]]).image() == F.submodule([1, 0]) True )r_imagers rimagezModuleHomomorphism.image\s%$ 99  DIyyrct)zCompute the kernel of ``self``.NotImplementedErrorrs rrzModuleHomomorphism._kernelr!!rct)zCompute the image of ``self``.r rs rrzModuleHomomorphism._imagevr"rctz%Implementation of domain restriction.r rsms r_restrict_domainz#ModuleHomomorphism._restrict_domainzr"rctz'Implementation of codomain restriction.r r&s r_restrict_codomainz%ModuleHomomorphism._restrict_codomain~r"rctz"Implementation of domain quotient.r r&s r_quotient_domainz#ModuleHomomorphism._quotient_domainr"rctz$Implementation of codomain quotient.r r&s r_quotient_codomainz%ModuleHomomorphism._quotient_codomainr"rc|jj|std|jd|||jk(r|S|j|S)a? Return ``self``, with the domain restricted to ``sm``. Here ``sm`` has to be a submodule of ``self.domain``. Examples ======== >>> from sympy import QQ >>> from sympy.abc import x >>> from sympy.polys.agca import homomorphism >>> F = QQ.old_poly_ring(x).free_module(2) >>> h = homomorphism(F, F, [[1, 0], [x, 0]]) >>> h Matrix([ [1, x], : QQ[x]**2 -> QQ[x]**2 [0, 0]]) >>> h.restrict_domain(F.submodule([1, 0])) Matrix([ [1, x], : <[1, 0]> -> QQ[x]**2 [0, 0]]) This is the same as just composing on the right with the submodule inclusion: >>> h * F.submodule([1, 0]).inclusion_hom() Matrix([ [1, x], : <[1, 0]> -> QQ[x]**2 [0, 0]]) zsm must be a submodule of , got )r is_submodulerr(r&s rrestrict_domainz"ModuleHomomorphism.restrict_domainsT@{{''+ $ R12 2  K$$R((rc|j|jstd|jd|||jk(r|S|j |S)a Return ``self``, with codomain restricted to to ``sm``. Here ``sm`` has to be a submodule of ``self.codomain`` containing the image. Examples ======== >>> from sympy import QQ >>> from sympy.abc import x >>> from sympy.polys.agca import homomorphism >>> F = QQ.old_poly_ring(x).free_module(2) >>> h = homomorphism(F, F, [[1, 0], [x, 0]]) >>> h Matrix([ [1, x], : QQ[x]**2 -> QQ[x]**2 [0, 0]]) >>> h.restrict_codomain(F.submodule([1, 0])) Matrix([ [1, x], : QQ[x]**2 -> <[1, 0]> [0, 0]]) z the image  must contain sm, got )r4rrrr+r&s rrestrict_codomainz$ModuleHomomorphism.restrict_codomainsU2tzz|, $ b23 3  K&&r**rc|jj|std|jd||jr|S|j |S)am Return ``self`` with domain replaced by ``domain/sm``. Here ``sm`` must be a submodule of ``self.kernel()``. Examples ======== >>> from sympy import QQ >>> from sympy.abc import x >>> from sympy.polys.agca import homomorphism >>> F = QQ.old_poly_ring(x).free_module(2) >>> h = homomorphism(F, F, [[1, 0], [x, 0]]) >>> h Matrix([ [1, x], : QQ[x]**2 -> QQ[x]**2 [0, 0]]) >>> h.quotient_domain(F.submodule([-x, 1])) Matrix([ [1, x], : QQ[x]**2/<[-x, 1]> -> QQ[x]**2 [0, 0]]) zkernel r7)rr4ris_zeror.r&s rquotient_domainz"ModuleHomomorphism.quotient_domainsT0{{}))"-"kkmR12 2 ::<K$$R((rc|jj|std|jd||jr|S|j |S)a: Return ``self`` with codomain replaced by ``codomain/sm``. Here ``sm`` must be a submodule of ``self.codomain``. Examples ======== >>> from sympy import QQ >>> from sympy.abc import x >>> from sympy.polys.agca import homomorphism >>> F = QQ.old_poly_ring(x).free_module(2) >>> h = homomorphism(F, F, [[1, 0], [x, 0]]) >>> h Matrix([ [1, x], : QQ[x]**2 -> QQ[x]**2 [0, 0]]) >>> h.quotient_codomain(F.submodule([1, 1])) Matrix([ [1, x], : QQ[x]**2 -> QQ[x]**2/<[1, 1]> [0, 0]]) This is the same as composing with the quotient map on the left: >>> (F/[(1, 1)]).quotient_hom() * h Matrix([ [1, x], : QQ[x]**2 -> QQ[x]**2/<[1, 1]> [0, 0]]) z#sm must be a submodule of codomain r3)rr4rr:r1r&s rquotient_codomainz$ModuleHomomorphism.quotient_codomainsP>}}))"- $ r34 4 ::<K&&r**rct)zApply ``self`` to ``elem``.r relems r_applyzModuleHomomorphism._applyr"rc|jj|j|jj|SN)rconvertrArr?s r__call__zModuleHomomorphism.__call__s/}}$$T[[1D1DT1J%KLLrct)a  Compose ``self`` with ``oth``, that is, return the homomorphism obtained by first applying then ``self``, then ``oth``. (This method is private since in this syntax, it is non-obvious which homomorphism is executed first.) r roths r_composezModuleHomomorphism._composes "!rct)z8Scalar multiplication. ``c`` is guaranteed in self.ring.r )rcs r _mul_scalarzModuleHomomorphism._mul_scalar'r"rct)zv Homomorphism addition. ``oth`` is guaranteed to be a homomorphism with same domain/codomain. r rGs r_addzModuleHomomorphism._add+s "!rct|tsy|j|jk(xr|j|jk(S)zEHelper to check that oth is a homomorphism with same domain/codomain.F)r r rrrGs r _check_homzModuleHomomorphism._check_hom2s5#12zzT[[(JS\\T]]-JJrct|tr*|j|jk(r|j |S |j |j j|S#t$r tcYSwxYwrC) r r rrrIrLrrDrNotImplementedrGs r__mul__zModuleHomomorphism.__mul__8se c- .4;;#,,3N<<% % "##DII$5$5c$:; ; "! ! "s)A&&A87A8c |jd|jj|z S#t$r tcYSwxYw)N)rLrrDrrRrGs r __truediv__zModuleHomomorphism.__truediv__CsA "##Adii&7&7&<$<= = "! ! "s,/AAcR|j|r|j|StSrC)rPrNrRrGs r__add__zModuleHomomorphism.__add__Is" ??3 99S> !rc|j|r9|j|j|jj dSt S)N)rPrNrLrrDrRrGs r__sub__zModuleHomomorphism.__sub__Ns; ??3 99S__TYY->->r-BCD Drc>|jjS)a Return True if ``self`` is injective. That is, check if the elements of the domain are mapped to the same codomain element. Examples ======== >>> from sympy import QQ >>> from sympy.abc import x >>> from sympy.polys.agca import homomorphism >>> F = QQ.old_poly_ring(x).free_module(2) >>> h = homomorphism(F, F, [[1, 0], [x, 0]]) >>> h.is_injective() False >>> h.quotient_domain(h.kernel()).is_injective() True )rr:rs r is_injectivezModuleHomomorphism.is_injectiveSs*{{}$$&&rc<|j|jk(S)a Return True if ``self`` is surjective. That is, check if every element of the codomain has at least one preimage. Examples ======== >>> from sympy import QQ >>> from sympy.abc import x >>> from sympy.polys.agca import homomorphism >>> F = QQ.old_poly_ring(x).free_module(2) >>> h = homomorphism(F, F, [[1, 0], [x, 0]]) >>> h.is_surjective() False >>> h.restrict_codomain(h.image()).is_surjective() True )rrrs r is_surjectivez ModuleHomomorphism.is_surjectivejs*zz|t}},,rcF|jxr|jS)a~ Return True if ``self`` is an isomorphism. That is, check if every element of the codomain has precisely one preimage. Equivalently, ``self`` is both injective and surjective. Examples ======== >>> from sympy import QQ >>> from sympy.abc import x >>> from sympy.polys.agca import homomorphism >>> F = QQ.old_poly_ring(x).free_module(2) >>> h = homomorphism(F, F, [[1, 0], [x, 0]]) >>> h = h.restrict_codomain(h.image()) >>> h.is_isomorphism() False >>> h.quotient_domain(h.kernel()).is_isomorphism() True )r]r_rs ris_isomorphismz!ModuleHomomorphism.is_isomorphisms!,  ";t'9'9';;rc>|jjS)aN Return True if ``self`` is a zero morphism. That is, check if every element of the domain is mapped to zero under self. Examples ======== >>> from sympy import QQ >>> from sympy.abc import x >>> from sympy.polys.agca import homomorphism >>> F = QQ.old_poly_ring(x).free_module(2) >>> h = homomorphism(F, F, [[1, 0], [x, 0]]) >>> h.is_zero() False >>> h.restrict_domain(F.submodule()).is_zero() True >>> h.quotient_codomain(h.image()).is_zero() True )rr:rs rr:zModuleHomomorphism.is_zeros.zz|##%%rcH ||z jS#t$rYywxYw)NF)r:r rGs r__eq__zModuleHomomorphism.__eq__s, 3J'') )  s  !!c||k( SrCrGs r__ne__zModuleHomomorphism.__ne__sCK  rN)"__name__ __module__ __qualname____doc__rrrrrr(r+r.r1r5r8r;r=rArErIrLrNrPrS__rmul__rVrXr[r]r_rar:rdrgrfrrr r s#J ,,""""""%)N+@)>$+L"M"""K "H"   '.-.<0&2 !rr cLeZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z y ) MatrixHomomorphisma Helper class for all homomoprhisms which are expressed via a matrix. That is, for such homomorphisms ``domain`` is contained in a module generated by finitely many elements `e_1, \ldots, e_n`, so that the homomorphism is determined uniquely by its action on the `e_i`. It can thus be represented as a vector of elements of the codomain module, or potentially a supermodule of the codomain module (and hence conventionally as a matrix, if there is a similar interpretation for elements of the codomain module). Note that this class does *not* assume that the `e_i` freely generate a submodule, nor that ``domain`` is even all of this submodule. It exists only to unify the interface. Do not instantiate. Attributes: - matrix - the list of images determining the homomorphism. NOTE: the elements of matrix belong to either self.codomain or self.codomain.container Still non-implemented methods: - kernel - _apply ctj|||t||jk7r$t d|jdt||j j t|j ttfr |j jj tfd|D|_ y)NzNeed to provide z elements, got c3.K|] }|ywrCrf).0x converters r z.MatrixHomomorphism.__init__..s9QIaL9s) r rlenrankrrrDr rr containertuplematrix)rrrryrss @rrzMatrixHomomorphism.__init__s##D&(; v;&++ % & S[:; ;MM)) dmmi1B%C D //77I9&99 rc "ddlm}d}t|jtt frd}||j Dcgc]1}||Dcgc]}|jj|c}3c}}jScc}wcc}}w)z=Helper function which returns a SymPy matrix ``self.matrix``.r)Matrixc|SrCrfrrs rz2MatrixHomomorphism._sympy_matrix..sarc|jSrC)datar}s rr~z2MatrixHomomorphism._sympy_matrix..s !&&r) sympy.matricesr{r rrrryrto_sympyT)rr{rKrrys r _sympy_matrixz MatrixHomomorphism._sympy_matrixsg)  dmmn6G%H I AdkkRqt  rU)reprrsplitrrrurangejoin)rlinestsnis r__repr__zMatrixHomomorphism.__repr__sT'')*006![[$-- 8 AJ JqAv A !HMH  a1f  q!tax# A !HMH yyrcDt||j|jSr%)SubModuleHomomorphismrryr&s rr(z#MatrixHomomorphism._restrict_domains$R DDrcP|j|j||jSr*) __class__rryr&s rr+z%MatrixHomomorphism._restrict_codomains~~dkk2t{{;;rcj|j|j|z |j|jSr-rrrryr&s rr.z#MatrixHomomorphism._quotient_domains%~~dkk"ndmmT[[IIrc 2|j|z }|j}t|jtr|jj}|j |j |j|z |jDcgc] }|| c}Scc}wr0)rrDr rrwrrry)rr'Qrsrrs rr1z%MatrixHomomorphism._quotient_codomainsq MM" II dmmY / ++I~~dkk4==+;#';; /aYq\ /1 1 /s>B c |j|j|jt|j|jDcgc] \}}||z c}}Scc}}wrC)rrrzipry)rrHrrrs rrNzMatrixHomomorphism._addsI~~dkk4==14T[[#**1MNAq1uNP PNsAc |j|j|j|jDcgc]}||z c}Scc}wrCr)rrKrrs rrLzMatrixHomomorphism._mul_scalars3~~dkk4== :T11Q3:TUU:Ts A c |j|j|j|jDcgc] }|| c}Scc}wrCr)rrHrrs rrIzMatrixHomomorphism._composes3~~dkk3<<$++9VQ#a&9VWW9VsA N)rhrirjrkrrrr(r+r.r1rNrLrIrfrrrnrns?: :V  E<J1PVXrrnc"eZdZdZdZdZdZy)FreeModuleHomomorphisma Concrete class for homomorphisms with domain a free module or a quotient thereof. Do not instantiate; the constructor does not check that your data is well defined. Use the ``homomorphism`` function instead: >>> from sympy import QQ >>> from sympy.abc import x >>> from sympy.polys.agca import homomorphism >>> F = QQ.old_poly_ring(x).free_module(2) >>> homomorphism(F, F, [[1, 0], [0, 1]]) Matrix([ [1, 0], : QQ[x]**2 -> QQ[x]**2 [0, 1]]) ct|jtr |j}t dt ||j DS)Nc3,K|] \}}||zywrCrfrqrres rrtz0FreeModuleHomomorphism._apply../ 299D>> from sympy import QQ >>> from sympy.abc import x >>> from sympy.polys.agca import homomorphism >>> M = QQ.old_poly_ring(x).free_module(2)*x >>> homomorphism(M, M, [[1, 0], [0, 1]]) Matrix([ [1, 0], : <[x, 0], [0, x]> -> <[x, 0], [0, x]> [0, 1]]) ct|jtr |j}t dt ||j DS)Nc3,K|] \}}||zywrCrfrs rrtz/SubModuleHomomorphism._apply..Trr)r rrrrrryr?s rrAzSubModuleHomomorphism._applyQs6 dkk#4 599D.\s?FB"R%?r)rrrrrrr)rrrs rrzSubModuleHomomorphism._kernelYsjjjl((*$t{{$$xx!?c!T[[-=-=&>??!" "!s7A>Nrrfrrrr>s$= M"rrc d}||\}}}}||\}} } } t|||D cgc] } | |  c} j|j| j| j |Scc} w)a> Create a homomorphism object. This function tries to build a homomorphism from ``domain`` to ``codomain`` via the matrix ``matrix``. Examples ======== >>> from sympy import QQ >>> from sympy.abc import x >>> from sympy.polys.agca import homomorphism >>> R = QQ.old_poly_ring(x) >>> T = R.free_module(2) If ``domain`` is a free module generated by `e_1, \ldots, e_n`, then ``matrix`` should be an n-element iterable `(b_1, \ldots, b_n)` where the `b_i` are elements of ``codomain``. The constructed homomorphism is the unique homomorphism sending `e_i` to `b_i`. >>> F = R.free_module(2) >>> h = homomorphism(F, T, [[1, x], [x**2, 0]]) >>> h Matrix([ [1, x**2], : QQ[x]**2 -> QQ[x]**2 [x, 0]]) >>> h([1, 0]) [1, x] >>> h([0, 1]) [x**2, 0] >>> h([1, 1]) [x**2 + 1, x] If ``domain`` is a submodule of a free module, them ``matrix`` determines a homomoprhism from the containing free module to ``codomain``, and the homomorphism returned is obtained by restriction to ``domain``. >>> S = F.submodule([1, 0], [0, x]) >>> homomorphism(S, T, [[1, x], [x**2, 0]]) Matrix([ [1, x**2], : <[1, 0], [0, x]> -> QQ[x]**2 [x, 0]]) If ``domain`` is a (sub)quotient `N/K`, then ``matrix`` determines a homomorphism from `N` to ``codomain``. If the kernel contains `K`, this homomorphism descends to ``domain`` and is returned; otherwise an exception is raised. >>> homomorphism(S/[(1, 0)], T, [0, [x**2, 0]]) Matrix([ [0, x**2], : <[1, 0] + <[1, 0]>, [0, x] + <[1, 0]>, [1, 0] + <[1, 0]>> -> QQ[x]**2 [0, 0]]) >>> homomorphism(S/[(0, x)], T, [0, [x**2, 0]]) Traceback (most recent call last): ... ValueError: kernel <[1, 0], [0, 0]> must contain sm, got <[0,x]> cttrjfdfSttr'jjj fdfStt r1jjjj fdfSjjfdfS)z Return a tuple ``(F, S, Q, c)`` where ``F`` is a free module, ``S`` is a submodule of ``F``, and ``Q`` a submodule of ``S``, such that ``module = S/Q``, and ``c`` is a conversion function. c&j|SrC)rDrrmodules rr~z0homomorphism..freepres..sPQARrc:j|jSrC)rDrrs rr~z0homomorphism..freepres..sfnnQ/44rcNjj|jSrC)rwrDrrs rr~z0homomorphism..freepres..sf..66q9>>rc:jj|SrC)rwrDrs rr~z0homomorphism..freepres..s&**2215r)r rrrbase killed_modulerrw)rs`rfreepreszhomomorphism..freepress fj )66#3#3#57RR R fn -KKf.B.B46 6 f/ 0KK))6;;8L8L>@ @  &&*:*:*<57 7r)rr5r8r=r;) rrryrSFSSSQ_TFTSTQrKrrs r homomorphismr`s~x7$V$MBBX&MBB !"b*@A1Q4*@ ?2 00  R !45*@sA; N)rksympy.polys.agca.modulesrrrrrsympy.polys.polyerrorsrr rnrrrrfrrrsX""1 g!g!T ZX+ZXz"0/"0J"."DS5r