modelparameters.sympy.polys.agca package

Submodules

modelparameters.sympy.polys.agca.homomorphisms module

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.

class modelparameters.sympy.polys.agca.homomorphisms.FreeModuleHomomorphism(domain, codomain, matrix)[source]

Bases: MatrixHomomorphism

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 ... import QQ
>>> from ...abc import x
>>> from ..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]])
class modelparameters.sympy.polys.agca.homomorphisms.MatrixHomomorphism(domain, codomain, matrix)[source]

Bases: ModuleHomomorphism

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

class modelparameters.sympy.polys.agca.homomorphisms.ModuleHomomorphism(domain, codomain)[source]

Bases: object

Abstract base class for module homomoprhisms. Do not instantiate.

Instead, use the homomorphism function:

>>> from ... import QQ
>>> from ...abc import x
>>> from ..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

image()[source]

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.

>>> from ... import QQ
>>> from ...abc import x
>>> from ..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
is_injective()[source]

Return True if self is injective.

That is, check if the elements of the domain are mapped to the same codomain element.

>>> from ... import QQ
>>> from ...abc import x
>>> from ..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
is_isomorphism()[source]

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.

>>> from ... import QQ
>>> from ...abc import x
>>> from ..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
is_surjective()[source]

Return True if self is surjective.

That is, check if every element of the codomain has at least one preimage.

>>> from ... import QQ
>>> from ...abc import x
>>> from ..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
is_zero()[source]

Return True if self is a zero morphism.

That is, check if every element of the domain is mapped to zero under self.

>>> from ... import QQ
>>> from ...abc import x
>>> from ..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
kernel()[source]

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.

>>> from ... import QQ
>>> from ...abc import x
>>> from ..agca import homomorphism
>>> F = QQ.old_poly_ring(x).free_module(2)
>>> homomorphism(F, F, [[1, 0], [x, 0]]).kernel()
<[x, -1]>
quotient_codomain(sm)[source]

Return self with codomain replaced by codomain/sm.

Here sm must be a submodule of self.codomain.

>>> from ... import QQ
>>> from ...abc import x
>>> from ..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]])
quotient_domain(sm)[source]

Return self with domain replaced by domain/sm.

Here sm must be a submodule of self.kernel().

>>> from ... import QQ
>>> from ...abc import x
>>> from ..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]])
restrict_codomain(sm)[source]

Return self, with codomain restricted to to sm.

Here sm has to be a submodule of self.codomain containing the image.

>>> from ... import QQ
>>> from ...abc import x
>>> from ..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]])
restrict_domain(sm)[source]

Return self, with the domain restricted to sm.

Here sm has to be a submodule of self.domain.

>>> from ... import QQ
>>> from ...abc import x
>>> from ..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]])
class modelparameters.sympy.polys.agca.homomorphisms.SubModuleHomomorphism(domain, codomain, matrix)[source]

Bases: MatrixHomomorphism

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 ... import QQ
>>> from ...abc import x
>>> from ..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]])
modelparameters.sympy.polys.agca.homomorphisms.homomorphism(domain, codomain, matrix)[source]

Create a homomorphism object.

This function tries to build a homomorphism from domain to codomain via the matrix matrix.

Examples

>>> from ... import QQ
>>> from ...abc import x
>>> from ..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]>

modelparameters.sympy.polys.agca.ideals module

Computations with ideals of polynomial rings.

class modelparameters.sympy.polys.agca.ideals.Ideal(ring)[source]

Bases: object

Abstract base class for ideals.

Do not instantiate - use explicit constructors in the ring class instead:

>>> from ... import QQ
>>> from ...abc import x
>>> QQ.old_poly_ring(x).ideal(x+1)
<x + 1>

Attributes

  • ring - the ring this ideal belongs to

Non-implemented methods:

  • _contains_elem

  • _contains_ideal

  • _quotient

  • _intersect

  • _union

  • _product

  • is_whole_ring

  • is_zero

  • is_prime, is_maximal, is_primary, is_radical

  • is_principal

  • height, depth

  • radical

Methods that likely should be overridden in subclasses:

  • reduce_element

contains(elem)[source]

Return True if elem is an element of this ideal.

>>> from ...abc import x
>>> from ... import QQ
>>> QQ.old_poly_ring(x).ideal(x+1, x-1).contains(3)
True
>>> QQ.old_poly_ring(x).ideal(x**2, x**3).contains(x)
False
depth()[source]

Compute the depth of self.

height()[source]

Compute the height of self.

intersect(J)[source]

Compute the intersection of self with ideal J.

>>> from ...abc import x, y
>>> from ... import QQ
>>> R = QQ.old_poly_ring(x, y)
>>> R.ideal(x).intersect(R.ideal(y))
<x*y>
is_maximal()[source]

Return True if self is a maximal ideal.

is_primary()[source]

Return True if self is a primary ideal.

is_prime()[source]

Return True if self is a prime ideal.

is_principal()[source]

Return True if self is a principal ideal.

is_radical()[source]

Return True if self is a radical ideal.

is_whole_ring()[source]

Return True if self is the whole ring.

is_zero()[source]

Return True if self is the zero ideal.

product(J)[source]

Compute the ideal product of self and J.

That is, compute the ideal generated by products xy, for x an element of self and y in J.

>>> from ...abc import x, y
>>> from ... import QQ
>>> QQ.old_poly_ring(x, y).ideal(x).product(QQ.old_poly_ring(x, y).ideal(y))
<x*y>
quotient(J, **opts)[source]

Compute the ideal quotient of self by J.

That is, if self is the ideal I, compute the set I : J = {x in R | xJ subset I }.

>>> from ...abc import x, y
>>> from ... import QQ
>>> R = QQ.old_poly_ring(x, y)
>>> R.ideal(x*y).quotient(R.ideal(x))
<y>
radical()[source]

Compute the radical of self.

reduce_element(x)[source]

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.

saturate(J)[source]

Compute the ideal saturation of self by J.

That is, if self is the ideal I, compute the set I : J^infty = {x in R | xJ^n subset I text{ for some } n}.

subset(other)[source]

Returns True if other is is a subset of self.

Here other may be an ideal.

>>> from ...abc import x
>>> from ... import QQ
>>> I = QQ.old_poly_ring(x).ideal(x+1)
>>> I.subset([x**2 - 1, x**2 + 2*x + 1])
True
>>> I.subset([x**2 + 1, x + 1])
False
>>> I.subset(QQ.old_poly_ring(x).ideal(x**2 - 1))
True
union(J)[source]

Compute the ideal generated by the union of self and J.

>>> from ...abc import x
>>> from ... import QQ
>>> QQ.old_poly_ring(x).ideal(x**2 - 1).union(QQ.old_poly_ring(x).ideal((x+1)**2)) == QQ.old_poly_ring(x).ideal(x+1)
True
class modelparameters.sympy.polys.agca.ideals.ModuleImplementedIdeal(ring, module)[source]

Bases: Ideal

Ideal implementation relying on the modules code.

Attributes:

  • _module - the underlying module

property gens

Return generators for self.

>>> from ... import QQ
>>> from ...abc import x, y
>>> list(QQ.old_poly_ring(x, y).ideal(x, y, x**2 + y).gens)
[x, y, x**2 + y]
in_terms_of_generators(e)[source]

Express e in terms of the generators of self.

>>> from ...abc import x
>>> from ... import QQ
>>> I = QQ.old_poly_ring(x).ideal(x**2 + 1, x)
>>> I.in_terms_of_generators(1)
[1, -x]
is_whole_ring()[source]

Return True if self is the whole ring, i.e. one generator is a unit.

>>> from ...abc import x
>>> from ... import QQ, ilex
>>> QQ.old_poly_ring(x).ideal(x).is_whole_ring()
False
>>> QQ.old_poly_ring(x).ideal(3).is_whole_ring()
True
>>> QQ.old_poly_ring(x, order=ilex).ideal(2 + x).is_whole_ring()
True
is_zero()[source]

Return True if self is the zero ideal.

>>> from ...abc import x
>>> from ... import QQ
>>> QQ.old_poly_ring(x).ideal(x).is_zero()
False
>>> QQ.old_poly_ring(x).ideal().is_zero()
True
reduce_element(x, **options)[source]

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.

modelparameters.sympy.polys.agca.modules module

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.

class modelparameters.sympy.polys.agca.modules.FreeModule(ring, rank)[source]

Bases: Module

Abstract base class for free modules.

Additional attributes:

  • rank - rank of the free module

Non-implemented methods:

  • submodule

basis()[source]

Return a set of basis elements.

>>> from ...abc import x
>>> from ... import QQ
>>> QQ.old_poly_ring(x).free_module(3).basis()
([1, 0, 0], [0, 1, 0], [0, 0, 1])
convert(elem, M=None)[source]

Convert elem into the internal representation.

This method is called implicitly whenever computations involve elements not in the internal representation.

>>> from ...abc import x
>>> from ... import QQ
>>> F = QQ.old_poly_ring(x).free_module(2)
>>> F.convert([1, 0])
[1, 0]
dtype

alias of FreeModuleElement

identity_hom()[source]

Return the identity homomorphism on self.

>>> from ...abc import x
>>> from ... import QQ
>>> QQ.old_poly_ring(x).free_module(2).identity_hom()
Matrix([
[1, 0], : QQ[x]**2 -> QQ[x]**2
[0, 1]])
is_submodule(other)[source]

Returns True if other is a submodule of self.

>>> from ...abc import x
>>> from ... 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
is_zero()[source]

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.)

>>> from ...abc import x
>>> from ... import QQ
>>> QQ.old_poly_ring(x).free_module(0).is_zero()
True
>>> QQ.old_poly_ring(x).free_module(1).is_zero()
False
multiply_ideal(other)[source]

Multiply self by the ideal other.

>>> from ...abc import x
>>> from ... 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]>
quotient_module(submodule)[source]

Return a quotient module.

>>> from ...abc import x
>>> from ... 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]>
class modelparameters.sympy.polys.agca.modules.FreeModuleElement(module, data)[source]

Bases: ModuleElement

Element of a free module. Data stored as a tuple.

add(d1, d2)[source]

Add data d1 and d2.

div(d, p)[source]

Divide module data m by coefficient d.

mul(d, p)[source]

Multiply module data m by coefficient d.

class modelparameters.sympy.polys.agca.modules.FreeModulePolyRing(ring, rank)[source]

Bases: FreeModule

Free module over a generalized polynomial ring.

Do not instantiate this, use the constructor method of the ring instead:

>>> from ...abc import x
>>> from ... 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
submodule(*gens, **opts)[source]

Generate a submodule.

>>> from ...abc import x, y
>>> from ... 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
class modelparameters.sympy.polys.agca.modules.FreeModuleQuotientRing(ring, rank)[source]

Bases: FreeModule

Free module over a quotient ring.

Do not instantiate this, use the constructor method of the ring instead:

>>> from ...abc import x
>>> from ... import QQ
>>> F = (QQ.old_poly_ring(x)/[x**2 + 1]).free_module(3)
>>> F
(QQ[x]/<x**2 + 1>)**3

Attributes

  • quot - the quotient module R^n / IR^n, where R/I is our ring

lift(elem)[source]

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.

>>> from ...abc import x
>>> from ... import QQ
>>> F = (QQ.old_poly_ring(x)/[x**2 + 1]).free_module(2)
>>> e = F.convert([1, 0])
>>> e
[1 + <x**2 + 1>, 0 + <x**2 + 1>]
>>> L = F.quot
>>> l = F.lift(e)
>>> l
[1, 0] + <[x**2 + 1, 0], [0, x**2 + 1]>
>>> L.contains(l)
True
submodule(*gens, **opts)[source]

Generate a submodule.

>>> from ...abc import x, y
>>> from ... import QQ
>>> M = (QQ.old_poly_ring(x, y)/[x**2 - y**2]).free_module(2).submodule([x, x + y])
>>> M
<[x + <x**2 - y**2>, x + y + <x**2 - y**2>]>
>>> M.contains([y**2, x**2 + x*y])
True
>>> M.contains([x, y])
False
unlift(elem)[source]

Push down an element of self.quot to self.

This undoes lift.

>>> from ...abc import x
>>> from ... 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
class modelparameters.sympy.polys.agca.modules.Module(ring)[source]

Bases: object

Abstract base class for modules.

Do not instantiate - use ring explicit constructors instead:

>>> from ... import QQ
>>> from ...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.

contains(elem)[source]

Return True if elem is an element of this module.

convert(elem, M=None)[source]

Convert elem into internal representation of this module.

If M is not None, it should be a module containing it.

identity_hom()[source]

Return the identity homomorphism on self.

is_submodule(other)[source]

Returns True if other is a submodule of self.

is_zero()[source]

Returns True if self is a zero module.

multiply_ideal(other)[source]

Multiply self by the ideal other.

quotient_module(other)[source]

Generate a quotient module.

submodule(*gens)[source]

Generate a submodule.

subset(other)[source]

Returns True if other is is a subset of self.

>>> from ...abc import x
>>> from ... 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
class modelparameters.sympy.polys.agca.modules.ModuleElement(module, data)[source]

Bases: object

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

add(d1, d2)[source]

Add data d1 and d2.

div(m, d)[source]

Divide module data m by coefficient d.

eq(d1, d2)[source]

Return true if d1 and d2 represent the same element.

mul(m, d)[source]

Multiply module data m by coefficient d.

class modelparameters.sympy.polys.agca.modules.ModuleOrder(o1, o2, TOP)[source]

Bases: ProductOrder

A product monomial order with a zeroth term as module index.

class modelparameters.sympy.polys.agca.modules.QuotientModule(ring, base, submodule)[source]

Bases: Module

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

convert(elem, M=None)[source]

Convert elem into the internal representation.

This method is called implicitly whenever computations involve elements not in the internal representation.

>>> from ...abc import x
>>> from ... 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]>
dtype

alias of QuotientModuleElement

identity_hom()[source]

Return the identity homomorphism on self.

>>> from ...abc import x
>>> from ... 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]])
is_submodule(other)[source]

Return True if other is a submodule of self.

>>> from ...abc import x
>>> from ... 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
is_zero()[source]

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.

>>> from ...abc import x
>>> from ... 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
quotient_hom()[source]

Return the quotient homomorphism to self.

That is, return a homomorphism representing the natural map from self.base to self.

>>> from ...abc import x
>>> from ... 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]])
submodule(*gens, **opts)[source]

Generate a submodule.

This is the same as taking a quotient of a submodule of the base module.

>>> from ...abc import x
>>> from ... import QQ
>>> Q = QQ.old_poly_ring(x).free_module(2) / [(x, x)]
>>> Q.submodule([x, 0])
<[x, 0] + <[x, x]>>
class modelparameters.sympy.polys.agca.modules.QuotientModuleElement(module, data)[source]

Bases: ModuleElement

Element of a quotient module.

eq(d1, d2)[source]

Equality comparison.

class modelparameters.sympy.polys.agca.modules.SubModule(gens, container)[source]

Bases: Module

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

convert(elem, M=None)[source]

Convert elem into the internal represantition.

Mostly called implicitly.

>>> from ...abc import x
>>> from ... import QQ
>>> M = QQ.old_poly_ring(x).free_module(2).submodule([1, x])
>>> M.convert([2, 2*x])
[2, 2*x]
identity_hom()[source]

Return the identity homomorphism on self.

>>> from ...abc import x
>>> from ... import QQ
>>> QQ.old_poly_ring(x).free_module(2).submodule([x, x]).identity_hom()
Matrix([
[1, 0], : <[x, x]> -> <[x, x]>
[0, 1]])
in_terms_of_generators(e)[source]

Express element e of self in terms of the generators.

>>> from ...abc import x
>>> from ... 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])
[-x**2 + x, x**2]
inclusion_hom()[source]

Return a homomorphism representing the inclusion map of self.

That is, the natural map from self to self.container.

>>> from ...abc import x
>>> from ... 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]])
intersect(other, **options)[source]

Returns the intersection of self with submodule other.

>>> from ...abc import x, y
>>> from ... 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]>, [(y,)], [(x,)])

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.

is_full_module()[source]

Return True if self is the entire free module.

>>> from ...abc import x
>>> from ... 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
is_submodule(other)[source]

Returns True if other is a submodule of self.

>>> from ...abc import x
>>> from ... 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
is_zero()[source]

Return True if self is a zero module.

>>> from ...abc import x
>>> from ... 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
module_quotient(other, **options)[source]

Returns the module quotient of self by submodule other.

That is, if self is the module M and other is N, then return the ideal {f in R | fN subset M}.

>>> from ... import QQ
>>> from ...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)
<y>

Some implementations allow further options to be passed. Currently, the only one implemented is relations=True, which may only be passed if other is prinicipal. 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)
(<y>, [[1]])

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.

multiply_ideal(I)[source]

Multiply self by the ideal I.

>>> from ...abc import x
>>> from ... 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]>
quotient_module(other, **opts)[source]

Return a quotient module.

This is the same as taking a submodule of a quotient of the containing module.

>>> from ...abc import x
>>> from ... 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]>>
reduce_element(x)[source]

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.

submodule(*gens)[source]

Generate a submodule.

>>> from ...abc import x
>>> from ... import QQ
>>> M = QQ.old_poly_ring(x).free_module(2).submodule([x, 1])
>>> M.submodule([x**2, x])
<[x**2, x]>
syzygy_module(**opts)[source]

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.

The syzygy module is zero iff the generators generate freely a free submodule:

>>> from ...abc import x, y
>>> from ... 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
union(other)[source]

Returns the module generated by the union of self and other.

>>> from ...abc import x
>>> from ... import QQ
>>> F = QQ.old_poly_ring(x).free_module(1)
>>> M = F.submodule([x**2 + x]) # <x(x+1)>
>>> N = F.submodule([x**2 - 1]) # <(x-1)(x+1)>
>>> M.union(N) == F.submodule([x+1])
True
class modelparameters.sympy.polys.agca.modules.SubModulePolyRing(gens, container, order='lex', TOP=True)[source]

Bases: SubModule

Submodule of a free module over a generalized polynomial ring.

Do not instantiate this, use the constructor method of FreeModule instead:

>>> from ...abc import x, y
>>> from ... 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

reduce_element(x, NF=None)[source]

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!).

class modelparameters.sympy.polys.agca.modules.SubModuleQuotientRing(gens, container)[source]

Bases: SubModule

Class for submodules of free modules over quotient rings.

Do not instantiate this. Instead use the submodule methods.

>>> from ...abc import x, y
>>> from ... import QQ
>>> M = (QQ.old_poly_ring(x, y)/[x**2 - y**2]).free_module(2).submodule([x, x + y])
>>> M
<[x + <x**2 - y**2>, x + y + <x**2 - y**2>]>
>>> 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

class modelparameters.sympy.polys.agca.modules.SubQuotientModule(gens, container, **opts)[source]

Bases: SubModule

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 ...abc import x
>>> from ... 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

is_full_module()[source]

Return True if self is the entire free module.

>>> from ...abc import x
>>> from ... 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
quotient_hom()[source]

Return the quotient homomorphism to self.

That is, return the natural map from self.base to self.

>>> from ...abc import x
>>> from ... 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]])

Module contents

Module for algebraic geometry and commutative algebra.