test_modules.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. """Test modules.py code."""
  2. from sympy.polys.agca.modules import FreeModule, ModuleOrder, FreeModulePolyRing
  3. from sympy.polys import CoercionFailed, QQ, lex, grlex, ilex, ZZ
  4. from sympy.abc import x, y, z
  5. from sympy.testing.pytest import raises
  6. from sympy.core.numbers import Rational
  7. def test_FreeModuleElement():
  8. M = QQ.old_poly_ring(x).free_module(3)
  9. e = M.convert([1, x, x**2])
  10. f = [QQ.old_poly_ring(x).convert(1), QQ.old_poly_ring(x).convert(x), QQ.old_poly_ring(x).convert(x**2)]
  11. assert list(e) == f
  12. assert f[0] == e[0]
  13. assert f[1] == e[1]
  14. assert f[2] == e[2]
  15. raises(IndexError, lambda: e[3])
  16. g = M.convert([x, 0, 0])
  17. assert e + g == M.convert([x + 1, x, x**2])
  18. assert f + g == M.convert([x + 1, x, x**2])
  19. assert -e == M.convert([-1, -x, -x**2])
  20. assert e - g == M.convert([1 - x, x, x**2])
  21. assert e != g
  22. assert M.convert([x, x, x]) / QQ.old_poly_ring(x).convert(x) == [1, 1, 1]
  23. R = QQ.old_poly_ring(x, order="ilex")
  24. assert R.free_module(1).convert([x]) / R.convert(x) == [1]
  25. def test_FreeModule():
  26. M1 = FreeModule(QQ.old_poly_ring(x), 2)
  27. assert M1 == FreeModule(QQ.old_poly_ring(x), 2)
  28. assert M1 != FreeModule(QQ.old_poly_ring(y), 2)
  29. assert M1 != FreeModule(QQ.old_poly_ring(x), 3)
  30. M2 = FreeModule(QQ.old_poly_ring(x, order="ilex"), 2)
  31. assert [x, 1] in M1
  32. assert [x] not in M1
  33. assert [2, y] not in M1
  34. assert [1/(x + 1), 2] not in M1
  35. e = M1.convert([x, x**2 + 1])
  36. X = QQ.old_poly_ring(x).convert(x)
  37. assert e == [X, X**2 + 1]
  38. assert e == [x, x**2 + 1]
  39. assert 2*e == [2*x, 2*x**2 + 2]
  40. assert e*2 == [2*x, 2*x**2 + 2]
  41. assert e/2 == [x/2, (x**2 + 1)/2]
  42. assert x*e == [x**2, x**3 + x]
  43. assert e*x == [x**2, x**3 + x]
  44. assert X*e == [x**2, x**3 + x]
  45. assert e*X == [x**2, x**3 + x]
  46. assert [x, 1] in M2
  47. assert [x] not in M2
  48. assert [2, y] not in M2
  49. assert [1/(x + 1), 2] in M2
  50. e = M2.convert([x, x**2 + 1])
  51. X = QQ.old_poly_ring(x, order="ilex").convert(x)
  52. assert e == [X, X**2 + 1]
  53. assert e == [x, x**2 + 1]
  54. assert 2*e == [2*x, 2*x**2 + 2]
  55. assert e*2 == [2*x, 2*x**2 + 2]
  56. assert e/2 == [x/2, (x**2 + 1)/2]
  57. assert x*e == [x**2, x**3 + x]
  58. assert e*x == [x**2, x**3 + x]
  59. assert e/(1 + x) == [x/(1 + x), (x**2 + 1)/(1 + x)]
  60. assert X*e == [x**2, x**3 + x]
  61. assert e*X == [x**2, x**3 + x]
  62. M3 = FreeModule(QQ.old_poly_ring(x, y), 2)
  63. assert M3.convert(e) == M3.convert([x, x**2 + 1])
  64. assert not M3.is_submodule(0)
  65. assert not M3.is_zero()
  66. raises(NotImplementedError, lambda: ZZ.old_poly_ring(x).free_module(2))
  67. raises(NotImplementedError, lambda: FreeModulePolyRing(ZZ, 2))
  68. raises(CoercionFailed, lambda: M1.convert(QQ.old_poly_ring(x).free_module(3)
  69. .convert([1, 2, 3])))
  70. raises(CoercionFailed, lambda: M3.convert(1))
  71. def test_ModuleOrder():
  72. o1 = ModuleOrder(lex, grlex, False)
  73. o2 = ModuleOrder(ilex, lex, False)
  74. assert o1 == ModuleOrder(lex, grlex, False)
  75. assert (o1 != ModuleOrder(lex, grlex, False)) is False
  76. assert o1 != o2
  77. assert o1((1, 2, 3)) == (1, (5, (2, 3)))
  78. assert o2((1, 2, 3)) == (-1, (2, 3))
  79. def test_SubModulePolyRing_global():
  80. R = QQ.old_poly_ring(x, y)
  81. F = R.free_module(3)
  82. Fd = F.submodule([1, 0, 0], [1, 2, 0], [1, 2, 3])
  83. M = F.submodule([x**2 + y**2, 1, 0], [x, y, 1])
  84. assert F == Fd
  85. assert Fd == F
  86. assert F != M
  87. assert M != F
  88. assert Fd != M
  89. assert M != Fd
  90. assert Fd == F.submodule(*F.basis())
  91. assert Fd.is_full_module()
  92. assert not M.is_full_module()
  93. assert not Fd.is_zero()
  94. assert not M.is_zero()
  95. assert Fd.submodule().is_zero()
  96. assert M.contains([x**2 + y**2 + x, 1 + y, 1])
  97. assert not M.contains([x**2 + y**2 + x, 1 + y, 2])
  98. assert M.contains([y**2, 1 - x*y, -x])
  99. assert not F.submodule([1 + x, 0, 0]) == F.submodule([1, 0, 0])
  100. assert F.submodule([1, 0, 0], [0, 1, 0]).union(F.submodule([0, 0, 1])) == F
  101. assert not M.is_submodule(0)
  102. m = F.convert([x**2 + y**2, 1, 0])
  103. n = M.convert(m)
  104. assert m.module is F
  105. assert n.module is M
  106. raises(ValueError, lambda: M.submodule([1, 0, 0]))
  107. raises(TypeError, lambda: M.union(1))
  108. raises(ValueError, lambda: M.union(R.free_module(1).submodule([x])))
  109. assert F.submodule([x, x, x]) != F.submodule([x, x, x], order="ilex")
  110. def test_SubModulePolyRing_local():
  111. R = QQ.old_poly_ring(x, y, order=ilex)
  112. F = R.free_module(3)
  113. Fd = F.submodule([1 + x, 0, 0], [1 + y, 2 + 2*y, 0], [1, 2, 3])
  114. M = F.submodule([x**2 + y**2, 1, 0], [x, y, 1])
  115. assert F == Fd
  116. assert Fd == F
  117. assert F != M
  118. assert M != F
  119. assert Fd != M
  120. assert M != Fd
  121. assert Fd == F.submodule(*F.basis())
  122. assert Fd.is_full_module()
  123. assert not M.is_full_module()
  124. assert not Fd.is_zero()
  125. assert not M.is_zero()
  126. assert Fd.submodule().is_zero()
  127. assert M.contains([x**2 + y**2 + x, 1 + y, 1])
  128. assert not M.contains([x**2 + y**2 + x, 1 + y, 2])
  129. assert M.contains([y**2, 1 - x*y, -x])
  130. assert F.submodule([1 + x, 0, 0]) == F.submodule([1, 0, 0])
  131. assert F.submodule(
  132. [1, 0, 0], [0, 1, 0]).union(F.submodule([0, 0, 1 + x*y])) == F
  133. raises(ValueError, lambda: M.submodule([1, 0, 0]))
  134. def test_SubModulePolyRing_nontriv_global():
  135. R = QQ.old_poly_ring(x, y, z)
  136. F = R.free_module(1)
  137. def contains(I, f):
  138. return F.submodule(*[[g] for g in I]).contains([f])
  139. assert contains([x, y], x)
  140. assert contains([x, y], x + y)
  141. assert not contains([x, y], 1)
  142. assert not contains([x, y], z)
  143. assert contains([x**2 + y, x**2 + x], x - y)
  144. assert not contains([x + y + z, x*y + x*z + y*z, x*y*z], x**2)
  145. assert contains([x + y + z, x*y + x*z + y*z, x*y*z], x**3)
  146. assert contains([x + y + z, x*y + x*z + y*z, x*y*z], x**4)
  147. assert not contains([x + y + z, x*y + x*z + y*z, x*y*z], x*y**2)
  148. assert contains([x + y + z, x*y + x*z + y*z, x*y*z], x**4 + y**3 + 2*z*y*x)
  149. assert contains([x + y + z, x*y + x*z + y*z, x*y*z], x*y*z)
  150. assert contains([x, 1 + x + y, 5 - 7*y], 1)
  151. assert contains(
  152. [x**3 + y**3, y**3 + z**3, z**3 + x**3, x**2*y + x**2*z + y**2*z],
  153. x**3)
  154. assert not contains(
  155. [x**3 + y**3, y**3 + z**3, z**3 + x**3, x**2*y + x**2*z + y**2*z],
  156. x**2 + y**2)
  157. # compare local order
  158. assert not contains([x*(1 + x + y), y*(1 + z)], x)
  159. assert not contains([x*(1 + x + y), y*(1 + z)], x + y)
  160. def test_SubModulePolyRing_nontriv_local():
  161. R = QQ.old_poly_ring(x, y, z, order=ilex)
  162. F = R.free_module(1)
  163. def contains(I, f):
  164. return F.submodule(*[[g] for g in I]).contains([f])
  165. assert contains([x, y], x)
  166. assert contains([x, y], x + y)
  167. assert not contains([x, y], 1)
  168. assert not contains([x, y], z)
  169. assert contains([x**2 + y, x**2 + x], x - y)
  170. assert not contains([x + y + z, x*y + x*z + y*z, x*y*z], x**2)
  171. assert contains([x*(1 + x + y), y*(1 + z)], x)
  172. assert contains([x*(1 + x + y), y*(1 + z)], x + y)
  173. def test_syzygy():
  174. R = QQ.old_poly_ring(x, y, z)
  175. M = R.free_module(1).submodule([x*y], [y*z], [x*z])
  176. S = R.free_module(3).submodule([0, x, -y], [z, -x, 0])
  177. assert M.syzygy_module() == S
  178. M2 = M / ([x*y*z],)
  179. S2 = R.free_module(3).submodule([z, 0, 0], [0, x, 0], [0, 0, y])
  180. assert M2.syzygy_module() == S2
  181. F = R.free_module(3)
  182. assert F.submodule(*F.basis()).syzygy_module() == F.submodule()
  183. R2 = QQ.old_poly_ring(x, y, z) / [x*y*z]
  184. M3 = R2.free_module(1).submodule([x*y], [y*z], [x*z])
  185. S3 = R2.free_module(3).submodule([z, 0, 0], [0, x, 0], [0, 0, y])
  186. assert M3.syzygy_module() == S3
  187. def test_in_terms_of_generators():
  188. R = QQ.old_poly_ring(x, order="ilex")
  189. M = R.free_module(2).submodule([2*x, 0], [1, 2])
  190. assert M.in_terms_of_generators(
  191. [x, x]) == [R.convert(Rational(1, 4)), R.convert(x/2)]
  192. raises(ValueError, lambda: M.in_terms_of_generators([1, 0]))
  193. M = R.free_module(2) / ([x, 0], [1, 1])
  194. SM = M.submodule([1, x])
  195. assert SM.in_terms_of_generators([2, 0]) == [R.convert(-2/(x - 1))]
  196. R = QQ.old_poly_ring(x, y) / [x**2 - y**2]
  197. M = R.free_module(2)
  198. SM = M.submodule([x, 0], [0, y])
  199. assert SM.in_terms_of_generators(
  200. [x**2, x**2]) == [R.convert(x), R.convert(y)]
  201. def test_QuotientModuleElement():
  202. R = QQ.old_poly_ring(x)
  203. F = R.free_module(3)
  204. N = F.submodule([1, x, x**2])
  205. M = F/N
  206. e = M.convert([x**2, 2, 0])
  207. assert M.convert([x + 1, x**2 + x, x**3 + x**2]) == 0
  208. assert e == [x**2, 2, 0] + N == F.convert([x**2, 2, 0]) + N == \
  209. M.convert(F.convert([x**2, 2, 0]))
  210. assert M.convert([x**2 + 1, 2*x + 2, x**2]) == e + [0, x, 0] == \
  211. e + M.convert([0, x, 0]) == e + F.convert([0, x, 0])
  212. assert M.convert([x**2 + 1, 2, x**2]) == e - [0, x, 0] == \
  213. e - M.convert([0, x, 0]) == e - F.convert([0, x, 0])
  214. assert M.convert([0, 2, 0]) == M.convert([x**2, 4, 0]) - e == \
  215. [x**2, 4, 0] - e == F.convert([x**2, 4, 0]) - e
  216. assert M.convert([x**3 + x**2, 2*x + 2, 0]) == (1 + x)*e == \
  217. R.convert(1 + x)*e == e*(1 + x) == e*R.convert(1 + x)
  218. assert -e == [-x**2, -2, 0]
  219. f = [x, x, 0] + N
  220. assert M.convert([1, 1, 0]) == f / x == f / R.convert(x)
  221. M2 = F/[(2, 2*x, 2*x**2), (0, 0, 1)]
  222. G = R.free_module(2)
  223. M3 = G/[[1, x]]
  224. M4 = F.submodule([1, x, x**2], [1, 0, 0]) / N
  225. raises(CoercionFailed, lambda: M.convert(G.convert([1, x])))
  226. raises(CoercionFailed, lambda: M.convert(M3.convert([1, x])))
  227. raises(CoercionFailed, lambda: M.convert(M2.convert([1, x, x])))
  228. assert M2.convert(M.convert([2, x, x**2])) == [2, x, 0]
  229. assert M.convert(M4.convert([2, 0, 0])) == [2, 0, 0]
  230. def test_QuotientModule():
  231. R = QQ.old_poly_ring(x)
  232. F = R.free_module(3)
  233. N = F.submodule([1, x, x**2])
  234. M = F/N
  235. assert M != F
  236. assert M != N
  237. assert M == F / [(1, x, x**2)]
  238. assert not M.is_zero()
  239. assert (F / F.basis()).is_zero()
  240. SQ = F.submodule([1, x, x**2], [2, 0, 0]) / N
  241. assert SQ == M.submodule([2, x, x**2])
  242. assert SQ != M.submodule([2, 1, 0])
  243. assert SQ != M
  244. assert M.is_submodule(SQ)
  245. assert not SQ.is_full_module()
  246. raises(ValueError, lambda: N/F)
  247. raises(ValueError, lambda: F.submodule([2, 0, 0]) / N)
  248. raises(ValueError, lambda: R.free_module(2)/F)
  249. raises(CoercionFailed, lambda: F.convert(M.convert([1, x, x**2])))
  250. M1 = F / [[1, 1, 1]]
  251. M2 = M1.submodule([1, 0, 0], [0, 1, 0])
  252. assert M1 == M2
  253. def test_ModulesQuotientRing():
  254. R = QQ.old_poly_ring(x, y, order=(("lex", x), ("ilex", y))) / [x**2 + 1]
  255. M1 = R.free_module(2)
  256. assert M1 == R.free_module(2)
  257. assert M1 != QQ.old_poly_ring(x).free_module(2)
  258. assert M1 != R.free_module(3)
  259. assert [x, 1] in M1
  260. assert [x] not in M1
  261. assert [1/(R.convert(x) + 1), 2] in M1
  262. assert [1, 2/(1 + y)] in M1
  263. assert [1, 2/y] not in M1
  264. assert M1.convert([x**2, y]) == [-1, y]
  265. F = R.free_module(3)
  266. Fd = F.submodule([x**2, 0, 0], [1, 2, 0], [1, 2, 3])
  267. M = F.submodule([x**2 + y**2, 1, 0], [x, y, 1])
  268. assert F == Fd
  269. assert Fd == F
  270. assert F != M
  271. assert M != F
  272. assert Fd != M
  273. assert M != Fd
  274. assert Fd == F.submodule(*F.basis())
  275. assert Fd.is_full_module()
  276. assert not M.is_full_module()
  277. assert not Fd.is_zero()
  278. assert not M.is_zero()
  279. assert Fd.submodule().is_zero()
  280. assert M.contains([x**2 + y**2 + x, -x**2 + y, 1])
  281. assert not M.contains([x**2 + y**2 + x, 1 + y, 2])
  282. assert M.contains([y**2, 1 - x*y, -x])
  283. assert F.submodule([x, 0, 0]) == F.submodule([1, 0, 0])
  284. assert not F.submodule([y, 0, 0]) == F.submodule([1, 0, 0])
  285. assert F.submodule([1, 0, 0], [0, 1, 0]).union(F.submodule([0, 0, 1])) == F
  286. assert not M.is_submodule(0)
  287. def test_module_mul():
  288. R = QQ.old_poly_ring(x)
  289. M = R.free_module(2)
  290. S1 = M.submodule([x, 0], [0, x])
  291. S2 = M.submodule([x**2, 0], [0, x**2])
  292. I = R.ideal(x)
  293. assert I*M == M*I == S1 == x*M == M*x
  294. assert I*S1 == S2 == x*S1
  295. def test_intersection():
  296. # SCA, example 2.8.5
  297. F = QQ.old_poly_ring(x, y).free_module(2)
  298. M1 = F.submodule([x, y], [y, 1])
  299. M2 = F.submodule([0, y - 1], [x, 1], [y, x])
  300. I = F.submodule([x, y], [y**2 - y, y - 1], [x*y + y, x + 1])
  301. I1, rel1, rel2 = M1.intersect(M2, relations=True)
  302. assert I1 == M2.intersect(M1) == I
  303. for i, g in enumerate(I1.gens):
  304. assert g == sum(c*x for c, x in zip(rel1[i], M1.gens)) \
  305. == sum(d*y for d, y in zip(rel2[i], M2.gens))
  306. assert F.submodule([x, y]).intersect(F.submodule([y, x])).is_zero()
  307. def test_quotient():
  308. # SCA, example 2.8.6
  309. R = QQ.old_poly_ring(x, y, z)
  310. F = R.free_module(2)
  311. assert F.submodule([x*y, x*z], [y*z, x*y]).module_quotient(
  312. F.submodule([y, z], [z, y])) == QQ.old_poly_ring(x, y, z).ideal(x**2*y**2 - x*y*z**2)
  313. assert F.submodule([x, y]).module_quotient(F.submodule()).is_whole_ring()
  314. M = F.submodule([x**2, x**2], [y**2, y**2])
  315. N = F.submodule([x + y, x + y])
  316. q, rel = M.module_quotient(N, relations=True)
  317. assert q == R.ideal(y**2, x - y)
  318. for i, g in enumerate(q.gens):
  319. assert g*N.gens[0] == sum(c*x for c, x in zip(rel[i], M.gens))
  320. def test_groebner_extendend():
  321. M = QQ.old_poly_ring(x, y, z).free_module(3).submodule([x + 1, y, 1], [x*y, z, z**2])
  322. G, R = M._groebner_vec(extended=True)
  323. for i, g in enumerate(G):
  324. assert g == sum(c*gen for c, gen in zip(R[i], M.gens))