
    Ed3                        d Z ddlmZ ddlmZ ddlmZ ddlmZ ddl	m
Z
 ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ d Zd Zd Zed             Ze G d d                      Zed             Zd Zedd            ZdS )z'Utilities for algebraic number theory.     )sympify)	factorint)QQ)ZZ)DMRankError)minpoly)IntervalPrinter)public)lambdify)mpc                 |    t          | t                    p't          j        |           pt	          j        |           S )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    Blib/python3.11/site-packages/sympy/polys/numberfields/utilities.pyis_ratr      s.    , a?A?"*Q--?    c                 T    t          | t                    pt          j        |           S )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                 <    t          |           }|j        |j        fS )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                    | dz  dvrt          d          | dk    ri ddifS | dk    ri i fS t          |           }i }i }d}|                                D ];\  }}|dz  dk    r%d||<   |dz  dk    r|dz  }|dk    r|dz
  dz  ||<   3|dz  ||<   <d|v }|s	|dz  dk    r+|d         }|dk    sJ |dk    r|d= n|dz
  |d<   |rdnd|d<   ||fS )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   sd   l 	1uF ^\]]]Av Aq6zAv 2v!I
A
A K!!  1q5A: 	AaD1uz !q Av $A!|!6AaDD 6D  {Q!#  qTAv7 	!6AaDqqa!a4Kr   c                   8    e Zd ZdZd	dZd Zd Zd Zd Zd Z	dS )
AlgIntPowersa  
    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                      | _         | _        |                                 _         fdt	          |j        j                  D             dd         g _         j         _        dS )a-  
        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.

        c                     g | ]}| z  	S  r2   ).0r   selfs     r   
<listcomp>z)AlgIntPowers.__init__.<locals>.<listcomp>   s     H H Hq!d H H Hr   N)Tmodulusdegreenreversedreppowers_n_and_up
max_so_far)r4   r7   r8   s   `  r   __init__zAlgIntPowers.__init__   sc      H H H HHQUY4G4G H H H" MN&r   c                 (    | j         |n	|| j         z  S N)r8   )r4   exps     r   redzAlgIntPowers.red   s    lBssdl0BBr   c                 ,    |                      |          S rA   )rC   )r4   others     r   __rmod__zAlgIntPowers.__rmod__   s    xxr   c           
      R     j         }||k    rd S  j         j        d         t          |dz   |dz             D ]]dz
  z
           dz
                               d         z   z  g fdt          d          D             z              ^| _         d S )Nr   r   c                 \    g | ](}d z
  z
           |d z
           |         z  z   z  )S )r   r2   )r3   ibr   kr:   r   r4   s     r   r5   z3AlgIntPowers.compute_up_through.<locals>.<listcomp>   sL     # # #89Qqs1uXac]QqT!V+t3# # #r   )r>   r:   r=   rangeappend)r4   r*   mrJ   r   rK   r:   r   s   `  @@@@@r   compute_up_throughzAlgIntPowers.compute_up_through   s    O666F aDqsAaC 	 	A!A#a%1AHH1a$ # # # # # # # # #=B1a[[# # #    
 r   c                     | j         }dk     rt          d          |k     rfdt          |          D             S |                                | j        |z
           S )Nr   zExponent must be non-negative.c                 $    g | ]}|k    rd ndS )r   r   r2   )r3   rI   r*   s     r   r5   z$AlgIntPowers.get.<locals>.<listcomp>   s&    9991a&AAQ999r   )r:   r"   rL   rO   r=   )r4   r*   r:   s    ` r   getzAlgIntPowers.get   sw    Fq5 	/=>>>U 	/9999a9999##A&&&'A..r   c                 ,    |                      |          S rA   )rR   )r4   items     r   __getitem__zAlgIntPowers.__getitem__  s    xx~~r   rA   )
__name__
__module____qualname____doc__r?   rC   rF   rO   rR   rU   r2   r   r   r/   r/      s        % %N! ! ! !&C C C    / / /    r   r/   c              #   D  K   |}|g| z  }	 ||k    s	||v s| |v r|dd         V  | dz
  }||         | k    r|dz  }||         | k    ||xx         dz  cc<   t          |dz   |           D ]}|||<   t          |           D ]}||         dk    r n|dz  }|g| z  })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.

    TNr   r   )rL   )rN   RR0r   jrI   s         r   coeff_searchr^     s     J 
B	
aA7 	a1f 	a 	AAA$JJJEdqbj 	FA dqbj 		!	q1ua 	 	AAaDDq 	 	Atqy  FAaAr   c                 V   | j         \  }}|                     |                     || j                            }|                                \  }}|d|         t          t          |                    k    rt          d          |dd|df         }|                                }|S )ax  
    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tuplerL   r   inv)Mr:   r   Maugr[   pivotsABs           r   supplement_a_subspacerl   =  s    F 7DAq 88AEE!QX&&''D		IAvbqbzU588__$ 75666
 	
!!!QRR%A	A
 Hr   NFc                    t          |           } | j        r| | fS | j        st          d          t	          d| dt                                }t          | d          }|                    d          }t          j	        d}}	 |sC |            } |D ]\  }}	|| j
        k    r| j        |	k    rd} n t          xj	        d	z  c_	        |C|t          _	        n# |t          _	        w xY w||                    ||	||          \  }}	||	fS )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 supportedr2   mpmath)modulesprinterT)polys)sqfFr    N)epsfast)r   is_Rationalis_realNotImplementedErrorr   r	   r   	intervalsr   dpsr$   rJ   refine_root)
algrs   rt   funcpolyrx   ry   doner$   rJ   s
             r   isolater     sF   N #,,C
 ;Sz[ ;!9; ; 	; BX7H7HIIID3d###D4((IC 	$&&C!  1: #%1* DE!  	 
 :1#D991q6Ms   AC C&)NF)rY   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   rn   r   r   r   r   r-   r/   r^   rl   r   r2   r   r   <module>r      s   - - & & & & & & + + + + + + 0 0 0 0 0 0 . . . . . . 7 7 7 7 7 7 4 4 4 4 4 4 5 5 5 5 5 5 , , , , , , - - - - - -      @ @ @2/ / /*& & & U U Up [ [ [ [ [ [ [ [| 4 4 4nT T Tn E E E E E Er   