K i!zddlmZddlmZmZddlmZddlmZddl m Z m Z m Z ddl mZdZd dZd Zdd Zd Zy ))prodgcdgcdextisprime)ZZ)gf_crtgf_crt1gf_crt2)as_intc ||dzkr|S||z S)zReturn the residual mod m such that it is within half of the modulus. >>> from sympy.ntheory.modular import symmetric_residue >>> symmetric_residue(1, 6) 1 >>> symmetric_residue(4, 6) -2 )ams [/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/sympy/ntheory/modular.pysymmetric_residuer s AF{ q5Lc|r2ttt|}ttt|}t||tt |}|rFt fdt||Ds(ttt||d|dS\}|r tt|t|fStt|fS)akChinese Remainder Theorem. The moduli in m are assumed to be pairwise coprime. The output is then an integer f, such that f = v_i mod m_i for each pair out of v and m. If ``symmetric`` is False a positive integer will be returned, else \|f\| will be less than or equal to the LCM of the moduli, and thus f may be negative. If the moduli are not co-prime the correct result will be returned if/when the test of the result is found to be incorrect. This result will be None if there is no solution. The keyword ``check`` can be set to False if it is known that the moduli are coprime. Examples ======== As an example consider a set of residues ``U = [49, 76, 65]`` and a set of moduli ``M = [99, 97, 95]``. Then we have:: >>> from sympy.ntheory.modular import crt >>> crt([99, 97, 95], [49, 76, 65]) (639985, 912285) This is the correct result because:: >>> [639985 % m for m in [99, 97, 95]] [49, 76, 65] If the moduli are not co-prime, you may receive an incorrect result if you use ``check=False``: >>> crt([12, 6, 17], [3, 4, 2], check=False) (954, 1224) >>> [954 % m for m in [12, 6, 17]] [6, 0, 2] >>> crt([12, 6, 17], [3, 4, 2]) is None True >>> crt([3, 6], [2, 5]) (5, 6) Note: the order of gf_crt's arguments is reversed relative to crt, and that solve_congruence takes residue, modulus pairs. Programmer's note: rather than checking that all pairs of moduli share no GCD (an O(n**2) test) and rather than factoring all moduli and seeing that there is no factor in common, a check that the result gives the indicated residuals is performed -- an O(n) operation. See Also ======== solve_congruence sympy.polys.galoistools.gf_crt : low level crt routine used by this routine c3:K|]\}}||z|zk(ywNr).0vrresults r zcrt..Zs"=41a1q5FQJ&=sF)check symmetric) listmapr r r rallzipsolve_congruenceintr)rrrrmmrs @rcrtr&st VQ  VQ  Aq" F aB =3q!9==%tC1I96F~ JFB$VR013r7:: v;B rc"t|tS)aCFirst part of Chinese Remainder Theorem, for multiple application. Examples ======== >>> from sympy.ntheory.modular import crt, crt1, crt2 >>> m = [99, 97, 95] >>> v = [49, 76, 65] The following two codes have the same result. >>> crt(m, v) (639985, 912285) >>> mm, e, s = crt1(m) >>> crt2(m, v, mm, e, s) (639985, 912285) However, it is faster when we want to fix ``m`` and compute for multiple ``v``, i.e. the following cases: >>> mm, e, s = crt1(m) >>> vs = [[52, 21, 37], [19, 46, 76]] >>> for v in vs: ... print(crt2(m, v, mm, e, s)) (397042, 912285) (803206, 912285) See Also ======== sympy.polys.galoistools.gf_crt1 : low level crt routine used by this routine sympy.ntheory.modular.crt sympy.ntheory.modular.crt2 )r r )rs rcrt1r(fsL 1b>rct|||||t}|r tt||t|fSt|t|fS)aSecond part of Chinese Remainder Theorem, for multiple application. See ``crt1`` for usage. Examples ======== >>> from sympy.ntheory.modular import crt1, crt2 >>> mm, e, s = crt1([18, 42, 6]) >>> crt2([18, 42, 6], [0, 0, 0], mm, e, s) (0, 4536) See Also ======== sympy.polys.galoistools.gf_crt2 : low level crt routine used by this routine sympy.ntheory.modular.crt sympy.ntheory.modular.crt1 )r r r$r)rrr%esrrs rcrt2r,sJ,Q2q!R (F$VR013r7:: v;B rc"d}|}|jdd}|jddr|Dcgc]\}}t|t|f}}}i}|D]\}}||z}||vr |||k7ry|||< |jDcgc] \}}||f }}}~td|Dr#t t |\}}t |||dSd }|D]} ||| }|y|\} }| |z} |rt |fS fScc}}wcc}}w) aCompute the integer ``n`` that has the residual ``ai`` when it is divided by ``mi`` where the ``ai`` and ``mi`` are given as pairs to this function: ((a1, m1), (a2, m2), ...). If there is no solution, return None. Otherwise return ``n`` and its modulus. The ``mi`` values need not be co-prime. If it is known that the moduli are not co-prime then the hint ``check`` can be set to False (default=True) and the check for a quicker solution via crt() (valid when the moduli are co-prime) will be skipped. If the hint ``symmetric`` is True (default is False), the value of ``n`` will be within 1/2 of the modulus, possibly negative. Examples ======== >>> from sympy.ntheory.modular import solve_congruence What number is 2 mod 3, 3 mod 5 and 2 mod 7? >>> solve_congruence((2, 3), (3, 5), (2, 7)) (23, 105) >>> [23 % m for m in [3, 5, 7]] [2, 3, 2] If you prefer to work with all remainder in one list and all moduli in another, send the arguments like this: >>> solve_congruence(*zip((2, 3, 2), (3, 5, 7))) (23, 105) The moduli need not be co-prime; in this case there may or may not be a solution: >>> solve_congruence((2, 3), (4, 6)) is None True >>> solve_congruence((2, 3), (5, 6)) (5, 6) The symmetric flag will make the result be within 1/2 of the modulus: >>> solve_congruence((2, 3), (5, 6), symmetric=True) (-1, 6) See Also ======== crt : high level routine implementing the Chinese Remainder Theorem c|\}}|\}}|||z |}}}t|||} |||fD cgc]} | | z c} \}}}|dk7rt||\} } } | dk7ry|| z}|||zz||z} }|| fScc} w)zReturn the tuple (a, m) which satisfies the requirement that n = a + i*m satisfy n = a1 + j*m1 and n = a2 = k*m2. References ========== .. [1] https://en.wikipedia.org/wiki/Method_of_successive_substitution Nr)c1c2a1m1a2m2rbcgiinv_a_rs rcombinez!solve_congruence..combinesBBb2gra1 1aL"#Q+A1a4+1a 6 A,KAuaAv JABqDy"Q$1!t ,s A,rFrTNc38K|]\}}t|ywrr)rrrs rrz#solve_congruence..s)dawqz)s)rr)rr/)getr itemsr!rr"r&r) remainder_modulus_pairshintr<rmrr>runiqrvrmins rr#r#sRh, !Be,I xx13 4Avay&)$ 4 4 DAq FADyQ<DG  "& .Aq!f . .  )b) )R>DAqq!y> > B  R  : 1 E  $Q*A- -!t S5*/s D D N)FT)F)mathrsympy.external.gmpyrrsympy.ntheory.primetestrsympy.polys.domainsr sympy.polys.galoistoolsr r r sympy.utilities.miscr rr&r(r,r#rrrrNs7++"<<' K \&R :wr