
    \h{                       S r SSKJrJr  SSKJr  SSKJr  SSKJ	r	  SSK
Jr  SSKJr  SSKJr  SS	KJr  SS
KJr  SSKJr  SSKJr  SSKJr  SSKJrJr  SSKJr  SSKJ r J!r!J"r"  SSK#J$r$J%r%J&r&  S r' " S S5      r( " S S\(5      r) " S S\(\5      r*S r+S*S jr, " S S\5      r- " S S\-5      r. " S  S!5      r/ " S" S#\/5      r0 " S$ S%\05      r1 " S& S'5      r2S+S) jr3g(),aR  Modules in number fields.

The classes defined here allow us to work with finitely generated, free
modules, whose generators are algebraic numbers.

There is an abstract base class called :py:class:`~.Module`, which has two
concrete subclasses, :py:class:`~.PowerBasis` and :py:class:`~.Submodule`.

Every module is defined by its basis, or set of generators:

* For a :py:class:`~.PowerBasis`, the generators are the first $n$ powers
  (starting with the zeroth) of an algebraic integer $\theta$ of degree $n$.
  The :py:class:`~.PowerBasis` is constructed by passing either the minimal
  polynomial of $\theta$, or an :py:class:`~.AlgebraicField` having $\theta$
  as its primitive element.

* For a :py:class:`~.Submodule`, the generators are a set of
  $\mathbb{Q}$-linear combinations of the generators of another module. That
  other module is then the "parent" of the :py:class:`~.Submodule`. The
  coefficients of the $\mathbb{Q}$-linear combinations may be given by an
  integer matrix, and a positive integer denominator. Each column of the matrix
  defines a generator.

>>> from sympy.polys import Poly, cyclotomic_poly, ZZ
>>> from sympy.abc import x
>>> from sympy.polys.matrices import DomainMatrix, DM
>>> from sympy.polys.numberfields.modules import PowerBasis
>>> T = Poly(cyclotomic_poly(5, x))
>>> A = PowerBasis(T)
>>> print(A)
PowerBasis(x**4 + x**3 + x**2 + x + 1)
>>> B = A.submodule_from_matrix(2 * DomainMatrix.eye(4, ZZ), denom=3)
>>> print(B)
Submodule[[2, 0, 0, 0], [0, 2, 0, 0], [0, 0, 2, 0], [0, 0, 0, 2]]/3
>>> print(B.parent)
PowerBasis(x**4 + x**3 + x**2 + x + 1)

Thus, every module is either a :py:class:`~.PowerBasis`,
or a :py:class:`~.Submodule`, some ancestor of which is a
:py:class:`~.PowerBasis`. (If ``S`` is a :py:class:`~.Submodule`, then its
ancestors are ``S.parent``, ``S.parent.parent``, and so on).

The :py:class:`~.ModuleElement` class represents a linear combination of the
generators of any module. Critically, the coefficients of this linear
combination are not restricted to be integers, but may be any rational
numbers. This is necessary so that any and all algebraic integers be
representable, starting from the power basis in a primitive element $\theta$
for the number field in question. For example, in a quadratic field
$\mathbb{Q}(\sqrt{d})$ where $d \equiv 1 \mod{4}$, a denominator of $2$ is
needed.

A :py:class:`~.ModuleElement` can be constructed from an integer column vector
and a denominator:

>>> U = Poly(x**2 - 5)
>>> M = PowerBasis(U)
>>> e = M(DM([[1], [1]], ZZ), denom=2)
>>> print(e)
[1, 1]/2
>>> print(e.module)
PowerBasis(x**2 - 5)

The :py:class:`~.PowerBasisElement` class is a subclass of
:py:class:`~.ModuleElement` that represents elements of a
:py:class:`~.PowerBasis`, and adds functionality pertinent to elements
represented directly over powers of the primitive element $\theta$.


Arithmetic with module elements
===============================

While a :py:class:`~.ModuleElement` represents a linear combination over the
generators of a particular module, recall that every module is either a
:py:class:`~.PowerBasis` or a descendant (along a chain of
:py:class:`~.Submodule` objects) thereof, so that in fact every
:py:class:`~.ModuleElement` represents an algebraic number in some field
$\mathbb{Q}(\theta)$, where $\theta$ is the defining element of some
:py:class:`~.PowerBasis`. It thus makes sense to talk about the number field
to which a given :py:class:`~.ModuleElement` belongs.

This means that any two :py:class:`~.ModuleElement` instances can be added,
subtracted, multiplied, or divided, provided they belong to the same number
field. Similarly, since $\mathbb{Q}$ is a subfield of every number field,
any :py:class:`~.ModuleElement` may be added, multiplied, etc. by any
rational number.

>>> from sympy import QQ
>>> from sympy.polys.numberfields.modules import to_col
>>> T = Poly(cyclotomic_poly(5))
>>> A = PowerBasis(T)
>>> C = A.submodule_from_matrix(3 * DomainMatrix.eye(4, ZZ))
>>> e = A(to_col([0, 2, 0, 0]), denom=3)
>>> f = A(to_col([0, 0, 0, 7]), denom=5)
>>> g = C(to_col([1, 1, 1, 1]))
>>> e + f
[0, 10, 0, 21]/15
>>> e - f
[0, 10, 0, -21]/15
>>> e - g
[-9, -7, -9, -9]/3
>>> e + QQ(7, 10)
[21, 20, 0, 0]/30
>>> e * f
[-14, -14, -14, -14]/15
>>> e ** 2
[0, 0, 4, 0]/9
>>> f // g
[7, 7, 7, 7]/15
>>> f * QQ(2, 3)
[0, 0, 0, 14]/15

However, care must be taken with arithmetic operations on
:py:class:`~.ModuleElement`, because the module $C$ to which the result will
belong will be the nearest common ancestor (NCA) of the modules $A$, $B$ to
which the two operands belong, and $C$ may be different from either or both
of $A$ and $B$.

>>> A = PowerBasis(T)
>>> B = A.submodule_from_matrix(2 * DomainMatrix.eye(4, ZZ))
>>> C = A.submodule_from_matrix(3 * DomainMatrix.eye(4, ZZ))
>>> print((B(0) * C(0)).module == A)
True

Before the arithmetic operation is performed, copies of the two operands are
automatically converted into elements of the NCA (the operands themselves are
not modified). This upward conversion along an ancestor chain is easy: it just
requires the successive multiplication by the defining matrix of each
:py:class:`~.Submodule`.

Conversely, downward conversion, i.e. representing a given
:py:class:`~.ModuleElement` in a submodule, is also supported -- namely by
the :py:meth:`~sympy.polys.numberfields.modules.Submodule.represent` method
-- but is not guaranteed to succeed in general, since the given element may
not belong to the submodule. The main circumstance in which this issue tends
to arise is with multiplication, since modules, while closed under addition,
need not be closed under multiplication.


Multiplication
--------------

Generally speaking, a module need not be closed under multiplication, i.e. need
not form a ring. However, many of the modules we work with in the context of
number fields are in fact rings, and our classes do support multiplication.

Specifically, any :py:class:`~.Module` can attempt to compute its own
multiplication table, but this does not happen unless an attempt is made to
multiply two :py:class:`~.ModuleElement` instances belonging to it.

>>> A = PowerBasis(T)
>>> print(A._mult_tab is None)
True
>>> a = A(0)*A(1)
>>> print(A._mult_tab is None)
False

Every :py:class:`~.PowerBasis` is, by its nature, closed under multiplication,
so instances of :py:class:`~.PowerBasis` can always successfully compute their
multiplication table.

When a :py:class:`~.Submodule` attempts to compute its multiplication table,
it converts each of its own generators into elements of its parent module,
multiplies them there, in every possible pairing, and then tries to
represent the results in itself, i.e. as $\mathbb{Z}$-linear combinations
over its own generators. This will succeed if and only if the submodule is
in fact closed under multiplication.


Module Homomorphisms
====================

Many important number theoretic algorithms require the calculation of the
kernel of one or more module homomorphisms. Accordingly we have several
lightweight classes, :py:class:`~.ModuleHomomorphism`,
:py:class:`~.ModuleEndomorphism`, :py:class:`~.InnerEndomorphism`, and
:py:class:`~.EndomorphismRing`, which provide the minimal necessary machinery
to support this.

    )igcdilcm)Dummy)ANP)Poly)dup_clear_denoms)AlgebraicField)FF)QQ)ZZ)DomainMatrix)DMBadInputError)hermite_normal_form)CoercionFailedUnificationFailed)IntegerPowerable   )ClosureFailureMissingUnityErrorStructureError)AlgIntPowersis_ratget_num_denomc                     [        U  Vs/ s H  n[        U5      PM     sn/S[        U 5      4[        5      R                  5       $ s  snf )z>Transform a list of integer coefficients into a column vector.r   )r   r   len	transpose)coeffscs     X/var/www/auris/envauris/lib/python3.13/site-packages/sympy/polys/numberfields/modules.pyto_colr       s<    0A"Q%01As6{3CRHRRTT0s   Ac                       \ rS rSrSr\S 5       rS r\S 5       rS r	SS jr
S rS	 r\S
 5       rS rSS jrS rS rS rS rS rSS jrSS jrS rS rSrg)Module   a:  
Generic finitely-generated module.

This is an abstract base class, and should not be instantiated directly.
The two concrete subclasses are :py:class:`~.PowerBasis` and
:py:class:`~.Submodule`.

Every :py:class:`~.Submodule` is derived from another module, referenced
by its ``parent`` attribute. If ``S`` is a submodule, then we refer to
``S.parent``, ``S.parent.parent``, and so on, as the "ancestors" of
``S``. Thus, every :py:class:`~.Module` is either a
:py:class:`~.PowerBasis` or a :py:class:`~.Submodule`, some ancestor of
which is a :py:class:`~.PowerBasis`.
c                     [         e)z(The number of generators of this module.NotImplementedErrorselfs    r   nModule.n   s
     "!    c                     [         e)a|  
Get the multiplication table for this module (if closed under mult).

Explanation
===========

Computes a dictionary ``M`` of dictionaries of lists, representing the
upper triangular half of the multiplication table.

In other words, if ``0 <= i <= j < self.n``, then ``M[i][j]`` is the
list ``c`` of coefficients such that
``g[i] * g[j] == sum(c[k]*g[k], k in range(self.n))``,
where ``g`` is the list of generators of this module.

If ``j < i`` then ``M[i][j]`` is undefined.

Examples
========

>>> from sympy.polys import Poly, cyclotomic_poly
>>> from sympy.polys.numberfields.modules import PowerBasis
>>> T = Poly(cyclotomic_poly(5))
>>> A = PowerBasis(T)
>>> print(A.mult_tab())  # doctest: +SKIP
{0: {0: [1, 0, 0, 0], 1: [0, 1, 0, 0], 2: [0, 0, 1, 0],     3: [0, 0, 0, 1]},
                  1: {1: [0, 0, 1, 0], 2: [0, 0, 0, 1],     3: [-1, -1, -1, -1]},
                                   2: {2: [-1, -1, -1, -1], 3: [1, 0, 0, 0]},
                                                        3: {3: [0, 1, 0, 0]}}

Returns
=======

dict of dict of lists

Raises
======

ClosureFailure
    If the module is not closed under multiplication.

r%   r'   s    r   mult_tabModule.mult_tab   s    T "!r+   c                     g)a  
The parent module, if any, for this module.

Explanation
===========

For a :py:class:`~.Submodule` this is its ``parent`` attribute; for a
:py:class:`~.PowerBasis` this is ``None``.

Returns
=======

:py:class:`~.Module`, ``None``

See Also
========

Module

N r'   s    r   parentModule.parent  s    , r+   c                     [         e)aY
  
Represent a module element as an integer-linear combination over the
generators of this module.

Explanation
===========

In our system, to "represent" always means to write a
:py:class:`~.ModuleElement` as a :ref:`ZZ`-linear combination over the
generators of the present :py:class:`~.Module`. Furthermore, the
incoming :py:class:`~.ModuleElement` must belong to an ancestor of
the present :py:class:`~.Module` (or to the present
:py:class:`~.Module` itself).

The most common application is to represent a
:py:class:`~.ModuleElement` in a :py:class:`~.Submodule`. For example,
this is involved in computing multiplication tables.

On the other hand, representing in a :py:class:`~.PowerBasis` is an
odd case, and one which tends not to arise in practice, except for
example when using a :py:class:`~.ModuleEndomorphism` on a
:py:class:`~.PowerBasis`.

In such a case, (1) the incoming :py:class:`~.ModuleElement` must
belong to the :py:class:`~.PowerBasis` itself (since the latter has no
proper ancestors) and (2) it is "representable" iff it belongs to
$\mathbb{Z}[\theta]$ (although generally a
:py:class:`~.PowerBasisElement` may represent any element of
$\mathbb{Q}(\theta)$, i.e. any algebraic number).

Examples
========

>>> from sympy import Poly, cyclotomic_poly
>>> from sympy.polys.numberfields.modules import PowerBasis, to_col
>>> from sympy.abc import zeta
>>> T = Poly(cyclotomic_poly(5))
>>> A = PowerBasis(T)
>>> a = A(to_col([2, 4, 6, 8]))

The :py:class:`~.ModuleElement` ``a`` has all even coefficients.
If we represent ``a`` in the submodule ``B = 2*A``, the coefficients in
the column vector will be halved:

>>> B = A.submodule_from_gens([2*A(i) for i in range(4)])
>>> b = B.represent(a)
>>> print(b.transpose())  # doctest: +SKIP
DomainMatrix([[1, 2, 3, 4]], (1, 4), ZZ)

However, the element of ``B`` so defined still represents the same
algebraic number:

>>> print(a.poly(zeta).as_expr())
8*zeta**3 + 6*zeta**2 + 4*zeta + 2
>>> print(B(b).over_power_basis().poly(zeta).as_expr())
8*zeta**3 + 6*zeta**2 + 4*zeta + 2

Parameters
==========

elt : :py:class:`~.ModuleElement`
    The module element to be represented. Must belong to some ancestor
    module of this module (including this module itself).

Returns
=======

:py:class:`~.DomainMatrix` over :ref:`ZZ`
    This will be a column vector, representing the coefficients of a
    linear combination of this module's generators, which equals the
    given element.

Raises
======

ClosureFailure
    If the given element cannot be represented as a :ref:`ZZ`-linear
    combination over this module.

See Also
========

.Submodule.represent
.PowerBasis.represent

r%   r(   elts     r   	representModule.represent%  s    n "!r+   c                 v    U R                   nUc  / OUR                  SS9nU(       a  UR                  U 5        U$ )z
Return the list of ancestor modules of this module, from the
foundational :py:class:`~.PowerBasis` downward, optionally including
``self``.

See Also
========

Module

Tinclude_self)r1   	ancestorsappend)r(   r:   r   as       r   r;   Module.ancestors~  s6     KK)B$!?HHTNr+   c                 p    [        U [        5      (       a  U $ U R                  nUb  UR                  5       $ g)ze
Return the :py:class:`~.PowerBasis` that is an ancestor of this module.

See Also
========

Module

N)
isinstance
PowerBasisr1   power_basis_ancestor)r(   r   s     r   rB   Module.power_basis_ancestor  s6     dJ''KKK=))++r+   c                     U R                  SS9nUR                  SS9nSn[        X#5       H  u  pVXV:X  a  UnM    U$    U$ )z
Locate the nearest common ancestor of this module and another.

Returns
=======

:py:class:`~.Module`, ``None``

See Also
========

Module

Tr9   N)r;   zip)r(   othersAoAncasaoas          r   nearest_common_ancestorModule.nearest_common_ancestor  sR     ^^^.__$_/"kFBx
 "
 
r+   c                 6    U R                  5       R                  $ )a  
Return the associated :py:class:`~.AlgebraicField`, if any.

Explanation
===========

A :py:class:`~.PowerBasis` can be constructed on a :py:class:`~.Poly`
$f$ or on an :py:class:`~.AlgebraicField` $K$. In the latter case, the
:py:class:`~.PowerBasis` and all its descendant modules will return $K$
as their ``.number_field`` property, while in the former case they will
all return ``None``.

Returns
=======

:py:class:`~.AlgebraicField`, ``None``

)rB   number_fieldr'   s    r   rO   Module.number_field  s    ( ((*777r+   c                     [        U[        5      =(       a8    UR                  U R                  S4:H  =(       a    UR                  R
                  $ )z>Say whether *col* is a suitable column vector for this module.r   )r@   r   shaper)   domainis_ZZ)r(   cols     r   is_compat_colModule.is_compat_col  s4    #|,^tvvqk1I^cjjN^N^^r+   c                 *   [        U[        5      (       aT  SUs=::  a  U R                  :  a=  O  O:[        R                  " U R                  [
        5      SS2U4   R                  5       nU R                  U5      (       d  [        S5      e[        XUS9$ )a  
Generate a :py:class:`~.ModuleElement` belonging to this module.

Examples
========

>>> from sympy.polys import Poly, cyclotomic_poly
>>> from sympy.polys.numberfields.modules import PowerBasis, to_col
>>> T = Poly(cyclotomic_poly(5))
>>> A = PowerBasis(T)
>>> e = A(to_col([1, 2, 3, 4]), denom=3)
>>> print(e)  # doctest: +SKIP
[1, 2, 3, 4]/3
>>> f = A(2)
>>> print(f)  # doctest: +SKIP
[0, 0, 1, 0]

Parameters
==========

spec : :py:class:`~.DomainMatrix`, int
    Specifies the numerators of the coefficients of the
    :py:class:`~.ModuleElement`. Can be either a column vector over
    :ref:`ZZ`, whose length must equal the number $n$ of generators of
    this module, or else an integer ``j``, $0 \leq j < n$, which is a
    shorthand for column $j$ of $I_n$, the $n \times n$ identity
    matrix.
denom : int, optional (default=1)
    Denominator for the coefficients of the
    :py:class:`~.ModuleElement`.

Returns
=======

:py:class:`~.ModuleElement`
    The coefficients are the entries of the *spec* vector, divided by
    *denom*.

r   Nz"Compatible column vector required.denom)
r@   intr)   r   eyer   to_denserV   
ValueErrormake_mod_elt)r(   specrZ   s      r   __call__Module.__call__  st    P dC  Q$%7%7##DFFB/48AACD!!$''ABBDe44r+   c                     [         e)z6Say whether the module's first generator equals unity.r%   r'   s    r   starts_with_unityModule.starts_with_unity  s    !!r+   c                 b    [        U R                  5       Vs/ s H
  o" U5      PM     sn$ s  snf )zN
Get list of :py:class:`~.ModuleElement` being the generators of this
module.
)ranger)   )r(   js     r   basis_elementsModule.basis_elements  s(    
 "'tvv/AQ///s   ,c                     U " S5      S-  $ )z7Return a :py:class:`~.ModuleElement` representing zero.r   r0   r'   s    r   zeroModule.zero  s    Aw{r+   c                 $    U R                  S5      $ )z
Return a :py:class:`~.ModuleElement` representing unity,
and belonging to the first ancestor of this module (including
itself) that starts with unity.
r   )element_from_rationalr'   s    r   one
Module.one  s     ))!,,r+   c                     [         e)az  
Return a :py:class:`~.ModuleElement` representing a rational number.

Explanation
===========

The returned :py:class:`~.ModuleElement` will belong to the first
module on this module's ancestor chain (including this module
itself) that starts with unity.

Examples
========

>>> from sympy.polys import Poly, cyclotomic_poly, QQ
>>> from sympy.polys.numberfields.modules import PowerBasis
>>> T = Poly(cyclotomic_poly(5))
>>> A = PowerBasis(T)
>>> a = A.element_from_rational(QQ(2, 3))
>>> print(a)  # doctest: +SKIP
[2, 0, 0, 0]/3

Parameters
==========

a : int, :ref:`ZZ`, :ref:`QQ`

Returns
=======

:py:class:`~.ModuleElement`

r%   r(   r=   s     r   ro   Module.element_from_rational  s    B "!r+   Nc                   ^  [        U 4S jU 5       5      (       d  [        S5      e[        U5      nUS:X  a  [        S5      eUS   R                  nUS:X  a  US   R                  O![        U Vs/ s H  ofR                  PM     sn6 n[        R                  " US4[        5      R                  " U Vs/ s H  ogUR                  -  UR                  -  PM      sn6 nU(       a	  [        XS9nT R                  XS9$ s  snf s  snf )a  
Form the submodule generated by a list of :py:class:`~.ModuleElement`
belonging to this module.

Examples
========

>>> from sympy.polys import Poly, cyclotomic_poly
>>> from sympy.polys.numberfields.modules import PowerBasis
>>> T = Poly(cyclotomic_poly(5))
>>> A = PowerBasis(T)
>>> gens = [A(0), 2*A(1), 3*A(2), 4*A(3)//5]
>>> B = A.submodule_from_gens(gens)
>>> print(B)  # doctest: +SKIP
Submodule[[5, 0, 0, 0], [0, 10, 0, 0], [0, 0, 15, 0], [0, 0, 0, 4]]/5

Parameters
==========

gens : list of :py:class:`~.ModuleElement` belonging to this module.
hnf : boolean, optional (default=True)
    If True, we will reduce the matrix into Hermite Normal Form before
    forming the :py:class:`~.Submodule`.
hnf_modulus : int, None, optional (default=None)
    Modulus for use in the HNF reduction algorithm. See
    :py:func:`~sympy.polys.matrices.normalforms.hermite_normal_form`.

Returns
=======

:py:class:`~.Submodule`

See Also
========

submodule_from_matrix

c              3   @   >#    U  H  oR                   T:H  v   M     g 7fN)module).0gr(   s     r   	<genexpr>-Module.submodule_from_gens.<locals>.<genexpr>c  s     2T88t#Ts   z&Generators must belong to this module.r   zNeed at least one generator.r   DrY   )allr^   r   r)   rZ   r   r   zerosr   hstackrU   r   submodule_from_matrix)	r(   genshnfhnf_modulusr)   mrz   dBs	   `        r   submodule_from_gensModule.submodule_from_gens<  s    N 2T222EFFI6;<<GII!VDGMM/FA/F)G1vr*11TX3YTXq!''\QUU4JTX3YZ#A5A))!)55	 0G3Ys   0C<4%Dc                     UR                   u  p4UR                  R                  (       d  [        S5      eX0R                  :X  d  [        S5      e[        XUS9$ )a  
Form the submodule generated by the elements of this module indicated
by the columns of a matrix, with an optional denominator.

Examples
========

>>> from sympy.polys import Poly, cyclotomic_poly, ZZ
>>> from sympy.polys.matrices import DM
>>> from sympy.polys.numberfields.modules import PowerBasis
>>> T = Poly(cyclotomic_poly(5))
>>> A = PowerBasis(T)
>>> B = A.submodule_from_matrix(DM([
...     [0, 10, 0, 0],
...     [0,  0, 7, 0],
... ], ZZ).transpose(), denom=15)
>>> print(B)  # doctest: +SKIP
Submodule[[0, 10, 0, 0], [0, 0, 7, 0]]/15

Parameters
==========

B : :py:class:`~.DomainMatrix` over :ref:`ZZ`
    Each column gives the numerators of the coefficients of one
    generator of the submodule. Thus, the number of rows of *B* must
    equal the number of generators of the present module.
denom : int, optional (default=1)
    Common denominator for all generators of the submodule.

Returns
=======

:py:class:`~.Submodule`

Raises
======

ValueError
    If the given matrix *B* is not over :ref:`ZZ` or its number of rows
    does not equal the number of generators of the present module.

See Also
========

submodule_from_gens

zMatrix must be over ZZ.z(Matrix row count must match base module.rY   )rR   rS   rT   r^   r)   	Submodule)r(   r   rZ   r   r)   s        r   r   Module.submodule_from_matrixo  sI    ` wwxx~~677FF{GHH..r+   c                 n    [         R                  " U R                  [        5      nU R	                  U5      $ )z
Return a submodule equal to this entire module.

Explanation
===========

This is useful when you have a :py:class:`~.PowerBasis` and want to
turn it into a :py:class:`~.Submodule` (in order to use methods
belonging to the latter).

)r   r\   r)   r   r   )r(   r   s     r   whole_submoduleModule.whole_submodule  s+     TVVR())!,,r+   c                     [        U 5      $ )z8Form the :py:class:`~.EndomorphismRing` for this module.)EndomorphismRingr'   s    r   endomorphism_ringModule.endomorphism_ring  s    %%r+   r0   )Fr   TN)__name__
__module____qualname____firstlineno____doc__propertyr)   r-   r1   r6   r;   rB   rL   rO   rV   ra   rd   ri   rl   rp   ro   r   r   r   r   __static_attributes__r0   r+   r   r"   r"      s     " "*"X  .W"r$"2 8 8*_,5\"0-!"F16f5/n-&r+   r"   c                       \ rS rSrSrS r\S 5       rS rS r	\S 5       r
S rS	 rS
 rS rS rS rS rS rS rSrg)rA   i  z;The module generated by the powers of an algebraic integer.c                     Sn[        U[        5      (       a  XR                  R                  5       pUR	                  [
        5      nX l        Xl        UR                  5       U l	        SU l
        g)a@  
Parameters
==========

T : :py:class:`~.Poly`, :py:class:`~.AlgebraicField`
    Either (1) the monic, irreducible, univariate polynomial over
    :ref:`ZZ`, a root of which is the generator of the power basis,
    or (2) an :py:class:`~.AlgebraicField` whose primitive element
    is the generator of the power basis.

N)r@   r	   extminpoly_of_element
set_domainr   KTdegree_n	_mult_tab)r(   r   r   s      r   __init__PowerBasis.__init__  sV     a((ee..0q LL((*r+   c                     U R                   $ rw   )r   r'   s    r   rO   PowerBasis.number_field  s    vvr+   c                 >    SU R                   R                  5        S3$ )NzPowerBasis())r   as_exprr'   s    r   __repr__PowerBasis.__repr__  s    TVV^^-.a00r+   c                 j    [        U[        5      (       a  U R                  UR                  :H  $ [        $ rw   )r@   rA   r   NotImplementedr(   rF   s     r   __eq__PowerBasis.__eq__  s(    eZ((66UWW$$r+   c                     U R                   $ rw   r   r'   s    r   r)   PowerBasis.n      wwr+   c                 T    U R                   c  U R                  5         U R                   $ rw   r   compute_mult_tabr'   s    r   r-   PowerBasis.mult_tab  "    >>!!!#~~r+   c                     [        U R                  5      n0 nU R                  n[        U5       H%  n0 X$'   [        XC5       H  nXU-      X$   U'   M     M'     X l        g rw   )r   r   r)   rg   r   )r(   	theta_powMr)   uvs         r   r   PowerBasis.compute_mult_tab  sZ     (	FFqAAD1[#E*Q !  r+   c                 x    UR                   U :X  a   UR                  S:X  a  UR                  5       $ [        S5      e)z
Represent a module element as an integer-linear combination over the
generators of this module.

See Also
========

.Module.represent
.Submodule.represent

r   z'Element not representable in ZZ[theta].)rx   rZ   columnr   r4   s     r   r6   PowerBasis.represent  s2     ::#))q.::< !JKKr+   c                     g)NTr0   r'   s    r   rd   PowerBasis.starts_with_unity  s    r+   c                     U " S5      U-  $ Nr   r0   rs   s     r   ro    PowerBasis.element_from_rational  s    Aw{r+   c                 b   U R                   UR                  5       p2X2:  a  XR                  -  nUS:X  a  U R                  5       $ [	        UR
                  R                  5       [        SS9u  pE[        [        U5      5      n[        U5      n[        S5      /X&-
  -  n[        XW-   5      nU " XS9$ )z
Produce an element of this module, representing *f* after reduction mod
our defining minimal polynomial.

Parameters
==========

f : :py:class:`~.Poly` over :ref:`ZZ` in same var as our defining poly.

Returns
=======

:py:class:`~.PowerBasisElement`

r   T)convertrY   )r)   r   r   rl   r   repto_listr   listreversedr   r   r    )	r(   fr)   kr   r   ellzrU   s	            r   element_from_polyPowerBasis.element_from_poly
  s      vvqxxz16FF
A699;TB!!fUGqwQUmC!!r+   c                     X R                   R                  R                  5       :w  a  [        S5      eU R	                  [        XR                   R                  5      5      $ )a^  
Produce a PowerBasisElement representing a given algebraic number.

Parameters
==========

rep : list of coeffs
    Represents the number as polynomial in the primitive element of the
    field.

mod : list of coeffs
    Represents the minimal polynomial of the primitive element of the
    field.

Returns
=======

:py:class:`~.PowerBasisElement`

z0Element does not appear to be in the same field.)r   r   r   r   r   r   gen)r(   r   mods      r   _element_from_rep_and_mod$PowerBasis._element_from_rep_and_mod&  sE    * &&**$$&&#$VWW%%d3

&;<<r+   c                 ^    U R                  UR                  5       UR                  5       5      $ )z)Convert an ANP into a PowerBasisElement. )r   r   mod_to_listrs   s     r   element_from_ANPPowerBasis.element_from_ANP?  s!    --aiik1==?KKr+   c                     U R                  UR                  R                  5       UR                  R                  R                  5       5      $ )z5Convert an AlgebraicNumber into a PowerBasisElement. )r   r   r   minpolyrs   s     r   element_from_alg_numPowerBasis.element_from_alg_numC  s0    --aeemmoqyy}}?T?T?VWWr+   )r   r   r   r   N)r   r   r   r   r   r   r   rO   r   r   r)   r-   r   r6   rd   ro   r   r   r   r   r   r0   r+   r   rA   rA     sl    E.  1
  
L""8=2LXr+   rA   c                      \ rS rSrSrSS jrS rS rS r\	S 5       r
S	 rS
 r\	S 5       r\	S 5       r\	S 5       r\	S 5       r\	S 5       rS rS rS rS rS rS rS rS rS S jrS r\rS S jrS r\rS r S r!Sr"g)!r   iH  zA submodule of another module.Nc                     Xl         X l        X0l        X@l        UR                  S   U l        SU l        SU l        SU l        g)a  
Parameters
==========

parent : :py:class:`~.Module`
    The module from which this one is derived.
matrix : :py:class:`~.DomainMatrix` over :ref:`ZZ`
    The matrix whose columns define this submodule's generators as
    linear combinations over the parent's generators.
denom : int, optional (default=1)
    Denominator for the coefficients given by the matrix.
mult_tab : dict, ``None``, optional
    If already known, the multiplication table for this module may be
    supplied.

r   N)	_parent_matrix_denomr   rR   r   
_QQ_matrix_starts_with_unity_is_sq_maxrank_HNF)r(   r1   matrixrZ   r-   s        r   r   Submodule.__init__K  s>    " !,,q/"&"&r+   c                     S[        U R                  R                  5       R                  5       R	                  5       5      -   nU R
                  S:  a  USU R
                   3-  nU$ )Nr   r   /)reprr   r   	to_MatrixtolistrZ   )r(   rs     r   r   Submodule.__repr__e  sU    $t{{446@@BIIKLL::>1TZZL!!Ar+   c                    U R                   S:X  a  U $ [        U R                   /U R                  Q76 nUS:X  a  U $ [        U 5      " U R                  U R
                  U-  R                  [        5      U R                   U-  U R                  S9$ )a  
Produce a reduced version of this submodule.

Explanation
===========

In the reduced version, it is guaranteed that 1 is the only positive
integer dividing both the submodule's denominator, and every entry in
the submodule's matrix.

Returns
=======

:py:class:`~.Submodule`

r   rZ   r-   )	rZ   r   r   typer1   r   
convert_tor   r   r(   rz   s     r   reducedSubmodule.reducedk  ss    " ::?K*dkk*6KDz$++a'C'CB'Gtzz]^imiwiwxxr+   c                 &   U R                   SS2US24   nU R                  U-
  nSnU R                  nUb>  0 n[        U5       H-  n0 XF'   [        Xc5       H  nXQU-      X-      US XF   U'   M     M/     [	        U R
                  X R                  US9$ )zM
Produce a new module by discarding all generators before a given
index *r*.
Nr   )r   r)   r   rg   r   r1   rZ   )r(   r   Wsr   mtr   r   s           r   discard_beforeSubmodule.discard_before  s    
 KK12FFQJ^^>A1XqA Qi.qr2ADG %  azzAFFr+   c                     U R                   $ rw   r   r'   s    r   r)   Submodule.n  r   r+   c                 T    U R                   c  U R                  5         U R                   $ rw   r   r'   s    r   r-   Submodule.mult_tab  r   r+   c                     U R                  5       n0 nU R                  n[        U5       HD  n0 X$'   [        XC5       H.  nU R                  X   X   -  5      R	                  5       X$   U'   M0     MF     X l        g rw   )basis_element_pullbacksr)   rg   r6   flatr   )r(   r   r   r)   r   r   s         r   r   Submodule.compute_mult_tab  sn    ++-FFqAAD1[..47):;@@BQ !  r+   c                     U R                   $ rw   )r   r'   s    r   r1   Submodule.parent      ||r+   c                     U R                   $ rw   )r   r'   s    r   r   Submodule.matrix  r  r+   c                 6    U R                   R                  5       $ rw   )r   r
  r'   s    r   r   Submodule.coeffs  s    {{!!r+   c                     U R                   $ rw   )r   r'   s    r   rZ   Submodule.denom  s    {{r+   c                     U R                   c,  U R                  U R                  -  R                  5       U l         U R                   $ )aq  
:py:class:`~.DomainMatrix` over :ref:`QQ`, equal to
``self.matrix / self.denom``, and guaranteed to be dense.

Explanation
===========

Depending on how it is formed, a :py:class:`~.DomainMatrix` may have
an internal representation that is sparse or dense. We guarantee a
dense representation here, so that tests for equivalence of submodules
always come out as expected.

Examples
========

>>> from sympy.polys import Poly, cyclotomic_poly, ZZ
>>> from sympy.abc import x
>>> from sympy.polys.matrices import DomainMatrix
>>> from sympy.polys.numberfields.modules import PowerBasis
>>> T = Poly(cyclotomic_poly(5, x))
>>> A = PowerBasis(T)
>>> B = A.submodule_from_matrix(3*DomainMatrix.eye(4, ZZ), denom=6)
>>> C = A.submodule_from_matrix(DomainMatrix.eye(4, ZZ), denom=2)
>>> print(B.QQ_matrix == C.QQ_matrix)
True

Returns
=======

:py:class:`~.DomainMatrix` over :ref:`QQ`

)r   r   rZ   r]   r'   s    r   	QQ_matrixSubmodule.QQ_matrix  s6    D ??"#{{TZZ7AACDOr+   c                 l    U R                   c  U " S5      R                  S5      U l         U R                   $ )Nr   r   )r   equivr'   s    r   rd   Submodule.starts_with_unity  s/    ""*&*1gmmA&6D#&&&r+   c                 h    U R                   c  [        U R                  5      U l         U R                   $ rw   )r   is_sq_maxrank_HNFr   r'   s    r   r  Submodule.is_sq_maxrank_HNF  s+    ""*&7&ED#&&&r+   c                 6    [        U R                  [        5      $ rw   )r@   r1   rA   r'   s    r   is_power_basis_submodule"Submodule.is_power_basis_submodule  s    $++z22r+   c                 x    U R                  5       (       a  U " S5      U-  $ U R                  R                  U5      $ r   )rd   r1   ro   rs   s     r   ro   Submodule.element_from_rational  s4    !!##7Q;;;44Q77r+   c                 h    U R                  5        Vs/ s H  oR                  5       PM     sn$ s  snf )z^
Return list of this submodule's basis elements as elements of the
submodule's parent module.
)ri   	to_parentr(   es     r   r	  !Submodule.basis_element_pullbacks  s+    
 (,':':'<='<!'<===s   /c                 B   UR                   U :X  a  UR                  5       $ UR                   U R                  :X  aR   U R                  nUR                  nUR                  U5      S   R                  5       nUR                  [        5      nU$ [        U R                  [        5      (       a=  U R                  R                  U5      nU R                  U5      nU R                  U5      $ [        S5      e! [         a    [        S5      e[         a    [        S5      ef = f)z
Represent a module element as an integer-linear combination over the
generators of this module.

See Also
========

.Module.represent
.PowerBasis.represent

r   z&Element outside QQ-span of this basis.z1Element in QQ-span but not ZZ-span of this basis.z.Element outside ancestor chain of this module.)rx   r   r1   r  QQ_col_solver   r   r   r   r   r   r@   r   r6   )r(   r5   Abxcoeffs_in_parentparent_elements          r   r6   Submodule.represent  s     ::::<ZZ4;;&Z NNJJHHQKN,,.LL$
 HY//#{{44S9![[)9:N>>.11 !QRR # O$%MNN! Z$%XYYZs   AC4 4*Dc                 b    [        U[        5      =(       a    UR                  U R                  :H  $ rw   )r@   r   r1   r   s     r   is_compat_submoduleSubmodule.is_compat_submodule  s!    %+K0KKr+   c                 l    U R                  U5      (       a  UR                  U R                  :H  $ [        $ rw   )r2  r  r   r   s     r   r   Submodule.__eq__  s,    ##E**??dnn44r+   c                     U R                   UR                   pT[        XE5      nXd-  Xe-  pXpR                  -  R                  XR                  -  5      n	U(       a	  [	        XS9n	U R
                  R                  XS9$ )aM  
Add this :py:class:`~.Submodule` to another.

Explanation
===========

This represents the module generated by the union of the two modules'
sets of generators.

Parameters
==========

other : :py:class:`~.Submodule`
hnf : boolean, optional (default=True)
    If ``True``, reduce the matrix of the combined module to its
    Hermite Normal Form.
hnf_modulus : :ref:`ZZ`, None, optional
    If a positive integer is provided, use this as modulus in the
    HNF reduction. See
    :py:func:`~sympy.polys.matrices.normalforms.hermite_normal_form`.

Returns
=======

:py:class:`~.Submodule`

r}   rY   )rZ   r   r   r   r   r1   r   )
r(   rF   r   r   r   r&  r   r=   r,  r   s
             r   addSubmodule.add"  si    8 zz5;;1Jvqv1_$$Q%56#A5A{{000<<r+   c                 \    U R                  U5      (       a  U R                  U5      $ [        $ rw   )r2  r7  r   r   s     r   __add__Submodule.__add__F  s'    ##E**88E?"r+   c                    [        U5      (       a[  [        U5      u  pEXEs=:X  a  S:X  a   U $   [        U R                  U R                  U-  U R
                  U-  SS9R                  5       $ [        U[        5      (       aV  UR                  U R                  :X  a<  U R                  5        Vs/ s H  oaU-  PM	     nnU R                  R                  XrUS9$ U R                  U5      (       aX  U R                  5       UR                  5       pU VVs/ s H  oI  H  oTU-  PM	     M     nnnU R                  R                  XrUS9$ [        $ s  snf s  snnf )a  
Multiply this :py:class:`~.Submodule` by a rational number, a
:py:class:`~.ModuleElement`, or another :py:class:`~.Submodule`.

Explanation
===========

To multiply by a rational number or :py:class:`~.ModuleElement` means
to form the submodule whose generators are the products of this
quantity with all the generators of the present submodule.

To multiply by another :py:class:`~.Submodule` means to form the
submodule whose generators are all the products of one generator from
the one submodule, and one generator from the other.

Parameters
==========

other : int, :ref:`ZZ`, :ref:`QQ`, :py:class:`~.ModuleElement`, :py:class:`~.Submodule`
hnf : boolean, optional (default=True)
    If ``True``, reduce the matrix of the product module to its
    Hermite Normal Form.
hnf_modulus : :ref:`ZZ`, None, optional
    If a positive integer is provided, use this as modulus in the
    HNF reduction. See
    :py:func:`~sympy.polys.matrices.normalforms.hermite_normal_form`.

Returns
=======

:py:class:`~.Submodule`

r   Nr   )r   r   )r   r   r   r1   r   rZ   r   r@   ModuleElementrx   r	  r   r2  r   )
r(   rF   r   r   r=   r,  r&  r   alphasbetass
             r   mulSubmodule.mulM  s1   D %== 'DA{{  !![[1_DJJN&*,,3GI6 }--%,,$++2M (,'C'C'EF'E!AI'EDF;;224k2ZZ%%e,, !88:E<Y<Y<[E#)96a5aE5E6D9;;224k2ZZ G :s   -EEc                 $    U R                  U5      $ rw   )r@  r   s     r   __mul__Submodule.__mul__  s    xxr+   c                     U $ rw   r0   r'   s    r   _first_powerSubmodule._first_power      r+   c                 x   UR                   U R                  :X  d  [        eU R                  5       (       d  Sn[	        U5      eU R                  5       nUn[        U R                  S-
  SS5       HG  nX5   nUR                  U   UR                  -  UR                  U   UR                  -  -  nXGU-  -  nMI     U$ )a  
If this submodule $B$ has defining matrix $W$ in square, maximal-rank
Hermite normal form, then, given an element $x$ of the parent module
$A$, we produce an element $y \in A$ such that $x - y \in B$, and the
$i$th coordinate of $y$ satisfies $0 \leq y_i < w_{i,i}$. This
representative $y$ is unique, in the sense that every element of
the coset $x + B$ reduces to it under this procedure.

Explanation
===========

In the special case where $A$ is a power basis for a number field $K$,
and $B$ is a submodule representing an ideal $I$, this operation
represents one of a few important ways of reducing an element of $K$
modulo $I$ to obtain a "small" representative. See [Cohen00]_ Section
1.4.3.

Examples
========

>>> from sympy import QQ, Poly, symbols
>>> t = symbols('t')
>>> k = QQ.alg_field_from_poly(Poly(t**3 + t**2 - 2*t + 8))
>>> Zk = k.maximal_order()
>>> A = Zk.parent
>>> B = (A(2) - 3*A(0))*Zk
>>> B.reduce_element(A(2))
[3, 0, 0]

Parameters
==========

elt : :py:class:`~.ModuleElement`
    An element of this submodule's parent module.

Returns
=======

elt : :py:class:`~.ModuleElement`
    An element of this submodule's parent module.

Raises
======

NotImplementedError
    If the given :py:class:`~.ModuleElement` does not belong to this
    submodule's parent module.
StructureError
    If this submodule's defining matrix is not in square, maximal-rank
    Hermite normal form.

References
==========

.. [Cohen00] Cohen, H. *Advanced Topics in Computational Number
   Theory.*

z;Reduction not implemented unless matrix square max-rank HNFr   )
rx   r1   r&   r  r   r	  rg   r)   r   rZ   )r(   r5   msgr   r=   ir,  qs           r   reduce_elementSubmodule.reduce_element  s    v zzT[[(%%%%''OC %%((*tvvz2r*AAAGG#AGG(;<A1HA + r+   )r   r   r   r   r   r   r   r   )r   Nr   )#r   r   r   r   r   r   r   r   r  r   r)   r-   r   r1   r   r   rZ   r  rd   r  r  ro   r	  r6   r2  r   r7  r:  __radd__r@  rC  __rmul__rF  rN  r   r0   r+   r   r   r   H  s    ('4y0G"  
     " "   # #J'
'
38>!SFL
"=H
 H5n HFr+   r   c                 ^   U R                   R                  (       a  U R                  (       a  U R                  (       ap  U R                  S   n[        U5       HQ  nXU4   R                  nUS::  a    g[        US-   U5       H#  nSXU4   R                  s=::  a  U:  a  M   O      g   MS     gg)aB  
Say whether a :py:class:`~.DomainMatrix` is in that special case of Hermite
Normal Form, in which the matrix is also square and of maximal rank.

Explanation
===========

We commonly work with :py:class:`~.Submodule` instances whose matrix is in
this form, and it can be useful to be able to check that this condition is
satisfied.

For example this is the case with the :py:class:`~.Submodule` ``ZK``
returned by :py:func:`~sympy.polys.numberfields.basis.round_two`, which
represents the maximal order in a number field, and with ideals formed
therefrom, such as ``2 * ZK``.

r   Fr   T)rS   rT   	is_squareis_upperrR   rg   element)dmr)   rL  r   rh   s        r   r  r    s    $ 
yy2<<BKKHHQKqAa4  AAv1q5!_R1X--11  %	  r+   c                 T    [        U [        5      (       a
  [        XUS9$ [        XUS9$ )z
Factory function which builds a :py:class:`~.ModuleElement`, but ensures
that it is a :py:class:`~.PowerBasisElement` if the module is a
:py:class:`~.PowerBasis`.
rY   )r@   rA   PowerBasisElementr=  )rx   rU   rZ   s      r   r_   r_     s+     &*%% E::V66r+   c                       \ rS rSrSrS S jrS rS rS r\	S S j5       r
\S 5       rS	 rS!S jr\S 5       r\S 5       rS rS rS rS rS rS rS rS r\rS rS rS rS r\rS rS r S r!S r"S r#Sr$g
)"r=  i   z
Represents an element of a :py:class:`~.Module`.

NOTE: Should not be constructed directly. Use the
:py:meth:`~.Module.__call__` method or the :py:func:`make_mod_elt()`
factory function instead.
c                 6    Xl         X l        X0l        SU l        g)a>  
Parameters
==========

module : :py:class:`~.Module`
    The module to which this element belongs.
col : :py:class:`~.DomainMatrix` over :ref:`ZZ`
    Column vector giving the numerators of the coefficients of this
    element.
denom : int, optional (default=1)
    Denominator for the coefficients of this element.

N)rx   rU   rZ   _QQ_col)r(   rx   rU   rZ   s       r   r   ModuleElement.__init__	  s     
r+   c                     [        U R                  R                  5        Vs/ s H  n[        U5      PM     sn5      nU R                  S:  a  USU R                   3-  nU$ s  snf )Nr   r   )strrU   r
  r[   rZ   )r(   r   r   s      r   r   ModuleElement.__repr__  sS    1AQ12::>1TZZL!!A 2s   A"c                    U R                   S:X  a  U $ [        U R                   /U R                  Q76 nUS:X  a  U $ [        U 5      " U R                  U R
                  U-  R                  [        5      U R                   U-  S9$ )z
Produce a reduced version of this ModuleElement, i.e. one in which the
gcd of the denominator together with all numerator coefficients is 1.
r   rY   )rZ   r   r   r   rx   rU   r   r   r   s     r   r   ModuleElement.reduced"  so    
 ::?K*dkk*6KDz$++!XX\55b9"&**/3 	3r+   c                     [        U R                  U R                  R                  [	        U5      5      R                  [
        5      U R                  S9$ )zv
Produce a version of this :py:class:`~.ModuleElement` in which all
numerator coefficients have been reduced mod *p*.
rY   )r_   rx   rU   r   r
   r   rZ   )r(   ps     r   reduced_mod_pModuleElement.reduced_mod_p0  s?    
 DKK HH//16AA"E"&**. 	.r+   c                 &    [        U5      nU " XUS9$ )zV
Make a :py:class:`~.ModuleElement` from a list of ints (instead of a
column vector).
rY   )r    )clsrx   r   rZ   rU   s        r   from_int_listModuleElement.from_int_list9  s     Vn6e,,r+   c                 .    U R                   R                  $ )z$The length of this element's column.)rx   r)   r'   s    r   r)   ModuleElement.nB       {{}}r+   c                     U R                   $ rw   )r)   r'   s    r   __len__ModuleElement.__len__G  s    vvr+   Nc                 r    Uc  U R                   R                  5       $ U R                   R                  U5      $ )zI
Get a copy of this element's column, optionally converting to a domain.
)rU   copyr   r(   rS   s     r   r   ModuleElement.columnJ  s.     >88==?"88&&v..r+   c                 6    U R                   R                  5       $ rw   )rU   r
  r'   s    r   r   ModuleElement.coeffsS  s    xx}}r+   c                     U R                   c,  U R                  U R                  -  R                  5       U l         U R                   $ )z
:py:class:`~.DomainMatrix` over :ref:`QQ`, equal to
``self.col / self.denom``, and guaranteed to be dense.

See Also
========

.Submodule.QQ_matrix

)r[  rU   rZ   r]   r'   s    r   r)  ModuleElement.QQ_colW  s5     << HHtzz1;;=DL||r+   c                    [        U R                  [        5      (       d  [        S5      e[	        U R                  R
                  U R                  R                  U R                  -  U R                  R                  U R                  -  S9$ )z`
Transform into a :py:class:`~.ModuleElement` belonging to the parent of
this element's module.
zNot an element of a Submodule.rY   )	r@   rx   r   r^   r_   r1   r   rU   rZ   r'   s    r   r$  ModuleElement.to_parentg  sf    
 $++y11=>>KK 2 2TXX =++##djj02 	2r+   c                 b    XR                   :X  a  U $ U R                  5       R                  U5      $ )z
Transform into a :py:class:`~.ModuleElement` belonging to a given
ancestor of this element's module.

Parameters
==========

anc : :py:class:`~.Module`

)rx   r$  to_ancestor)r(   ancs     r   r{  ModuleElement.to_ancestorr  s+     ++K>>#//44r+   c                     U n[        UR                  [        5      (       d1  UR                  5       n[        UR                  [        5      (       d  M1  U$ )z^
Transform into a :py:class:`~.PowerBasisElement` over our
:py:class:`~.PowerBasis` ancestor.
)r@   rx   rA   r$  r%  s     r   over_power_basisModuleElement.over_power_basis  s=    
 QXXz22A QXXz22r+   c                 b    [        U[        5      =(       a    UR                  U R                  :H  $ )zM
Test whether other is another :py:class:`~.ModuleElement` with same
module.
)r@   r=  rx   r   s     r   	is_compatModuleElement.is_compat  s#    
 %/OELLDKK4OOr+   c                     U R                   UR                   :X  a  X4$ U R                   R                  UR                   5      nUb"  U R                  U5      UR                  U5      4$ [        SU  SU 35      e)a5  
Try to make a compatible pair of :py:class:`~.ModuleElement`, one
equivalent to this one, and one equivalent to the other.

Explanation
===========

We search for the nearest common ancestor module for the pair of
elements, and represent each one there.

Returns
=======

Pair ``(e1, e2)``
    Each ``ei`` is a :py:class:`~.ModuleElement`, they belong to the
    same :py:class:`~.Module`, ``e1`` is equivalent to ``self``, and
    ``e2`` is equivalent to ``other``.

Raises
======

UnificationFailed
    If ``self`` and ``other`` have no common ancestor module.

zCannot unify z with )rx   rL   r{  r   )r(   rF   rI   s      r   unifyModuleElement.unify  sr    4 ;;%,,&;kk11%,,??##C(%*;*;C*@@@-vVE7 CDDr+   c                 l    U R                  U5      (       a  U R                  UR                  :H  $ [        $ rw   )r  r)  r   r   s     r   r   ModuleElement.__eq__  s*    >>%  ;;%,,..r+   c                    X:X  a  g[        U[        5      (       a  U R                  U5      u  p#X#:H  $ [        U5      (       aJ  [        U [        5      (       a  X R                  S5      U-  :H  $ U R                  5       R                  U5      $ g)a  
A :py:class:`~.ModuleElement` may test as equivalent to a rational
number or another :py:class:`~.ModuleElement`, if they represent the
same algebraic number.

Explanation
===========

This method is intended to check equivalence only in those cases in
which it is easy to test; namely, when *other* is either a
:py:class:`~.ModuleElement` that can be unified with this one (i.e. one
which shares a common :py:class:`~.PowerBasis` ancestor), or else a
rational number (which is easy because every :py:class:`~.PowerBasis`
represents every rational number).

Parameters
==========

other : int, :ref:`ZZ`, :ref:`QQ`, :py:class:`~.ModuleElement`

Returns
=======

bool

Raises
======

UnificationFailed
    If ``self`` and ``other`` do not share a common
    :py:class:`~.PowerBasis` ancestor.

Tr   F)r@   r=  r  r   rX  rx   r  r  )r(   rF   r=   r,  s       r   r  ModuleElement.equiv  s{    D =}--::e$DA6ME]]$ 122{{1~555,,.44U;;r+   c           	      R   U R                  U5      (       a  U R                  UR                  p2[        X#5      nXB-  XC-  pe[        [	        U R
                  UR
                  5       VVs/ s H  u  pxXW-  Xh-  -   PM     snn5      n	[        U 5      " U R                  XS9R                  5       $ [        U[        5      (       a   U R                  U5      u  pxXx-   $ [        U5      (       a  X R                  R                  U5      -   $ [        $ s  snnf ! [         a	    [        s $ f = f)a  
A :py:class:`~.ModuleElement` can be added to a rational number, or to
another :py:class:`~.ModuleElement`.

Explanation
===========

When the other summand is a rational number, it will be converted into
a :py:class:`~.ModuleElement` (belonging to the first ancestor of this
module that starts with unity).

In all cases, the sum belongs to the nearest common ancestor (NCA) of
the modules of the two summands. If the NCA does not exist, we return
``NotImplemented``.
rY   )r  rZ   r   r    rE   r   r   rx   r   r@   r=  r  r   r   r   ro   )
r(   rF   r   r&  r   r   r   r=   r,  rU   s
             r   r:  ModuleElement.__add__  s      >>%  ::u{{qQ
A616qCU\\4RS4RDA!%!%-4RSTC:dkk38@@BB}--&zz%( 5LE]]++;;EBBB T
 % &%%&s   (D
D D&%D&c                     U S-  $ )NrJ  r0   r'   s    r   __neg__ModuleElement.__neg__	  s    byr+   c                     X* -   $ rw   r0   r   s     r   __sub__ModuleElement.__sub__  s    vr+   c                     U * U-   $ rw   r0   r   s     r   __rsub__ModuleElement.__rsub__  s    uu}r+   c           	         U R                  U5      (       Ga  U R                  R                  5       nU R                  R	                  5       UR                  R	                  5       pCU R
                  nS/U-  n[        U5       Ha  n[        Xu5       HO  nX7   XH   -  n	X:  a  XU   XG   -  -  n	U	S:w  d  M%  X'   U   n
[        U5       H  nXk==   XU   -  -  ss'   M     MQ     Mc     U R                  UR                  -  nU R                  U R                  XlS9$ [        U[        5      (       a   U R                  U5      u  pX-  $ [        U5      (       aZ  [        U5      u  pXs=:X  a  S:X  a   U $   [!        U R                  U R                  U-  U R                  U-  S9R#                  5       $ [        $ ! [         a	    [        s $ f = f)an  
A :py:class:`~.ModuleElement` can be multiplied by a rational number,
or by another :py:class:`~.ModuleElement`.

Explanation
===========

When the multiplier is a rational number, the product is computed by
operating directly on the coefficients of this
:py:class:`~.ModuleElement`.

When the multiplier is another :py:class:`~.ModuleElement`, the product
will belong to the nearest common ancestor (NCA) of the modules of the
two operands, and that NCA must have a multiplication table. If the NCA
does not exist, we return ``NotImplemented``. If the NCA does not have
a mult. table, ``ClosureFailure`` will be raised.
r   rY   r   )r  rx   r-   rU   r
  r)   rg   rZ   rh  r@   r=  r  r   r   r   r   r_   r   )r(   rF   r   r+  r   r)   Cr   r   r   Rr   r   r=   r,  s                  r   rC  ModuleElement.__mul__  s   $ >>%  $$&A88==?EIINN$4qAaA1XqAqtAuqTAD[(AvDG!&qADA!H,D "* %  

U[[(A%%dkk1%>>}--&zz%( 5LE]] 'DA{{  $DKK!%ATZZ!^EELWYO % &%%&s   0F7 7G
	G
c                 6    U R                   R                  5       $ rw   )rx   rp   r'   s    r   _zeroth_powerModuleElement._zeroth_powerE  s    {{  r+   c                     U $ rw   r0   r'   s    r   rF  ModuleElement._first_powerH  rH  r+   c                     [        U5      (       a  [        U5      nU SU-  -  $ [        U[        5      (       a  U SU-  -  $ [        $ )Nr   )r   r   r@   r=  r   rs   s     r   __floordiv__ModuleElement.__floordiv__K  sC    !991A1Q3<=))1a4= r+   c                 &    XR                  5       -  $ rw   )r  rs   s     r   __rfloordiv__ModuleElement.__rfloordiv__S  s    ))+++r+   c                     [        U5      (       a  XR                  R                  5       -  n[        U[        5      (       a+  UR
                  U R                  :X  a  UR                  U 5      $ [        $ )a  
Reduce this :py:class:`~.ModuleElement` mod a :py:class:`~.Submodule`.

Parameters
==========

m : int, :ref:`ZZ`, :ref:`QQ`, :py:class:`~.Submodule`
    If a :py:class:`~.Submodule`, reduce ``self`` relative to this.
    If an integer or rational, reduce relative to the
    :py:class:`~.Submodule` that is our own module times this constant.

See Also
========

.Submodule.reduce_element

)r   rx   r   r@   r   r1   rN  r   )r(   r   s     r   __mod__ModuleElement.__mod__V  sU    $ !99KK//11Aa##DKK(?##D))r+   )r[  rU   rZ   rx   r   rw   )%r   r   r   r   r   r   r   r   rd  classmethodrh  r   r)   rn  r   r   r)  r$  r{  r  r  r  r   r  r:  rP  r  r  r  rC  rQ  r  rF  r  r  r  r   r0   r+   r   r=  r=     s    &3. - -  /    	25 PEB
,\@ H/b H!,r+   r=  c                       \ rS rSrSr\S 5       rSS jrSS jr\S 5       r	\S 5       r
SS	 jrSS
 jrS rS rSS jrS rS rSrg)rX  io  z`
Subclass for :py:class:`~.ModuleElement` instances whose module is a
:py:class:`~.PowerBasis`.
c                 .    U R                   R                  $ )z?Access the defining polynomial of the :py:class:`~.PowerBasis`.)rx   r   r'   s    r   r   PowerBasisElement.Tu  rl  r+   Nc                     U=(       d    U R                   R                  n[        [        U R                  5      U[
        S9$ )z4Obtain the numerator as a polynomial over :ref:`ZZ`.rS   )r   r   r   r   r   r   r(   r-  s     r   	numeratorPowerBasisElement.numeratorz  s+    OHT[[)1R88r+   c                 :    U R                  US9U R                  -  $ )z1Obtain the number as a polynomial over :ref:`QQ`.r-  )r  rZ   r  s     r   polyPowerBasisElement.poly  s    ~~~"djj00r+   c                 @    U R                   SS2SS24   R                  $ )z6Say whether this element represents a rational number.r   N)rU   is_zero_matrixr'   s    r   is_rationalPowerBasisElement.is_rational  s     xxA---r+   c                     U R                   R                  nU(       a1  UR                  R                  (       a  UR                  R                  $ U R
                  R                  $ )a.  
Return a :py:class:`~.Symbol` to be used when expressing this element
as a polynomial.

If we have an associated :py:class:`~.AlgebraicField` whose primitive
element has an alias symbol, we use that. Otherwise we use the variable
of the minimal polynomial defining the power basis to which we belong.
)rx   rO   r   
is_aliasedaliasr   r   r(   r   s     r   	generatorPowerBasisElement.generator  s<     KK$$AEE$4$4quu{{D$&&**Dr+   c                 f    U R                  U=(       d    U R                  5      R                  5       $ )z)Create a Basic expression from ``self``. )r  r  r   r  s     r   r   PowerBasisElement.as_expr  s#    yy,dnn-5577r+   c                     U=(       d    U R                   nUR                  nU R                  US9nUR                  U5      U R                  U R
                  -  -  $ )z Compute the norm of this number.r  )r   r   r  	resultantrZ   r)   )r(   r   r-  r+  s       r   normPowerBasisElement.norm  sH    KEENNQN{{1~tvv!555r+   c                     U R                  5       nUR                  U R                  5      nU R                  R	                  U5      $ rw   )r  invertr   rx   r   )r(   r   f_invs      r   inversePowerBasisElement.inverse  s4    IIK {{,,U33r+   c                 (    U R                  5       U-  $ rw   )r  rs   s     r   r  PowerBasisElement.__rfloordiv__  s    ||~!!r+   c                 :    U R                  5       [        U5      -  $ rw   )r  abs)r(   r&  modulos      r   _negative_power!PowerBasisElement._negative_power  s    ||~Q''r+   c                     [        [        [        U R                  R	                  5       5      5      [
        R                  " U R                  R                  R                  5       5      [
        5      $ )z,Convert to an equivalent :py:class:`~.ANP`. )
r   r   r   r)  r
  r   mapr   r   r   r'   s    r   to_ANPPowerBasisElement.to_ANP  sC    4!1!1!345rvvdffjj>P>P>R7SUWXXr+   c                     U R                   R                  nU(       a  UR                  U R                  5       5      $ [	        S5      e)a
  
Try to convert to an equivalent :py:class:`~.AlgebraicNumber`.

Explanation
===========

In general, the conversion from an :py:class:`~.AlgebraicNumber` to a
:py:class:`~.PowerBasisElement` throws away information, because an
:py:class:`~.AlgebraicNumber` specifies a complex embedding, while a
:py:class:`~.PowerBasisElement` does not. However, in some cases it is
possible to convert a :py:class:`~.PowerBasisElement` back into an
:py:class:`~.AlgebraicNumber`, namely when the associated
:py:class:`~.PowerBasis` has a reference to an
:py:class:`~.AlgebraicField`.

Returns
=======

:py:class:`~.AlgebraicNumber`

Raises
======

StructureError
    If the :py:class:`~.PowerBasis` to which this element belongs does
    not have an associated :py:class:`~.AlgebraicField`.

zNo associated AlgebraicField)rx   rO   
to_alg_numr  r   r  s     r   r  PowerBasisElement.to_alg_num  s7    : KK$$<<..;<<r+   r0   rw   )r   r   r   r   r   r   r   r  r  r  r  r   r  r  r  r  r  r  r   r0   r+   r   rX  rX  o  ss    
  9
1 . . 
E 
E864
"(Y =r+   rX  c                   2    \ rS rSrSrS rSS jrSS jrSrg)	ModuleHomomorphismi  z*A homomorphism from one module to another.c                 (    Xl         X l        X0l        g)a'  
Parameters
==========

domain : :py:class:`~.Module`
    The domain of the mapping.

codomain : :py:class:`~.Module`
    The codomain of the mapping.

mapping : callable
    An arbitrary callable is accepted, but should be chosen so as
    to represent an actual module homomorphism. In particular, should
    accept elements of *domain* and return elements of *codomain*.

Examples
========

>>> from sympy import Poly, cyclotomic_poly
>>> from sympy.polys.numberfields.modules import PowerBasis, ModuleHomomorphism
>>> T = Poly(cyclotomic_poly(5))
>>> A = PowerBasis(T)
>>> B = A.submodule_from_gens([2*A(j) for j in range(4)])
>>> phi = ModuleHomomorphism(A, B, lambda x: 6*x)
>>> print(phi.matrix())  # doctest: +SKIP
DomainMatrix([[3, 0, 0, 0], [0, 3, 0, 0], [0, 0, 3, 0], [0, 0, 0, 3]], (4, 4), ZZ)

N)rS   codomainmapping)r(   rS   r  r  s       r   r   ModuleHomomorphism.__init__  s    :  r+   Nc                    U R                   R                  5       nU Vs/ s H,  o0R                  R                  U R	                  U5      5      PM.     nnU(       d?  [
        R                  " U R                  R                  S4[        5      R                  5       $ US   R                  " USS 6 nU(       a  UR                  [        U5      5      nU$ s  snf )a-  
Compute the matrix of this homomorphism.

Parameters
==========

modulus : int, optional
    A positive prime number $p$ if the matrix should be reduced mod
    $p$.

Returns
=======

:py:class:`~.DomainMatrix`
    The matrix is over :ref:`ZZ`, or else over :ref:`GF(p)` if a
    modulus was given.

r   r   N)rS   ri   r  r6   r  r   r   r)   r   r]   r   r   r
   )r(   modulusbasisr5   colsr   s         r   r   ModuleHomomorphism.matrix  s    & **,FKLes''S(9:eL%%t}}&:B?HHJJGNNDH%R[)A Ms   3Cc                     U R                  US9nUc  UR                  [        5      nUR                  5       R                  [        5      R                  5       nU R                  R                  U5      $ )a{  
Compute a Submodule representing the kernel of this homomorphism.

Parameters
==========

modulus : int, optional
    A positive prime number $p$ if the kernel should be computed mod
    $p$.

Returns
=======

:py:class:`~.Submodule`
    This submodule's generators span the kernel of this
    homomorphism over :ref:`ZZ`, or else over :ref:`GF(p)` if a
    modulus was given.

r  )r   r   r   	nullspacer   r   rS   r   )r(   r  r   r   s       r   kernelModuleHomomorphism.kernel  s]    ( KKK(?R A KKM$$R(224{{0033r+   )r  rS   r  rw   )	r   r   r   r   r   r   r   r  r   r0   r+   r   r  r    s    5B8"4r+   r  c                   ,   ^  \ rS rSrSrU 4S jrSrU =r$ )ModuleEndomorphismi7  z)A homomorphism from one module to itself.c                 &   > [         TU ]  XU5        g)a2  
Parameters
==========

domain : :py:class:`~.Module`
    The common domain and codomain of the mapping.

mapping : callable
    An arbitrary callable is accepted, but should be chosen so as
    to represent an actual module endomorphism. In particular, should
    accept and return elements of *domain*.

N)superr   )r(   rS   r  	__class__s      r   r   ModuleEndomorphism.__init__:  s     	1r+   r0   r   r   r   r   r   r   r   __classcell__r  s   @r   r  r  7  s    42 2r+   r  c                   ,   ^  \ rS rSrSrU 4S jrSrU =r$ )InnerEndomorphismiK  zn
An inner endomorphism on a module, i.e. the endomorphism corresponding to
multiplication by a fixed element.
c                 >   >^ [         TU ]  UU4S j5        TU l        g)z
Parameters
==========

domain : :py:class:`~.Module`
    The domain and codomain of the endomorphism.

multiplier : :py:class:`~.ModuleElement`
    The element $a$ defining the mapping as $x \mapsto a x$.

c                    > TU -  $ rw   r0   )r-  
multipliers    r   <lambda>,InnerEndomorphism.__init__.<locals>.<lambda>]  s	    :>r+   N)r  r   r  )r(   rS   r  r  s     `r   r   InnerEndomorphism.__init__Q  s     	!9:$r+   )r  r  r  s   @r   r  r  K  s    
% %r+   r  c                   *    \ rS rSrSrS rS rS rSrg)r   ia  z&The ring of endomorphisms on a module.c                     Xl         g)zi
Parameters
==========

domain : :py:class:`~.Module`
    The domain and codomain of the endomorphisms.

Nr  rr  s     r   r   EndomorphismRing.__init__d  s	     r+   c                 .    [        U R                  U5      $ )z
Form an inner endomorphism belonging to this endomorphism ring.

Parameters
==========

multiplier : :py:class:`~.ModuleElement`
    Element $a$ defining the inner endomorphism $x \mapsto a x$.

Returns
=======

:py:class:`~.InnerEndomorphism`

)r  rS   )r(   r  s     r   inner_endomorphism#EndomorphismRing.inner_endomorphismo  s      !j99r+   c                 0   [        U[        5      (       aw  UR                  U R                  :X  a]  UR                  5       nUR                  u  p4US:X  a  U$ USS2S4   R
                  " [        SU5       Vs/ s H  oRSS2U4   PM     sn6 $ [        es  snf )a  
Represent an element of this endomorphism ring, as a single column
vector.

Explanation
===========

Let $M$ be a module, and $E$ its ring of endomorphisms. Let $N$ be
another module, and consider a homomorphism $\varphi: N \rightarrow E$.
In the event that $\varphi$ is to be represented by a matrix $A$, each
column of $A$ must represent an element of $E$. This is possible when
the elements of $E$ are themselves representable as matrices, by
stacking the columns of such a matrix into a single column.

This method supports calculating such matrices $A$, by representing
an element of this endomorphism ring first as a matrix, and then
stacking that matrix's columns into a single column.

Examples
========

Note that in these examples we print matrix transposes, to make their
columns easier to inspect.

>>> from sympy import Poly, cyclotomic_poly
>>> from sympy.polys.numberfields.modules import PowerBasis
>>> from sympy.polys.numberfields.modules import ModuleHomomorphism
>>> T = Poly(cyclotomic_poly(5))
>>> M = PowerBasis(T)
>>> E = M.endomorphism_ring()

Let $\zeta$ be a primitive 5th root of unity, a generator of our field,
and consider the inner endomorphism $\tau$ on the ring of integers,
induced by $\zeta$:

>>> zeta = M(1)
>>> tau = E.inner_endomorphism(zeta)
>>> tau.matrix().transpose()  # doctest: +SKIP
DomainMatrix(
    [[0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1], [-1, -1, -1, -1]],
    (4, 4), ZZ)

The matrix representation of $\tau$ is as expected. The first column
shows that multiplying by $\zeta$ carries $1$ to $\zeta$, the second
column that it carries $\zeta$ to $\zeta^2$, and so forth.

The ``represent`` method of the endomorphism ring ``E`` stacks these
into a single column:

>>> E.represent(tau).transpose()  # doctest: +SKIP
DomainMatrix(
    [[0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -1, -1, -1, -1]],
    (1, 16), ZZ)

This is useful when we want to consider a homomorphism $\varphi$ having
``E`` as codomain:

>>> phi = ModuleHomomorphism(M, E, lambda x: E.inner_endomorphism(x))

and we want to compute the matrix of such a homomorphism:

>>> phi.matrix().transpose()  # doctest: +SKIP
DomainMatrix(
    [[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
    [0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -1, -1, -1, -1],
    [0, 0, 1, 0, 0, 0, 0, 1, -1, -1, -1, -1, 1, 0, 0, 0],
    [0, 0, 0, 1, -1, -1, -1, -1, 1, 0, 0, 0, 0, 1, 0, 0]],
    (4, 16), ZZ)

Note that the stacked matrix of $\tau$ occurs as the second column in
this example. This is because $\zeta$ is the second basis element of
``M``, and $\varphi(\zeta) = \tau$.

Parameters
==========

element : :py:class:`~.ModuleEndomorphism` belonging to this ring.

Returns
=======

:py:class:`~.DomainMatrix`
    Column vector equalling the vertical stacking of all the columns
    of the matrix that represents the given *element* as a mapping.

r   Nr   )r@   r  rS   r   rR   vstackrg   r&   )r(   rU  r   r   r)   rh   s         r   r6   EndomorphismRing.represent  s    n g122w~~7T A 77DAAvQT7>>U1a[#A[adG[#ABB!! $Bs   7Br  N)	r   r   r   r   r   r   r  r6   r   r0   r+   r   r   r   a  s    1	:$_"r+   r   Nc                    U R                   nUR                  5       (       d  [        S5      eUc  / nU" S5      nUR                  U5        UR	                  US9nU nSn[        SUR                  S-   5       H  n	UR                  U5        UR	                  US9n
 UR                  U
5      S   nS/[        UR                  5       5       Vs/ s H  o* PM     sn-   nU=(       d    [        S5      nUR                  (       a  [        XUR                  S9nO
[        XUS9n  U$    U$ s  snf ! [         a    UR                  U
5      nXp-  n M  f = f)a  
Find a polynomial of least degree (not necessarily irreducible) satisfied
by an element of a finitely-generated ring with unity.

Examples
========

For the $n$th cyclotomic field, $n$ an odd prime, consider the quadratic
equation whose roots are the two periods of length $(n-1)/2$. Article 356
of Gauss tells us that we should get $x^2 + x - (n-1)/4$ or
$x^2 + x + (n+1)/4$ according to whether $n$ is 1 or 3 mod 4, respectively.

>>> from sympy import Poly, cyclotomic_poly, primitive_root, QQ
>>> from sympy.abc import x
>>> from sympy.polys.numberfields.modules import PowerBasis, find_min_poly
>>> n = 13
>>> g = primitive_root(n)
>>> C = PowerBasis(Poly(cyclotomic_poly(n, x)))
>>> ee = [g**(2*k+1) % n for k in range((n-1)//2)]
>>> eta = sum(C(e) for e in ee)
>>> print(find_min_poly(eta, QQ, x=x).as_expr())
x**2 + x - 3
>>> n = 19
>>> g = primitive_root(n)
>>> C = PowerBasis(Poly(cyclotomic_poly(n, x)))
>>> ee = [g**(2*k+2) % n for k in range((n-1)//2)]
>>> eta = sum(C(e) for e in ee)
>>> print(find_min_poly(eta, QQ, x=x).as_expr())
x**2 + x + 5

Parameters
==========

alpha : :py:class:`~.ModuleElement`
    The element whose min poly is to be found, and whose module has
    multiplication and starts with unity.

domain : :py:class:`~.Domain`
    The desired domain of the polynomial.

x : :py:class:`~.Symbol`, optional
    The desired variable for the polynomial.

powers : list, optional
    If desired, pass an empty list. The powers of *alpha* (as
    :py:class:`~.ModuleElement` instances) from the zeroth up to the degree
    of the min poly will be recorded here, as we compute them.

Returns
=======

:py:class:`~.Poly`, ``None``
    The minimal polynomial for alpha, or ``None`` if no polynomial could be
    found over the desired domain.

Raises
======

MissingUnityError
    If the module to which alpha belongs does not start with unity.
ClosureFailure
    If the module to which alpha belongs is not closed under
    multiplication.

z8alpha must belong to finitely generated ring with unity.Nr   r  r   r-  r  )rx   rd   r   r<   r   rg   r)   r*  r   to_list_flatr   is_FFr   r   r   r   )alpharS   r-  powersr  rp   powers_matrixakr   r   ak_colXr   r   s                 r   find_min_polyr    sI   D 	A   Z[[~
A$C
MM#JJfJ-M	BA1accAgb&)	$$V,Q/A S1A(BC(B1B(BCCFU3ZA||FJJ762H' & H D  	)008MKB	s   D-D(-EEr   )NN)4r   sympy.core.intfuncr   r   sympy.core.symbolr   sympy.polys.polyclassesr   sympy.polys.polytoolsr   sympy.polys.densetoolsr   "sympy.polys.domains.algebraicfieldr	   sympy.polys.domains.finitefieldr
   !sympy.polys.domains.rationalfieldr   sympy.polys.domains.integerringr   !sympy.polys.matrices.domainmatrixr   sympy.polys.matrices.exceptionsr    sympy.polys.matrices.normalformsr   sympy.polys.polyerrorsr   r   sympy.polys.polyutilsr   
exceptionsr   r   r   	utilitiesr   r   r   r    r"   rA   r   r  r_   r=  rX  r  r  r  r   r  r0   r+   r   <module>r     s   rh * # ' & 3 = . 0 . : ; @ D 2 I I : :U
k& k&\KX KX\J( JZ>	7l$ l^`= `=Fb4 b4J2+ 2(%* %," "D_r+   