
    sg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y)z'Utilities for algebraic number theory.     )sympify)	factorint)QQ)ZZ)DMRankError)minpoly)IntervalPrinter)public)lambdify)mpc                 ~    t        | t              xs, t        j                  |       xs 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    U/var/www/html/venv/lib/python3.12/site-packages/sympy/polys/numberfields/utilities.pyis_ratr      s+    , a?A?"**Q-?    c                 P    t        | t              xs 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                 H    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                 x   | 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}|j                         D ]9  \  }}|dz  dk(  r$d||<   |dz  dk(  r|dz  }|dk\  s&|dz
  dz  ||<   2|dz  ||<   ; d|v }|s|dz  dk(  r&|d   }|dkD  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   s"   l 	1uF\]]AvAq6zAv2v!I
A
A K! 1q5A:AaD1uzq AvA!|!6AaD 6D{Q!#qTAvv7!6AaDqa!a4Kr   c                   6    e Zd ZdZd	dZd Zd Zd Zd Zd Z	y)
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                     || _         || _        |j                         | _        t	        |j
                  j                               D cg c]  }| | z  
 c}dd g| _        | j                  | _        yc c}w )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.

        N)	Tmodulusdegreenreversedrepto_listpowers_n_and_up
max_so_far)selfr2   r3   r   s       r   __init__zAlgIntPowers.__init__   sc     4<QUU]]_4M Nq!d NsPR ST&& !Os   	A4c                 <    | j                   |S || j                   z  S N)r3   )r;   exps     r   redzAlgIntPowers.red   s    ll*sBdll0BBr   c                 $    | j                  |      S r>   )r@   )r;   others     r   __rmod__zAlgIntPowers.__rmod__   s    xxr   c           
      l   | j                   }||k  ry | j                  }| j                  }|d   }t        |dz   |dz         D ]d  }||dz
  |z
     |dz
     }|j	                  |d   |z  | z  gt        d|      D cg c]  }||dz
  |z
     |dz
     ||   |z  z   | z  ! c}z          f || _         y c c}w )Nr   r   )r:   r5   r9   rangeappend)	r;   r*   mr5   r   r   kbis	            r   compute_up_throughzAlgIntPowers.compute_up_through   s    OO66FF  aDqsAaC 	A!A#a%1AHH1a$=B1a[#89Qqs1uXac]QqT!V+t3# 	 	#s   :$B1c                     | j                   }|dk  rt        d      ||k  r t        |      D cg c]  }||k(  rdnd c}S | j                  |       | j                  ||z
     S c c}w )Nr   zExponent must be non-negative.r   )r5   r"   rE   rK   r9   )r;   r*   r5   rJ   s       r   getzAlgIntPowers.get   sm    FFq5=>>U05a91aAQ&99##A&''A.. :s   A%c                 $    | j                  |      S r>   )rM   )r;   items     r   __getitem__zAlgIntPowers.__getitem__  s    xx~r   r>   )
__name__
__module____qualname____doc__r<   r@   rC   rK   rM   rP    r   r   r/   r/      s'    %N!&C/r   r/   c              #     K   |}|g| z  }	 ||k(  s	||v s| |v r|dd  | dz
  }||   | k(  r|dz  }||   | k(  r||xx   dz  cc<   t        |dz   |       D ]  }|||<   	 t        |       D ]  }||   dk7  s n |dz  }|g| z  }~w)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   )rE   )rG   RR0r   jrJ   s         r   coeff_searchrZ     s     J 
B	
aA
7a1faA$JEdqbjFA dqbj	!	q1ua 	AAaD	q 	Atqy	 FAaA s   ;B
<B
;B
c                     | j                   \  }}| j                  | j                  || j                              }|j	                         \  }}|d| t        t        |            k7  rt        d      |dd|df   }|j                         }|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tuplerE   r   inv)Mr5   r   MaugrW   pivotsABs           r   supplement_a_subspacerh   =  s    F 77DAq 88AEE!QXX&'D		IAvbqzU58_$566
 	
!QR%A	A
 Hr   Nc                    t        |       } | j                  r| | fS | j                  st        d      t	        d| dt                     }t        | d      }|j                  d      }t        j                  d}}	 |sP |       } |D ](  \  }}	|| j                  k  s| j                  |	k  s&d} n t        xj                  d	z  c_	        |sP|t        _	        ||j                  	||
      \  }}		fS # |t        _	        w xY w)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 supportedrU   mpmath)modulesprinterT)polys)sqfFr    )epsfast)r   is_Rationalis_realNotImplementedErrorr   r	   r   	intervalsr   dpsr$   rI   refine_root)
algro   rp   funcpolyrt   ru   doner$   rI   s
             r   isolater{     s   N #,C
Sz[[!9; 	; BX7HID3d#D4(IC&C! 1:#%%1*D
 !  
1#D91q6M s   < C7 C7 - C7 7D)NF)rT   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   rj   r   r   r   r   r-   r/   rZ   rh   r{   rU   r   r   <module>r      s    - & + 0 . 7 4 5 , - @2/*& U Up [ [ [| 4 4nTn E Er   