
    ЦiG                         S SK Jr  S SKJrJrJr  S SKJr  S SK	J
r
  S SKJrJr   " S S5      r " S S	5      rS
 rSS jrS rS rS rS rS rS rS rSS jrg)    )_randint)gcdinvertsqrt)_sqrt_mod_prime_power)isprime)logr   c                   $    \ rS rSrSS jrS rSrg)SievePolynomial   Nc                 (    Xl         X l        X0l        g)aT  This class denotes the seive polynomial.
If ``g(x) = (a*x + b)**2 - N``. `g(x)` can be expanded
to ``a*x**2 + 2*a*b*x + b**2 - N``, so the coefficient
is stored in the form `[a**2, 2*a*b, b**2 - N]`. This
ensures faster `eval` method because we dont have to
perform `a**2, 2*a*b, b**2` every time we call the
`eval` method. As multiplication is more expensive
than addition, by using modified_coefficient we get
a faster seiving process.

Parameters
==========

modified_coeff : modified_coefficient of sieve polynomial
a : parameter of the sieve polynomial
b : parameter of the sieve polynomial
N)modified_coeffab)selfr   r   r   s       O/var/www/html/ai-image-ml/venv/lib/python3.13/site-packages/sympy/ntheory/qs.py__init__SievePolynomial.__init__	   s    $ -    c                 @    SnU R                    H  nX!-  nX#-  nM     U$ )zz
Compute the value of the sieve polynomial at point x.

Parameters
==========

x : Integer parameter for sieve polynomial
r   )r   )r   xanscoeffs       r   evalSievePolynomial.eval   s.     ((EHCLC ) 
r   )r   r   r   ) NN)__name__
__module____qualname____firstlineno__r   r   __static_attributes__r   r   r   r   r      s    ,r   r   c                       \ rS rSrSrS rSrg)FactorBaseElem/   z7This class stores an element of the `factor_base`.
    c                 `    Xl         X l        X0l        SU l        SU l        SU l        SU l        g)z
Initialization of factor_base_elem.

Parameters
==========

prime : prime number of the factor_base
tmem_p : Integer square root of x**2 = n mod prime
log_p : Compute Natural Logarithm of the prime
N)primetmem_plog_psoln1soln2a_invb_ainv)r   r&   r'   r(   s       r   r   FactorBaseElem.__init__2   s/     




r   )r+   r,   r(   r&   r)   r*   r'   N)r   r   r   r    __doc__r   r!   r   r   r   r#   r#   /   s    r   r#   c                 b   SSK Jn  / nSu  pEUR                  SU 5       H  n[        XS-
  S-  U5      S:X  d  M  US:  a  Uc  [	        U5      S-
  nUS:  a  Uc  [	        U5      S-
  n[        XS5      S   n[        [        U5      S-  5      nUR                  [        XgU5      5        M     XEU4$ )	a  Generate `factor_base` for Quadratic Sieve. The `factor_base`
consists of all the points whose ``legendre_symbol(n, p) == 1``
and ``p < num_primes``. Along with the prime `factor_base` also stores
natural logarithm of prime and the residue n modulo p.
It also returns the of primes numbers in the `factor_base` which are
close to 1000 and 5000.

Parameters
==========

prime_bound : upper prime bound of the factor_base
n : integer to be factored
r   )sieveNN      i  i     )
sympy.ntheory.generater0   
primerangepowlenr   roundr	   appendr#   )	prime_boundnr0   factor_baseidx_1000idx_5000r&   residuer(   s	            r   _generate_factor_baserA   F   s     -K#H!!![1q19"E*a/t| 0{+a/t| 0{+a/+Aa8;G#e*U*+E~eeDE 2 {**r   Nc                 p   [        U5      n[        SU -  5      U-  nSu  pn
Uc  SOUnUc  [        U5      S-
  OUn[        S5       H  nSn/ nX:  aR  SnUS:X  d  UU;   a  U" X5      nUS:X  a  M  UU;   a  M  UU   R                  nUU-  nUR                  U5        X:  a  MR  X-  nU
b   [        US-
  5      [        U
S-
  5      :  d  M  Un	UnUn
M     UnU	n/ nU HY  nUU   R                  nUU   R                  [        UU-  U5      -  U-  nUUS-  :  a  UU-
  nUR                  UU-  U-  5        M[     [        U5      n[        X-  SU-  U-  UU-  U -
  /UU5      nU H  nUUR                  -  S:X  a  M  [        UUR                  5      Ul        U Vs/ s H"  nSU-  UR                  -  UR                  -  PM$     snUl        UR                  UR                  U-
  -  UR                  -  Ul        UR                  UR                  * U-
  -  UR                  -  Ul        M     UU4$ s  snf )a#  This step is the initialization of the 1st sieve polynomial.
Here `a` is selected as a product of several primes of the factor_base
such that `a` is about to ``sqrt(2*N) / M``. Other initial values of
factor_base elem are also initialized which includes a_inv, b_ainv, soln1,
soln2 which are used when the sieve polynomial is changed. The b_ainv
is required for fast polynomial change as we do not have to calculate
`2*b*invert(a, prime)` every time.
We also ensure that the `factor_base` primes which make `a` are between
1000 and 5000.

Parameters
==========

N : Number to be factored
M : sieve interval
factor_base : factor_base primes
idx_1000 : index of prime number in the factor_base near 1000
idx_5000 : index of prime number in the factor_base near to 5000
seed : Generate pseudoprime numbers
r3   )NNNr   r2   2   )r   r   r8   ranger&   r:   absr'   r   sumr   r+   r,   r)   r*   )NMr=   r>   r?   seedrandint
approx_valbest_abest_q
best_ratiostartend_r   qrand_ppratioBvalq_lgammar   gfbb_elems                              r   _initialize_first_polynomialr]   c   sP   * tnGacQJ
 "2FJ!AxE"*"2#k
Q
C2YnFA+1 , A+1F#))AFAHHV n UQY#j1n2E!EFFJ   	AA
A#$$C ''&c3*??#E37?%KE	C  	AAac!eQqS1W-q!4Arxx<1!RXX&@ABfQvXbhh&1B	HHbii!m,8HHryyj1n-9  a4K Cs   )H3c                    SSK Jn  SnUnUS-  S:X  a  US-  nUS-  nUS-  S:X  a  M  U" USU-  -  5      S-  S:X  a  SnOSnUR                  SU-  XFS-
     -  -   n	UR                  n
[	        X-  SU
-  U	-  X-  U -
  /X5      nU H}  nXR
                  -  S:X  a  M  UR                  XR                  US-
     -  -
  UR
                  -  Ul        UR                  XR                  US-
     -  -
  UR
                  -  Ul        M     U$ )a  Initialization stage of ith poly. After we finish sieving 1`st polynomial
here we quickly change to the next polynomial from which we will again
start sieving. Suppose we generated ith sieve polynomial and now we
want to generate (i + 1)th polynomial, where ``1 <= i <= 2**(j - 1) - 1``
where `j` is the number of prime factors of the coefficient `a`
then this function can be used to go to the next polynomial. If
``i = 2**(j - 1) - 1`` then go to _initialize_first_polynomial stage.

Parameters
==========

N : number to be factored
factor_base : factor_base primes
i : integer denoting ith polynomial
g : (i - 1)th polynomial
B : array that stores a//q_l*gamma
r   )ceilingr2   r3   )	#sympy.functions.elementary.integersr_   r   r   r   r&   r)   r,   r*   )rG   r=   irZ   rV   r_   vjneg_powr   r   r[   s               r   _initialize_ith_polyrf      s   $ <	A	A
a%1*	Q	a a%1* qAqDzQ!#	aia%  A	Aac!eQS1W-q4Axx<1HHwyyQ'777288CHHwyyQ'777288C	  Hr   c                    S/SU -  S-   -  nU H  nUR                   c  M  [        XR                   -   UR                  -  SU -  UR                  5       H  nX$==   UR                  -  ss'   M     UR                  S:X  a  Mt  [        XR                  -   UR                  -  SU -  UR                  5       H  nX$==   UR                  -  ss'   M     M     U$ )a  Sieve Stage of the Quadratic Sieve. For every prime in the factor_base
that does not divide the coefficient `a` we add log_p over the sieve_array
such that ``-M <= soln1 + i*p <=  M`` and ``-M <= soln2 + i*p <=  M`` where `i`
is an integer. When p = 2 then log_p is only added using
``-M <= soln1 + i*p <=  M``.

Parameters
==========

M : sieve interval
factor_base : factor_base primes
r   r3   r2   )r)   rD   r&   r(   r*   )rH   r=   sieve_arrayfactoridxs        r   _gen_sieve_arrayrk      s     #qsQw-K<<!ll*fll:AaCNC, O<<1!ll*fll:AaCNC, O  r   c                    / nU S:  a  UR                  S5        U S-  n OUR                  S5        U Hw  nXR                  -  S:w  a  UR                  S5        M(  SnXR                  -  S:X  a'  US-  nXR                  -  n XR                  -  S:X  a  M'  UR                  US-  5        My     U S:X  a  US4$ [        U 5      (       a  U S4$ g)a6  Here we check that if `num` is a smooth number or not. If `a` is a smooth
number then it returns a vector of prime exponents modulo 2. For example
if a = 2 * 5**2 * 7**3 and the factor base contains {2, 3, 5, 7} then
`a` is a smooth number and this function returns ([1, 0, 0, 1], True). If
`a` is a partial relation which means that `a` a has one prime factor
greater than the `factor_base` then it returns `(a, False)` which denotes `a`
is a partial relation.

Parameters
==========

a : integer whose smootheness is to be checked
factor_base : factor_base primes
r   r2   r`   r3   TFr1   )r:   r&   r   )numr=   vecri   
factor_exps        r   _check_smoothnessrp      s     C
Qw

1r	

1"JJqM
LL A%!OJLL C LL A% 	

:>"  axDys||Ezr   c                 t   [        U 5      n[        X-  5      S-  U-
  n/ n	[        5       n
SUS   R                  -  n[	        U5       H  u  pX:  a  M  X-
  nUR                  U5      n[        X5      u  nnUc  M4  UR                  U-  UR                  -   nUSL a`  UnUU:  a  M_  UU;  a	  UU4UU'   Mn  UU   u  nnUR                  U5         [        UU 5      nUU-  U-  nUU-  UU-  -  n[        X5      u  nnU	R                  UUU45        M     X4$ ! [         a    U
R                  U5         M  f = f)a  Trial division stage. Here we trial divide the values generetated
by sieve_poly in the sieve interval and if it is a smooth number then
it is stored in `smooth_relations`. Moreover, if we find two partial relations
with same large prime then they are combined to form a smooth relation.
First we iterate over sieve array and look for values which are greater
than accumulated_val, as these values have a high chance of being smooth
number. Then using these values we find smooth relations.
In general, let ``t**2 = u*p modN`` and ``r**2 = v*p modN`` be two partial relations
with the same large prime p. Then they can be combined ``(t*r/p)**2 = u*v modN``
to form a smooth relation.

Parameters
==========

N : Number to be factored
M : sieve interval
factor_base : factor_base primes
sieve_array : stores log_p values
sieve_poly : polynomial from which we find smooth relations
partial_relations : stores partial relations with one large prime
ERROR_TERM : error term for accumulated_val
r4      r`   F)isqrtr	   setr&   	enumerater   rp   r   r   popr   ZeroDivisionErroraddr:   )rG   rH   r=   rh   
sieve_polypartial_relations
ERROR_TERMsqrt_naccumulated_valsmooth_relationsproper_factorpartial_relation_upper_boundrj   rW   r   rc   rn   	is_smoothularge_primeu_prevv_prevlarge_prime_invs                          r   _trial_division_stager     sv   . 1XF!*oe+j8OEM#&{2'<'<#< k* GOOA*1:YLLNZ\\) K99"3323Q!+.!2;!?!%%k2&,[!&<O fH_,fH[!89!21!BYAs,? +@ ** ) !%%k2s   DD76D7c                 D    / nU  H  nUR                  US   5        M     U$ )zlBuild a 2D matrix from smooth relations.

Parameters
==========

smooth_relations : Stores smooth relations
r3   )r:   )r~   matrix
s_relations      r   _build_matrixr   R  s(     F&
jm$ 'Mr   c                    SSK nUR                  U 5      n[        U5      n[        US   5      nS/U-  n[        U5       Hv  n[        U5       H  nX'   U   S:X  d  M    O   SUW'   [        U5       H@  nX:X  a  M
  X'   U   S:X  d  M  [        U5       H  n	X)   U   X)   U   -   S-  X)   U'   M     MB     Mx     / n
[	        U5       H"  u  pUS:X  d  M  U
R                  X+   U/5        M$     XU4$ )a  Fast gaussian reduction for modulo 2 matrix.

Parameters
==========

A : Matrix

Examples
========

>>> from sympy.ntheory.qs import _gauss_mod_2
>>> _gauss_mod_2([[0, 1, 1], [1, 0, 1], [0, 1, 0], [1, 1, 1]])
([[[1, 0, 1], 3]],
 [True, True, True, False],
 [[0, 1, 0], [1, 0, 0], [0, 0, 1], [1, 0, 1]])

Reference
==========

.. [1] A fast algorithm for gaussian elimination over GF(2) and
its implementation on the GAPP. Cetin K.Koc, Sarath N.Arachchiger   NFr2   Tr3   )copydeepcopyr8   rD   ru   r:   )Ar   r   rowcolmarkcrc1r2dependent_rowrj   rW   s                r   _gauss_mod_2r   `  s   , ]]1F
f+C
fQi.C73;D3ZsAy|q   Q*Bwy}!*B&,jnvz!}&D%IFJrN %	   MdO%<  &+s!34 $ &&r   c                    X   S   nXF   S   /nXF   S   /nX   S   n	[        U	5       Hl  u  pUS:X  d  M  [        [        U5      5       HG  nX,   U
   S:X  d  M  X   S:X  d  M  UR                  XL   S   5        UR                  XL   S   5          Mj     Mn     SnSnU H  nX-  nM	     U H  nX-  nM	     [	        U5      n[        X-
  U5      $ )a_  Finds proper factor of N. Here, transform the dependent rows as a
combination of independent rows of the gauss_matrix to form the desired
relation of the form ``X**2 = Y**2 modN``. After obtaining the desired relation
we obtain a proper factor of N by `gcd(X - Y, N)`.

Parameters
==========

dependent_rows : denoted dependent rows in the reduced matrix form
mark : boolean array to denoted dependent and independent rows
gauss_matrix : Reduced form of the smooth relations matrix
index : denoted the index of the dependent_rows
smooth_relations : Smooth relations vectors matrix
N : Number to be factored
r2   r   T)ru   rD   r8   r:   rs   r   )dependent_rowsr   gauss_matrixindexr~   rG   idx_in_smoothindependent_uindependent_vdept_rowrj   rW   r   r   rc   rb   s                   r   _find_factorr     s      #)!,M%4Q78M%4Q78M$Q'Hh'!8S./$S)Q.493D!(()9)>q)AB!(()9)>q)AB	 0 ( 	
A	A	 	  	aAqua=r   c           	         US-  n[        X5      u  pVn/ nSn	0 n
[        5       nS[        U5      -  S-  n U	S:X  a  [        XXuU5      u  pO[	        XU	WW5      nU	S-  n	U	S[        U5      S-
  -  :  a  Sn	[        X'5      n[        XXXU5      u  nnUU-  nUU-  n[        U5      [        U5      U-   :  a  OM  [        U5      n[        U5      u  nnnU n[        [        U5      5       Hy  n[        UUUUX5      nUS:  d  M  UU :  d  M"  UR                  U5        UU-  S:X  a  UU-  nUU-  S:X  a  M  [        U5      (       a  UR                  U5          U$ US:X  d  Mx    U$    U$ )a  Performs factorization using Self-Initializing Quadratic Sieve.
In SIQS, let N be a number to be factored, and this N should not be a
perfect power. If we find two integers such that ``X**2 = Y**2 modN`` and
``X != +-Y modN``, then `gcd(X + Y, N)` will reveal a proper factor of N.
In order to find these integers X and Y we try to find relations of form
t**2 = u modN where u is a product of small primes. If we have enough of
these relations then we can form ``(t1*t2...ti)**2 = u1*u2...ui modN`` such that
the right hand side is a square, thus we found a relation of ``X**2 = Y**2 modN``.

Here, several optimizations are done like using multiple polynomials for
sieving, fast changing between polynomials and using partial relations.
The use of partial relations can speeds up the factoring by 2 times.

Parameters
==========

N : Number to be Factored
prime_bound : upper bound for primes in the factor base
M : Sieve Interval
ERROR_TERM : Error term for checking smoothness
threshold : Extra smooth relations for factorization
seed : generate pseudo prime numbers

Examples
========

>>> from sympy.ntheory import qs
>>> qs(25645121643901801, 2000, 10000)
{5394769, 4753701529}
>>> qs(9804659461513846513, 2000, 10000)
{4641991, 2112166839943}

References
==========

.. [1] https://pdfs.semanticscholar.org/5c52/8a975c1405bd35c65993abf5a4edb667c1db.pdf
.. [2] https://www.rieselprime.de/ziki/Self-initializing_quadratic_sieve
r4   r      d   r2   r3   )rA   rt   r8   r]   rf   rk   r   r   r   rD   r   rx   r   )rG   r;   rH   r{   rI   r>   r?   r=   r~   ith_polyrz   r   	thresholdith_sieve_polyB_arrayrh   s_relp_fr   r   r   r   N_copyr   ri   s                            r   qsr     s   N J&;K&K#HHEM#k""c)I
q=&B1`h&i#NG1!(N\cdNAq3w<!+,,H&q6*1>nxy
sE! C$4y$@@  +,F(4V(<%M4Fs=)*mT<HX\A:&1*f%6/Q&6! 6/Q&v!!&)  { + r   )N)   i  )sympy.core.randomr   sympy.external.gmpyr   r   r   rs   sympy.ntheory.residue_ntheoryr   sympy.ntheoryr   mathr	   r   r#   rA   r]   rf   rk   rp   r   r   r   r   r   r   r   r   <module>r      sf    & : : ? ! $ $N .+:CL%P6#L<+@*'Z%PJr   