
    \h3                         S 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 rS rS r\S 5       r\ " S S5      5       r\S 5       rS r\SS j5       rg)z'Utilities for algebraic number theory.     )sympify)	factorint)QQ)ZZ)DMRankError)minpoly)IntervalPrinter)public)lambdify)mpc                     [        U [        5      =(       d3    [        R                  " U 5      =(       d    [        R                  " U 5      $ )z
Test whether an argument is of an acceptable type to be used as a rational
number.

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

Returns ``True`` on any argument of type ``int``, :ref:`ZZ`, or :ref:`QQ`.

See Also
========

is_int

)
isinstanceintr   of_typer   cs    Z/var/www/auris/envauris/lib/python3.13/site-packages/sympy/polys/numberfields/utilities.pyis_ratr      s+    , a?A?"**Q-?    c                 \    [        U [        5      =(       d    [        R                  " U 5      $ )z
Test whether an argument is of an acceptable type to be used as an integer.

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

Returns ``True`` on any argument of type ``int`` or :ref:`ZZ`.

See Also
========

is_rat

)r   r   r   r   r   s    r   is_intr   )   s    $ a.A.r   c                 H    [        U 5      nUR                  UR                  4$ )z
Given any argument on which :py:func:`~.is_rat` is ``True``, return the
numerator and denominator of this number.

See Also
========

is_rat

)r   	numeratordenominator)r   rs     r   get_num_denomr   >   s      	1A;;%%r   c                    U S-  S;  a  [        S5      eU S:X  a  0 SS04$ U S:X  a  0 0 4$ [        U 5      n0 n0 nSnUR                  5        H;  u  pVUS-  S:X  a&  SX%'   US-  S:X  a  US-  nUS:  a  US-
  S-  X5'   M2  M4  US-  X5'   M=     SU;   nU(       d	  US-  S:X  a-  US   nUS:  d   eUS:X  a  US	 OUS-
  US'   U(       a  SOSUS'   X#4$ )a  
Extract a fundamental discriminant from an integer *a*.

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

Given any rational integer *a* that is 0 or 1 mod 4, write $a = d f^2$,
where $d$ is either 1 or a fundamental discriminant, and return a pair
of dictionaries ``(D, F)`` giving the prime factorizations of $d$ and $f$
respectively, in the same format returned by :py:func:`~.factorint`.

A fundamental discriminant $d$ is different from unity, and is either
1 mod 4 and squarefree, or is 0 mod 4 and such that $d/4$ is squarefree
and 2 or 3 mod 4. This is the same as being the discriminant of some
quadratic field.

Examples
========

>>> from sympy.polys.numberfields.utilities import extract_fundamental_discriminant
>>> print(extract_fundamental_discriminant(-432))
({3: 1, -1: 1}, {2: 2, 3: 1})

For comparison:

>>> from sympy import factorint
>>> print(factorint(-432))
{2: 4, 3: 3, -1: 1}

Parameters
==========

a: int, must be 0 or 1 mod 4

Returns
=======

Pair ``(D, F)``  of dictionaries.

Raises
======

ValueError
    If *a* is not 0 or 1 mod 4.

References
==========

.. [1] Cohen, H. *A Course in Computational Algebraic Number Theory.*
   (See Prop. 5.1.3)

   )r      zATo extract fundamental discriminant, number must be 0 or 1 mod 4.r   r         )
ValueErrorr   items)	a	a_factorsDFnum_3_mod_4peevene2s	            r    extract_fundamental_discriminantr-   M   s   l 	1uF\]]AvAq6zAv2v!I
A
A K!q5A:AD1uzq AvA!|  6AD " 6D{Q!#qTAvv7!6AaDqa!4Kr   c                   @    \ rS rSrSrSS jrS rS rS rS r	S	 r
S
rg)AlgIntPowers   a  
Compute the powers of an algebraic integer.

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

Given an algebraic integer $\theta$ by its monic irreducible polynomial
``T`` over :ref:`ZZ`, this class computes representations of arbitrarily
high powers of $\theta$, as :ref:`ZZ`-linear combinations over
$\{1, \theta, \ldots, \theta^{n-1}\}$, where $n = \deg(T)$.

The representations are computed using the linear recurrence relations for
powers of $\theta$, derived from the polynomial ``T``. See [1], Sec. 4.2.2.

Optionally, the representations may be reduced with respect to a modulus.

Examples
========

>>> from sympy import Poly, cyclotomic_poly
>>> from sympy.polys.numberfields.utilities import AlgIntPowers
>>> T = Poly(cyclotomic_poly(5))
>>> zeta_pow = AlgIntPowers(T)
>>> print(zeta_pow[0])
[1, 0, 0, 0]
>>> print(zeta_pow[1])
[0, 1, 0, 0]
>>> print(zeta_pow[4])  # doctest: +SKIP
[-1, -1, -1, -1]
>>> print(zeta_pow[24])  # doctest: +SKIP
[-1, -1, -1, -1]

References
==========

.. [1] Cohen, H. *A Course in Computational Algebraic Number Theory.*

Nc                     Xl         X l        UR                  5       U l        [	        UR
                  R                  5       5       Vs/ s H  o3* U -  PM
     snSS /U l        U R                  U l        gs  snf )z
Parameters
==========

T : :py:class:`~.Poly`
    The monic irreducible polynomial over :ref:`ZZ` defining the
    algebraic integer.

modulus : int, None, optional
    If not ``None``, all representations will be reduced w.r.t. this.

N)	Tmodulusdegreenreversedrepto_listpowers_n_and_up
max_so_far)selfr3   r4   r   s       r   __init__AlgIntPowers.__init__   sc     4<QUU]]_4M N4Mqd4M NsPR ST&& !Os   A4c                 <    U R                   c  U$ XR                   -  $ N)r4   )r<   exps     r   redAlgIntPowers.red   s    ll*sBll0BBr   c                 $    U R                  U5      $ r@   )rB   )r<   others     r   __rmod__AlgIntPowers.__rmod__   s    xxr   c           
      n   U R                   nX::  a  g U R                  nU R                  nUS   n[        US-   US-   5       He  nXFS-
  U-
     US-
     nUR	                  US   U-  U -  /[        SU5       Vs/ s H  oUS-
  U-
     US-
     XX   U-  -   U -  PM      sn-   5        Mg     Xl         g s  snf )Nr   r   )r;   r6   r:   rangeappend)	r<   r*   mr6   r   r   kbis	            r   compute_up_throughAlgIntPowers.compute_up_through   s    OO66FF  aDqsAaCAA#a%1AHH1a$=B1a[#=Hqs1uXac]QT!V+t3[#  ! 	#s   9%B2c                     U R                   nUS:  a  [        S5      eX:  a#  [        U5       Vs/ s H  o3U:X  a  SOSPM     sn$ U R                  U5        U R                  X-
     $ s  snf )Nr   zExponent must be non-negative.r   )r6   r"   rI   rO   r:   )r<   r*   r6   rN   s       r   getAlgIntPowers.get   sk    FFq5=>>U05a91aAQ&99##A&''.. :s   A(c                 $    U R                  U5      $ r@   )rR   )r<   items     r   __getitem__AlgIntPowers.__getitem__  s    xx~r   )r3   r;   r4   r6   r:   r@   )__name__
__module____qualname____firstlineno____doc__r=   rB   rF   rO   rR   rV   __static_attributes__ r   r   r/   r/      s'    %N!&C/r   r/   c              #   &  #    UnU/U -  n X:X  d  X;   d  U* U;   a  USS v   U S-
  nX4   U* :X  a  US-  nX4   U* :X  a  M  X4==   S-  ss'   [        US-   U 5       H  nXU'   M	     [        U 5       H  nX4   S:w  d  M    O   US-  nU/U -  nM  7f)a  
Generate coefficients for searching through polynomials.

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

Lead coeff is always non-negative. Explore all combinations with coeffs
bounded in absolute value before increasing the bound. Skip the all-zero
list, and skip any repeats. See examples.

Examples
========

>>> from sympy.polys.numberfields.utilities import coeff_search
>>> cs = coeff_search(2, 1)
>>> C = [next(cs) for i in range(13)]
>>> print(C)
[[1, 1], [1, 0], [1, -1], [0, 1], [2, 2], [2, 1], [2, 0], [2, -1], [2, -2],
 [1, 2], [1, -2], [0, 2], [3, 3]]

Parameters
==========

m : int
    Length of coeff list.
R : int
    Initial max abs val for coeffs (will increase as search proceeds).

Returns
=======

generator
    Infinite generator of lists of coefficients.

Nr   r   )rI   )rK   RR0r   jrN   s         r   coeff_searchrc     s     J 
B	
aA
7afaA$JEdqbjFA dqbj		q1uaAaD !qAtqy  FAaA s   >B:B Bc                    U R                   u  pU R                  U R                  XR                  5      5      nUR	                  5       u  pEUSU [        [        U5      5      :w  a  [        S5      eUSS2US24   nUR                  5       nU$ )a  
Extend a basis for a subspace to a basis for the whole space.

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

Given an $n \times r$ matrix *M* of rank $r$ (so $r \leq n$), this function
computes an invertible $n \times n$ matrix $B$ such that the first $r$
columns of $B$ equal *M*.

This operation can be interpreted as a way of extending a basis for a
subspace, to give a basis for the whole space.

To be precise, suppose you have an $n$-dimensional vector space $V$, with
basis $\{v_1, v_2, \ldots, v_n\}$, and an $r$-dimensional subspace $W$ of
$V$, spanned by a basis $\{w_1, w_2, \ldots, w_r\}$, where the $w_j$ are
given as linear combinations of the $v_i$. If the columns of *M* represent
the $w_j$ as such linear combinations, then the columns of the matrix $B$
computed by this function give a new basis $\{u_1, u_2, \ldots, u_n\}$ for
$V$, again relative to the $\{v_i\}$ basis, and such that $u_j = w_j$
for $1 \leq j \leq r$.

Examples
========

Note: The function works in terms of columns, so in these examples we
print matrix transposes in order to make the columns easier to inspect.

>>> from sympy.polys.matrices import DM
>>> from sympy import QQ, FF
>>> from sympy.polys.numberfields.utilities import supplement_a_subspace
>>> M = DM([[1, 7, 0], [2, 3, 4]], QQ).transpose()
>>> print(supplement_a_subspace(M).to_Matrix().transpose())
Matrix([[1, 7, 0], [2, 3, 4], [1, 0, 0]])

>>> M2 = M.convert_to(FF(7))
>>> print(M2.to_Matrix().transpose())
Matrix([[1, 0, 0], [2, 3, -3]])
>>> print(supplement_a_subspace(M2).to_Matrix().transpose())
Matrix([[1, 0, 0], [2, 3, -3], [0, 1, 0]])

Parameters
==========

M : :py:class:`~.DomainMatrix`
    The columns give the basis for the subspace.

Returns
=======

:py:class:`~.DomainMatrix`
    This matrix is invertible and its first $r$ columns equal *M*.

Raises
======

DMRankError
    If *M* was not of maximal rank.

References
==========

.. [1] Cohen, H. *A Course in Computational Algebraic Number Theory*
   (See Sec. 2.3.2.)

NzM was not of maximal rank)	shapehstackeyedomainrreftuplerI   r   inv)Mr6   r   Maugr`   pivotsABs           r   supplement_a_subspacerq   =  s    F 77DA 88AEE!XX&'D		IAbqzU58_$566
 	
!QR%A	A
 Hr   Nc                     [        U 5      n U R                  (       a  X 4$ U R                  (       d  [        S5      e[	        SU S[        5       S9n[        U SS9nUR                  SS9n[        R                  Spv U(       dY  U" 5       n U H*  u  pXR                  ::  d  M  U R                  U	::  d  M(  Sn  O   [        =R                  S	-  sl	        U(       d  MY  U[        l	        Ub  UR                  WW	XS
9u  pWW	4$ ! U[        l	        f = f)a  
Find a rational isolating interval for a real algebraic number.

Examples
========

>>> from sympy import isolate, sqrt, Rational
>>> print(isolate(sqrt(2)))  # doctest: +SKIP
(1, 2)
>>> print(isolate(sqrt(2), eps=Rational(1, 100)))
(24/17, 17/12)

Parameters
==========

alg : str, int, :py:class:`~.Expr`
    The algebraic number to be isolated. Must be a real number, to use this
    particular function. However, see also :py:meth:`.Poly.intervals`,
    which isolates complex roots when you pass ``all=True``.
eps : positive element of :ref:`QQ`, None, optional (default=None)
    Precision to be passed to :py:meth:`.Poly.refine_root`
fast : boolean, optional (default=False)
    Say whether fast refinement procedure should be used.
    (Will be passed to :py:meth:`.Poly.refine_root`.)

Returns
=======

Pair of rational numbers defining an isolating interval for the given
algebraic number.

See Also
========

.Poly.intervals

z+complex algebraic numbers are not supportedr^   mpmath)modulesprinterT)polys)sqfFr    )epsfast)r   is_Rationalis_realNotImplementedErrorr   r	   r   	intervalsr   dpsr$   rM   refine_root)
algrx   ry   funcpolyr}   r~   doner$   rM   s
             r   isolater     s    N #,C
z[[!9; 	; BX7HID3d#D4(I&C!:#%%1*D "
 ! $ 
1#9q6M s   ;"D  !D  3&D   D)NF)r\   sympy.core.sympifyr   sympy.ntheory.factor_r   !sympy.polys.domains.rationalfieldr   sympy.polys.domains.integerringr   sympy.polys.matrices.exceptionsr    sympy.polys.numberfields.minpolyr   sympy.printing.lambdareprr	   sympy.utilities.decoratorr
   sympy.utilities.lambdifyr   rs   r   r   r   r   r-   r/   rc   rq   r   r^   r   r   <module>r      s    - & + 0 . 7 4 5 , - @2/*& U Up [ [ [| 4 4nTn E Er   