densetools.py 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438
  1. """Advanced tools for dense recursive polynomials in ``K[x]`` or ``K[X]``. """
  2. from sympy.polys.densearith import (
  3. dup_add_term, dmp_add_term,
  4. dup_lshift,
  5. dup_add, dmp_add,
  6. dup_sub, dmp_sub,
  7. dup_mul, dmp_mul,
  8. dup_sqr,
  9. dup_div,
  10. dup_rem, dmp_rem,
  11. dup_mul_ground, dmp_mul_ground,
  12. dup_quo_ground, dmp_quo_ground,
  13. dup_exquo_ground, dmp_exquo_ground,
  14. )
  15. from sympy.polys.densebasic import (
  16. dup_strip, dmp_strip,
  17. dup_convert, dmp_convert,
  18. dup_degree, dmp_degree,
  19. dmp_to_dict,
  20. dmp_from_dict,
  21. dup_LC, dmp_LC, dmp_ground_LC,
  22. dup_TC, dmp_TC,
  23. dmp_zero, dmp_ground,
  24. dmp_zero_p,
  25. dup_to_raw_dict, dup_from_raw_dict,
  26. dmp_zeros,
  27. dmp_include,
  28. )
  29. from sympy.polys.polyerrors import (
  30. MultivariatePolynomialError,
  31. DomainError
  32. )
  33. from math import ceil as _ceil, log2 as _log2
  34. def dup_integrate(f, m, K):
  35. """
  36. Computes the indefinite integral of ``f`` in ``K[x]``.
  37. Examples
  38. ========
  39. >>> from sympy.polys import ring, QQ
  40. >>> R, x = ring("x", QQ)
  41. >>> R.dup_integrate(x**2 + 2*x, 1)
  42. 1/3*x**3 + x**2
  43. >>> R.dup_integrate(x**2 + 2*x, 2)
  44. 1/12*x**4 + 1/3*x**3
  45. """
  46. if m <= 0 or not f:
  47. return f
  48. g = [K.zero]*m
  49. for i, c in enumerate(reversed(f)):
  50. n = i + 1
  51. for j in range(1, m):
  52. n *= i + j + 1
  53. g.insert(0, K.exquo(c, K(n)))
  54. return g
  55. def dmp_integrate(f, m, u, K):
  56. """
  57. Computes the indefinite integral of ``f`` in ``x_0`` in ``K[X]``.
  58. Examples
  59. ========
  60. >>> from sympy.polys import ring, QQ
  61. >>> R, x,y = ring("x,y", QQ)
  62. >>> R.dmp_integrate(x + 2*y, 1)
  63. 1/2*x**2 + 2*x*y
  64. >>> R.dmp_integrate(x + 2*y, 2)
  65. 1/6*x**3 + x**2*y
  66. """
  67. if not u:
  68. return dup_integrate(f, m, K)
  69. if m <= 0 or dmp_zero_p(f, u):
  70. return f
  71. g, v = dmp_zeros(m, u - 1, K), u - 1
  72. for i, c in enumerate(reversed(f)):
  73. n = i + 1
  74. for j in range(1, m):
  75. n *= i + j + 1
  76. g.insert(0, dmp_quo_ground(c, K(n), v, K))
  77. return g
  78. def _rec_integrate_in(g, m, v, i, j, K):
  79. """Recursive helper for :func:`dmp_integrate_in`."""
  80. if i == j:
  81. return dmp_integrate(g, m, v, K)
  82. w, i = v - 1, i + 1
  83. return dmp_strip([ _rec_integrate_in(c, m, w, i, j, K) for c in g ], v)
  84. def dmp_integrate_in(f, m, j, u, K):
  85. """
  86. Computes the indefinite integral of ``f`` in ``x_j`` in ``K[X]``.
  87. Examples
  88. ========
  89. >>> from sympy.polys import ring, QQ
  90. >>> R, x,y = ring("x,y", QQ)
  91. >>> R.dmp_integrate_in(x + 2*y, 1, 0)
  92. 1/2*x**2 + 2*x*y
  93. >>> R.dmp_integrate_in(x + 2*y, 1, 1)
  94. x*y + y**2
  95. """
  96. if j < 0 or j > u:
  97. raise IndexError("0 <= j <= u expected, got u = %d, j = %d" % (u, j))
  98. return _rec_integrate_in(f, m, u, 0, j, K)
  99. def dup_diff(f, m, K):
  100. """
  101. ``m``-th order derivative of a polynomial in ``K[x]``.
  102. Examples
  103. ========
  104. >>> from sympy.polys import ring, ZZ
  105. >>> R, x = ring("x", ZZ)
  106. >>> R.dup_diff(x**3 + 2*x**2 + 3*x + 4, 1)
  107. 3*x**2 + 4*x + 3
  108. >>> R.dup_diff(x**3 + 2*x**2 + 3*x + 4, 2)
  109. 6*x + 4
  110. """
  111. if m <= 0:
  112. return f
  113. n = dup_degree(f)
  114. if n < m:
  115. return []
  116. deriv = []
  117. if m == 1:
  118. for coeff in f[:-m]:
  119. deriv.append(K(n)*coeff)
  120. n -= 1
  121. else:
  122. for coeff in f[:-m]:
  123. k = n
  124. for i in range(n - 1, n - m, -1):
  125. k *= i
  126. deriv.append(K(k)*coeff)
  127. n -= 1
  128. return dup_strip(deriv)
  129. def dmp_diff(f, m, u, K):
  130. """
  131. ``m``-th order derivative in ``x_0`` of a polynomial in ``K[X]``.
  132. Examples
  133. ========
  134. >>> from sympy.polys import ring, ZZ
  135. >>> R, x,y = ring("x,y", ZZ)
  136. >>> f = x*y**2 + 2*x*y + 3*x + 2*y**2 + 3*y + 1
  137. >>> R.dmp_diff(f, 1)
  138. y**2 + 2*y + 3
  139. >>> R.dmp_diff(f, 2)
  140. 0
  141. """
  142. if not u:
  143. return dup_diff(f, m, K)
  144. if m <= 0:
  145. return f
  146. n = dmp_degree(f, u)
  147. if n < m:
  148. return dmp_zero(u)
  149. deriv, v = [], u - 1
  150. if m == 1:
  151. for coeff in f[:-m]:
  152. deriv.append(dmp_mul_ground(coeff, K(n), v, K))
  153. n -= 1
  154. else:
  155. for coeff in f[:-m]:
  156. k = n
  157. for i in range(n - 1, n - m, -1):
  158. k *= i
  159. deriv.append(dmp_mul_ground(coeff, K(k), v, K))
  160. n -= 1
  161. return dmp_strip(deriv, u)
  162. def _rec_diff_in(g, m, v, i, j, K):
  163. """Recursive helper for :func:`dmp_diff_in`."""
  164. if i == j:
  165. return dmp_diff(g, m, v, K)
  166. w, i = v - 1, i + 1
  167. return dmp_strip([ _rec_diff_in(c, m, w, i, j, K) for c in g ], v)
  168. def dmp_diff_in(f, m, j, u, K):
  169. """
  170. ``m``-th order derivative in ``x_j`` of a polynomial in ``K[X]``.
  171. Examples
  172. ========
  173. >>> from sympy.polys import ring, ZZ
  174. >>> R, x,y = ring("x,y", ZZ)
  175. >>> f = x*y**2 + 2*x*y + 3*x + 2*y**2 + 3*y + 1
  176. >>> R.dmp_diff_in(f, 1, 0)
  177. y**2 + 2*y + 3
  178. >>> R.dmp_diff_in(f, 1, 1)
  179. 2*x*y + 2*x + 4*y + 3
  180. """
  181. if j < 0 or j > u:
  182. raise IndexError("0 <= j <= %s expected, got %s" % (u, j))
  183. return _rec_diff_in(f, m, u, 0, j, K)
  184. def dup_eval(f, a, K):
  185. """
  186. Evaluate a polynomial at ``x = a`` in ``K[x]`` using Horner scheme.
  187. Examples
  188. ========
  189. >>> from sympy.polys import ring, ZZ
  190. >>> R, x = ring("x", ZZ)
  191. >>> R.dup_eval(x**2 + 2*x + 3, 2)
  192. 11
  193. """
  194. if not a:
  195. return K.convert(dup_TC(f, K))
  196. result = K.zero
  197. for c in f:
  198. result *= a
  199. result += c
  200. return result
  201. def dmp_eval(f, a, u, K):
  202. """
  203. Evaluate a polynomial at ``x_0 = a`` in ``K[X]`` using the Horner scheme.
  204. Examples
  205. ========
  206. >>> from sympy.polys import ring, ZZ
  207. >>> R, x,y = ring("x,y", ZZ)
  208. >>> R.dmp_eval(2*x*y + 3*x + y + 2, 2)
  209. 5*y + 8
  210. """
  211. if not u:
  212. return dup_eval(f, a, K)
  213. if not a:
  214. return dmp_TC(f, K)
  215. result, v = dmp_LC(f, K), u - 1
  216. for coeff in f[1:]:
  217. result = dmp_mul_ground(result, a, v, K)
  218. result = dmp_add(result, coeff, v, K)
  219. return result
  220. def _rec_eval_in(g, a, v, i, j, K):
  221. """Recursive helper for :func:`dmp_eval_in`."""
  222. if i == j:
  223. return dmp_eval(g, a, v, K)
  224. v, i = v - 1, i + 1
  225. return dmp_strip([ _rec_eval_in(c, a, v, i, j, K) for c in g ], v)
  226. def dmp_eval_in(f, a, j, u, K):
  227. """
  228. Evaluate a polynomial at ``x_j = a`` in ``K[X]`` using the Horner scheme.
  229. Examples
  230. ========
  231. >>> from sympy.polys import ring, ZZ
  232. >>> R, x,y = ring("x,y", ZZ)
  233. >>> f = 2*x*y + 3*x + y + 2
  234. >>> R.dmp_eval_in(f, 2, 0)
  235. 5*y + 8
  236. >>> R.dmp_eval_in(f, 2, 1)
  237. 7*x + 4
  238. """
  239. if j < 0 or j > u:
  240. raise IndexError("0 <= j <= %s expected, got %s" % (u, j))
  241. return _rec_eval_in(f, a, u, 0, j, K)
  242. def _rec_eval_tail(g, i, A, u, K):
  243. """Recursive helper for :func:`dmp_eval_tail`."""
  244. if i == u:
  245. return dup_eval(g, A[-1], K)
  246. else:
  247. h = [ _rec_eval_tail(c, i + 1, A, u, K) for c in g ]
  248. if i < u - len(A) + 1:
  249. return h
  250. else:
  251. return dup_eval(h, A[-u + i - 1], K)
  252. def dmp_eval_tail(f, A, u, K):
  253. """
  254. Evaluate a polynomial at ``x_j = a_j, ...`` in ``K[X]``.
  255. Examples
  256. ========
  257. >>> from sympy.polys import ring, ZZ
  258. >>> R, x,y = ring("x,y", ZZ)
  259. >>> f = 2*x*y + 3*x + y + 2
  260. >>> R.dmp_eval_tail(f, [2])
  261. 7*x + 4
  262. >>> R.dmp_eval_tail(f, [2, 2])
  263. 18
  264. """
  265. if not A:
  266. return f
  267. if dmp_zero_p(f, u):
  268. return dmp_zero(u - len(A))
  269. e = _rec_eval_tail(f, 0, A, u, K)
  270. if u == len(A) - 1:
  271. return e
  272. else:
  273. return dmp_strip(e, u - len(A))
  274. def _rec_diff_eval(g, m, a, v, i, j, K):
  275. """Recursive helper for :func:`dmp_diff_eval`."""
  276. if i == j:
  277. return dmp_eval(dmp_diff(g, m, v, K), a, v, K)
  278. v, i = v - 1, i + 1
  279. return dmp_strip([ _rec_diff_eval(c, m, a, v, i, j, K) for c in g ], v)
  280. def dmp_diff_eval_in(f, m, a, j, u, K):
  281. """
  282. Differentiate and evaluate a polynomial in ``x_j`` at ``a`` in ``K[X]``.
  283. Examples
  284. ========
  285. >>> from sympy.polys import ring, ZZ
  286. >>> R, x,y = ring("x,y", ZZ)
  287. >>> f = x*y**2 + 2*x*y + 3*x + 2*y**2 + 3*y + 1
  288. >>> R.dmp_diff_eval_in(f, 1, 2, 0)
  289. y**2 + 2*y + 3
  290. >>> R.dmp_diff_eval_in(f, 1, 2, 1)
  291. 6*x + 11
  292. """
  293. if j > u:
  294. raise IndexError("-%s <= j < %s expected, got %s" % (u, u, j))
  295. if not j:
  296. return dmp_eval(dmp_diff(f, m, u, K), a, u, K)
  297. return _rec_diff_eval(f, m, a, u, 0, j, K)
  298. def dup_trunc(f, p, K):
  299. """
  300. Reduce a ``K[x]`` polynomial modulo a constant ``p`` in ``K``.
  301. Examples
  302. ========
  303. >>> from sympy.polys import ring, ZZ
  304. >>> R, x = ring("x", ZZ)
  305. >>> R.dup_trunc(2*x**3 + 3*x**2 + 5*x + 7, ZZ(3))
  306. -x**3 - x + 1
  307. """
  308. if K.is_ZZ:
  309. g = []
  310. for c in f:
  311. c = c % p
  312. if c > p // 2:
  313. g.append(c - p)
  314. else:
  315. g.append(c)
  316. elif K.is_FiniteField:
  317. # XXX: python-flint's nmod does not support %
  318. pi = int(p)
  319. g = [ K(int(c) % pi) for c in f ]
  320. else:
  321. g = [ c % p for c in f ]
  322. return dup_strip(g)
  323. def dmp_trunc(f, p, u, K):
  324. """
  325. Reduce a ``K[X]`` polynomial modulo a polynomial ``p`` in ``K[Y]``.
  326. Examples
  327. ========
  328. >>> from sympy.polys import ring, ZZ
  329. >>> R, x,y = ring("x,y", ZZ)
  330. >>> f = 3*x**2*y + 8*x**2 + 5*x*y + 6*x + 2*y + 3
  331. >>> g = (y - 1).drop(x)
  332. >>> R.dmp_trunc(f, g)
  333. 11*x**2 + 11*x + 5
  334. """
  335. return dmp_strip([ dmp_rem(c, p, u - 1, K) for c in f ], u)
  336. def dmp_ground_trunc(f, p, u, K):
  337. """
  338. Reduce a ``K[X]`` polynomial modulo a constant ``p`` in ``K``.
  339. Examples
  340. ========
  341. >>> from sympy.polys import ring, ZZ
  342. >>> R, x,y = ring("x,y", ZZ)
  343. >>> f = 3*x**2*y + 8*x**2 + 5*x*y + 6*x + 2*y + 3
  344. >>> R.dmp_ground_trunc(f, ZZ(3))
  345. -x**2 - x*y - y
  346. """
  347. if not u:
  348. return dup_trunc(f, p, K)
  349. v = u - 1
  350. return dmp_strip([ dmp_ground_trunc(c, p, v, K) for c in f ], u)
  351. def dup_monic(f, K):
  352. """
  353. Divide all coefficients by ``LC(f)`` in ``K[x]``.
  354. Examples
  355. ========
  356. >>> from sympy.polys import ring, ZZ, QQ
  357. >>> R, x = ring("x", ZZ)
  358. >>> R.dup_monic(3*x**2 + 6*x + 9)
  359. x**2 + 2*x + 3
  360. >>> R, x = ring("x", QQ)
  361. >>> R.dup_monic(3*x**2 + 4*x + 2)
  362. x**2 + 4/3*x + 2/3
  363. """
  364. if not f:
  365. return f
  366. lc = dup_LC(f, K)
  367. if K.is_one(lc):
  368. return f
  369. else:
  370. return dup_exquo_ground(f, lc, K)
  371. def dmp_ground_monic(f, u, K):
  372. """
  373. Divide all coefficients by ``LC(f)`` in ``K[X]``.
  374. Examples
  375. ========
  376. >>> from sympy.polys import ring, ZZ, QQ
  377. >>> R, x,y = ring("x,y", ZZ)
  378. >>> f = 3*x**2*y + 6*x**2 + 3*x*y + 9*y + 3
  379. >>> R.dmp_ground_monic(f)
  380. x**2*y + 2*x**2 + x*y + 3*y + 1
  381. >>> R, x,y = ring("x,y", QQ)
  382. >>> f = 3*x**2*y + 8*x**2 + 5*x*y + 6*x + 2*y + 3
  383. >>> R.dmp_ground_monic(f)
  384. x**2*y + 8/3*x**2 + 5/3*x*y + 2*x + 2/3*y + 1
  385. """
  386. if not u:
  387. return dup_monic(f, K)
  388. if dmp_zero_p(f, u):
  389. return f
  390. lc = dmp_ground_LC(f, u, K)
  391. if K.is_one(lc):
  392. return f
  393. else:
  394. return dmp_exquo_ground(f, lc, u, K)
  395. def dup_content(f, K):
  396. """
  397. Compute the GCD of coefficients of ``f`` in ``K[x]``.
  398. Examples
  399. ========
  400. >>> from sympy.polys import ring, ZZ, QQ
  401. >>> R, x = ring("x", ZZ)
  402. >>> f = 6*x**2 + 8*x + 12
  403. >>> R.dup_content(f)
  404. 2
  405. >>> R, x = ring("x", QQ)
  406. >>> f = 6*x**2 + 8*x + 12
  407. >>> R.dup_content(f)
  408. 2
  409. """
  410. from sympy.polys.domains import QQ
  411. if not f:
  412. return K.zero
  413. cont = K.zero
  414. if K == QQ:
  415. for c in f:
  416. cont = K.gcd(cont, c)
  417. else:
  418. for c in f:
  419. cont = K.gcd(cont, c)
  420. if K.is_one(cont):
  421. break
  422. return cont
  423. def dmp_ground_content(f, u, K):
  424. """
  425. Compute the GCD of coefficients of ``f`` in ``K[X]``.
  426. Examples
  427. ========
  428. >>> from sympy.polys import ring, ZZ, QQ
  429. >>> R, x,y = ring("x,y", ZZ)
  430. >>> f = 2*x*y + 6*x + 4*y + 12
  431. >>> R.dmp_ground_content(f)
  432. 2
  433. >>> R, x,y = ring("x,y", QQ)
  434. >>> f = 2*x*y + 6*x + 4*y + 12
  435. >>> R.dmp_ground_content(f)
  436. 2
  437. """
  438. from sympy.polys.domains import QQ
  439. if not u:
  440. return dup_content(f, K)
  441. if dmp_zero_p(f, u):
  442. return K.zero
  443. cont, v = K.zero, u - 1
  444. if K == QQ:
  445. for c in f:
  446. cont = K.gcd(cont, dmp_ground_content(c, v, K))
  447. else:
  448. for c in f:
  449. cont = K.gcd(cont, dmp_ground_content(c, v, K))
  450. if K.is_one(cont):
  451. break
  452. return cont
  453. def dup_primitive(f, K):
  454. """
  455. Compute content and the primitive form of ``f`` in ``K[x]``.
  456. Examples
  457. ========
  458. >>> from sympy.polys import ring, ZZ, QQ
  459. >>> R, x = ring("x", ZZ)
  460. >>> f = 6*x**2 + 8*x + 12
  461. >>> R.dup_primitive(f)
  462. (2, 3*x**2 + 4*x + 6)
  463. >>> R, x = ring("x", QQ)
  464. >>> f = 6*x**2 + 8*x + 12
  465. >>> R.dup_primitive(f)
  466. (2, 3*x**2 + 4*x + 6)
  467. """
  468. if not f:
  469. return K.zero, f
  470. cont = dup_content(f, K)
  471. if K.is_one(cont):
  472. return cont, f
  473. else:
  474. return cont, dup_quo_ground(f, cont, K)
  475. def dmp_ground_primitive(f, u, K):
  476. """
  477. Compute content and the primitive form of ``f`` in ``K[X]``.
  478. Examples
  479. ========
  480. >>> from sympy.polys import ring, ZZ, QQ
  481. >>> R, x,y = ring("x,y", ZZ)
  482. >>> f = 2*x*y + 6*x + 4*y + 12
  483. >>> R.dmp_ground_primitive(f)
  484. (2, x*y + 3*x + 2*y + 6)
  485. >>> R, x,y = ring("x,y", QQ)
  486. >>> f = 2*x*y + 6*x + 4*y + 12
  487. >>> R.dmp_ground_primitive(f)
  488. (2, x*y + 3*x + 2*y + 6)
  489. """
  490. if not u:
  491. return dup_primitive(f, K)
  492. if dmp_zero_p(f, u):
  493. return K.zero, f
  494. cont = dmp_ground_content(f, u, K)
  495. if K.is_one(cont):
  496. return cont, f
  497. else:
  498. return cont, dmp_quo_ground(f, cont, u, K)
  499. def dup_extract(f, g, K):
  500. """
  501. Extract common content from a pair of polynomials in ``K[x]``.
  502. Examples
  503. ========
  504. >>> from sympy.polys import ring, ZZ
  505. >>> R, x = ring("x", ZZ)
  506. >>> R.dup_extract(6*x**2 + 12*x + 18, 4*x**2 + 8*x + 12)
  507. (2, 3*x**2 + 6*x + 9, 2*x**2 + 4*x + 6)
  508. """
  509. fc = dup_content(f, K)
  510. gc = dup_content(g, K)
  511. gcd = K.gcd(fc, gc)
  512. if not K.is_one(gcd):
  513. f = dup_quo_ground(f, gcd, K)
  514. g = dup_quo_ground(g, gcd, K)
  515. return gcd, f, g
  516. def dmp_ground_extract(f, g, u, K):
  517. """
  518. Extract common content from a pair of polynomials in ``K[X]``.
  519. Examples
  520. ========
  521. >>> from sympy.polys import ring, ZZ
  522. >>> R, x,y = ring("x,y", ZZ)
  523. >>> R.dmp_ground_extract(6*x*y + 12*x + 18, 4*x*y + 8*x + 12)
  524. (2, 3*x*y + 6*x + 9, 2*x*y + 4*x + 6)
  525. """
  526. fc = dmp_ground_content(f, u, K)
  527. gc = dmp_ground_content(g, u, K)
  528. gcd = K.gcd(fc, gc)
  529. if not K.is_one(gcd):
  530. f = dmp_quo_ground(f, gcd, u, K)
  531. g = dmp_quo_ground(g, gcd, u, K)
  532. return gcd, f, g
  533. def dup_real_imag(f, K):
  534. """
  535. Find ``f1`` and ``f2``, such that ``f(x+I*y) = f1(x,y) + f2(x,y)*I``.
  536. Examples
  537. ========
  538. >>> from sympy.polys import ring, ZZ
  539. >>> R, x,y = ring("x,y", ZZ)
  540. >>> R.dup_real_imag(x**3 + x**2 + x + 1)
  541. (x**3 + x**2 - 3*x*y**2 + x - y**2 + 1, 3*x**2*y + 2*x*y - y**3 + y)
  542. >>> from sympy.abc import x, y, z
  543. >>> from sympy import I
  544. >>> (z**3 + z**2 + z + 1).subs(z, x+I*y).expand().collect(I)
  545. x**3 + x**2 - 3*x*y**2 + x - y**2 + I*(3*x**2*y + 2*x*y - y**3 + y) + 1
  546. """
  547. if not K.is_ZZ and not K.is_QQ:
  548. raise DomainError("computing real and imaginary parts is not supported over %s" % K)
  549. f1 = dmp_zero(1)
  550. f2 = dmp_zero(1)
  551. if not f:
  552. return f1, f2
  553. g = [[[K.one, K.zero]], [[K.one], []]]
  554. h = dmp_ground(f[0], 2)
  555. for c in f[1:]:
  556. h = dmp_mul(h, g, 2, K)
  557. h = dmp_add_term(h, dmp_ground(c, 1), 0, 2, K)
  558. H = dup_to_raw_dict(h)
  559. for k, h in H.items():
  560. m = k % 4
  561. if not m:
  562. f1 = dmp_add(f1, h, 1, K)
  563. elif m == 1:
  564. f2 = dmp_add(f2, h, 1, K)
  565. elif m == 2:
  566. f1 = dmp_sub(f1, h, 1, K)
  567. else:
  568. f2 = dmp_sub(f2, h, 1, K)
  569. return f1, f2
  570. def dup_mirror(f, K):
  571. """
  572. Evaluate efficiently the composition ``f(-x)`` in ``K[x]``.
  573. Examples
  574. ========
  575. >>> from sympy.polys import ring, ZZ
  576. >>> R, x = ring("x", ZZ)
  577. >>> R.dup_mirror(x**3 + 2*x**2 - 4*x + 2)
  578. -x**3 + 2*x**2 + 4*x + 2
  579. """
  580. f = list(f)
  581. for i in range(len(f) - 2, -1, -2):
  582. f[i] = -f[i]
  583. return f
  584. def dup_scale(f, a, K):
  585. """
  586. Evaluate efficiently composition ``f(a*x)`` in ``K[x]``.
  587. Examples
  588. ========
  589. >>> from sympy.polys import ring, ZZ
  590. >>> R, x = ring("x", ZZ)
  591. >>> R.dup_scale(x**2 - 2*x + 1, ZZ(2))
  592. 4*x**2 - 4*x + 1
  593. """
  594. f, n, b = list(f), len(f) - 1, a
  595. for i in range(n - 1, -1, -1):
  596. f[i], b = b*f[i], b*a
  597. return f
  598. def dup_shift(f, a, K):
  599. """
  600. Evaluate efficiently Taylor shift ``f(x + a)`` in ``K[x]``.
  601. Examples
  602. ========
  603. >>> from sympy.polys import ring, ZZ
  604. >>> R, x = ring("x", ZZ)
  605. >>> R.dup_shift(x**2 - 2*x + 1, ZZ(2))
  606. x**2 + 2*x + 1
  607. """
  608. f, n = list(f), len(f) - 1
  609. for i in range(n, 0, -1):
  610. for j in range(0, i):
  611. f[j + 1] += a*f[j]
  612. return f
  613. def dmp_shift(f, a, u, K):
  614. """
  615. Evaluate efficiently Taylor shift ``f(X + A)`` in ``K[X]``.
  616. Examples
  617. ========
  618. >>> from sympy import symbols, ring, ZZ
  619. >>> x, y = symbols('x y')
  620. >>> R, _, _ = ring([x, y], ZZ)
  621. >>> p = x**2*y + 2*x*y + 3*x + 4*y + 5
  622. >>> R.dmp_shift(R(p), [ZZ(1), ZZ(2)])
  623. x**2*y + 2*x**2 + 4*x*y + 11*x + 7*y + 22
  624. >>> p.subs({x: x + 1, y: y + 2}).expand()
  625. x**2*y + 2*x**2 + 4*x*y + 11*x + 7*y + 22
  626. """
  627. if not u:
  628. return dup_shift(f, a[0], K)
  629. if dmp_zero_p(f, u):
  630. return f
  631. a0, a1 = a[0], a[1:]
  632. if any(a1):
  633. f = [ dmp_shift(c, a1, u-1, K) for c in f ]
  634. else:
  635. f = list(f)
  636. if a0:
  637. n = len(f) - 1
  638. for i in range(n, 0, -1):
  639. for j in range(0, i):
  640. afj = dmp_mul_ground(f[j], a0, u-1, K)
  641. f[j + 1] = dmp_add(f[j + 1], afj, u-1, K)
  642. return dmp_strip(f, u)
  643. def dup_transform(f, p, q, K):
  644. """
  645. Evaluate functional transformation ``q**n * f(p/q)`` in ``K[x]``.
  646. Examples
  647. ========
  648. >>> from sympy.polys import ring, ZZ
  649. >>> R, x = ring("x", ZZ)
  650. >>> R.dup_transform(x**2 - 2*x + 1, x**2 + 1, x - 1)
  651. x**4 - 2*x**3 + 5*x**2 - 4*x + 4
  652. """
  653. if not f:
  654. return []
  655. n = len(f) - 1
  656. h, Q = [f[0]], [[K.one]]
  657. for i in range(0, n):
  658. Q.append(dup_mul(Q[-1], q, K))
  659. for c, q in zip(f[1:], Q[1:]):
  660. h = dup_mul(h, p, K)
  661. q = dup_mul_ground(q, c, K)
  662. h = dup_add(h, q, K)
  663. return h
  664. def dup_compose(f, g, K):
  665. """
  666. Evaluate functional composition ``f(g)`` in ``K[x]``.
  667. Examples
  668. ========
  669. >>> from sympy.polys import ring, ZZ
  670. >>> R, x = ring("x", ZZ)
  671. >>> R.dup_compose(x**2 + x, x - 1)
  672. x**2 - x
  673. """
  674. if len(g) <= 1:
  675. return dup_strip([dup_eval(f, dup_LC(g, K), K)])
  676. if not f:
  677. return []
  678. h = [f[0]]
  679. for c in f[1:]:
  680. h = dup_mul(h, g, K)
  681. h = dup_add_term(h, c, 0, K)
  682. return h
  683. def dmp_compose(f, g, u, K):
  684. """
  685. Evaluate functional composition ``f(g)`` in ``K[X]``.
  686. Examples
  687. ========
  688. >>> from sympy.polys import ring, ZZ
  689. >>> R, x,y = ring("x,y", ZZ)
  690. >>> R.dmp_compose(x*y + 2*x + y, y)
  691. y**2 + 3*y
  692. """
  693. if not u:
  694. return dup_compose(f, g, K)
  695. if dmp_zero_p(f, u):
  696. return f
  697. h = [f[0]]
  698. for c in f[1:]:
  699. h = dmp_mul(h, g, u, K)
  700. h = dmp_add_term(h, c, 0, u, K)
  701. return h
  702. def _dup_right_decompose(f, s, K):
  703. """Helper function for :func:`_dup_decompose`."""
  704. n = len(f) - 1
  705. lc = dup_LC(f, K)
  706. f = dup_to_raw_dict(f)
  707. g = { s: K.one }
  708. r = n // s
  709. for i in range(1, s):
  710. coeff = K.zero
  711. for j in range(0, i):
  712. if not n + j - i in f:
  713. continue
  714. if not s - j in g:
  715. continue
  716. fc, gc = f[n + j - i], g[s - j]
  717. coeff += (i - r*j)*fc*gc
  718. g[s - i] = K.quo(coeff, i*r*lc)
  719. return dup_from_raw_dict(g, K)
  720. def _dup_left_decompose(f, h, K):
  721. """Helper function for :func:`_dup_decompose`."""
  722. g, i = {}, 0
  723. while f:
  724. q, r = dup_div(f, h, K)
  725. if dup_degree(r) > 0:
  726. return None
  727. else:
  728. g[i] = dup_LC(r, K)
  729. f, i = q, i + 1
  730. return dup_from_raw_dict(g, K)
  731. def _dup_decompose(f, K):
  732. """Helper function for :func:`dup_decompose`."""
  733. df = len(f) - 1
  734. for s in range(2, df):
  735. if df % s != 0:
  736. continue
  737. h = _dup_right_decompose(f, s, K)
  738. if h is not None:
  739. g = _dup_left_decompose(f, h, K)
  740. if g is not None:
  741. return g, h
  742. return None
  743. def dup_decompose(f, K):
  744. """
  745. Computes functional decomposition of ``f`` in ``K[x]``.
  746. Given a univariate polynomial ``f`` with coefficients in a field of
  747. characteristic zero, returns list ``[f_1, f_2, ..., f_n]``, where::
  748. f = f_1 o f_2 o ... f_n = f_1(f_2(... f_n))
  749. and ``f_2, ..., f_n`` are monic and homogeneous polynomials of at
  750. least second degree.
  751. Unlike factorization, complete functional decompositions of
  752. polynomials are not unique, consider examples:
  753. 1. ``f o g = f(x + b) o (g - b)``
  754. 2. ``x**n o x**m = x**m o x**n``
  755. 3. ``T_n o T_m = T_m o T_n``
  756. where ``T_n`` and ``T_m`` are Chebyshev polynomials.
  757. Examples
  758. ========
  759. >>> from sympy.polys import ring, ZZ
  760. >>> R, x = ring("x", ZZ)
  761. >>> R.dup_decompose(x**4 - 2*x**3 + x**2)
  762. [x**2, x**2 - x]
  763. References
  764. ==========
  765. .. [1] [Kozen89]_
  766. """
  767. F = []
  768. while True:
  769. result = _dup_decompose(f, K)
  770. if result is not None:
  771. f, h = result
  772. F = [h] + F
  773. else:
  774. break
  775. return [f] + F
  776. def dmp_alg_inject(f, u, K):
  777. """
  778. Convert polynomial from ``K(a)[X]`` to ``K[a,X]``.
  779. Examples
  780. ========
  781. >>> from sympy.polys.densetools import dmp_alg_inject
  782. >>> from sympy import QQ, sqrt
  783. >>> K = QQ.algebraic_field(sqrt(2))
  784. >>> p = [K.from_sympy(sqrt(2)), K.zero, K.one]
  785. >>> P, lev, dom = dmp_alg_inject(p, 0, K)
  786. >>> P
  787. [[1, 0, 0], [1]]
  788. >>> lev
  789. 1
  790. >>> dom
  791. QQ
  792. """
  793. if K.is_GaussianRing or K.is_GaussianField:
  794. return _dmp_alg_inject_gaussian(f, u, K)
  795. elif K.is_Algebraic:
  796. return _dmp_alg_inject_alg(f, u, K)
  797. else:
  798. raise DomainError('computation can be done only in an algebraic domain')
  799. def _dmp_alg_inject_gaussian(f, u, K):
  800. """Helper function for :func:`dmp_alg_inject`."""
  801. f, h = dmp_to_dict(f, u), {}
  802. for f_monom, g in f.items():
  803. x, y = g.x, g.y
  804. if x:
  805. h[(0,) + f_monom] = x
  806. if y:
  807. h[(1,) + f_monom] = y
  808. F = dmp_from_dict(h, u + 1, K.dom)
  809. return F, u + 1, K.dom
  810. def _dmp_alg_inject_alg(f, u, K):
  811. """Helper function for :func:`dmp_alg_inject`."""
  812. f, h = dmp_to_dict(f, u), {}
  813. for f_monom, g in f.items():
  814. for g_monom, c in g.to_dict().items():
  815. h[g_monom + f_monom] = c
  816. F = dmp_from_dict(h, u + 1, K.dom)
  817. return F, u + 1, K.dom
  818. def dmp_lift(f, u, K):
  819. """
  820. Convert algebraic coefficients to integers in ``K[X]``.
  821. Examples
  822. ========
  823. >>> from sympy.polys import ring, QQ
  824. >>> from sympy import I
  825. >>> K = QQ.algebraic_field(I)
  826. >>> R, x = ring("x", K)
  827. >>> f = x**2 + K([QQ(1), QQ(0)])*x + K([QQ(2), QQ(0)])
  828. >>> R.dmp_lift(f)
  829. x**4 + x**2 + 4*x + 4
  830. """
  831. # Circular import. Probably dmp_lift should be moved to euclidtools
  832. from .euclidtools import dmp_resultant
  833. F, v, K2 = dmp_alg_inject(f, u, K)
  834. p_a = K.mod.to_list()
  835. P_A = dmp_include(p_a, list(range(1, v + 1)), 0, K2)
  836. return dmp_resultant(F, P_A, v, K2)
  837. def dup_sign_variations(f, K):
  838. """
  839. Compute the number of sign variations of ``f`` in ``K[x]``.
  840. Examples
  841. ========
  842. >>> from sympy.polys import ring, ZZ
  843. >>> R, x = ring("x", ZZ)
  844. >>> R.dup_sign_variations(x**4 - x**2 - x + 1)
  845. 2
  846. """
  847. def is_negative_sympy(a):
  848. if not a:
  849. # XXX: requires zero equivalence testing in the domain
  850. return False
  851. else:
  852. # XXX: This is inefficient. It should not be necessary to use a
  853. # symbolic expression here at least for algebraic fields. If the
  854. # domain elements can be numerically evaluated to real values with
  855. # precision then this should work. We first need to rule out zero
  856. # elements though.
  857. return bool(K.to_sympy(a) < 0)
  858. # XXX: There should be a way to check for real numeric domains and
  859. # Domain.is_negative should be fixed to handle all real numeric domains.
  860. # It should not be necessary to special case all these different domains
  861. # in this otherwise generic function.
  862. if K.is_ZZ or K.is_QQ or K.is_RR:
  863. is_negative = K.is_negative
  864. elif K.is_AlgebraicField and K.ext.is_comparable:
  865. is_negative = is_negative_sympy
  866. elif ((K.is_PolynomialRing or K.is_FractionField) and len(K.symbols) == 1 and
  867. (K.dom.is_ZZ or K.dom.is_QQ or K.is_AlgebraicField) and
  868. K.symbols[0].is_transcendental and K.symbols[0].is_comparable):
  869. # We can handle a polynomial ring like QQ[E] if there is a single
  870. # transcendental generator because then zero equivalence is assured.
  871. is_negative = is_negative_sympy
  872. else:
  873. raise DomainError("sign variation counting not supported over %s" % K)
  874. prev, k = K.zero, 0
  875. for coeff in f:
  876. if is_negative(coeff*prev):
  877. k += 1
  878. if coeff:
  879. prev = coeff
  880. return k
  881. def dup_clear_denoms(f, K0, K1=None, convert=False):
  882. """
  883. Clear denominators, i.e. transform ``K_0`` to ``K_1``.
  884. Examples
  885. ========
  886. >>> from sympy.polys import ring, QQ
  887. >>> R, x = ring("x", QQ)
  888. >>> f = QQ(1,2)*x + QQ(1,3)
  889. >>> R.dup_clear_denoms(f, convert=False)
  890. (6, 3*x + 2)
  891. >>> R.dup_clear_denoms(f, convert=True)
  892. (6, 3*x + 2)
  893. """
  894. if K1 is None:
  895. if K0.has_assoc_Ring:
  896. K1 = K0.get_ring()
  897. else:
  898. K1 = K0
  899. common = K1.one
  900. for c in f:
  901. common = K1.lcm(common, K0.denom(c))
  902. if K1.is_one(common):
  903. if not convert:
  904. return common, f
  905. else:
  906. return common, dup_convert(f, K0, K1)
  907. # Use quo rather than exquo to handle inexact domains by discarding the
  908. # remainder.
  909. f = [K0.numer(c)*K1.quo(common, K0.denom(c)) for c in f]
  910. if not convert:
  911. return common, dup_convert(f, K1, K0)
  912. else:
  913. return common, f
  914. def _rec_clear_denoms(g, v, K0, K1):
  915. """Recursive helper for :func:`dmp_clear_denoms`."""
  916. common = K1.one
  917. if not v:
  918. for c in g:
  919. common = K1.lcm(common, K0.denom(c))
  920. else:
  921. w = v - 1
  922. for c in g:
  923. common = K1.lcm(common, _rec_clear_denoms(c, w, K0, K1))
  924. return common
  925. def dmp_clear_denoms(f, u, K0, K1=None, convert=False):
  926. """
  927. Clear denominators, i.e. transform ``K_0`` to ``K_1``.
  928. Examples
  929. ========
  930. >>> from sympy.polys import ring, QQ
  931. >>> R, x,y = ring("x,y", QQ)
  932. >>> f = QQ(1,2)*x + QQ(1,3)*y + 1
  933. >>> R.dmp_clear_denoms(f, convert=False)
  934. (6, 3*x + 2*y + 6)
  935. >>> R.dmp_clear_denoms(f, convert=True)
  936. (6, 3*x + 2*y + 6)
  937. """
  938. if not u:
  939. return dup_clear_denoms(f, K0, K1, convert=convert)
  940. if K1 is None:
  941. if K0.has_assoc_Ring:
  942. K1 = K0.get_ring()
  943. else:
  944. K1 = K0
  945. common = _rec_clear_denoms(f, u, K0, K1)
  946. if not K1.is_one(common):
  947. f = dmp_mul_ground(f, common, u, K0)
  948. if not convert:
  949. return common, f
  950. else:
  951. return common, dmp_convert(f, u, K0, K1)
  952. def dup_revert(f, n, K):
  953. """
  954. Compute ``f**(-1)`` mod ``x**n`` using Newton iteration.
  955. This function computes first ``2**n`` terms of a polynomial that
  956. is a result of inversion of a polynomial modulo ``x**n``. This is
  957. useful to efficiently compute series expansion of ``1/f``.
  958. Examples
  959. ========
  960. >>> from sympy.polys import ring, QQ
  961. >>> R, x = ring("x", QQ)
  962. >>> f = -QQ(1,720)*x**6 + QQ(1,24)*x**4 - QQ(1,2)*x**2 + 1
  963. >>> R.dup_revert(f, 8)
  964. 61/720*x**6 + 5/24*x**4 + 1/2*x**2 + 1
  965. """
  966. g = [K.revert(dup_TC(f, K))]
  967. h = [K.one, K.zero, K.zero]
  968. N = int(_ceil(_log2(n)))
  969. for i in range(1, N + 1):
  970. a = dup_mul_ground(g, K(2), K)
  971. b = dup_mul(f, dup_sqr(g, K), K)
  972. g = dup_rem(dup_sub(a, b, K), h, K)
  973. h = dup_lshift(h, dup_degree(h), K)
  974. return g
  975. def dmp_revert(f, g, u, K):
  976. """
  977. Compute ``f**(-1)`` mod ``x**n`` using Newton iteration.
  978. Examples
  979. ========
  980. >>> from sympy.polys import ring, QQ
  981. >>> R, x,y = ring("x,y", QQ)
  982. """
  983. if not u:
  984. return dup_revert(f, g, K)
  985. else:
  986. raise MultivariatePolynomialError(f, g)