m2m模型翻译
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1531 lines
39 KiB

6 months ago
  1. from sympy.core.function import Function
  2. from sympy.core.numbers import igcd, igcdex, mod_inverse
  3. from sympy.core.power import isqrt
  4. from sympy.core.singleton import S
  5. from sympy.polys.domains import ZZ
  6. from .primetest import isprime
  7. from .factor_ import factorint, trailing, totient, multiplicity
  8. from sympy.utilities.misc import as_int
  9. from sympy.core.random import _randint, randint
  10. from itertools import cycle, product
  11. def n_order(a, n):
  12. """Returns the order of ``a`` modulo ``n``.
  13. The order of ``a`` modulo ``n`` is the smallest integer
  14. ``k`` such that ``a**k`` leaves a remainder of 1 with ``n``.
  15. Examples
  16. ========
  17. >>> from sympy.ntheory import n_order
  18. >>> n_order(3, 7)
  19. 6
  20. >>> n_order(4, 7)
  21. 3
  22. """
  23. from collections import defaultdict
  24. a, n = as_int(a), as_int(n)
  25. if igcd(a, n) != 1:
  26. raise ValueError("The two numbers should be relatively prime")
  27. factors = defaultdict(int)
  28. f = factorint(n)
  29. for px, kx in f.items():
  30. if kx > 1:
  31. factors[px] += kx - 1
  32. fpx = factorint(px - 1)
  33. for py, ky in fpx.items():
  34. factors[py] += ky
  35. group_order = 1
  36. for px, kx in factors.items():
  37. group_order *= px**kx
  38. order = 1
  39. if a > n:
  40. a = a % n
  41. for p, e in factors.items():
  42. exponent = group_order
  43. for f in range(e + 1):
  44. if pow(a, exponent, n) != 1:
  45. order *= p ** (e - f + 1)
  46. break
  47. exponent = exponent // p
  48. return order
  49. def _primitive_root_prime_iter(p):
  50. """
  51. Generates the primitive roots for a prime ``p``
  52. Examples
  53. ========
  54. >>> from sympy.ntheory.residue_ntheory import _primitive_root_prime_iter
  55. >>> list(_primitive_root_prime_iter(19))
  56. [2, 3, 10, 13, 14, 15]
  57. References
  58. ==========
  59. .. [1] W. Stein "Elementary Number Theory" (2011), page 44
  60. """
  61. # it is assumed that p is an int
  62. v = [(p - 1) // i for i in factorint(p - 1).keys()]
  63. a = 2
  64. while a < p:
  65. for pw in v:
  66. # a TypeError below may indicate that p was not an int
  67. if pow(a, pw, p) == 1:
  68. break
  69. else:
  70. yield a
  71. a += 1
  72. def primitive_root(p):
  73. """
  74. Returns the smallest primitive root or None
  75. Parameters
  76. ==========
  77. p : positive integer
  78. Examples
  79. ========
  80. >>> from sympy.ntheory.residue_ntheory import primitive_root
  81. >>> primitive_root(19)
  82. 2
  83. References
  84. ==========
  85. .. [1] W. Stein "Elementary Number Theory" (2011), page 44
  86. .. [2] P. Hackman "Elementary Number Theory" (2009), Chapter C
  87. """
  88. p = as_int(p)
  89. if p < 1:
  90. raise ValueError('p is required to be positive')
  91. if p <= 2:
  92. return 1
  93. f = factorint(p)
  94. if len(f) > 2:
  95. return None
  96. if len(f) == 2:
  97. if 2 not in f or f[2] > 1:
  98. return None
  99. # case p = 2*p1**k, p1 prime
  100. for p1, e1 in f.items():
  101. if p1 != 2:
  102. break
  103. i = 1
  104. while i < p:
  105. i += 2
  106. if i % p1 == 0:
  107. continue
  108. if is_primitive_root(i, p):
  109. return i
  110. else:
  111. if 2 in f:
  112. if p == 4:
  113. return 3
  114. return None
  115. p1, n = list(f.items())[0]
  116. if n > 1:
  117. # see Ref [2], page 81
  118. g = primitive_root(p1)
  119. if is_primitive_root(g, p1**2):
  120. return g
  121. else:
  122. for i in range(2, g + p1 + 1):
  123. if igcd(i, p) == 1 and is_primitive_root(i, p):
  124. return i
  125. return next(_primitive_root_prime_iter(p))
  126. def is_primitive_root(a, p):
  127. """
  128. Returns True if ``a`` is a primitive root of ``p``
  129. ``a`` is said to be the primitive root of ``p`` if gcd(a, p) == 1 and
  130. totient(p) is the smallest positive number s.t.
  131. a**totient(p) cong 1 mod(p)
  132. Examples
  133. ========
  134. >>> from sympy.ntheory import is_primitive_root, n_order, totient
  135. >>> is_primitive_root(3, 10)
  136. True
  137. >>> is_primitive_root(9, 10)
  138. False
  139. >>> n_order(3, 10) == totient(10)
  140. True
  141. >>> n_order(9, 10) == totient(10)
  142. False
  143. """
  144. a, p = as_int(a), as_int(p)
  145. if igcd(a, p) != 1:
  146. raise ValueError("The two numbers should be relatively prime")
  147. if a > p:
  148. a = a % p
  149. return n_order(a, p) == totient(p)
  150. def _sqrt_mod_tonelli_shanks(a, p):
  151. """
  152. Returns the square root in the case of ``p`` prime with ``p == 1 (mod 8)``
  153. References
  154. ==========
  155. .. [1] R. Crandall and C. Pomerance "Prime Numbers", 2nt Ed., page 101
  156. """
  157. s = trailing(p - 1)
  158. t = p >> s
  159. # find a non-quadratic residue
  160. while 1:
  161. d = randint(2, p - 1)
  162. r = legendre_symbol(d, p)
  163. if r == -1:
  164. break
  165. #assert legendre_symbol(d, p) == -1
  166. A = pow(a, t, p)
  167. D = pow(d, t, p)
  168. m = 0
  169. for i in range(s):
  170. adm = A*pow(D, m, p) % p
  171. adm = pow(adm, 2**(s - 1 - i), p)
  172. if adm % p == p - 1:
  173. m += 2**i
  174. #assert A*pow(D, m, p) % p == 1
  175. x = pow(a, (t + 1)//2, p)*pow(D, m//2, p) % p
  176. return x
  177. def sqrt_mod(a, p, all_roots=False):
  178. """
  179. Find a root of ``x**2 = a mod p``
  180. Parameters
  181. ==========
  182. a : integer
  183. p : positive integer
  184. all_roots : if True the list of roots is returned or None
  185. Notes
  186. =====
  187. If there is no root it is returned None; else the returned root
  188. is less or equal to ``p // 2``; in general is not the smallest one.
  189. It is returned ``p // 2`` only if it is the only root.
  190. Use ``all_roots`` only when it is expected that all the roots fit
  191. in memory; otherwise use ``sqrt_mod_iter``.
  192. Examples
  193. ========
  194. >>> from sympy.ntheory import sqrt_mod
  195. >>> sqrt_mod(11, 43)
  196. 21
  197. >>> sqrt_mod(17, 32, True)
  198. [7, 9, 23, 25]
  199. """
  200. if all_roots:
  201. return sorted(list(sqrt_mod_iter(a, p)))
  202. try:
  203. p = abs(as_int(p))
  204. it = sqrt_mod_iter(a, p)
  205. r = next(it)
  206. if r > p // 2:
  207. return p - r
  208. elif r < p // 2:
  209. return r
  210. else:
  211. try:
  212. r = next(it)
  213. if r > p // 2:
  214. return p - r
  215. except StopIteration:
  216. pass
  217. return r
  218. except StopIteration:
  219. return None
  220. def _product(*iters):
  221. """
  222. Cartesian product generator
  223. Notes
  224. =====
  225. Unlike itertools.product, it works also with iterables which do not fit
  226. in memory. See http://bugs.python.org/issue10109
  227. Author: Fernando Sumudu
  228. with small changes
  229. """
  230. inf_iters = tuple(cycle(enumerate(it)) for it in iters)
  231. num_iters = len(inf_iters)
  232. cur_val = [None]*num_iters
  233. first_v = True
  234. while True:
  235. i, p = 0, num_iters
  236. while p and not i:
  237. p -= 1
  238. i, cur_val[p] = next(inf_iters[p])
  239. if not p and not i:
  240. if first_v:
  241. first_v = False
  242. else:
  243. break
  244. yield cur_val
  245. def sqrt_mod_iter(a, p, domain=int):
  246. """
  247. Iterate over solutions to ``x**2 = a mod p``
  248. Parameters
  249. ==========
  250. a : integer
  251. p : positive integer
  252. domain : integer domain, ``int``, ``ZZ`` or ``Integer``
  253. Examples
  254. ========
  255. >>> from sympy.ntheory.residue_ntheory import sqrt_mod_iter
  256. >>> list(sqrt_mod_iter(11, 43))
  257. [21, 22]
  258. """
  259. from sympy.polys.galoistools import gf_crt1, gf_crt2
  260. a, p = as_int(a), abs(as_int(p))
  261. if isprime(p):
  262. a = a % p
  263. if a == 0:
  264. res = _sqrt_mod1(a, p, 1)
  265. else:
  266. res = _sqrt_mod_prime_power(a, p, 1)
  267. if res:
  268. if domain is ZZ:
  269. yield from res
  270. else:
  271. for x in res:
  272. yield domain(x)
  273. else:
  274. f = factorint(p)
  275. v = []
  276. pv = []
  277. for px, ex in f.items():
  278. if a % px == 0:
  279. rx = _sqrt_mod1(a, px, ex)
  280. if not rx:
  281. return
  282. else:
  283. rx = _sqrt_mod_prime_power(a, px, ex)
  284. if not rx:
  285. return
  286. v.append(rx)
  287. pv.append(px**ex)
  288. mm, e, s = gf_crt1(pv, ZZ)
  289. if domain is ZZ:
  290. for vx in _product(*v):
  291. r = gf_crt2(vx, pv, mm, e, s, ZZ)
  292. yield r
  293. else:
  294. for vx in _product(*v):
  295. r = gf_crt2(vx, pv, mm, e, s, ZZ)
  296. yield domain(r)
  297. def _sqrt_mod_prime_power(a, p, k):
  298. """
  299. Find the solutions to ``x**2 = a mod p**k`` when ``a % p != 0``
  300. Parameters
  301. ==========
  302. a : integer
  303. p : prime number
  304. k : positive integer
  305. Examples
  306. ========
  307. >>> from sympy.ntheory.residue_ntheory import _sqrt_mod_prime_power
  308. >>> _sqrt_mod_prime_power(11, 43, 1)
  309. [21, 22]
  310. References
  311. ==========
  312. .. [1] P. Hackman "Elementary Number Theory" (2009), page 160
  313. .. [2] http://www.numbertheory.org/php/squareroot.html
  314. .. [3] [Gathen99]_
  315. """
  316. pk = p**k
  317. a = a % pk
  318. if k == 1:
  319. if p == 2:
  320. return [ZZ(a)]
  321. if not (a % p < 2 or pow(a, (p - 1) // 2, p) == 1):
  322. return None
  323. if p % 4 == 3:
  324. res = pow(a, (p + 1) // 4, p)
  325. elif p % 8 == 5:
  326. sign = pow(a, (p - 1) // 4, p)
  327. if sign == 1:
  328. res = pow(a, (p + 3) // 8, p)
  329. else:
  330. b = pow(4*a, (p - 5) // 8, p)
  331. x = (2*a*b) % p
  332. if pow(x, 2, p) == a:
  333. res = x
  334. else:
  335. res = _sqrt_mod_tonelli_shanks(a, p)
  336. # ``_sqrt_mod_tonelli_shanks(a, p)`` is not deterministic;
  337. # sort to get always the same result
  338. return sorted([ZZ(res), ZZ(p - res)])
  339. if k > 1:
  340. # see Ref.[2]
  341. if p == 2:
  342. if a % 8 != 1:
  343. return None
  344. if k <= 3:
  345. s = set()
  346. for i in range(0, pk, 4):
  347. s.add(1 + i)
  348. s.add(-1 + i)
  349. return list(s)
  350. # according to Ref.[2] for k > 2 there are two solutions
  351. # (mod 2**k-1), that is four solutions (mod 2**k), which can be
  352. # obtained from the roots of x**2 = 0 (mod 8)
  353. rv = [ZZ(1), ZZ(3), ZZ(5), ZZ(7)]
  354. # hensel lift them to solutions of x**2 = 0 (mod 2**k)
  355. # if r**2 - a = 0 mod 2**nx but not mod 2**(nx+1)
  356. # then r + 2**(nx - 1) is a root mod 2**(nx+1)
  357. n = 3
  358. res = []
  359. for r in rv:
  360. nx = n
  361. while nx < k:
  362. r1 = (r**2 - a) >> nx
  363. if r1 % 2:
  364. r = r + (1 << (nx - 1))
  365. #assert (r**2 - a)% (1 << (nx + 1)) == 0
  366. nx += 1
  367. if r not in res:
  368. res.append(r)
  369. x = r + (1 << (k - 1))
  370. #assert (x**2 - a) % pk == 0
  371. if x < (1 << nx) and x not in res:
  372. if (x**2 - a) % pk == 0:
  373. res.append(x)
  374. return res
  375. rv = _sqrt_mod_prime_power(a, p, 1)
  376. if not rv:
  377. return None
  378. r = rv[0]
  379. fr = r**2 - a
  380. # hensel lifting with Newton iteration, see Ref.[3] chapter 9
  381. # with f(x) = x**2 - a; one has f'(a) != 0 (mod p) for p != 2
  382. n = 1
  383. px = p
  384. while 1:
  385. n1 = n
  386. n1 *= 2
  387. if n1 > k:
  388. break
  389. n = n1
  390. px = px**2
  391. frinv = igcdex(2*r, px)[0]
  392. r = (r - fr*frinv) % px
  393. fr = r**2 - a
  394. if n < k:
  395. px = p**k
  396. frinv = igcdex(2*r, px)[0]
  397. r = (r - fr*frinv) % px
  398. return [r, px - r]
  399. def _sqrt_mod1(a, p, n):
  400. """
  401. Find solution to ``x**2 == a mod p**n`` when ``a % p == 0``
  402. see http://www.numbertheory.org/php/squareroot.html
  403. """
  404. pn = p**n
  405. a = a % pn
  406. if a == 0:
  407. # case gcd(a, p**k) = p**n
  408. m = n // 2
  409. if n % 2 == 1:
  410. pm1 = p**(m + 1)
  411. def _iter0a():
  412. i = 0
  413. while i < pn:
  414. yield i
  415. i += pm1
  416. return _iter0a()
  417. else:
  418. pm = p**m
  419. def _iter0b():
  420. i = 0
  421. while i < pn:
  422. yield i
  423. i += pm
  424. return _iter0b()
  425. # case gcd(a, p**k) = p**r, r < n
  426. f = factorint(a)
  427. r = f[p]
  428. if r % 2 == 1:
  429. return None
  430. m = r // 2
  431. a1 = a >> r
  432. if p == 2:
  433. if n - r == 1:
  434. pnm1 = 1 << (n - m + 1)
  435. pm1 = 1 << (m + 1)
  436. def _iter1():
  437. k = 1 << (m + 2)
  438. i = 1 << m
  439. while i < pnm1:
  440. j = i
  441. while j < pn:
  442. yield j
  443. j += k
  444. i += pm1
  445. return _iter1()
  446. if n - r == 2:
  447. res = _sqrt_mod_prime_power(a1, p, n - r)
  448. if res is None:
  449. return None
  450. pnm = 1 << (n - m)
  451. def _iter2():
  452. s = set()
  453. for r in res:
  454. i = 0
  455. while i < pn:
  456. x = (r << m) + i
  457. if x not in s:
  458. s.add(x)
  459. yield x
  460. i += pnm
  461. return _iter2()
  462. if n - r > 2:
  463. res = _sqrt_mod_prime_power(a1, p, n - r)
  464. if res is None:
  465. return None
  466. pnm1 = 1 << (n - m - 1)
  467. def _iter3():
  468. s = set()
  469. for r in res:
  470. i = 0
  471. while i < pn:
  472. x = ((r << m) + i) % pn
  473. if x not in s:
  474. s.add(x)
  475. yield x
  476. i += pnm1
  477. return _iter3()
  478. else:
  479. m = r // 2
  480. a1 = a // p**r
  481. res1 = _sqrt_mod_prime_power(a1, p, n - r)
  482. if res1 is None:
  483. return None
  484. pm = p**m
  485. pnr = p**(n-r)
  486. pnm = p**(n-m)
  487. def _iter4():
  488. s = set()
  489. pm = p**m
  490. for rx in res1:
  491. i = 0
  492. while i < pnm:
  493. x = ((rx + i) % pn)
  494. if x not in s:
  495. s.add(x)
  496. yield x*pm
  497. i += pnr
  498. return _iter4()
  499. def is_quad_residue(a, p):
  500. """
  501. Returns True if ``a`` (mod ``p``) is in the set of squares mod ``p``,
  502. i.e a % p in set([i**2 % p for i in range(p)]). If ``p`` is an odd
  503. prime, an iterative method is used to make the determination:
  504. >>> from sympy.ntheory import is_quad_residue
  505. >>> sorted(set([i**2 % 7 for i in range(7)]))
  506. [0, 1, 2, 4]
  507. >>> [j for j in range(7) if is_quad_residue(j, 7)]
  508. [0, 1, 2, 4]
  509. See Also
  510. ========
  511. legendre_symbol, jacobi_symbol
  512. """
  513. a, p = as_int(a), as_int(p)
  514. if p < 1:
  515. raise ValueError('p must be > 0')
  516. if a >= p or a < 0:
  517. a = a % p
  518. if a < 2 or p < 3:
  519. return True
  520. if not isprime(p):
  521. if p % 2 and jacobi_symbol(a, p) == -1:
  522. return False
  523. r = sqrt_mod(a, p)
  524. if r is None:
  525. return False
  526. else:
  527. return True
  528. return pow(a, (p - 1) // 2, p) == 1
  529. def is_nthpow_residue(a, n, m):
  530. """
  531. Returns True if ``x**n == a (mod m)`` has solutions.
  532. References
  533. ==========
  534. .. [1] P. Hackman "Elementary Number Theory" (2009), page 76
  535. """
  536. a = a % m
  537. a, n, m = as_int(a), as_int(n), as_int(m)
  538. if m <= 0:
  539. raise ValueError('m must be > 0')
  540. if n < 0:
  541. raise ValueError('n must be >= 0')
  542. if n == 0:
  543. if m == 1:
  544. return False
  545. return a == 1
  546. if a == 0:
  547. return True
  548. if n == 1:
  549. return True
  550. if n == 2:
  551. return is_quad_residue(a, m)
  552. return _is_nthpow_residue_bign(a, n, m)
  553. def _is_nthpow_residue_bign(a, n, m):
  554. """Returns True if ``x**n == a (mod m)`` has solutions for n > 2."""
  555. # assert n > 2
  556. # assert a > 0 and m > 0
  557. if primitive_root(m) is None or igcd(a, m) != 1:
  558. # assert m >= 8
  559. for prime, power in factorint(m).items():
  560. if not _is_nthpow_residue_bign_prime_power(a, n, prime, power):
  561. return False
  562. return True
  563. f = totient(m)
  564. k = f // igcd(f, n)
  565. return pow(a, k, m) == 1
  566. def _is_nthpow_residue_bign_prime_power(a, n, p, k):
  567. """Returns True/False if a solution for ``x**n == a (mod(p**k))``
  568. does/doesn't exist."""
  569. # assert a > 0
  570. # assert n > 2
  571. # assert p is prime
  572. # assert k > 0
  573. if a % p:
  574. if p != 2:
  575. return _is_nthpow_residue_bign(a, n, pow(p, k))
  576. if n & 1:
  577. return True
  578. c = trailing(n)
  579. return a % pow(2, min(c + 2, k)) == 1
  580. else:
  581. a %= pow(p, k)
  582. if not a:
  583. return True
  584. mu = multiplicity(p, a)
  585. if mu % n:
  586. return False
  587. pm = pow(p, mu)
  588. return _is_nthpow_residue_bign_prime_power(a//pm, n, p, k - mu)
  589. def _nthroot_mod2(s, q, p):
  590. f = factorint(q)
  591. v = []
  592. for b, e in f.items():
  593. v.extend([b]*e)
  594. for qx in v:
  595. s = _nthroot_mod1(s, qx, p, False)
  596. return s
  597. def _nthroot_mod1(s, q, p, all_roots):
  598. """
  599. Root of ``x**q = s mod p``, ``p`` prime and ``q`` divides ``p - 1``
  600. References
  601. ==========
  602. .. [1] A. M. Johnston "A Generalized qth Root Algorithm"
  603. """
  604. g = primitive_root(p)
  605. if not isprime(q):
  606. r = _nthroot_mod2(s, q, p)
  607. else:
  608. f = p - 1
  609. assert (p - 1) % q == 0
  610. # determine k
  611. k = 0
  612. while f % q == 0:
  613. k += 1
  614. f = f // q
  615. # find z, x, r1
  616. f1 = igcdex(-f, q)[0] % q
  617. z = f*f1
  618. x = (1 + z) // q
  619. r1 = pow(s, x, p)
  620. s1 = pow(s, f, p)
  621. h = pow(g, f*q, p)
  622. t = discrete_log(p, s1, h)
  623. g2 = pow(g, z*t, p)
  624. g3 = igcdex(g2, p)[0]
  625. r = r1*g3 % p
  626. #assert pow(r, q, p) == s
  627. res = [r]
  628. h = pow(g, (p - 1) // q, p)
  629. #assert pow(h, q, p) == 1
  630. hx = r
  631. for i in range(q - 1):
  632. hx = (hx*h) % p
  633. res.append(hx)
  634. if all_roots:
  635. res.sort()
  636. return res
  637. return min(res)
  638. def _help(m, prime_modulo_method, diff_method, expr_val):
  639. """
  640. Helper function for _nthroot_mod_composite and polynomial_congruence.
  641. Parameters
  642. ==========
  643. m : positive integer
  644. prime_modulo_method : function to calculate the root of the congruence
  645. equation for the prime divisors of m
  646. diff_method : function to calculate derivative of expression at any
  647. given point
  648. expr_val : function to calculate value of the expression at any
  649. given point
  650. """
  651. from sympy.ntheory.modular import crt
  652. f = factorint(m)
  653. dd = {}
  654. for p, e in f.items():
  655. tot_roots = set()
  656. if e == 1:
  657. tot_roots.update(prime_modulo_method(p))
  658. else:
  659. for root in prime_modulo_method(p):
  660. diff = diff_method(root, p)
  661. if diff != 0:
  662. ppow = p
  663. m_inv = mod_inverse(diff, p)
  664. for j in range(1, e):
  665. ppow *= p
  666. root = (root - expr_val(root, ppow) * m_inv) % ppow
  667. tot_roots.add(root)
  668. else:
  669. new_base = p
  670. roots_in_base = {root}
  671. while new_base < pow(p, e):
  672. new_base *= p
  673. new_roots = set()
  674. for k in roots_in_base:
  675. if expr_val(k, new_base)!= 0:
  676. continue
  677. while k not in new_roots:
  678. new_roots.add(k)
  679. k = (k + (new_base // p)) % new_base
  680. roots_in_base = new_roots
  681. tot_roots = tot_roots | roots_in_base
  682. if tot_roots == set():
  683. return []
  684. dd[pow(p, e)] = tot_roots
  685. a = []
  686. m = []
  687. for x, y in dd.items():
  688. m.append(x)
  689. a.append(list(y))
  690. return sorted({crt(m, list(i))[0] for i in product(*a)})
  691. def _nthroot_mod_composite(a, n, m):
  692. """
  693. Find the solutions to ``x**n = a mod m`` when m is not prime.
  694. """
  695. return _help(m,
  696. lambda p: nthroot_mod(a, n, p, True),
  697. lambda root, p: (pow(root, n - 1, p) * (n % p)) % p,
  698. lambda root, p: (pow(root, n, p) - a) % p)
  699. def nthroot_mod(a, n, p, all_roots=False):
  700. """
  701. Find the solutions to ``x**n = a mod p``
  702. Parameters
  703. ==========
  704. a : integer
  705. n : positive integer
  706. p : positive integer
  707. all_roots : if False returns the smallest root, else the list of roots
  708. Examples
  709. ========
  710. >>> from sympy.ntheory.residue_ntheory import nthroot_mod
  711. >>> nthroot_mod(11, 4, 19)
  712. 8
  713. >>> nthroot_mod(11, 4, 19, True)
  714. [8, 11]
  715. >>> nthroot_mod(68, 3, 109)
  716. 23
  717. """
  718. a = a % p
  719. a, n, p = as_int(a), as_int(n), as_int(p)
  720. if n == 2:
  721. return sqrt_mod(a, p, all_roots)
  722. # see Hackman "Elementary Number Theory" (2009), page 76
  723. if not isprime(p):
  724. return _nthroot_mod_composite(a, n, p)
  725. if a % p == 0:
  726. return [0]
  727. if not is_nthpow_residue(a, n, p):
  728. return [] if all_roots else None
  729. if (p - 1) % n == 0:
  730. return _nthroot_mod1(a, n, p, all_roots)
  731. # The roots of ``x**n - a = 0 (mod p)`` are roots of
  732. # ``gcd(x**n - a, x**(p - 1) - 1) = 0 (mod p)``
  733. pa = n
  734. pb = p - 1
  735. b = 1
  736. if pa < pb:
  737. a, pa, b, pb = b, pb, a, pa
  738. while pb:
  739. # x**pa - a = 0; x**pb - b = 0
  740. # x**pa - a = x**(q*pb + r) - a = (x**pb)**q * x**r - a =
  741. # b**q * x**r - a; x**r - c = 0; c = b**-q * a mod p
  742. q, r = divmod(pa, pb)
  743. c = pow(b, q, p)
  744. c = igcdex(c, p)[0]
  745. c = (c * a) % p
  746. pa, pb = pb, r
  747. a, b = b, c
  748. if pa == 1:
  749. if all_roots:
  750. res = [a]
  751. else:
  752. res = a
  753. elif pa == 2:
  754. return sqrt_mod(a, p, all_roots)
  755. else:
  756. res = _nthroot_mod1(a, pa, p, all_roots)
  757. return res
  758. def quadratic_residues(p):
  759. """
  760. Returns the list of quadratic residues.
  761. Examples
  762. ========
  763. >>> from sympy.ntheory.residue_ntheory import quadratic_residues
  764. >>> quadratic_residues(7)
  765. [0, 1, 2, 4]
  766. """
  767. p = as_int(p)
  768. r = set()
  769. for i in range(p // 2 + 1):
  770. r.add(pow(i, 2, p))
  771. return sorted(list(r))
  772. def legendre_symbol(a, p):
  773. r"""
  774. Returns the Legendre symbol `(a / p)`.
  775. For an integer ``a`` and an odd prime ``p``, the Legendre symbol is
  776. defined as
  777. .. math ::
  778. \genfrac(){}{}{a}{p} = \begin{cases}
  779. 0 & \text{if } p \text{ divides } a\\
  780. 1 & \text{if } a \text{ is a quadratic residue modulo } p\\
  781. -1 & \text{if } a \text{ is a quadratic nonresidue modulo } p
  782. \end{cases}
  783. Parameters
  784. ==========
  785. a : integer
  786. p : odd prime
  787. Examples
  788. ========
  789. >>> from sympy.ntheory import legendre_symbol
  790. >>> [legendre_symbol(i, 7) for i in range(7)]
  791. [0, 1, 1, -1, 1, -1, -1]
  792. >>> sorted(set([i**2 % 7 for i in range(7)]))
  793. [0, 1, 2, 4]
  794. See Also
  795. ========
  796. is_quad_residue, jacobi_symbol
  797. """
  798. a, p = as_int(a), as_int(p)
  799. if not isprime(p) or p == 2:
  800. raise ValueError("p should be an odd prime")
  801. a = a % p
  802. if not a:
  803. return 0
  804. if pow(a, (p - 1) // 2, p) == 1:
  805. return 1
  806. return -1
  807. def jacobi_symbol(m, n):
  808. r"""
  809. Returns the Jacobi symbol `(m / n)`.
  810. For any integer ``m`` and any positive odd integer ``n`` the Jacobi symbol
  811. is defined as the product of the Legendre symbols corresponding to the
  812. prime factors of ``n``:
  813. .. math ::
  814. \genfrac(){}{}{m}{n} =
  815. \genfrac(){}{}{m}{p^{1}}^{\alpha_1}
  816. \genfrac(){}{}{m}{p^{2}}^{\alpha_2}
  817. ...
  818. \genfrac(){}{}{m}{p^{k}}^{\alpha_k}
  819. \text{ where } n =
  820. p_1^{\alpha_1}
  821. p_2^{\alpha_2}
  822. ...
  823. p_k^{\alpha_k}
  824. Like the Legendre symbol, if the Jacobi symbol `\genfrac(){}{}{m}{n} = -1`
  825. then ``m`` is a quadratic nonresidue modulo ``n``.
  826. But, unlike the Legendre symbol, if the Jacobi symbol
  827. `\genfrac(){}{}{m}{n} = 1` then ``m`` may or may not be a quadratic residue
  828. modulo ``n``.
  829. Parameters
  830. ==========
  831. m : integer
  832. n : odd positive integer
  833. Examples
  834. ========
  835. >>> from sympy.ntheory import jacobi_symbol, legendre_symbol
  836. >>> from sympy import S
  837. >>> jacobi_symbol(45, 77)
  838. -1
  839. >>> jacobi_symbol(60, 121)
  840. 1
  841. The relationship between the ``jacobi_symbol`` and ``legendre_symbol`` can
  842. be demonstrated as follows:
  843. >>> L = legendre_symbol
  844. >>> S(45).factors()
  845. {3: 2, 5: 1}
  846. >>> jacobi_symbol(7, 45) == L(7, 3)**2 * L(7, 5)**1
  847. True
  848. See Also
  849. ========
  850. is_quad_residue, legendre_symbol
  851. """
  852. m, n = as_int(m), as_int(n)
  853. if n < 0 or not n % 2:
  854. raise ValueError("n should be an odd positive integer")
  855. if m < 0 or m > n:
  856. m %= n
  857. if not m:
  858. return int(n == 1)
  859. if n == 1 or m == 1:
  860. return 1
  861. if igcd(m, n) != 1:
  862. return 0
  863. j = 1
  864. if m < 0:
  865. m = -m
  866. if n % 4 == 3:
  867. j = -j
  868. while m != 0:
  869. while m % 2 == 0 and m > 0:
  870. m >>= 1
  871. if n % 8 in [3, 5]:
  872. j = -j
  873. m, n = n, m
  874. if m % 4 == n % 4 == 3:
  875. j = -j
  876. m %= n
  877. if n != 1:
  878. j = 0
  879. return j
  880. class mobius(Function):
  881. """
  882. Mobius function maps natural number to {-1, 0, 1}
  883. It is defined as follows:
  884. 1) `1` if `n = 1`.
  885. 2) `0` if `n` has a squared prime factor.
  886. 3) `(-1)^k` if `n` is a square-free positive integer with `k`
  887. number of prime factors.
  888. It is an important multiplicative function in number theory
  889. and combinatorics. It has applications in mathematical series,
  890. algebraic number theory and also physics (Fermion operator has very
  891. concrete realization with Mobius Function model).
  892. Parameters
  893. ==========
  894. n : positive integer
  895. Examples
  896. ========
  897. >>> from sympy.ntheory import mobius
  898. >>> mobius(13*7)
  899. 1
  900. >>> mobius(1)
  901. 1
  902. >>> mobius(13*7*5)
  903. -1
  904. >>> mobius(13**2)
  905. 0
  906. References
  907. ==========
  908. .. [1] https://en.wikipedia.org/wiki/M%C3%B6bius_function
  909. .. [2] Thomas Koshy "Elementary Number Theory with Applications"
  910. """
  911. @classmethod
  912. def eval(cls, n):
  913. if n.is_integer:
  914. if n.is_positive is not True:
  915. raise ValueError("n should be a positive integer")
  916. else:
  917. raise TypeError("n should be an integer")
  918. if n.is_prime:
  919. return S.NegativeOne
  920. elif n is S.One:
  921. return S.One
  922. elif n.is_Integer:
  923. a = factorint(n)
  924. if any(i > 1 for i in a.values()):
  925. return S.Zero
  926. return S.NegativeOne**len(a)
  927. def _discrete_log_trial_mul(n, a, b, order=None):
  928. """
  929. Trial multiplication algorithm for computing the discrete logarithm of
  930. ``a`` to the base ``b`` modulo ``n``.
  931. The algorithm finds the discrete logarithm using exhaustive search. This
  932. naive method is used as fallback algorithm of ``discrete_log`` when the
  933. group order is very small.
  934. Examples
  935. ========
  936. >>> from sympy.ntheory.residue_ntheory import _discrete_log_trial_mul
  937. >>> _discrete_log_trial_mul(41, 15, 7)
  938. 3
  939. See Also
  940. ========
  941. discrete_log
  942. References
  943. ==========
  944. .. [1] "Handbook of applied cryptography", Menezes, A. J., Van, O. P. C., &
  945. Vanstone, S. A. (1997).
  946. """
  947. a %= n
  948. b %= n
  949. if order is None:
  950. order = n
  951. x = 1
  952. for i in range(order):
  953. if x == a:
  954. return i
  955. x = x * b % n
  956. raise ValueError("Log does not exist")
  957. def _discrete_log_shanks_steps(n, a, b, order=None):
  958. """
  959. Baby-step giant-step algorithm for computing the discrete logarithm of
  960. ``a`` to the base ``b`` modulo ``n``.
  961. The algorithm is a time-memory trade-off of the method of exhaustive
  962. search. It uses `O(sqrt(m))` memory, where `m` is the group order.
  963. Examples
  964. ========
  965. >>> from sympy.ntheory.residue_ntheory import _discrete_log_shanks_steps
  966. >>> _discrete_log_shanks_steps(41, 15, 7)
  967. 3
  968. See Also
  969. ========
  970. discrete_log
  971. References
  972. ==========
  973. .. [1] "Handbook of applied cryptography", Menezes, A. J., Van, O. P. C., &
  974. Vanstone, S. A. (1997).
  975. """
  976. a %= n
  977. b %= n
  978. if order is None:
  979. order = n_order(b, n)
  980. m = isqrt(order) + 1
  981. T = dict()
  982. x = 1
  983. for i in range(m):
  984. T[x] = i
  985. x = x * b % n
  986. z = mod_inverse(b, n)
  987. z = pow(z, m, n)
  988. x = a
  989. for i in range(m):
  990. if x in T:
  991. return i * m + T[x]
  992. x = x * z % n
  993. raise ValueError("Log does not exist")
  994. def _discrete_log_pollard_rho(n, a, b, order=None, retries=10, rseed=None):
  995. """
  996. Pollard's Rho algorithm for computing the discrete logarithm of ``a`` to
  997. the base ``b`` modulo ``n``.
  998. It is a randomized algorithm with the same expected running time as
  999. ``_discrete_log_shanks_steps``, but requires a negligible amount of memory.
  1000. Examples
  1001. ========
  1002. >>> from sympy.ntheory.residue_ntheory import _discrete_log_pollard_rho
  1003. >>> _discrete_log_pollard_rho(227, 3**7, 3)
  1004. 7
  1005. See Also
  1006. ========
  1007. discrete_log
  1008. References
  1009. ==========
  1010. .. [1] "Handbook of applied cryptography", Menezes, A. J., Van, O. P. C., &
  1011. Vanstone, S. A. (1997).
  1012. """
  1013. a %= n
  1014. b %= n
  1015. if order is None:
  1016. order = n_order(b, n)
  1017. randint = _randint(rseed)
  1018. for i in range(retries):
  1019. aa = randint(1, order - 1)
  1020. ba = randint(1, order - 1)
  1021. xa = pow(b, aa, n) * pow(a, ba, n) % n
  1022. c = xa % 3
  1023. if c == 0:
  1024. xb = a * xa % n
  1025. ab = aa
  1026. bb = (ba + 1) % order
  1027. elif c == 1:
  1028. xb = xa * xa % n
  1029. ab = (aa + aa) % order
  1030. bb = (ba + ba) % order
  1031. else:
  1032. xb = b * xa % n
  1033. ab = (aa + 1) % order
  1034. bb = ba
  1035. for j in range(order):
  1036. c = xa % 3
  1037. if c == 0:
  1038. xa = a * xa % n
  1039. ba = (ba + 1) % order
  1040. elif c == 1:
  1041. xa = xa * xa % n
  1042. aa = (aa + aa) % order
  1043. ba = (ba + ba) % order
  1044. else:
  1045. xa = b * xa % n
  1046. aa = (aa + 1) % order
  1047. c = xb % 3
  1048. if c == 0:
  1049. xb = a * xb % n
  1050. bb = (bb + 1) % order
  1051. elif c == 1:
  1052. xb = xb * xb % n
  1053. ab = (ab + ab) % order
  1054. bb = (bb + bb) % order
  1055. else:
  1056. xb = b * xb % n
  1057. ab = (ab + 1) % order
  1058. c = xb % 3
  1059. if c == 0:
  1060. xb = a * xb % n
  1061. bb = (bb + 1) % order
  1062. elif c == 1:
  1063. xb = xb * xb % n
  1064. ab = (ab + ab) % order
  1065. bb = (bb + bb) % order
  1066. else:
  1067. xb = b * xb % n
  1068. ab = (ab + 1) % order
  1069. if xa == xb:
  1070. r = (ba - bb) % order
  1071. try:
  1072. e = mod_inverse(r, order) * (ab - aa) % order
  1073. if (pow(b, e, n) - a) % n == 0:
  1074. return e
  1075. except ValueError:
  1076. pass
  1077. break
  1078. raise ValueError("Pollard's Rho failed to find logarithm")
  1079. def _discrete_log_pohlig_hellman(n, a, b, order=None):
  1080. """
  1081. Pohlig-Hellman algorithm for computing the discrete logarithm of ``a`` to
  1082. the base ``b`` modulo ``n``.
  1083. In order to compute the discrete logarithm, the algorithm takes advantage
  1084. of the factorization of the group order. It is more efficient when the
  1085. group order factors into many small primes.
  1086. Examples
  1087. ========
  1088. >>> from sympy.ntheory.residue_ntheory import _discrete_log_pohlig_hellman
  1089. >>> _discrete_log_pohlig_hellman(251, 210, 71)
  1090. 197
  1091. See Also
  1092. ========
  1093. discrete_log
  1094. References
  1095. ==========
  1096. .. [1] "Handbook of applied cryptography", Menezes, A. J., Van, O. P. C., &
  1097. Vanstone, S. A. (1997).
  1098. """
  1099. from .modular import crt
  1100. a %= n
  1101. b %= n
  1102. if order is None:
  1103. order = n_order(b, n)
  1104. f = factorint(order)
  1105. l = [0] * len(f)
  1106. for i, (pi, ri) in enumerate(f.items()):
  1107. for j in range(ri):
  1108. gj = pow(b, l[i], n)
  1109. aj = pow(a * mod_inverse(gj, n), order // pi**(j + 1), n)
  1110. bj = pow(b, order // pi, n)
  1111. cj = discrete_log(n, aj, bj, pi, True)
  1112. l[i] += cj * pi**j
  1113. d, _ = crt([pi**ri for pi, ri in f.items()], l)
  1114. return d
  1115. def discrete_log(n, a, b, order=None, prime_order=None):
  1116. """
  1117. Compute the discrete logarithm of ``a`` to the base ``b`` modulo ``n``.
  1118. This is a recursive function to reduce the discrete logarithm problem in
  1119. cyclic groups of composite order to the problem in cyclic groups of prime
  1120. order.
  1121. It employs different algorithms depending on the problem (subgroup order
  1122. size, prime order or not):
  1123. * Trial multiplication
  1124. * Baby-step giant-step
  1125. * Pollard's Rho
  1126. * Pohlig-Hellman
  1127. Examples
  1128. ========
  1129. >>> from sympy.ntheory import discrete_log
  1130. >>> discrete_log(41, 15, 7)
  1131. 3
  1132. References
  1133. ==========
  1134. .. [1] http://mathworld.wolfram.com/DiscreteLogarithm.html
  1135. .. [2] "Handbook of applied cryptography", Menezes, A. J., Van, O. P. C., &
  1136. Vanstone, S. A. (1997).
  1137. """
  1138. n, a, b = as_int(n), as_int(a), as_int(b)
  1139. if order is None:
  1140. order = n_order(b, n)
  1141. if prime_order is None:
  1142. prime_order = isprime(order)
  1143. if order < 1000:
  1144. return _discrete_log_trial_mul(n, a, b, order)
  1145. elif prime_order:
  1146. if order < 1000000000000:
  1147. return _discrete_log_shanks_steps(n, a, b, order)
  1148. return _discrete_log_pollard_rho(n, a, b, order)
  1149. return _discrete_log_pohlig_hellman(n, a, b, order)
  1150. def quadratic_congruence(a, b, c, p):
  1151. """
  1152. Find the solutions to ``a x**2 + b x + c = 0 mod p
  1153. a : integer
  1154. b : integer
  1155. c : integer
  1156. p : positive integer
  1157. """
  1158. from sympy.polys.galoistools import linear_congruence
  1159. a = as_int(a)
  1160. b = as_int(b)
  1161. c = as_int(c)
  1162. p = as_int(p)
  1163. a = a % p
  1164. b = b % p
  1165. c = c % p
  1166. if a == 0:
  1167. return linear_congruence(b, -c, p)
  1168. if p == 2:
  1169. roots = []
  1170. if c % 2 == 0:
  1171. roots.append(0)
  1172. if (a + b + c) % 2 == 0:
  1173. roots.append(1)
  1174. return roots
  1175. if isprime(p):
  1176. inv_a = mod_inverse(a, p)
  1177. b *= inv_a
  1178. c *= inv_a
  1179. if b % 2 == 1:
  1180. b = b + p
  1181. d = ((b * b) // 4 - c) % p
  1182. y = sqrt_mod(d, p, all_roots=True)
  1183. res = set()
  1184. for i in y:
  1185. res.add((i - b // 2) % p)
  1186. return sorted(res)
  1187. y = sqrt_mod(b * b - 4 * a * c, 4 * a * p, all_roots=True)
  1188. res = set()
  1189. for i in y:
  1190. root = linear_congruence(2 * a, i - b, 4 * a * p)
  1191. for j in root:
  1192. res.add(j % p)
  1193. return sorted(res)
  1194. def _polynomial_congruence_prime(coefficients, p):
  1195. """A helper function used by polynomial_congruence.
  1196. It returns the root of a polynomial modulo prime number
  1197. by naive search from [0, p).
  1198. Parameters
  1199. ==========
  1200. coefficients : list of integers
  1201. p : prime number
  1202. """
  1203. roots = []
  1204. rank = len(coefficients)
  1205. for i in range(0, p):
  1206. f_val = 0
  1207. for coeff in range(0,rank - 1):
  1208. f_val = (f_val + pow(i, int(rank - coeff - 1), p) * coefficients[coeff]) % p
  1209. f_val = f_val + coefficients[-1]
  1210. if f_val % p == 0:
  1211. roots.append(i)
  1212. return roots
  1213. def _diff_poly(root, coefficients, p):
  1214. """A helper function used by polynomial_congruence.
  1215. It returns the derivative of the polynomial evaluated at the
  1216. root (mod p).
  1217. Parameters
  1218. ==========
  1219. coefficients : list of integers
  1220. p : prime number
  1221. root : integer
  1222. """
  1223. diff = 0
  1224. rank = len(coefficients)
  1225. for coeff in range(0, rank - 1):
  1226. if not coefficients[coeff]:
  1227. continue
  1228. diff = (diff + pow(root, rank - coeff - 2, p)*(rank - coeff - 1)*
  1229. coefficients[coeff]) % p
  1230. return diff % p
  1231. def _val_poly(root, coefficients, p):
  1232. """A helper function used by polynomial_congruence.
  1233. It returns value of the polynomial at root (mod p).
  1234. Parameters
  1235. ==========
  1236. coefficients : list of integers
  1237. p : prime number
  1238. root : integer
  1239. """
  1240. rank = len(coefficients)
  1241. f_val = 0
  1242. for coeff in range(0, rank - 1):
  1243. f_val = (f_val + pow(root, rank - coeff - 1, p)*
  1244. coefficients[coeff]) % p
  1245. f_val = f_val + coefficients[-1]
  1246. return f_val % p
  1247. def _valid_expr(expr):
  1248. """
  1249. return coefficients of expr if it is a univariate polynomial
  1250. with integer coefficients else raise a ValueError.
  1251. """
  1252. if not expr.is_polynomial():
  1253. raise ValueError("The expression should be a polynomial")
  1254. from sympy.polys import Poly
  1255. polynomial = Poly(expr)
  1256. if not polynomial.is_univariate:
  1257. raise ValueError("The expression should be univariate")
  1258. if not polynomial.domain == ZZ:
  1259. raise ValueError("The expression should should have integer coefficients")
  1260. return polynomial.all_coeffs()
  1261. def polynomial_congruence(expr, m):
  1262. """
  1263. Find the solutions to a polynomial congruence equation modulo m.
  1264. Parameters
  1265. ==========
  1266. coefficients : Coefficients of the Polynomial
  1267. m : positive integer
  1268. Examples
  1269. ========
  1270. >>> from sympy.ntheory import polynomial_congruence
  1271. >>> from sympy.abc import x
  1272. >>> expr = x**6 - 2*x**5 -35
  1273. >>> polynomial_congruence(expr, 6125)
  1274. [3257]
  1275. """
  1276. coefficients = _valid_expr(expr)
  1277. coefficients = [num % m for num in coefficients]
  1278. rank = len(coefficients)
  1279. if rank == 3:
  1280. return quadratic_congruence(*coefficients, m)
  1281. if rank == 2:
  1282. return quadratic_congruence(0, *coefficients, m)
  1283. if coefficients[0] == 1 and 1 + coefficients[-1] == sum(coefficients):
  1284. return nthroot_mod(-coefficients[-1], rank - 1, m, True)
  1285. if isprime(m):
  1286. return _polynomial_congruence_prime(coefficients, m)
  1287. return _help(m,
  1288. lambda p: _polynomial_congruence_prime(coefficients, p),
  1289. lambda root, p: _diff_poly(root, coefficients, p),
  1290. lambda root, p: _val_poly(root, coefficients, p))