test_polyclasses.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601
  1. """Tests for OO layer of several polynomial representations. """
  2. from sympy.functions.elementary.miscellaneous import sqrt
  3. from sympy.polys.domains import ZZ, QQ
  4. from sympy.polys.polyclasses import DMP, DMF, ANP
  5. from sympy.polys.polyerrors import (CoercionFailed, ExactQuotientFailed,
  6. NotInvertible)
  7. from sympy.polys.specialpolys import f_polys
  8. from sympy.testing.pytest import raises, warns_deprecated_sympy
  9. f_0, f_1, f_2, f_3, f_4, f_5, f_6 = [ f.to_dense() for f in f_polys() ]
  10. def test_DMP___init__():
  11. f = DMP([[ZZ(0)], [], [ZZ(0), ZZ(1), ZZ(2)], [ZZ(3)]], ZZ)
  12. assert f._rep == [[1, 2], [3]]
  13. assert f.dom == ZZ
  14. assert f.lev == 1
  15. f = DMP([[ZZ(1), ZZ(2)], [ZZ(3)]], ZZ, 1)
  16. assert f._rep == [[1, 2], [3]]
  17. assert f.dom == ZZ
  18. assert f.lev == 1
  19. f = DMP.from_dict({(1, 1): ZZ(1), (0, 0): ZZ(2)}, 1, ZZ)
  20. assert f._rep == [[1, 0], [2]]
  21. assert f.dom == ZZ
  22. assert f.lev == 1
  23. def test_DMP_rep_deprecation():
  24. f = DMP([1, 2, 3], ZZ)
  25. with warns_deprecated_sympy():
  26. assert f.rep == [1, 2, 3]
  27. def test_DMP___eq__():
  28. assert DMP([[ZZ(1), ZZ(2)], [ZZ(3)]], ZZ) == \
  29. DMP([[ZZ(1), ZZ(2)], [ZZ(3)]], ZZ)
  30. assert DMP([[ZZ(1), ZZ(2)], [ZZ(3)]], ZZ) == \
  31. DMP([[QQ(1), QQ(2)], [QQ(3)]], QQ)
  32. assert DMP([[QQ(1), QQ(2)], [QQ(3)]], QQ) == \
  33. DMP([[ZZ(1), ZZ(2)], [ZZ(3)]], ZZ)
  34. assert DMP([[[ZZ(1)]]], ZZ) != DMP([[ZZ(1)]], ZZ)
  35. assert DMP([[ZZ(1)]], ZZ) != DMP([[[ZZ(1)]]], ZZ)
  36. def test_DMP___bool__():
  37. assert bool(DMP([[]], ZZ)) is False
  38. assert bool(DMP([[ZZ(1)]], ZZ)) is True
  39. def test_DMP_to_dict():
  40. f = DMP([[ZZ(3)], [], [ZZ(2)], [], [ZZ(8)]], ZZ)
  41. assert f.to_dict() == \
  42. {(4, 0): 3, (2, 0): 2, (0, 0): 8}
  43. assert f.to_sympy_dict() == \
  44. {(4, 0): ZZ.to_sympy(3), (2, 0): ZZ.to_sympy(2), (0, 0):
  45. ZZ.to_sympy(8)}
  46. def test_DMP_properties():
  47. assert DMP([[]], ZZ).is_zero is True
  48. assert DMP([[ZZ(1)]], ZZ).is_zero is False
  49. assert DMP([[ZZ(1)]], ZZ).is_one is True
  50. assert DMP([[ZZ(2)]], ZZ).is_one is False
  51. assert DMP([[ZZ(1)]], ZZ).is_ground is True
  52. assert DMP([[ZZ(1)], [ZZ(2)], [ZZ(1)]], ZZ).is_ground is False
  53. assert DMP([[ZZ(1)], [ZZ(2), ZZ(0)], [ZZ(1), ZZ(0)]], ZZ).is_sqf is True
  54. assert DMP([[ZZ(1)], [ZZ(2), ZZ(0)], [ZZ(1), ZZ(0), ZZ(0)]], ZZ).is_sqf is False
  55. assert DMP([[ZZ(1), ZZ(2)], [ZZ(3)]], ZZ).is_monic is True
  56. assert DMP([[ZZ(2), ZZ(2)], [ZZ(3)]], ZZ).is_monic is False
  57. assert DMP([[ZZ(1), ZZ(2)], [ZZ(3)]], ZZ).is_primitive is True
  58. assert DMP([[ZZ(2), ZZ(4)], [ZZ(6)]], ZZ).is_primitive is False
  59. def test_DMP_arithmetics():
  60. f = DMP([[ZZ(2)], [ZZ(2), ZZ(0)]], ZZ)
  61. assert f.mul_ground(2) == DMP([[ZZ(4)], [ZZ(4), ZZ(0)]], ZZ)
  62. assert f.quo_ground(2) == DMP([[ZZ(1)], [ZZ(1), ZZ(0)]], ZZ)
  63. raises(ExactQuotientFailed, lambda: f.exquo_ground(3))
  64. f = DMP([[ZZ(-5)]], ZZ)
  65. g = DMP([[ZZ(5)]], ZZ)
  66. assert f.abs() == g
  67. assert abs(f) == g
  68. assert g.neg() == f
  69. assert -g == f
  70. h = DMP([[]], ZZ)
  71. assert f.add(g) == h
  72. assert f + g == h
  73. assert g + f == h
  74. assert f + 5 == h
  75. assert 5 + f == h
  76. h = DMP([[ZZ(-10)]], ZZ)
  77. assert f.sub(g) == h
  78. assert f - g == h
  79. assert g - f == -h
  80. assert f - 5 == h
  81. assert 5 - f == -h
  82. h = DMP([[ZZ(-25)]], ZZ)
  83. assert f.mul(g) == h
  84. assert f * g == h
  85. assert g * f == h
  86. assert f * 5 == h
  87. assert 5 * f == h
  88. h = DMP([[ZZ(25)]], ZZ)
  89. assert f.sqr() == h
  90. assert f.pow(2) == h
  91. assert f**2 == h
  92. raises(TypeError, lambda: f.pow('x'))
  93. f = DMP([[ZZ(1)], [], [ZZ(1), ZZ(0), ZZ(0)]], ZZ)
  94. g = DMP([[ZZ(2)], [ZZ(-2), ZZ(0)]], ZZ)
  95. q = DMP([[ZZ(2)], [ZZ(2), ZZ(0)]], ZZ)
  96. r = DMP([[ZZ(8), ZZ(0), ZZ(0)]], ZZ)
  97. assert f.pdiv(g) == (q, r)
  98. assert f.pquo(g) == q
  99. assert f.prem(g) == r
  100. raises(ExactQuotientFailed, lambda: f.pexquo(g))
  101. f = DMP([[ZZ(1)], [], [ZZ(1), ZZ(0), ZZ(0)]], ZZ)
  102. g = DMP([[ZZ(1)], [ZZ(-1), ZZ(0)]], ZZ)
  103. q = DMP([[ZZ(1)], [ZZ(1), ZZ(0)]], ZZ)
  104. r = DMP([[ZZ(2), ZZ(0), ZZ(0)]], ZZ)
  105. assert f.div(g) == (q, r)
  106. assert f.quo(g) == q
  107. assert f.rem(g) == r
  108. assert divmod(f, g) == (q, r)
  109. assert f // g == q
  110. assert f % g == r
  111. raises(ExactQuotientFailed, lambda: f.exquo(g))
  112. f = DMP([ZZ(1), ZZ(0), ZZ(-1)], ZZ)
  113. g = DMP([ZZ(2), ZZ(-2)], ZZ)
  114. q = DMP([], ZZ)
  115. r = f
  116. pq = DMP([ZZ(2), ZZ(2)], ZZ)
  117. pr = DMP([], ZZ)
  118. assert f.div(g) == (q, r)
  119. assert f.quo(g) == q
  120. assert f.rem(g) == r
  121. assert divmod(f, g) == (q, r)
  122. assert f // g == q
  123. assert f % g == r
  124. raises(ExactQuotientFailed, lambda: f.exquo(g))
  125. assert f.pdiv(g) == (pq, pr)
  126. assert f.pquo(g) == pq
  127. assert f.prem(g) == pr
  128. assert f.pexquo(g) == pq
  129. def test_DMP_functionality():
  130. f = DMP([[ZZ(1)], [ZZ(2), ZZ(0)], [ZZ(1), ZZ(0), ZZ(0)]], ZZ)
  131. g = DMP([[ZZ(1)], [ZZ(1), ZZ(0)]], ZZ)
  132. h = DMP([[ZZ(1)]], ZZ)
  133. assert f.degree() == 2
  134. assert f.degree_list() == (2, 2)
  135. assert f.total_degree() == 2
  136. assert f.LC() == ZZ(1)
  137. assert f.TC() == ZZ(0)
  138. assert f.nth(1, 1) == ZZ(2)
  139. raises(TypeError, lambda: f.nth(0, 'x'))
  140. assert f.max_norm() == 2
  141. assert f.l1_norm() == 4
  142. u = DMP([[ZZ(2)], [ZZ(2), ZZ(0)]], ZZ)
  143. assert f.diff(m=1, j=0) == u
  144. assert f.diff(m=1, j=1) == u
  145. raises(TypeError, lambda: f.diff(m='x', j=0))
  146. u = DMP([ZZ(1), ZZ(2), ZZ(1)], ZZ)
  147. v = DMP([ZZ(1), ZZ(2), ZZ(1)], ZZ)
  148. assert f.eval(a=1, j=0) == u
  149. assert f.eval(a=1, j=1) == v
  150. assert f.eval(1).eval(1) == ZZ(4)
  151. assert f.cofactors(g) == (g, g, h)
  152. assert f.gcd(g) == g
  153. assert f.lcm(g) == f
  154. u = DMP([[QQ(45), QQ(30), QQ(5)]], QQ)
  155. v = DMP([[QQ(1), QQ(2, 3), QQ(1, 9)]], QQ)
  156. assert u.monic() == v
  157. assert (4*f).content() == ZZ(4)
  158. assert (4*f).primitive() == (ZZ(4), f)
  159. f = DMP([QQ(1,3), QQ(1)], QQ)
  160. g = DMP([QQ(1,7), QQ(1)], QQ)
  161. assert f.cancel(g) == f.cancel(g, include=True) == (
  162. DMP([QQ(7), QQ(21)], QQ),
  163. DMP([QQ(3), QQ(21)], QQ)
  164. )
  165. assert f.cancel(g, include=False) == (
  166. QQ(7),
  167. QQ(3),
  168. DMP([QQ(1), QQ(3)], QQ),
  169. DMP([QQ(1), QQ(7)], QQ)
  170. )
  171. f = DMP([[ZZ(1)], [ZZ(2)], [ZZ(3)], [ZZ(4)], [ZZ(5)], [ZZ(6)]], ZZ)
  172. assert f.trunc(3) == DMP([[ZZ(1)], [ZZ(-1)], [], [ZZ(1)], [ZZ(-1)], []], ZZ)
  173. f = DMP(f_4, ZZ)
  174. assert f.sqf_part() == -f
  175. assert f.sqf_list() == (ZZ(-1), [(-f, 1)])
  176. f = DMP([[ZZ(-1)], [], [], [ZZ(5)]], ZZ)
  177. g = DMP([[ZZ(3), ZZ(1)], [], []], ZZ)
  178. h = DMP([[ZZ(45), ZZ(30), ZZ(5)]], ZZ)
  179. r = DMP([ZZ(675), ZZ(675), ZZ(225), ZZ(25)], ZZ)
  180. assert f.subresultants(g) == [f, g, h]
  181. assert f.resultant(g) == r
  182. f = DMP([ZZ(1), ZZ(3), ZZ(9), ZZ(-13)], ZZ)
  183. assert f.discriminant() == -11664
  184. f = DMP([QQ(2), QQ(0)], QQ)
  185. g = DMP([QQ(1), QQ(0), QQ(-16)], QQ)
  186. s = DMP([QQ(1, 32), QQ(0)], QQ)
  187. t = DMP([QQ(-1, 16)], QQ)
  188. h = DMP([QQ(1)], QQ)
  189. assert f.half_gcdex(g) == (s, h)
  190. assert f.gcdex(g) == (s, t, h)
  191. assert f.invert(g) == s
  192. f = DMP([[QQ(1)], [QQ(2)], [QQ(3)]], QQ)
  193. raises(ValueError, lambda: f.half_gcdex(f))
  194. raises(ValueError, lambda: f.gcdex(f))
  195. raises(ValueError, lambda: f.invert(f))
  196. f = DMP(ZZ.map([1, 0, 20, 0, 150, 0, 500, 0, 625, -2, 0, -10, 9]), ZZ)
  197. g = DMP([ZZ(1), ZZ(0), ZZ(0), ZZ(-2), ZZ(9)], ZZ)
  198. h = DMP([ZZ(1), ZZ(0), ZZ(5), ZZ(0)], ZZ)
  199. assert g.compose(h) == f
  200. assert f.decompose() == [g, h]
  201. f = DMP([[QQ(1)], [QQ(2)], [QQ(3)]], QQ)
  202. raises(ValueError, lambda: f.decompose())
  203. raises(ValueError, lambda: f.sturm())
  204. def test_DMP_exclude():
  205. f = [[[[[[[[[[[[[[[[[[[[[[[[[[ZZ(1)]], [[]]]]]]]]]]]]]]]]]]]]]]]]]]
  206. J = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
  207. 18, 19, 20, 21, 22, 24, 25]
  208. assert DMP(f, ZZ).exclude() == (J, DMP([ZZ(1), ZZ(0)], ZZ))
  209. assert DMP([[ZZ(1)], [ZZ(1), ZZ(0)]], ZZ).exclude() ==\
  210. ([], DMP([[ZZ(1)], [ZZ(1), ZZ(0)]], ZZ))
  211. def test_DMF__init__():
  212. f = DMF(([[0], [], [0, 1, 2], [3]], [[1, 2, 3]]), ZZ)
  213. assert f.num == [[1, 2], [3]]
  214. assert f.den == [[1, 2, 3]]
  215. assert f.lev == 1
  216. assert f.dom == ZZ
  217. f = DMF(([[1, 2], [3]], [[1, 2, 3]]), ZZ, 1)
  218. assert f.num == [[1, 2], [3]]
  219. assert f.den == [[1, 2, 3]]
  220. assert f.lev == 1
  221. assert f.dom == ZZ
  222. f = DMF(([[-1], [-2]], [[3], [-4]]), ZZ)
  223. assert f.num == [[-1], [-2]]
  224. assert f.den == [[3], [-4]]
  225. assert f.lev == 1
  226. assert f.dom == ZZ
  227. f = DMF(([[1], [2]], [[-3], [4]]), ZZ)
  228. assert f.num == [[-1], [-2]]
  229. assert f.den == [[3], [-4]]
  230. assert f.lev == 1
  231. assert f.dom == ZZ
  232. f = DMF(([[1], [2]], [[-3], [4]]), ZZ)
  233. assert f.num == [[-1], [-2]]
  234. assert f.den == [[3], [-4]]
  235. assert f.lev == 1
  236. assert f.dom == ZZ
  237. f = DMF(([[]], [[-3], [4]]), ZZ)
  238. assert f.num == [[]]
  239. assert f.den == [[1]]
  240. assert f.lev == 1
  241. assert f.dom == ZZ
  242. f = DMF(17, ZZ, 1)
  243. assert f.num == [[17]]
  244. assert f.den == [[1]]
  245. assert f.lev == 1
  246. assert f.dom == ZZ
  247. f = DMF(([[1], [2]]), ZZ)
  248. assert f.num == [[1], [2]]
  249. assert f.den == [[1]]
  250. assert f.lev == 1
  251. assert f.dom == ZZ
  252. f = DMF([[0], [], [0, 1, 2], [3]], ZZ)
  253. assert f.num == [[1, 2], [3]]
  254. assert f.den == [[1]]
  255. assert f.lev == 1
  256. assert f.dom == ZZ
  257. f = DMF({(1, 1): 1, (0, 0): 2}, ZZ, 1)
  258. assert f.num == [[1, 0], [2]]
  259. assert f.den == [[1]]
  260. assert f.lev == 1
  261. assert f.dom == ZZ
  262. f = DMF(([[QQ(1)], [QQ(2)]], [[-QQ(3)], [QQ(4)]]), QQ)
  263. assert f.num == [[-QQ(1)], [-QQ(2)]]
  264. assert f.den == [[QQ(3)], [-QQ(4)]]
  265. assert f.lev == 1
  266. assert f.dom == QQ
  267. f = DMF(([[QQ(1, 5)], [QQ(2, 5)]], [[-QQ(3, 7)], [QQ(4, 7)]]), QQ)
  268. assert f.num == [[-QQ(7)], [-QQ(14)]]
  269. assert f.den == [[QQ(15)], [-QQ(20)]]
  270. assert f.lev == 1
  271. assert f.dom == QQ
  272. raises(ValueError, lambda: DMF(([1], [[1]]), ZZ))
  273. raises(ZeroDivisionError, lambda: DMF(([1], []), ZZ))
  274. def test_DMF__bool__():
  275. assert bool(DMF([[]], ZZ)) is False
  276. assert bool(DMF([[1]], ZZ)) is True
  277. def test_DMF_properties():
  278. assert DMF([[]], ZZ).is_zero is True
  279. assert DMF([[]], ZZ).is_one is False
  280. assert DMF([[1]], ZZ).is_zero is False
  281. assert DMF([[1]], ZZ).is_one is True
  282. assert DMF(([[1]], [[2]]), ZZ).is_one is False
  283. def test_DMF_arithmetics():
  284. f = DMF([[7], [-9]], ZZ)
  285. g = DMF([[-7], [9]], ZZ)
  286. assert f.neg() == -f == g
  287. f = DMF(([[1]], [[1], []]), ZZ)
  288. g = DMF(([[1]], [[1, 0]]), ZZ)
  289. h = DMF(([[1], [1, 0]], [[1, 0], []]), ZZ)
  290. assert f.add(g) == f + g == h
  291. assert g.add(f) == g + f == h
  292. h = DMF(([[-1], [1, 0]], [[1, 0], []]), ZZ)
  293. assert f.sub(g) == f - g == h
  294. h = DMF(([[1]], [[1, 0], []]), ZZ)
  295. assert f.mul(g) == f*g == h
  296. assert g.mul(f) == g*f == h
  297. h = DMF(([[1, 0]], [[1], []]), ZZ)
  298. assert f.quo(g) == f/g == h
  299. h = DMF(([[1]], [[1], [], [], []]), ZZ)
  300. assert f.pow(3) == f**3 == h
  301. h = DMF(([[1]], [[1, 0, 0, 0]]), ZZ)
  302. assert g.pow(3) == g**3 == h
  303. h = DMF(([[1, 0]], [[1]]), ZZ)
  304. assert g.pow(-1) == g**-1 == h
  305. def test_ANP___init__():
  306. rep = [QQ(1), QQ(1)]
  307. mod = [QQ(1), QQ(0), QQ(1)]
  308. f = ANP(rep, mod, QQ)
  309. assert f.to_list() == [QQ(1), QQ(1)]
  310. assert f.mod_to_list() == [QQ(1), QQ(0), QQ(1)]
  311. assert f.dom == QQ
  312. rep = {1: QQ(1), 0: QQ(1)}
  313. mod = {2: QQ(1), 0: QQ(1)}
  314. f = ANP(rep, mod, QQ)
  315. assert f.to_list() == [QQ(1), QQ(1)]
  316. assert f.mod_to_list() == [QQ(1), QQ(0), QQ(1)]
  317. assert f.dom == QQ
  318. f = ANP(1, mod, QQ)
  319. assert f.to_list() == [QQ(1)]
  320. assert f.mod_to_list() == [QQ(1), QQ(0), QQ(1)]
  321. assert f.dom == QQ
  322. f = ANP([1, 0.5], mod, QQ)
  323. assert all(QQ.of_type(a) for a in f.to_list())
  324. raises(CoercionFailed, lambda: ANP([sqrt(2)], mod, QQ))
  325. def test_ANP___eq__():
  326. a = ANP([QQ(1), QQ(1)], [QQ(1), QQ(0), QQ(1)], QQ)
  327. b = ANP([QQ(1), QQ(1)], [QQ(1), QQ(0), QQ(2)], QQ)
  328. assert (a == a) is True
  329. assert (a != a) is False
  330. assert (a == b) is False
  331. assert (a != b) is True
  332. b = ANP([QQ(1), QQ(2)], [QQ(1), QQ(0), QQ(1)], QQ)
  333. assert (a == b) is False
  334. assert (a != b) is True
  335. def test_ANP___bool__():
  336. assert bool(ANP([], [QQ(1), QQ(0), QQ(1)], QQ)) is False
  337. assert bool(ANP([QQ(1)], [QQ(1), QQ(0), QQ(1)], QQ)) is True
  338. def test_ANP_properties():
  339. mod = [QQ(1), QQ(0), QQ(1)]
  340. assert ANP([QQ(0)], mod, QQ).is_zero is True
  341. assert ANP([QQ(1)], mod, QQ).is_zero is False
  342. assert ANP([QQ(1)], mod, QQ).is_one is True
  343. assert ANP([QQ(2)], mod, QQ).is_one is False
  344. def test_ANP_arithmetics():
  345. mod = [QQ(1), QQ(0), QQ(0), QQ(-2)]
  346. a = ANP([QQ(2), QQ(-1), QQ(1)], mod, QQ)
  347. b = ANP([QQ(1), QQ(2)], mod, QQ)
  348. c = ANP([QQ(-2), QQ(1), QQ(-1)], mod, QQ)
  349. assert a.neg() == -a == c
  350. c = ANP([QQ(2), QQ(0), QQ(3)], mod, QQ)
  351. assert a.add(b) == a + b == c
  352. assert b.add(a) == b + a == c
  353. c = ANP([QQ(2), QQ(-2), QQ(-1)], mod, QQ)
  354. assert a.sub(b) == a - b == c
  355. c = ANP([QQ(-2), QQ(2), QQ(1)], mod, QQ)
  356. assert b.sub(a) == b - a == c
  357. c = ANP([QQ(3), QQ(-1), QQ(6)], mod, QQ)
  358. assert a.mul(b) == a*b == c
  359. assert b.mul(a) == b*a == c
  360. c = ANP([QQ(-1, 43), QQ(9, 43), QQ(5, 43)], mod, QQ)
  361. assert a.pow(0) == a**(0) == ANP(1, mod, QQ)
  362. assert a.pow(1) == a**(1) == a
  363. assert a.pow(-1) == a**(-1) == c
  364. assert a.quo(a) == a.mul(a.pow(-1)) == a*a**(-1) == ANP(1, mod, QQ)
  365. c = ANP([], [1, 0, 0, -2], QQ)
  366. r1 = a.rem(b)
  367. (q, r2) = a.div(b)
  368. assert r1 == r2 == c == a % b
  369. raises(NotInvertible, lambda: a.div(c))
  370. raises(NotInvertible, lambda: a.rem(c))
  371. # Comparison with "hard-coded" value fails despite looking identical
  372. # from sympy import Rational
  373. # c = ANP([Rational(11, 10), Rational(-1, 5), Rational(-3, 5)], [1, 0, 0, -2], QQ)
  374. assert q == a/b # == c
  375. def test_ANP_unify():
  376. mod_z = [ZZ(1), ZZ(0), ZZ(-2)]
  377. mod_q = [QQ(1), QQ(0), QQ(-2)]
  378. a = ANP([QQ(1)], mod_q, QQ)
  379. b = ANP([ZZ(1)], mod_z, ZZ)
  380. assert a.unify(b)[0] == QQ
  381. assert b.unify(a)[0] == QQ
  382. assert a.unify(a)[0] == QQ
  383. assert b.unify(b)[0] == ZZ
  384. assert a.unify_ANP(b)[-1] == QQ
  385. assert b.unify_ANP(a)[-1] == QQ
  386. assert a.unify_ANP(a)[-1] == QQ
  387. assert b.unify_ANP(b)[-1] == ZZ
  388. def test_zero_poly():
  389. from sympy import Symbol
  390. x = Symbol('x')
  391. R_old = ZZ.old_poly_ring(x)
  392. zero_poly_old = R_old(0)
  393. cont_old, prim_old = zero_poly_old.primitive()
  394. assert cont_old == 0
  395. assert prim_old == zero_poly_old
  396. assert prim_old.is_primitive is False