K idZddlmZddlmZddlmZddlmZddlm Z m Z ddl m Z ddl mZdd lmZdd lmZGd d ZGd dZGddeZGddeZGddeZGddeZGddeZGddeZdZdZGdde ZGdd eZGd!d"eZGd#d$eZ Gd%d&eZ!y')(ao Computations with modules over polynomial rings. This module implements various classes that encapsulate groebner basis computations for modules. Most of them should not be instantiated by hand. Instead, use the constructing routines on objects you already have. For example, to construct a free module over ``QQ[x, y]``, call ``QQ[x, y].free_module(rank)`` instead of the ``FreeModule`` constructor. In fact ``FreeModule`` is an abstract base class that should not be instantiated, the ``free_module`` method instead returns the implementing class ``FreeModulePolyRing``. In general, the abstract base classes implement most functionality in terms of a few non-implemented methods. The concrete base classes supply only these non-implemented methods. They may also supply new implementations of the convenience methods, for example if there are faster algorithms available. )copy)reduce)Ideal)Field) ProductOrder monomial_key)DMP)CoercionFailed)_aresame)iterablecpeZdZdZdZddZdZdZdZdZ d Z d Z d Z d Z d ZdZdZdZeZdZy)Modulea Abstract base class for modules. Do not instantiate - use ring explicit constructors instead: >>> from sympy import QQ >>> from sympy.abc import x >>> QQ.old_poly_ring(x).free_module(2) QQ[x]**2 Attributes: - dtype - type of elements - ring - containing ring Non-implemented methods: - submodule - quotient_module - is_zero - is_submodule - multiply_ideal The method convert likely needs to be changed in subclasses. c||_yN)ring)selfrs ^/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/sympy/polys/agca/modules.py__init__zModule.__init__Gs  Nc>t||jst|S)z Convert ``elem`` into internal representation of this module. If ``M`` is not None, it should be a module containing it. ) isinstancedtyper relemMs rconvertzModule.convertJs $ +  rct)zGenerate a submodule.NotImplementedErrorrgenss r submodulezModule.submoduleT!!rct)zGenerate a quotient module.rrothers rquotient_modulezModule.quotient_moduleXr#rcbt|ts|j|}|j|Sr)rrr"r'res r __truediv__zModule.__truediv__\s-!V$"A##A&&rcF |j|y#t$rYywxYw)z5Return True if ``elem`` is an element of this module.TF)rr rrs rcontainszModule.containsas(  LL   s   c$|j|Srr.r-s r __contains__zModule.__contains__is}}T""rc,tfd|DS)aN Returns True if ``other`` is is a subset of ``self``. Examples ======== >>> from sympy.abc import x >>> from sympy import QQ >>> F = QQ.old_poly_ring(x).free_module(2) >>> F.subset([(1, x), (x, 2)]) True >>> F.subset([(1/x, x), (x, 2)]) False c3@K|]}j|ywrr0.0xrs r z Module.subset..{s34==#3)allr%s` rsubsetz Module.subsetls3U333rcJ|j|xr|j|Sr) is_submoduler%s r__eq__z Module.__eq__}s#  'DE,>,>t,DDrc||k( Srr%s r__ne__z Module.__ne__sEM""rct)z*Returns True if ``self`` is a zero module.rrs ris_zerozModule.is_zeror#rct)z5Returns True if ``other`` is a submodule of ``self``.rr%s rr<zModule.is_submoduler#rct)z; Multiply ``self`` by the ideal ``other``. rr%s rmultiply_idealzModule.multiply_ideals "!rct|ts |jj|}|j|S#tt f$r t cYSwxYwr)rrridealr rNotImplementedrFr)s r__mul__zModule.__mul__sS!U# &IIOOA&""1%%#$78 &%% &s>AAct)z-Return the identity homomorphism on ``self``.rrBs r identity_homzModule.identity_homr#rr)__name__ __module__ __qualname____doc__rrr"r'r+r.r1r:r=r@rCr<rFrJ__rmul__rLr?rrrr,sZ4""' #4"E#""" &H"rrcfeZdZdZdZdZdZdZdZdZ e Z dZ d Z d Z d ZeZd Zd ZdZy) ModuleElementa Base class for module element wrappers. Use this class to wrap primitive data types as module elements. It stores a reference to the containing module, and implements all the arithmetic operators. Attributes: - module - containing module - data - internal data Methods that likely need change in subclasses: - add - mul - div - eq c ||_||_yr)moduledata)rrUrVs rrzModuleElement.__init__s  rc ||zS)zAdd data ``d1`` and ``d2``.r?rd1d2s raddzModuleElement.adds Bwrc ||zS)z,Multiply module data ``m`` by coefficient d.r?rmds rmulzModuleElement.mul 1u rc ||z S)z*Divide module data ``m`` by coefficient d.r?r]s rdivzModuleElement.divrarc ||k(S)z4Return true if d1 and d2 represent the same element.r?rXs reqzModuleElement.eqs RxrcBt||jr|j|jk7r |jj|}|j|j|j |j|jS#t$r t cYSwxYwr)r __class__rUrr rIr[rVroms r__add__zModuleElement.__add__sy"dnn-dkk1I &[[((,~~dkk488DIIrww+GHH" &%% &sB BBc |j|j|j|j|jjj dS)N)rgrUr`rVrrrBs r__neg__zModuleElement.__neg__sB~~dkk488DII{{''//3,56 6rct||jr|j|jk7r |jj|}|j | S#t$r t cYSwxYwr)rrgrUrr rIrjrhs r__sub__zModuleElement.__sub__sb"dnn-dkk1I &[[((,||RC  " &%% &sAA0/A0c&| j|Sr)rjrhs r__rsub__zModuleElement.__rsub__sr""rc8t||jjjs& |jjj |}|j|j|j|j|S#t $r t cYSwxYwr) rrUrrrr rIrgr`rVros rrJzModuleElement.__mul__x!T[[--334 &KK$$,,Q/~~dkk488DIIq+ABB" &%% &%BBBc8t||jjjs& |jjj |}|j|j|j|j|S#t $r t cYSwxYwr) rrUrrrr rIrgrcrVrss rr+zModuleElement.__truediv__rurvct||jr|j|jk7r |jj|}|j |j |j S#t$rYywxYwNF)rrgrUrr rerVrhs rr=zModuleElement.__eq__sg"dnn-dkk1I [[((,wwtyy"''**"  sA22 A>=A>c||k( Srr?rhs rr@zModuleElement.__ne__s2:~rN)rMrNrOrPrr[r`rcrerj__radd__rmrorqrJrQr+r=r@r?rrrSrSsY(IH6!#CHC+rrSc4eZdZdZdZdZdZdZdZdZ y) FreeModuleElementz1Element of a free module. Data stored as a tuple.c:tdt||DS)Nc3,K|] \}}||zywrr?)r5r6ys rr7z(FreeModuleElement.add..s3tq!QU3s)tupleziprXs rr[zFreeModuleElement.adds3s2r{333rc,tfd|DS)Nc3(K|] }|z ywrr?r5r6ps rr7z(FreeModuleElement.mul.. &qQU&rrr_rs `rr`zFreeModuleElement.mul &A&&&rc,tfd|DS)Nc3(K|] }|z  ywrr?rs rr7z(FreeModuleElement.div..rrrrs `rrczFreeModuleElement.div rrcddlm|j}td|Dr2|Dcgc]'}|jj j |)}}ddjfd|DzdzScc}w)Nr)sstrc3<K|]}t|tywr)rr r5r6s rr7z-FreeModuleElement.__repr__..s0az!S!0s[, c3.K|] }|ywrr?)r5r6rs rr7z-FreeModuleElement.__repr__..s51tAw5s])sympy.printing.strrrVanyrUrto_sympyjoin)rrVr6rs @r__repr__zFreeModuleElement.__repr__sj+yy 040 0:>?QDKK$$--a0?D?TYY5555;;@s,A8c6|jjSr)rV__iter__rBs rrzFreeModuleElement.__iter__syy!!##rc |j|Sr)rV)ridxs r __getitem__zFreeModuleElement.__getitem__syy~rN) rMrNrOrPr[r`rcrrrr?rrr}r}s#;4''<$rr}cLeZdZdZeZdZdZdZd dZ dZ dZ d Z d Z d Zy) FreeModulez Abstract base class for free modules. Additional attributes: - rank - rank of the free module Non-implemented methods: - submodule c>tj||||_yr)rrrank)rrrs rrzFreeModule.__init__-sd# rc^t|jdzt|jzS)N**reprrrrBs rrzFreeModule.__repr__1s"DII%TYY77rct|tr|j|k(St|tr4|j|jk(xr|j |j k(Sy)a Returns True if ``other`` is a submodule of ``self``. Examples ======== >>> from sympy.abc import x >>> from sympy import QQ >>> F = QQ.old_poly_ring(x).free_module(2) >>> M = F.submodule([2, x]) >>> F.is_submodule(F) True >>> F.is_submodule(M) True >>> M.is_submodule(F) False F)r SubModule containerrrrr%s rr<zFreeModule.is_submodule4sO$ eY '??d* * eZ (::*FuzzTYY/F FrNcttrbjurSjjjk7rttt fdj DStr>t fdD}t|jk7rtt|Stdr3tjjdfjzSt)a Convert ``elem`` into the internal representation. This method is called implicitly whenever computations involve elements not in the internal representation. Examples ======== >>> from sympy.abc import x >>> from sympy import QQ >>> F = QQ.old_poly_ring(x).free_module(2) >>> F.convert([1, 0]) [1, 0] c3~K|]4}jj|jj6ywr)rrrU)r5r6rrs rr7z%FreeModule.convert..bs,Ua499,,Q 0@0@AU:=c3TK|]}jj|!ywr)rrr4s rr7z%FreeModule.convert..ds ; ))!,;s%(r) rr}rUrr rrVr lenr rr)rrrtpls`` rrzFreeModule.convertLs d- .{{d" {{499,$$$TU499UUW W d^;d;;C3x499$$$$T3/ / dA $TDII,=,=a,@+B499+LM M rc |jdk(S)a Returns True if ``self`` is a zero module. (If, as this implementation assumes, the coefficient ring is not the zero ring, then this is equivalent to the rank being zero.) Examples ======== >>> from sympy.abc import x >>> from sympy import QQ >>> QQ.old_poly_ring(x).free_module(0).is_zero() True >>> QQ.old_poly_ring(x).free_module(1).is_zero() False r)rrBs rrCzFreeModule.is_zeroms"yyA~rcddlm}|jtfdt jDS)z Return a set of basis elements. Examples ======== >>> from sympy.abc import x >>> from sympy import QQ >>> QQ.old_poly_ring(x).free_module(3).basis() ([1, 0, 0], [0, 1, 0], [0, 0, 1]) r)eyec3^K|]$}jj|&ywr)rrow)r5irrs rr7z#FreeModule.basis..s"FT\\!%%(+Fs*-)sympy.matricesrrrrange)rrrs` @rbasiszFreeModule.basiss/ '  NFU4995EFFFrc0t|j||S)a Return a quotient module. Examples ======== >>> from sympy.abc import x >>> from sympy import QQ >>> M = QQ.old_poly_ring(x).free_module(2) >>> M.quotient_module(M.submodule([1, x], [x, 2])) QQ[x]**2/<[1, x], [x, 2]> Or more conicisely, using the overloaded division operator: >>> QQ.old_poly_ring(x).free_module(2) / [[1, x], [x, 2]] QQ[x]**2/<[1, x], [x, 2]> )QuotientModuler)rr"s rr'zFreeModule.quotient_modules$diiy99rcZ|j|jj|S)a= Multiply ``self`` by the ideal ``other``. Examples ======== >>> from sympy.abc import x >>> from sympy import QQ >>> I = QQ.old_poly_ring(x).ideal(x) >>> F = QQ.old_poly_ring(x).free_module(2) >>> F.multiply_ideal(I) <[x, 0], [0, x]> )r"rrFr%s rrFzFreeModule.multiply_ideals&t~~tzz|,;;EBBrc>ddlm}||||jS)a/ Return the identity homomorphism on ``self``. Examples ======== >>> from sympy.abc import x >>> from sympy import QQ >>> QQ.old_poly_ring(x).free_module(2).identity_hom() Matrix([ [1, 0], : QQ[x]**2 -> QQ[x]**2 [0, 1]]) r) homomorphism)sympy.polys.agca.homomorphismsrr)rrs rrLzFreeModule.identity_homs @D$ 55rr)rMrNrOrPr}rrrr<rrCrr'rFrLr?rrrrs>  E80!B&G :(C 6rrceZdZdZdZdZy)FreeModulePolyRingaw Free module over a generalized polynomial ring. Do not instantiate this, use the constructor method of the ring instead: Examples ======== >>> from sympy.abc import x >>> from sympy import QQ >>> F = QQ.old_poly_ring(x).free_module(3) >>> F QQ[x]**3 >>> F.contains([x, 1, 0]) True >>> F.contains([1/x, 0, 1]) False cddlm}tj|||t ||st dd|zzt |j tst dd|j zzy)Nr)PolynomialRingBase$This implementation only works over zpolynomial rings, got %szGround domain must be a field, zgot %s)&sympy.polys.domains.old_polynomialringrrrrrdomr)rrrrs rrzFreeModulePolyRing.__init__svMD$-$ 23%&L(BT(I'JK K$((E*%&G(0488(;'<= =+rct||fi|S)ae Generate a submodule. Examples ======== >>> from sympy.abc import x, y >>> from sympy import QQ >>> M = QQ.old_poly_ring(x, y).free_module(2).submodule([x, x + y]) >>> M <[x, x + y]> >>> M.contains([2*x, 2*x + 2*y]) True >>> M.contains([x, y]) False )SubModulePolyRingrr!optss rr"zFreeModulePolyRing.submodules"!t4t44rN)rMrNrOrPrr"r?rrrrs&=5rrc.eZdZdZdZdZdZdZdZy)FreeModuleQuotientRinga Free module over a quotient ring. Do not instantiate this, use the constructor method of the ring instead: Examples ======== >>> from sympy.abc import x >>> from sympy import QQ >>> F = (QQ.old_poly_ring(x)/[x**2 + 1]).free_module(3) >>> F (QQ[x]/)**3 Attributes - quot - the quotient module `R^n / IR^n`, where `R/I` is our ring cddlm}tj|||t ||st dd|zz|j j j|j}||j j|zz |_ y)Nr) QuotientRingrzquotient rings, got %s) sympy.polys.domains.quotientringrrrrrr free_moduler base_idealquot)rrrrFs rrzFreeModuleQuotientRing.__init__ swAD$-$ -%&L7$>'?@ @ IINN & &tyy 1--a/0 rcjdt|jzdzdzt|jzS)N()rrrBs rrzFreeModuleQuotientRing.__repr__s,T$))_$s*T1DOCCrct||fi|S)a Generate a submodule. Examples ======== >>> from sympy.abc import x, y >>> from sympy import QQ >>> M = (QQ.old_poly_ring(x, y)/[x**2 - y**2]).free_module(2).submodule([x, x + y]) >>> M <[x + , x + y + ]> >>> M.contains([y**2, x**2 + x*y]) True >>> M.contains([x, y]) False )SubModuleQuotientRingrs rr"z FreeModuleQuotientRing.submodules"%T48488rcr|jj|Dcgc]}|jc}Scc}w)ae Lift the element ``elem`` of self to the module self.quot. Note that self.quot is the same set as self, just as an R-module and not as an R/I-module, so this makes sense. Examples ======== >>> from sympy.abc import x >>> from sympy import QQ >>> F = (QQ.old_poly_ring(x)/[x**2 + 1]).free_module(2) >>> e = F.convert([1, 0]) >>> e [1 + , 0 + ] >>> L = F.quot >>> l = F.lift(e) >>> l [1, 0] + <[x**2 + 1, 0], [0, x**2 + 1]> >>> L.contains(l) True )rrrVrrr6s rliftzFreeModuleQuotientRing.lift+s+.yy  $!7Q!&&!788!7s4c8|j|jS)a Push down an element of self.quot to self. This undoes ``lift``. Examples ======== >>> from sympy.abc import x >>> from sympy import QQ >>> F = (QQ.old_poly_ring(x)/[x**2 + 1]).free_module(2) >>> e = F.convert([1, 0]) >>> l = F.lift(e) >>> e == l False >>> e == F.unlift(l) True )rrVr-s runliftzFreeModuleQuotientRing.unliftDs&||DII&&rN) rMrNrOrPrrr"rrr?rrrrs!&1D9&92'rrceZdZdZdZdZdZdZdZddZ d Z d Z d Z d Z d ZdZdZdZdZdZdZdZdZdZeZdZdZdZy)ra Base class for submodules. Attributes: - container - containing module - gens - generators (subset of containing module) - rank - rank of containing module Non-implemented methods: - _contains - _syzygies - _in_terms_of_generators - _intersect - _module_quotient Methods that likely need change in subclasses: - reduce_element ctj|jtfd|D|_|_j |_j|_j|_y)Nc3@K|]}j|ywr)r)r5r6rs rr7z%SubModule.__init__..ws=1)++A.=r8)rrrrr!rrr)rr!rs `rrzSubModule.__init__usOinn-=== "NN NN __ rcRddjd|jDzdzS)N.~s:1tAw:s>)rr!rBs rrzSubModule.__repr__}s%TYY: :::S@@rct)zVImplementation of containment. Other is guaranteed to be FreeModuleElement.rr%s r _containszSubModule._contains "!rct)z9Implementation of syzygy computation wrt self generators.rrBs r _syzygieszSubModule._syzygiesr#rct)z4Implementation of expression in terms of generators.rr)s r_in_terms_of_generatorsz!SubModule._in_terms_of_generatorsr#rNct||jjr|j|ur|St |jj ||}||_|j |st|S)aF Convert ``elem`` into the internal represantition. Mostly called implicitly. Examples ======== >>> from sympy.abc import x >>> from sympy import QQ >>> M = QQ.old_poly_ring(x).free_module(2).submodule([1, x]) >>> M.convert([2, 2*x]) [2, 2*x] )rrrrUrrrr )rrrrs rrzSubModule.convertsa dDNN00 1dkkT6IK ''a0 1~~a  rct)zeImplementation of intersection. Other is guaranteed to be a submodule of same free module.rr%s r _intersectzSubModule._intersectrrct)zaImplementation of quotient. Other is guaranteed to be a submodule of same free module.rr%s r_module_quotientzSubModule._module_quotientrrc t|tstd|z|j|jk7rt d|z|j |fi|S)a Returns the intersection of ``self`` with submodule ``other``. Examples ======== >>> from sympy.abc import x, y >>> from sympy import QQ >>> F = QQ.old_poly_ring(x, y).free_module(2) >>> F.submodule([x, x]).intersect(F.submodule([y, y])) <[x*y, x*y]> Some implementation allow further options to be passed. Currently, to only one implemented is ``relations=True``, in which case the function will return a triple ``(res, rela, relb)``, where ``res`` is the intersection module, and ``rela`` and ``relb`` are lists of coefficient vectors, expressing the generators of ``res`` in terms of the generators of ``self`` (``rela``) and ``other`` (``relb``). >>> F.submodule([x, x]).intersect(F.submodule([y, y]), relations=True) (<[x*y, x*y]>, [(DMP_Python([[1, 0]], QQ),)], [(DMP_Python([[1], []], QQ),)]) The above result says: the intersection module is generated by the single element `(-xy, -xy) = -y (x, x) = -x (y, y)`, where `(x, x)` and `(y, y)` respectively are the unique generators of the two modules being intersected. %s is not a SubModule*%s is contained in a different free module)rr TypeErrorr ValueErrorrrr&optionss r intersectzSubModule.intersects\8%+3e;< < ??dnn ,>> from sympy import QQ >>> from sympy.abc import x, y >>> F = QQ.old_poly_ring(x, y).free_module(2) >>> S = F.submodule([x*y, x*y]) >>> T = F.submodule([x, x]) >>> S.module_quotient(T) Some implementations allow further options to be passed. Currently, the only one implemented is ``relations=True``, which may only be passed if ``other`` is principal. In this case the function will return a pair ``(res, rel)`` where ``res`` is the ideal, and ``rel`` is a list of coefficient vectors, expressing the generators of the ideal, multiplied by the generator of ``other`` in terms of generators of ``self``. >>> S.module_quotient(T, relations=True) (, [[DMP_Python([[1]], QQ)]]) This means that the quotient ideal is generated by the single element `y`, and that `y (x, x) = 1 (xy, xy)`, `(x, x)` and `(xy, xy)` being the generators of `T` and `S`, respectively. rr)rrrrrrrs rmodule_quotientzSubModule.module_quotients_B%+3e;< < ??dnn ,>> from sympy.abc import x >>> from sympy import QQ >>> F = QQ.old_poly_ring(x).free_module(1) >>> M = F.submodule([x**2 + x]) # >>> N = F.submodule([x**2 - 1]) # <(x-1)(x+1)> >>> M.union(N) == F.submodule([x+1]) True rr)rrrrrrgr!r%s runionzSubModule.unionsh%+3e;< < ??dnn ,>> from sympy.abc import x >>> from sympy import QQ >>> F = QQ.old_poly_ring(x).free_module(2) >>> F.submodule([x, 1]).is_zero() False >>> F.submodule([0, 0]).is_zero() True c3&K|] }|dk( yw)rNr?rs rr7z$SubModule.is_zero..s-a16-s)r9r!rBs rrCzSubModule.is_zeros-499---rc||j|st|d||j||jS)a  Generate a submodule. Examples ======== >>> from sympy.abc import x >>> from sympy import QQ >>> M = QQ.old_poly_ring(x).free_module(2).submodule([x, 1]) >>> M.submodule([x**2, x]) <[x**2, x]> z not a subset of )r:rrgrr s rr"zSubModule.submodule s5{{4 dCD D~~dDNN33rc\tfdjjDS)e Return True if ``self`` is the entire free module. Examples ======== >>> from sympy.abc import x >>> from sympy import QQ >>> F = QQ.old_poly_ring(x).free_module(2) >>> F.submodule([x, 1]).is_full_module() False >>> F.submodule([1, 1], [1, 2]).is_full_module() True c3@K|]}j|ywrr0r4s rr7z+SubModule.is_full_module..@sD4==#Dr8)r9rrrBs`ris_full_modulezSubModule.is_full_module1s#DT^^-A-A-CDDDrct|tr9j|jk(xrtfd|jDSt|t t fr!j|k(xrjSy)a Returns True if ``other`` is a submodule of ``self``. >>> from sympy.abc import x >>> from sympy import QQ >>> F = QQ.old_poly_ring(x).free_module(2) >>> M = F.submodule([2, x]) >>> N = M.submodule([2*x, x**2]) >>> M.is_submodule(M) True >>> M.is_submodule(N) True >>> N.is_submodule(M) False c3@K|]}j|ywrr0r4s rr7z)SubModule.is_submodule..Ts9DMM!$9r8F)rrrr9r!rrrr%s` rr<zSubModule.is_submoduleBsj eY '>>U__4:9ejj99 : ej.9 :>>U*Dt/B/B/D Drc |jjt|j}|j|j Dcgc]}|j |dk7s|c}i|Scc}w)a Compute the syzygy module of the generators of ``self``. Suppose `M` is generated by `f_1, \ldots, f_n` over the ring `R`. Consider the homomorphism `\phi: R^n \to M`, given by sending `(r_1, \ldots, r_n) \to r_1 f_1 + \cdots + r_n f_n`. The syzygy module is defined to be the kernel of `\phi`. Examples ======== The syzygy module is zero iff the generators generate freely a free submodule: >>> from sympy.abc import x, y >>> from sympy import QQ >>> QQ.old_poly_ring(x).free_module(2).submodule([1, 0], [1, 1]).syzygy_module().is_zero() True A slightly more interesting example: >>> M = QQ.old_poly_ring(x, y).free_module(2).submodule([x, 2*x], [y, 2*y]) >>> S = QQ.old_poly_ring(x, y).free_module(2).submodule([y, -x]) >>> M.syzygy_module() == S True r)rrrr!r"rr)rrrr6s r syzygy_modulezSubModule.syzygy_moduleYsc6 II ! !#dii. 1q{{(8N1AIIaLA>> from sympy.abc import x >>> from sympy import QQ >>> F = QQ.old_poly_ring(x).free_module(2) >>> M = F.submodule([1, 0], [1, 1]) >>> M.in_terms_of_generators([x, x**2]) # doctest: +SKIP [DMP_Python([-1, 1, 0], QQ), DMP_Python([1, 0, 0], QQ)] z is not an element of )rr rrr)s rin_terms_of_generatorsz SubModule.in_terms_of_generators{sK G QA++A.. GQEF F Gs$>c|S)z Reduce the element ``x`` of our ring modulo the ideal ``self``. Here "reduce" has no specific meaning, it could return a unique normal form, simplify the expression a bit, or just do nothing. r?rr6s rreduce_elementzSubModule.reduce_elements rc |j|st|d|t|j|jj |fi|S)aI Return a quotient module. This is the same as taking a submodule of a quotient of the containing module. Examples ======== >>> from sympy.abc import x >>> from sympy import QQ >>> F = QQ.old_poly_ring(x).free_module(2) >>> S1 = F.submodule([x, 1]) >>> S2 = F.submodule([x**2, x]) >>> S1.quotient_module(S2) <[x, 1] + <[x**2, x]>> Or more coincisely, using the overloaded division operator: >>> F.submodule([x, 1]) / [(x**2, x)] <[x, 1] + <[x**2, x]>> z not a submodule of )r<rSubQuotientModuler!rr')rr&rs rr'zSubModule.quotient_modulesO.  '5$GH H ..u5?9=? ?rcV|jj|j|Sr)rr'r)roths rrjzSubModule.__add__s"~~--d3;;C@@rc |j|jjDcgc]\}|jD]}||z c}}Scc}}w)a< Multiply ``self`` by the ideal ``I``. Examples ======== >>> from sympy.abc import x >>> from sympy import QQ >>> I = QQ.old_poly_ring(x).ideal(x**2) >>> M = QQ.old_poly_ring(x).free_module(2).submodule([1, 1]) >>> I*M <[x**2, x**2]> )r"_moduler!)rIr6gs rrFzSubModule.multiply_idealsAt~~qyy~~QtyyQ!!QQRRQsA cT|jjj|S)a Return a homomorphism representing the inclusion map of ``self``. That is, the natural map from ``self`` to ``self.container``. Examples ======== >>> from sympy.abc import x >>> from sympy import QQ >>> QQ.old_poly_ring(x).free_module(2).submodule([x, x]).inclusion_hom() Matrix([ [1, 0], : <[x, x]> -> QQ[x]**2 [0, 1]]) )rrLrestrict_domainrBs r inclusion_homzSubModule.inclusion_homs" ~~**,<>> from sympy.abc import x >>> from sympy import QQ >>> QQ.old_poly_ring(x).free_module(2).submodule([x, x]).identity_hom() Matrix([ [1, 0], : <[x, x]> -> <[x, x]> [0, 1]]) )rrLrrestrict_codomainrBs rrLzSubModule.identity_homs2~~**,<< ##D) *rr)rMrNrOrPrrrrrrrrrrrrCr"rr<rr r r'rjr{rFrrLr?rrrr^s,%A" ""." " !1F&7PF,."4"E". #D/(?8AHS C$*rrc4eZdZdZdZdZdZdZdZdZ y) ra Submodule of a quotient module. Equivalently, quotient module of a submodule. Do not instantiate this, instead use the submodule or quotient_module constructing methods: >>> from sympy.abc import x >>> from sympy import QQ >>> F = QQ.old_poly_ring(x).free_module(2) >>> S = F.submodule([1, 0], [1, x]) >>> Q = F/[(1, 0)] >>> S/[(1, 0)] == Q.submodule([5, x]) True Attributes: - base - base module we are quotient of - killed_module - submodule used to form the quotient c >tj||||jj|_|jjj |j Dcgc]}|jc}i|j|j|_ycc}wr) rrr killed_modulebaser"r!rVr)rr!rrr6s rrzSubQuotientModule.__init__sz4y1!^^992DNN''11"ii (aff (2,0227%8J8J2K (s!BcL|jj|jSr)rr.rVr-s rrzSubQuotientModule._contains syy!!$)),,rc|jjDcgc]}|dt|jc}Scc}wr)rrrr!)rXs rrzSubQuotientModule._syzygiess4-1II,?,?,ABq/3tyy>"BBBs?cx|jj|jdt|jSr)rrrVrr!r)s rrz)SubQuotientModule._in_terms_of_generatorss*yy008#dii.IIrc6|jjS)r)rrrBs rrz SubQuotientModule.is_full_modulesyy''))rch|jjj|jS)a Return the quotient homomorphism to self. That is, return the natural map from ``self.base`` to ``self``. Examples ======== >>> from sympy.abc import x >>> from sympy import QQ >>> M = (QQ.old_poly_ring(x).free_module(2) / [(1, x)]).submodule([1, 0]) >>> M.quotient_hom() Matrix([ [1, 0], : <[1, 0], [1, x]> -> <[1, 0] + <[1, x]>, [1, x] + <[1, x]>> [0, 1]]) rrLquotient_codomainrrBs r quotient_homzSubQuotientModule.quotient_hom0s("yy%%'99$:L:LMMrN) rMrNrOrPrrrrrr'r?rrrrs)*L- CJ*"Nrrc |dS)Nrr?r6s rr*Ds 1Q4rc |ddS)Nr?r)s rr*r*Es 1QR5rceZdZdZdZy) ModuleOrderz>> from sympy.abc import x, y >>> from sympy import QQ >>> F = QQ.old_poly_ring(x, y).free_module(2) >>> F.submodule([x, y], [1, 0]) <[x, y], [1, 0]> Attributes: - order - monomial order used ctj|||t|tst dd|zzt t ||jj||_d|_ d|_ y)Nz)This implementation is for submodules of zFreeModulePolyRing, got %s) rrrrrr.rrorder_gb_gbe)rr!rr7r4s rrzSubModulePolyRing.__init__fsj4y1)%78%&Q;iG'HI I e!4diioosK  rct|tr|j|jk7rytj ||Sry)rrr7rr=r%s rr=zSubModulePolyRing.__eq__os2 e. /DJJ%++4Me,,rc ddlm}m}|j|r||jDcgc](}|j j ||j*c}||j|j jd\}}t|t|c|_ |_|jst||jDcgc](}|j j ||j*c}||j|j j|_ |r|j|jfS|jScc}wcc}w)z%Returns a standard basis in sdm form.r) sdm_groebner sdm_nf_moraTextended) sympy.polys.distributedmodulesr<r=r9r!r_vector_to_sdmr7rrr8)rr?r<r=r6gbgbes r _groebnerzSubModulePolyRing._groebnertsL 99 "BF))LQ))!TZZ8LTZZGGB#()U3Z DHdi 88 \OSyyY!dii66q$**EYDJJ 78DH 88TYY& &88OM Zs -E-E c |sU|jDcgc];}t|t|jj ||j =c}S|jd\}}|Dcgc]7}|j |jj ||j 9c}|Dcgc]1}|jj |t|j3c}fScc}wcc}wcc}w)z)Returns a standard basis in element form.Tr>) rDr}rr_sdm_to_vectorrrrr!)rr?r6rBrCs r _groebner_veczSubModulePolyRing._groebner_vecs"^^-/&ddii66q$))DEG/ /..$./Cdii66q$))DEFIJ))!S^<JL L /JsAC-1>+TZZH J rc t|j}|j}|jj d|jj d}|jj ||z}g}t |jD]k\}}dg||zz}t |D] \} } | || < t|D]} || k(r|n||| z<t|t|}|j|m|j|ddd} | j} | D cgc]} tfd| d|Ds| |d!}} |Scc} w)z-Compute syzygies. See [SCA, algorithm 2.5.4].rr,ilexFr7r4c3(K|] }|k( ywrr?)r5rzeros rr7z.SubModulePolyRing._syzygies..s%?Aa4i%?rN)rr!rrrr enumeraterr}rappendr"rGr9)rkroneRkrnewgensjfr^rvrGr6G0rNs @rrzSubModulePolyRing._syzygiessN  N IIyy  #ii"ii##AE*dii( DAqQU A!!  1! 1X 3"#q&3d!a% 3!#uQx0A NN1   CMM7&e < OO  @#%?2A%?"?ae @ @ As #E E ct|jj|jj|f|jz}|j dd}|j }|Dcgc]#}|jj|ds"|%c}d}|ddDcgc] }| |dz  c}Scc}wcc}w)z4Expression in terms of generators. See [SCA, 2.8.1].rKFrLrr,N)rrrr"r!rrGis_unit)rr*rSrXr6s rrz)SubModulePolyRing._in_terms_of_generatorss 7DII ! !$)) , 6 6! 9I K OOe  % OO  51TYY..qt4Q 5a 8!"12'A1Q4'' 6's(#B0 B0B5Nc Fddlm}||}|jj|jj ||jj ||j|j|j|jj|jS)z Reduce the element ``x`` of our container modulo ``self``. This applies the normal form ``NF`` to ``x``. If ``NF`` is passed as none, the default Mora normal form is used (which is not unique!). r)r=) r@r=rrrrFrAr7rDrr)rr6NFr=s rr z SubModulePolyRing.reduce_elements| ? :B~~%%dii&>&>r II $ $Q 3T^^5E JJ @' II' rc $j}|j}jtDcgc] }dgdzz }}tD]}d|||<d|||z<|Dcgc]}t|dgzz} }|D cgc]} dgzt| z} } jj dzj || z| zj} | D cgc]} tfd| dDs| }} jj fd|D}|D cgc]} | t|z}} |D cgc]} | t|zd}} |r|||fS|Scc}wcc}wcc} wcc} wcc} wcc} w)Nrr,c3PK|]}|jjk7ywrrrNr5rrs rr7z/SubModulePolyRing._intersect..s(Ldiinn)<(L#&c3PK|]}|dDcgc]}| c}ycc}wwrr?)r5r6rrs rr7z/SubModulePolyRing._intersect..s'(Nae)<1")<(N)*FF3FF c 6|rt|jdk7rtt|jdk(rjj dSt|jdk(rmt |jddgz}jDcgc]}t |dgz}}jj jdzj|g|zddd}|sOjj|jDcgc]}tfd|ddDr|d c}S|jd \}}t|D cgc]\} }tfd |ddDr|  } } }jj| D cgc] } || d c} | D cgc]} || ddDcgc]}| c}c}} fStd fd |jDScc}wcc}wcc}} wcc} wcc}wcc}} w) Nr,rrKFrLc3PK|]}|jjk(ywrrbrcs rr7z5SubModulePolyRing._module_quotient..s,QQQ$))..-@,QrdrlTr>c3PK|]}|jjk(ywrrbrcs rr7z5SubModulePolyRing._module_quotient..sCqqDIINN2Crdc$|j|Sr)r)r6rs rr*z4SubModulePolyRing._module_quotient..s1;;q>rc3rK|].}jjj|0ywr)rrr"r4s rr7z5SubModulePolyRing._module_quotient..s+ TAT " "4>>#;#;A#> ? Ts47) rr!rrrHrfrrr"rGr9rOr) rr&rgg1r6girrXRrindicess ` rrz"SubModulePolyRing._module_quotients UZZA-% % uzz?a 99??1% % _ ! ejjm$s*B)-3A$q'QC-3B3> %%dii!m4>>"28eEA&tyy8I)S1),,Q!CR&,Q)Q*+2)STT51)21EACAcrFCCEE' G)Dq!A$r()DE9@AAad12h/1"/ACC 1 T TV V!4 )SE)D/As0G;#H!#H!H 8H HHH)lexT)Fr)rMrNrOrPrr=rDrGrrrr rrr?rrrrRs<&- " L B ( (Vrrc(eZdZdZdZdZdZdZy)ra Class for submodules of free modules over quotient rings. Do not instantiate this. Instead use the submodule methods. >>> from sympy.abc import x, y >>> from sympy import QQ >>> M = (QQ.old_poly_ring(x, y)/[x**2 - y**2]).free_module(2).submodule([x, x + y]) >>> M <[x + , x + y + ]> >>> M.contains([y**2, x**2 + x*y]) True >>> M.contains([x, y]) False Attributes: - quot - the subquotient of `R^n/IR^n` generated by lifts of our generators ctj||||jjj|j Dcgc]}|jj |c}|_ycc}wr)rrrrr"r!r)rr!rr6s rrzSubModuleQuotientRing.__init__sV4y11DNN''11.2ii 8dnn!!!$ 8: 8s"A2cj|jj|jj|Sr)rrrrr-s rrzSubModuleQuotientRing._contains s&yy""4>>#6#6t#<==rcjjDcgc]}tfd|Dc}Scc}w)Nc3~K|]4}jj|jj6ywr)rrrrcs rr7z2SubModuleQuotientRing._syzygies..$s*Fqdii''499>>:Fr)rrrr s` rrzSubModuleQuotientRing._syzygies#s;,,.0FAFF0 00s<c|jj|jj|Dcgc]2}|jj ||jj4c}Scc}wr)rrrrrrrs rrz-SubModuleQuotientRing._in_terms_of_generators'sY II - -dnn.A.A$.G HJ !!!TYY^^4J JJs7A1N)rMrNrOrPrrrrr?rrrrs(: >0JrrceZdZdZdZdZy)QuotientModuleElementzElement of a quotient module.cR|jjj||z S)zEquality comparison.)rUrr.rXs rrezQuotientModuleElement.eq3s!{{((11"r'::rcrt|jdzt|jjzS)Nz + )rrVrUrrBs rrzQuotientModuleElement.__repr__7s)DII&dkk.G.G)HHHrN)rMrNrOrPrerr?rrrr0s';IrrcFeZdZdZeZdZdZdZdZ dZ d dZ d Z d Z y) ra Class for quotient modules. Do not instantiate this directly. For subquotients, see the SubQuotientModule class. Attributes: - base - the base module we are a quotient of - killed_module - the submodule used to form the quotient - rank of the base ctj|||j|st|d|||_||_|j |_y)Nz is not a submodule of )rrr<rrrr)rrrr"s rrzQuotientModule.__init__KsHd#  +iNO O &II rc^t|jdzt|jzS)N/)rrrrBs rrzQuotientModule.__repr__Ss%DII$tD,>,>'???rc4|j|jk(S)a Return True if ``self`` is a zero module. This happens if and only if the base module is the same as the submodule being killed. Examples ======== >>> from sympy.abc import x >>> from sympy import QQ >>> F = QQ.old_poly_ring(x).free_module(2) >>> (F/[(1, 0)]).is_zero() False >>> (F/[(1, 0), (0, 1)]).is_zero() True )rrrBs rrCzQuotientModule.is_zeroVs$yyD....rct|tr@|j|jk(xr%|jj |jSt|t r|j |k(Sy)ah Return True if ``other`` is a submodule of ``self``. Examples ======== >>> from sympy.abc import x >>> from sympy import QQ >>> Q = QQ.old_poly_ring(x).free_module(2) / [(x, x)] >>> S = Q.submodule([1, 0]) >>> Q.is_submodule(S) True >>> S.is_submodule(Q) False F)rrrrr<rrr%s rr<zQuotientModule.is_submodulejs_ e^ ,%%)<)<<3 &&uzz2 3 e. /??d* *rct||fi|S)ad Generate a submodule. This is the same as taking a quotient of a submodule of the base module. Examples ======== >>> from sympy.abc import x >>> from sympy import QQ >>> Q = QQ.old_poly_ring(x).free_module(2) / [(x, x)] >>> Q.submodule([x, 0]) <[x, 0] + <[x, x]>> )rrs rr"zQuotientModule.submodules !t4t44rNcTt|trt|j|ur|S|jj |jjr/t||j j |jStt||j j |S)a Convert ``elem`` into the internal representation. This method is called implicitly whenever computations involve elements not in the internal representation. Examples ======== >>> from sympy.abc import x >>> from sympy import QQ >>> F = QQ.old_poly_ring(x).free_module(2) / [(1, 2), (1, x)] >>> F.convert([1, 0]) [1, 0] + <[1, 2], [1, x]> ) rrrUrr<rrrVr rs rrzQuotientModule.converts d1 2{{d" !!..t{{/H/HI,T4993D3DTYY3OPP $T499+<+>> from sympy.abc import x >>> from sympy import QQ >>> M = QQ.old_poly_ring(x).free_module(2) / [(1, 2), (1, x)] >>> M.identity_hom() Matrix([ [1, 0], : QQ[x]**2/<[1, 2], [1, x]> -> QQ[x]**2/<[1, 2], [1, x]> [0, 1]]) )rrLr&rquotient_domainrBs rrLzQuotientModule.identity_homs>yy%%'99    /0B0B C Drch|jjj|jS)a Return the quotient homomorphism to ``self``. That is, return a homomorphism representing the natural map from ``self.base`` to ``self``. Examples ======== >>> from sympy.abc import x >>> from sympy import QQ >>> M = QQ.old_poly_ring(x).free_module(2) / [(1, 2), (1, x)] >>> M.quotient_hom() Matrix([ [1, 0], : QQ[x]**2 -> QQ[x]**2/<[1, 2], [1, x]> [0, 1]]) r%rBs rr'zQuotientModule.quotient_homs-$yy%%'99     rr)rMrNrOrPrrrrrCr<r"rrLr'r?rrrr;s9  "E@/(.5$D0D$ rrN)"rPr functoolsrsympy.polys.agca.idealsrsympy.polys.domains.fieldrsympy.polys.orderingsrrsympy.polys.polyclassesr sympy.polys.polyerrorsr sympy.core.basicr sympy.utilities.iterablesr rrSr}rrrrrr1r0r.rrrrr?rrrs()+<'1%.q"q"h]]H 4e6e6P/5/5d_'Z_'LL*L*^ TN TNn  D,DqV qVh#JI#JTIMIU VU r