+
    iU                         R t ^ RIHtHtHtHtHt ^ RIHt  ! R R4      t	 ! R R]	4      t
 ! R R]
4      t ! R	 R
]
4      tR tR# )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
FreeModuleQuotientModule	SubModuleSubQuotientModule)CoercionFailedc                      a  ] tR t^t o RtR tR tR tR tR t	R t
R tR	 tR
 tR tR tR tR tR tR tR tR tR tR tR t]tR tR tR tR tR tR tR t R t!R t"Rt#V t$R # )!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                X   \        V\        4      '       g   \        R V,          4      h\        V\        4      '       g   \        RV,          4      hVP                  VP                  8w  d   \	        RV: RV: 24      hWn        W n        VP                  V n        RV n        RV n        R# )zSource must be a module, got %szTarget must be a module, got %sz0Source and codomain must be over same ring, got z != N)	
isinstancer   	TypeErrorring
ValueErrordomaincodomain_ker_img)selfr   r   s   &&&\/var/www/html/photoedit/myenv/lib/python3.14/site-packages/sympy/polys/agca/homomorphisms.py__init__ModuleHomomorphism.__init__8   s    &&))=FGG(F++=HII;;(--'/5xA B B KK			    c                `    V P                   f   V P                  4       V n         V P                   # )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   _kernelr   s   &r   kernelModuleHomomorphism.kernelF   s%    $ 99DIyyr   c                `    V P                   f   V P                  4       V n         V P                   # )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   _imager   s   &r   imageModuleHomomorphism.image\   s%    $ 99DIyyr   c                    \         h)zCompute the kernel of ``self``.NotImplementedErrorr   s   &r   r   ModuleHomomorphism._kernelr       !!r   c                    \         h)zCompute the image of ``self``.r"   r   s   &r   r   ModuleHomomorphism._imagev   r%   r   c                    \         hz%Implementation of domain restriction.r"   r   sms   &&r   _restrict_domain#ModuleHomomorphism._restrict_domainz   r%   r   c                    \         hz'Implementation of codomain restriction.r"   r*   s   &&r   _restrict_codomain%ModuleHomomorphism._restrict_codomain~   r%   r   c                    \         hz"Implementation of domain quotient.r"   r*   s   &&r   _quotient_domain#ModuleHomomorphism._quotient_domain   r%   r   c                    \         hz$Implementation of codomain quotient.r"   r*   s   &&r   _quotient_codomain%ModuleHomomorphism._quotient_codomain   r%   r   c                    V P                   P                  V4      '       g   \        RV P                   : RV: 24      hWP                   8X  d   V # V P                  V4      # )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]])
zsm must be a submodule of , got )r   is_submoduler   r,   r*   s   &&r   restrict_domain"ModuleHomomorphism.restrict_domain   sU    @ {{''++ $R1 2 2K$$R((r   c                    VP                  V P                  4       4      '       g"   \        RV P                  4       : RV: 24      hWP                  8X  d   V # V P	                  V4      # )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 )r<   r   r   r   r0   r*   s   &&r   restrict_codomain$ModuleHomomorphism.restrict_codomain   sV    2 tzz|,, $

b2 3 3K&&r**r   c                    V P                  4       P                  V4      '       g"   \        RV P                  4       : RV: 24      hVP                  4       '       d   V # V P	                  V4      # )a  
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]])
zkernel r@   )r   r<   r   is_zeror4   r*   s   &&r   quotient_domain"ModuleHomomorphism.quotient_domain   sY    0 {{}))"--"kkmR1 2 2::<<K$$R((r   c                    V P                   P                  V4      '       g   \        RV P                   : RV: 24      hVP                  4       '       d   V # V P	                  V4      # )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 r;   )r   r<   r   rD   r8   r*   s   &&r   quotient_codomain$ModuleHomomorphism.quotient_codomain   sU    > }}))"-- $r3 4 4::<<K&&r**r   c                    \         h)zApply ``self`` to ``elem``.r"   r   elems   &&r   _applyModuleHomomorphism._apply  r%   r   c                    V P                   P                  V P                  V P                  P                  V4      4      4      # N)r   convertrM   r   rK   s   &&r   __call__ModuleHomomorphism.__call__  s/    }}$$T[[1D1DT1J%KLLr   c                    \         h)z
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"   r   oths   &&r   _composeModuleHomomorphism._compose  s
     "!r   c                    \         h)z8Scalar multiplication. ``c`` is guaranteed in self.ring.r"   )r   cs   &&r   _mul_scalarModuleHomomorphism._mul_scalar'  r%   r   c                    \         h)z^
Homomorphism addition.
``oth`` is guaranteed to be a homomorphism with same domain/codomain.
r"   rU   s   &&r   _addModuleHomomorphism._add+  s
    
 "!r   c                    \        V\        4      '       g   R# VP                  V P                  8H  ;'       d    VP                  V P                  8H  # )zEHelper to check that oth is a homomorphism with same domain/codomain.F)r   r	   r   r   rU   s   &&r   
_check_homModuleHomomorphism._check_hom2  s;    #122zzT[[(JJS\\T]]-JJr   c                
   \        V\        4      '       d-   V P                  VP                  8X  d   VP	                  V 4      #  V P                  V P                  P                  V4      4      #   \         d
    \        u # i ; irP   )
r   r	   r   r   rW   r[   r   rQ   r   NotImplementedrU   s   &&r   __mul__ModuleHomomorphism.__mul__8  sh    c-..4;;#,,3N<<%%	"##DII$5$5c$:;; 	"!!	"s   )A. .BBc                     V P                  ^V P                  P                  V4      ,          4      #   \         d
    \        u # i ; i)   )r[   r   rQ   r   rd   rU   s   &&r   __truediv__ModuleHomomorphism.__truediv__C  sA    	"##Adii&7&7&<$<== 	"!!	"s   03 AAc                ^    V P                  V4      '       d   V P                  V4      # \        # rP   )ra   r^   rd   rU   s   &&r   __add__ModuleHomomorphism.__add__I  s%    ??399S>!r   c                    V P                  V4      '       d:   V P                  VP                  V P                  P	                  R4      4      4      # \
        # )rh   )ra   r^   r[   r   rQ   rd   rU   s   &&r   __sub__ModuleHomomorphism.__sub__N  s>    ??399S__TYY->->r-BCDDr   c                >    V P                  4       P                  4       # )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
)r   rD   r   s   &r   is_injectiveModuleHomomorphism.is_injectiveS  s    * {{}$$&&r   c                <    V P                  4       V P                  8H  # )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
)r   r   r   s   &r   is_surjective ModuleHomomorphism.is_surjectivej  s    * zz|t}},,r   c                R    V P                  4       ;'       d    V P                  4       # )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
)rs   rv   r   s   &r   is_isomorphism!ModuleHomomorphism.is_isomorphism  s$    ,   ";;t'9'9';;r   c                >    V P                  4       P                  4       # )a  
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
)r   rD   r   s   &r   rD   ModuleHomomorphism.is_zero  s    . zz|##%%r   c                T     W,
          P                  4       #   \         d     R # i ; i)F)rD   r   rU   s   &&r   __eq__ModuleHomomorphism.__eq__  s*    	J'')) 		s    ''c                    W8X  * # rP    rU   s   &&r   __ne__ModuleHomomorphism.__ne__  s      r   )r   r   r   r   r   N)%__name__
__module____qualname____firstlineno____doc__r   r   r   r   r   r,   r0   r4   r8   r=   rA   rE   rH   rM   rR   rW   r[   r^   ra   re   __rmul__ri   rl   rp   rs   rv   ry   rD   r~   r   __static_attributes____classdictcell____classdict__s   @r   r	   r	      s     #J,,""""""%)N+@)>$+L"M"""K" H"

'.-.<0&2! !r   r	   c                   `   a  ] tR tRt o RtR tR tR tR tR t	R t
R	 tR
 tR tR tRtV tR# )MatrixHomomorphismi  a  
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
c                  a \         P                  WV4       \        V4      VP                  8w  d'   \	        R VP                  : R\        V4      : 24      hV P
                  P                  o\        V P
                  \        \        34      '       d!   V P
                  P                  P                  o\        ;QJ d    . V3R lV 4       F  NK  	  5V n        R# ! V3R lV 4       4      V n        R# )zNeed to provide z elements, got c              3   4   <"   T F  pS! V4      x  K  	  R # 5irP   r   ).0x	converters   & r   	<genexpr>.MatrixHomomorphism.__init__.<locals>.<genexpr>  s     9&QIaLL&s   N)r	   r   lenrankr   r   rQ   r   r   r   	containertuplematrix)r   r   r   r   r   s   &&&&@r   r   MatrixHomomorphism.__init__  s    ##D(;v;&++% &S[: ; ; MM))	dmmi1B%CDD//77Ie9&9ee9&99r   c                2   ^ RI Hp R p\        V P                  \        \
        34      '       d   R pT! V P                   UUu. uF2  q2! V4       Uu. uF  q@P                  P                  V4      NK  	  upNK4  	  upp4      P                  # u upi u uppi )z=Helper function which returns a SymPy matrix ``self.matrix``.)Matrixc                     V # rP   r   r   s   &r   <lambda>2MatrixHomomorphism._sympy_matrix.<locals>.<lambda>  s    ar   c                     V P                   # rP   )datar   s   &r   r   r     s    !&&r   )
sympy.matricesr   r   r   r   r   r   r   to_sympyT)r   r   rZ   r   ys   &    r   _sympy_matrix MatrixHomomorphism._sympy_matrix  sp    )dmmn6G%HII AdkkRkqt<t!		**1-t<kRSUUU<Rs   B
#B5B
B
c                   \        V P                  4       4      P                  R 4      pRV P                  : RV P                  : 2pR\        V4      ,          p\        V4      p\        V^,          4       F  pW;;,          V,          uu&   K  	  W^,          ;;,          V,          uu&   \        V^,          ^,           V4       F  pW;;,          V,          uu&   K  	  R P                  V4      # )
z : z ->  )reprr   splitr   r   r   rangejoin)r   linestsnis   &     r   __repr__MatrixHomomorphism.__repr__  s    T'')*006![[$--8AJJqAvAHMH 1fq!tax#AHMH $yyr   c                B    \        WP                  V P                  4      # r)   )SubModuleHomomorphismr   r   r*   s   &&r   r,   #MatrixHomomorphism._restrict_domain  s    $RDDr   c                N    V P                  V P                  WP                  4      # r/   )	__class__r   r   r*   s   &&r   r0   %MatrixHomomorphism._restrict_codomain  s    ~~dkk2{{;;r   c                r    V P                  V P                  V,          V P                  V P                  4      # r3   r   r   r   r   r*   s   &&r   r4   #MatrixHomomorphism._quotient_domain  s%    ~~dkk"ndmmT[[IIr   c           
     P   V P                   V,          pVP                  p\        V P                   \        4      '       d   VP                  P                  pT P                  V P                  V P                   V,          V P                   Uu. uF
  qC! V4      NK  	  up4      # u upi r7   )r   rQ   r   r   r   r   r   r   )r   r+   Qr   r   s   &&   r   r8   %MatrixHomomorphism._quotient_codomain  sx    MM"II	dmmY//++I~~dkk4==+;#';;/;aYq\;/1 	1/s   B#c           
         T P                  V P                  V P                  \        V P                  VP                  4       UUu. uF  w  r#W#,           NK  	  upp4      # u uppi rP   )r   r   r   zipr   )r   rV   r   r   s   &&  r   r^   MatrixHomomorphism._add  sM    ~~dkk4==14T[[#**1MN1Mquu1MNP 	PNs   A c           	         T P                  V P                  V P                  V P                   Uu. uF  q!V,          NK  	  up4      # u upi rP   r   )r   rZ   r   s   && r   r[   MatrixHomomorphism._mul_scalar  s7    ~~dkk4==:T1Q33:TUU:Ts   Ac           
         T P                  V P                  VP                  V P                   Uu. uF
  q!! V4      NK  	  up4      # u upi rP   r   )r   rV   r   s   && r   rW   MatrixHomomorphism._compose  s7    ~~dkk3<<$++9V+Q#a&+9VWW9Vs   A)r   N)r   r   r   r   r   r   r   r   r,   r0   r4   r8   r^   r[   rW   r   r   r   s   @r   r   r     sH     :	:V
 E<J1PVX Xr   r   c                   6   a  ] tR tRt o RtR tR tR tRtV t	R# )FreeModuleHomomorphismi  a  
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]])
c                    \        V P                  \        4      '       d   VP                  p\	        R  \        WP                  4       4       4      # )c              3   6   "   T F  w  rW,          x  K  	  R # 5irP   r   r   r   es   &  r   r   0FreeModuleHomomorphism._apply.<locals>.<genexpr>/       <%;TQ155%;   )r   r   r   r   sumr   r   rK   s   &&r   rM   FreeModuleHomomorphism._apply,  s6    dkk>2299D<S{{%;<<<r   c                J    V P                   P                  ! V P                  !  # rP   )r   	submoduler   r   s   &r   r   FreeModuleHomomorphism._image1  s    }}&&44r   c                    V P                  4       P                  4       pV P                  P                  ! VP                  !  # rP   )r   syzygy_moduler   r   gens)r   syzs   & r   r   FreeModuleHomomorphism._kernel4  s1     jjl((*{{$$chh//r   r   N
r   r   r   r   r   rM   r   r   r   r   r   s   @r   r   r     s     $=
50 0r   r   c                   6   a  ] tR tRt o RtR tR tR tRtV t	R# )r   i>  a  
Concrete class for homomorphism with domain a submodule of 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

>>> 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]])
c                    \        V P                  \        4      '       d   VP                  p\	        R  \        WP                  4       4       4      # )c              3   6   "   T F  w  rW,          x  K  	  R # 5irP   r   r   s   &  r   r   /SubModuleHomomorphism._apply.<locals>.<genexpr>T  r   r   )r   r   r   r   r   r   r   rK   s   &&r   rM   SubModuleHomomorphism._applyQ  s7    dkk#45599D<S{{%;<<<r   c                    V P                   P                  ! V P                  P                   Uu. uF
  q! V4      NK  	  up!  # u upi rP   )r   r   r   r   )r   r   s   & r   r   SubModuleHomomorphism._imageV  s9    }}&&$++:J:J(K:JQa:J(KLL(Ks   Ac                
   V P                  4       P                  4       pV P                  P                  ! VP                   Uu. uF2  p\        R  \        W P                  P                  4       4       4      NK4  	  up!  # u upi )c              3   6   "   T F  w  rW,          x  K  	  R # 5irP   r   )r   xigis   &  r   r   0SubModuleHomomorphism._kernel.<locals>.<genexpr>\  s     ?&>FB"%%&>r   )r   r   r   r   r   r   r   )r   r   r   s   &  r   r   SubModuleHomomorphism._kernelY  sk    jjl((*{{$$xx!! ?c![[-=-=&>??!" 	"!s   8B r   Nr   r   s   @r   r   r   >  s     $=
M" "r   r   c           
         R pV! V 4      w  rErgV! V4      w  rr\        YHV Uu. uF
  q! V4      NK  	  up4      P                  V4      P                  V	4      P                  V
4      P	                  V4      # u upi )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]>

c                  a  \        S \        4      '       d   S S S P                  4       V 3R l3# \        S \        4      '       d)   S P                  S P                  S P
                  V 3R l3# \        S \        4      '       d3   S P                  P                  S P                  S P
                  V 3R l3# S P                  S S P                  4       V 3R l3# )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                 &   < SP                  V 4      # rP   )rQ   r   modules   &r   r   0homomorphism.<locals>.freepres.<locals>.<lambda>  s    PQARr   c                 :   < SP                  V 4      P                  # rP   )rQ   r   r   s   &r   r   r     s    fnnQ/44r   c                 N   < SP                   P                  V 4      P                  # rP   )r   rQ   r   r   s   &r   r   r     s    f..66q9>>r   c                 :   < SP                   P                  V 4      # rP   )r   rQ   r   s   &r   r   r     s    &**2215r   )r   r   r   r   basekilled_moduler   r   )r   s   fr   freepreshomomorphism.<locals>.freepres  s     fj))66#3#3#57RRRfn--KKf.B.B46 6f/00KK))6;;8L8L>@ @   &&*:*:*<57 	7r   )r   r=   rA   rH   rE   )r   r   r   r   SFSSSQ_TFTSTQrZ   r   s   &&&          r   homomorphismr  `  sx    x7$ V$MBBX&MBB!"*@A1Q4*@ ?200  R !45*@s   A7N)r   sympy.polys.agca.modulesr   r   r   r   r   sympy.polys.polyerrorsr   r	   r   r   r   r  r   r   r   <module>r     sX   " " 1g! g!TZX+ ZXz"0/ "0J". "DS5r   