test_groebnertools.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533
  1. """Tests for Groebner bases. """
  2. from sympy.polys.groebnertools import (
  3. groebner, sig, sig_key,
  4. lbp, lbp_key, critical_pair,
  5. cp_key, is_rewritable_or_comparable,
  6. Sign, Polyn, Num, s_poly, f5_reduce,
  7. groebner_lcm, groebner_gcd, is_groebner,
  8. is_reduced
  9. )
  10. from sympy.polys.fglmtools import _representing_matrices
  11. from sympy.polys.orderings import lex, grlex
  12. from sympy.polys.rings import ring, xring
  13. from sympy.polys.domains import ZZ, QQ
  14. from sympy.testing.pytest import slow
  15. from sympy.polys import polyconfig as config
  16. def _do_test_groebner():
  17. R, x,y = ring("x,y", QQ, lex)
  18. f = x**2 + 2*x*y**2
  19. g = x*y + 2*y**3 - 1
  20. assert groebner([f, g], R) == [x, y**3 - QQ(1,2)]
  21. R, y,x = ring("y,x", QQ, lex)
  22. f = 2*x**2*y + y**2
  23. g = 2*x**3 + x*y - 1
  24. assert groebner([f, g], R) == [y, x**3 - QQ(1,2)]
  25. R, x,y,z = ring("x,y,z", QQ, lex)
  26. f = x - z**2
  27. g = y - z**3
  28. assert groebner([f, g], R) == [f, g]
  29. R, x,y = ring("x,y", QQ, grlex)
  30. f = x**3 - 2*x*y
  31. g = x**2*y + x - 2*y**2
  32. assert groebner([f, g], R) == [x**2, x*y, -QQ(1,2)*x + y**2]
  33. R, x,y,z = ring("x,y,z", QQ, lex)
  34. f = -x**2 + y
  35. g = -x**3 + z
  36. assert groebner([f, g], R) == [x**2 - y, x*y - z, x*z - y**2, y**3 - z**2]
  37. R, x,y,z = ring("x,y,z", QQ, grlex)
  38. f = -x**2 + y
  39. g = -x**3 + z
  40. assert groebner([f, g], R) == [y**3 - z**2, x**2 - y, x*y - z, x*z - y**2]
  41. R, x,y,z = ring("x,y,z", QQ, lex)
  42. f = -x**2 + z
  43. g = -x**3 + y
  44. assert groebner([f, g], R) == [x**2 - z, x*y - z**2, x*z - y, y**2 - z**3]
  45. R, x,y,z = ring("x,y,z", QQ, grlex)
  46. f = -x**2 + z
  47. g = -x**3 + y
  48. assert groebner([f, g], R) == [-y**2 + z**3, x**2 - z, x*y - z**2, x*z - y]
  49. R, x,y,z = ring("x,y,z", QQ, lex)
  50. f = x - y**2
  51. g = -y**3 + z
  52. assert groebner([f, g], R) == [x - y**2, y**3 - z]
  53. R, x,y,z = ring("x,y,z", QQ, grlex)
  54. f = x - y**2
  55. g = -y**3 + z
  56. assert groebner([f, g], R) == [x**2 - y*z, x*y - z, -x + y**2]
  57. R, x,y,z = ring("x,y,z", QQ, lex)
  58. f = x - z**2
  59. g = y - z**3
  60. assert groebner([f, g], R) == [x - z**2, y - z**3]
  61. R, x,y,z = ring("x,y,z", QQ, grlex)
  62. f = x - z**2
  63. g = y - z**3
  64. assert groebner([f, g], R) == [x**2 - y*z, x*z - y, -x + z**2]
  65. R, x,y,z = ring("x,y,z", QQ, lex)
  66. f = -y**2 + z
  67. g = x - y**3
  68. assert groebner([f, g], R) == [x - y*z, y**2 - z]
  69. R, x,y,z = ring("x,y,z", QQ, grlex)
  70. f = -y**2 + z
  71. g = x - y**3
  72. assert groebner([f, g], R) == [-x**2 + z**3, x*y - z**2, y**2 - z, -x + y*z]
  73. R, x,y,z = ring("x,y,z", QQ, lex)
  74. f = y - z**2
  75. g = x - z**3
  76. assert groebner([f, g], R) == [x - z**3, y - z**2]
  77. R, x,y,z = ring("x,y,z", QQ, grlex)
  78. f = y - z**2
  79. g = x - z**3
  80. assert groebner([f, g], R) == [-x**2 + y**3, x*z - y**2, -x + y*z, -y + z**2]
  81. R, x,y,z = ring("x,y,z", QQ, lex)
  82. f = 4*x**2*y**2 + 4*x*y + 1
  83. g = x**2 + y**2 - 1
  84. assert groebner([f, g], R) == [
  85. x - 4*y**7 + 8*y**5 - 7*y**3 + 3*y,
  86. y**8 - 2*y**6 + QQ(3,2)*y**4 - QQ(1,2)*y**2 + QQ(1,16),
  87. ]
  88. def test_groebner_buchberger():
  89. with config.using(groebner='buchberger'):
  90. _do_test_groebner()
  91. def test_groebner_f5b():
  92. with config.using(groebner='f5b'):
  93. _do_test_groebner()
  94. def _do_test_benchmark_minpoly():
  95. R, x,y,z = ring("x,y,z", QQ, lex)
  96. F = [x**3 + x + 1, y**2 + y + 1, (x + y) * z - (x**2 + y)]
  97. G = [x + QQ(155,2067)*z**5 - QQ(355,689)*z**4 + QQ(6062,2067)*z**3 - QQ(3687,689)*z**2 + QQ(6878,2067)*z - QQ(25,53),
  98. y + QQ(4,53)*z**5 - QQ(91,159)*z**4 + QQ(523,159)*z**3 - QQ(387,53)*z**2 + QQ(1043,159)*z - QQ(308,159),
  99. z**6 - 7*z**5 + 41*z**4 - 82*z**3 + 89*z**2 - 46*z + 13]
  100. assert groebner(F, R) == G
  101. def test_benchmark_minpoly_buchberger():
  102. with config.using(groebner='buchberger'):
  103. _do_test_benchmark_minpoly()
  104. def test_benchmark_minpoly_f5b():
  105. with config.using(groebner='f5b'):
  106. _do_test_benchmark_minpoly()
  107. def test_benchmark_coloring():
  108. V = range(1, 12 + 1)
  109. E = [(1, 2), (2, 3), (1, 4), (1, 6), (1, 12), (2, 5), (2, 7), (3, 8), (3, 10),
  110. (4, 11), (4, 9), (5, 6), (6, 7), (7, 8), (8, 9), (9, 10), (10, 11),
  111. (11, 12), (5, 12), (5, 9), (6, 10), (7, 11), (8, 12), (3, 4)]
  112. R, V = xring([ "x%d" % v for v in V ], QQ, lex)
  113. E = [(V[i - 1], V[j - 1]) for i, j in E]
  114. x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12 = V
  115. I3 = [x**3 - 1 for x in V]
  116. Ig = [x**2 + x*y + y**2 for x, y in E]
  117. I = I3 + Ig
  118. assert groebner(I[:-1], R) == [
  119. x1 + x11 + x12,
  120. x2 - x11,
  121. x3 - x12,
  122. x4 - x12,
  123. x5 + x11 + x12,
  124. x6 - x11,
  125. x7 - x12,
  126. x8 + x11 + x12,
  127. x9 - x11,
  128. x10 + x11 + x12,
  129. x11**2 + x11*x12 + x12**2,
  130. x12**3 - 1,
  131. ]
  132. assert groebner(I, R) == [1]
  133. def _do_test_benchmark_katsura_3():
  134. R, x0,x1,x2 = ring("x:3", ZZ, lex)
  135. I = [x0 + 2*x1 + 2*x2 - 1,
  136. x0**2 + 2*x1**2 + 2*x2**2 - x0,
  137. 2*x0*x1 + 2*x1*x2 - x1]
  138. assert groebner(I, R) == [
  139. -7 + 7*x0 + 8*x2 + 158*x2**2 - 420*x2**3,
  140. 7*x1 + 3*x2 - 79*x2**2 + 210*x2**3,
  141. x2 + x2**2 - 40*x2**3 + 84*x2**4,
  142. ]
  143. R, x0,x1,x2 = ring("x:3", ZZ, grlex)
  144. I = [ i.set_ring(R) for i in I ]
  145. assert groebner(I, R) == [
  146. 7*x1 + 3*x2 - 79*x2**2 + 210*x2**3,
  147. -x1 + x2 - 3*x2**2 + 5*x1**2,
  148. -x1 - 4*x2 + 10*x1*x2 + 12*x2**2,
  149. -1 + x0 + 2*x1 + 2*x2,
  150. ]
  151. def test_benchmark_katsura3_buchberger():
  152. with config.using(groebner='buchberger'):
  153. _do_test_benchmark_katsura_3()
  154. def test_benchmark_katsura3_f5b():
  155. with config.using(groebner='f5b'):
  156. _do_test_benchmark_katsura_3()
  157. def _do_test_benchmark_katsura_4():
  158. R, x0,x1,x2,x3 = ring("x:4", ZZ, lex)
  159. I = [x0 + 2*x1 + 2*x2 + 2*x3 - 1,
  160. x0**2 + 2*x1**2 + 2*x2**2 + 2*x3**2 - x0,
  161. 2*x0*x1 + 2*x1*x2 + 2*x2*x3 - x1,
  162. x1**2 + 2*x0*x2 + 2*x1*x3 - x2]
  163. assert groebner(I, R) == [
  164. 5913075*x0 - 159690237696*x3**7 + 31246269696*x3**6 + 27439610544*x3**5 - 6475723368*x3**4 - 838935856*x3**3 + 275119624*x3**2 + 4884038*x3 - 5913075,
  165. 1971025*x1 - 97197721632*x3**7 + 73975630752*x3**6 - 12121915032*x3**5 - 2760941496*x3**4 + 814792828*x3**3 - 1678512*x3**2 - 9158924*x3,
  166. 5913075*x2 + 371438283744*x3**7 - 237550027104*x3**6 + 22645939824*x3**5 + 11520686172*x3**4 - 2024910556*x3**3 - 132524276*x3**2 + 30947828*x3,
  167. 128304*x3**8 - 93312*x3**7 + 15552*x3**6 + 3144*x3**5 -
  168. 1120*x3**4 + 36*x3**3 + 15*x3**2 - x3,
  169. ]
  170. R, x0,x1,x2,x3 = ring("x:4", ZZ, grlex)
  171. I = [ i.set_ring(R) for i in I ]
  172. assert groebner(I, R) == [
  173. 393*x1 - 4662*x2**2 + 4462*x2*x3 - 59*x2 + 224532*x3**4 - 91224*x3**3 - 678*x3**2 + 2046*x3,
  174. -x1 + 196*x2**3 - 21*x2**2 + 60*x2*x3 - 18*x2 - 168*x3**3 + 83*x3**2 - 9*x3,
  175. -6*x1 + 1134*x2**2*x3 - 189*x2**2 - 466*x2*x3 + 32*x2 - 630*x3**3 + 57*x3**2 + 51*x3,
  176. 33*x1 + 63*x2**2 + 2268*x2*x3**2 - 188*x2*x3 + 34*x2 + 2520*x3**3 - 849*x3**2 + 3*x3,
  177. 7*x1**2 - x1 - 7*x2**2 - 24*x2*x3 + 3*x2 - 15*x3**2 + 5*x3,
  178. 14*x1*x2 - x1 + 14*x2**2 + 18*x2*x3 - 4*x2 + 6*x3**2 - 2*x3,
  179. 14*x1*x3 - x1 + 7*x2**2 + 32*x2*x3 - 4*x2 + 27*x3**2 - 9*x3,
  180. x0 + 2*x1 + 2*x2 + 2*x3 - 1,
  181. ]
  182. def test_benchmark_kastura_4_buchberger():
  183. with config.using(groebner='buchberger'):
  184. _do_test_benchmark_katsura_4()
  185. def test_benchmark_kastura_4_f5b():
  186. with config.using(groebner='f5b'):
  187. _do_test_benchmark_katsura_4()
  188. def _do_test_benchmark_czichowski():
  189. R, x,t = ring("x,t", ZZ, lex)
  190. I = [9*x**8 + 36*x**7 - 32*x**6 - 252*x**5 - 78*x**4 + 468*x**3 + 288*x**2 - 108*x + 9,
  191. (-72 - 72*t)*x**7 + (-256 - 252*t)*x**6 + (192 + 192*t)*x**5 + (1280 + 1260*t)*x**4 + (312 + 312*t)*x**3 + (-404*t)*x**2 + (-576 - 576*t)*x + 96 + 108*t]
  192. assert groebner(I, R) == [
  193. 3725588592068034903797967297424801242396746870413359539263038139343329273586196480000*x -
  194. 160420835591776763325581422211936558925462474417709511019228211783493866564923546661604487873*t**7 -
  195. 1406108495478033395547109582678806497509499966197028487131115097902188374051595011248311352864*t**6 -
  196. 5241326875850889518164640374668786338033653548841427557880599579174438246266263602956254030352*t**5 -
  197. 10758917262823299139373269714910672770004760114329943852726887632013485035262879510837043892416*t**4 -
  198. 13119383576444715672578819534846747735372132018341964647712009275306635391456880068261130581248*t**3 -
  199. 9491412317016197146080450036267011389660653495578680036574753839055748080962214787557853941760*t**2 -
  200. 3767520915562795326943800040277726397326609797172964377014046018280260848046603967211258368000*t -
  201. 632314652371226552085897259159210286886724229880266931574701654721512325555116066073245696000,
  202. 610733380717522355121*t**8 +
  203. 6243748742141230639968*t**7 +
  204. 27761407182086143225024*t**6 +
  205. 70066148869420956398592*t**5 +
  206. 109701225644313784229376*t**4 +
  207. 109009005495588442152960*t**3 +
  208. 67072101084384786432000*t**2 +
  209. 23339979742629593088000*t +
  210. 3513592776846090240000,
  211. ]
  212. R, x,t = ring("x,t", ZZ, grlex)
  213. I = [ i.set_ring(R) for i in I ]
  214. assert groebner(I, R) == [
  215. 16996618586000601590732959134095643086442*t**3*x -
  216. 32936701459297092865176560282688198064839*t**3 +
  217. 78592411049800639484139414821529525782364*t**2*x -
  218. 120753953358671750165454009478961405619916*t**2 +
  219. 120988399875140799712152158915653654637280*t*x -
  220. 144576390266626470824138354942076045758736*t +
  221. 60017634054270480831259316163620768960*x**2 +
  222. 61976058033571109604821862786675242894400*x -
  223. 56266268491293858791834120380427754600960,
  224. 576689018321912327136790519059646508441672750656050290242749*t**4 +
  225. 2326673103677477425562248201573604572527893938459296513327336*t**3 +
  226. 110743790416688497407826310048520299245819959064297990236000*t**2*x +
  227. 3308669114229100853338245486174247752683277925010505284338016*t**2 +
  228. 323150205645687941261103426627818874426097912639158572428800*t*x +
  229. 1914335199925152083917206349978534224695445819017286960055680*t +
  230. 861662882561803377986838989464278045397192862768588480000*x**2 +
  231. 235296483281783440197069672204341465480107019878814196672000*x +
  232. 361850798943225141738895123621685122544503614946436727532800,
  233. -117584925286448670474763406733005510014188341867*t**3 +
  234. 68566565876066068463853874568722190223721653044*t**2*x -
  235. 435970731348366266878180788833437896139920683940*t**2 +
  236. 196297602447033751918195568051376792491869233408*t*x -
  237. 525011527660010557871349062870980202067479780112*t +
  238. 517905853447200553360289634770487684447317120*x**3 +
  239. 569119014870778921949288951688799397569321920*x**2 +
  240. 138877356748142786670127389526667463202210102080*x -
  241. 205109210539096046121625447192779783475018619520,
  242. -3725142681462373002731339445216700112264527*t**3 +
  243. 583711207282060457652784180668273817487940*t**2*x -
  244. 12381382393074485225164741437227437062814908*t**2 +
  245. 151081054097783125250959636747516827435040*t*x**2 +
  246. 1814103857455163948531448580501928933873280*t*x -
  247. 13353115629395094645843682074271212731433648*t +
  248. 236415091385250007660606958022544983766080*x**2 +
  249. 1390443278862804663728298060085399578417600*x -
  250. 4716885828494075789338754454248931750698880,
  251. ]
  252. # NOTE: This is very slow (> 2 minutes on 3.4 GHz) without GMPY
  253. @slow
  254. def test_benchmark_czichowski_buchberger():
  255. with config.using(groebner='buchberger'):
  256. _do_test_benchmark_czichowski()
  257. def test_benchmark_czichowski_f5b():
  258. with config.using(groebner='f5b'):
  259. _do_test_benchmark_czichowski()
  260. def _do_test_benchmark_cyclic_4():
  261. R, a,b,c,d = ring("a,b,c,d", ZZ, lex)
  262. I = [a + b + c + d,
  263. a*b + a*d + b*c + b*d,
  264. a*b*c + a*b*d + a*c*d + b*c*d,
  265. a*b*c*d - 1]
  266. assert groebner(I, R) == [
  267. 4*a + 3*d**9 - 4*d**5 - 3*d,
  268. 4*b + 4*c - 3*d**9 + 4*d**5 + 7*d,
  269. 4*c**2 + 3*d**10 - 4*d**6 - 3*d**2,
  270. 4*c*d**4 + 4*c - d**9 + 4*d**5 + 5*d, d**12 - d**8 - d**4 + 1
  271. ]
  272. R, a,b,c,d = ring("a,b,c,d", ZZ, grlex)
  273. I = [ i.set_ring(R) for i in I ]
  274. assert groebner(I, R) == [
  275. 3*b*c - c**2 + d**6 - 3*d**2,
  276. -b + 3*c**2*d**3 - c - d**5 - 4*d,
  277. -b + 3*c*d**4 + 2*c + 2*d**5 + 2*d,
  278. c**4 + 2*c**2*d**2 - d**4 - 2,
  279. c**3*d + c*d**3 + d**4 + 1,
  280. b*c**2 - c**3 - c**2*d - 2*c*d**2 - d**3,
  281. b**2 - c**2, b*d + c**2 + c*d + d**2,
  282. a + b + c + d
  283. ]
  284. def test_benchmark_cyclic_4_buchberger():
  285. with config.using(groebner='buchberger'):
  286. _do_test_benchmark_cyclic_4()
  287. def test_benchmark_cyclic_4_f5b():
  288. with config.using(groebner='f5b'):
  289. _do_test_benchmark_cyclic_4()
  290. def test_sig_key():
  291. s1 = sig((0,) * 3, 2)
  292. s2 = sig((1,) * 3, 4)
  293. s3 = sig((2,) * 3, 2)
  294. assert sig_key(s1, lex) > sig_key(s2, lex)
  295. assert sig_key(s2, lex) < sig_key(s3, lex)
  296. def test_lbp_key():
  297. R, x,y,z,t = ring("x,y,z,t", ZZ, lex)
  298. p1 = lbp(sig((0,) * 4, 3), R.zero, 12)
  299. p2 = lbp(sig((0,) * 4, 4), R.zero, 13)
  300. p3 = lbp(sig((0,) * 4, 4), R.zero, 12)
  301. assert lbp_key(p1) > lbp_key(p2)
  302. assert lbp_key(p2) < lbp_key(p3)
  303. def test_critical_pair():
  304. # from cyclic4 with grlex
  305. R, x,y,z,t = ring("x,y,z,t", QQ, grlex)
  306. p1 = (((0, 0, 0, 0), 4), y*z*t**2 + z**2*t**2 - t**4 - 1, 4)
  307. q1 = (((0, 0, 0, 0), 2), -y**2 - y*t - z*t - t**2, 2)
  308. p2 = (((0, 0, 0, 2), 3), z**3*t**2 + z**2*t**3 - z - t, 5)
  309. q2 = (((0, 0, 2, 2), 2), y*z + z*t**5 + z*t + t**6, 13)
  310. assert critical_pair(p1, q1, R) == (
  311. ((0, 0, 1, 2), 2), ((0, 0, 1, 2), QQ(-1, 1)), (((0, 0, 0, 0), 2), -y**2 - y*t - z*t - t**2, 2),
  312. ((0, 1, 0, 0), 4), ((0, 1, 0, 0), QQ(1, 1)), (((0, 0, 0, 0), 4), y*z*t**2 + z**2*t**2 - t**4 - 1, 4)
  313. )
  314. assert critical_pair(p2, q2, R) == (
  315. ((0, 0, 4, 2), 2), ((0, 0, 2, 0), QQ(1, 1)), (((0, 0, 2, 2), 2), y*z + z*t**5 + z*t + t**6, 13),
  316. ((0, 0, 0, 5), 3), ((0, 0, 0, 3), QQ(1, 1)), (((0, 0, 0, 2), 3), z**3*t**2 + z**2*t**3 - z - t, 5)
  317. )
  318. def test_cp_key():
  319. # from cyclic4 with grlex
  320. R, x,y,z,t = ring("x,y,z,t", QQ, grlex)
  321. p1 = (((0, 0, 0, 0), 4), y*z*t**2 + z**2*t**2 - t**4 - 1, 4)
  322. q1 = (((0, 0, 0, 0), 2), -y**2 - y*t - z*t - t**2, 2)
  323. p2 = (((0, 0, 0, 2), 3), z**3*t**2 + z**2*t**3 - z - t, 5)
  324. q2 = (((0, 0, 2, 2), 2), y*z + z*t**5 + z*t + t**6, 13)
  325. cp1 = critical_pair(p1, q1, R)
  326. cp2 = critical_pair(p2, q2, R)
  327. assert cp_key(cp1, R) < cp_key(cp2, R)
  328. cp1 = critical_pair(p1, p2, R)
  329. cp2 = critical_pair(q1, q2, R)
  330. assert cp_key(cp1, R) < cp_key(cp2, R)
  331. def test_is_rewritable_or_comparable():
  332. # from katsura4 with grlex
  333. R, x,y,z,t = ring("x,y,z,t", QQ, grlex)
  334. p = lbp(sig((0, 0, 2, 1), 2), R.zero, 2)
  335. B = [lbp(sig((0, 0, 0, 1), 2), QQ(2,45)*y**2 + QQ(1,5)*y*z + QQ(5,63)*y*t + z**2*t + QQ(4,45)*z**2 + QQ(76,35)*z*t**2 - QQ(32,105)*z*t + QQ(13,7)*t**3 - QQ(13,21)*t**2, 6)]
  336. # rewritable:
  337. assert is_rewritable_or_comparable(Sign(p), Num(p), B) is True
  338. p = lbp(sig((0, 1, 1, 0), 2), R.zero, 7)
  339. B = [lbp(sig((0, 0, 0, 0), 3), QQ(10,3)*y*z + QQ(4,3)*y*t - QQ(1,3)*y + 4*z**2 + QQ(22,3)*z*t - QQ(4,3)*z + 4*t**2 - QQ(4,3)*t, 3)]
  340. # comparable:
  341. assert is_rewritable_or_comparable(Sign(p), Num(p), B) is True
  342. def test_f5_reduce():
  343. # katsura3 with lex
  344. R, x,y,z = ring("x,y,z", QQ, lex)
  345. F = [(((0, 0, 0), 1), x + 2*y + 2*z - 1, 1),
  346. (((0, 0, 0), 2), 6*y**2 + 8*y*z - 2*y + 6*z**2 - 2*z, 2),
  347. (((0, 0, 0), 3), QQ(10,3)*y*z - QQ(1,3)*y + 4*z**2 - QQ(4,3)*z, 3),
  348. (((0, 0, 1), 2), y + 30*z**3 - QQ(79,7)*z**2 + QQ(3,7)*z, 4),
  349. (((0, 0, 2), 2), z**4 - QQ(10,21)*z**3 + QQ(1,84)*z**2 + QQ(1,84)*z, 5)]
  350. cp = critical_pair(F[0], F[1], R)
  351. s = s_poly(cp)
  352. assert f5_reduce(s, F) == (((0, 2, 0), 1), R.zero, 1)
  353. s = lbp(sig(Sign(s)[0], 100), Polyn(s), Num(s))
  354. assert f5_reduce(s, F) == s
  355. def test_representing_matrices():
  356. R, x,y = ring("x,y", QQ, grlex)
  357. basis = [(0, 0), (0, 1), (1, 0), (1, 1)]
  358. F = [x**2 - x - 3*y + 1, -2*x + y**2 + y - 1]
  359. assert _representing_matrices(basis, F, R) == [
  360. [[QQ(0, 1), QQ(0, 1),-QQ(1, 1), QQ(3, 1)],
  361. [QQ(0, 1), QQ(0, 1), QQ(3, 1),-QQ(4, 1)],
  362. [QQ(1, 1), QQ(0, 1), QQ(1, 1), QQ(6, 1)],
  363. [QQ(0, 1), QQ(1, 1), QQ(0, 1), QQ(1, 1)]],
  364. [[QQ(0, 1), QQ(1, 1), QQ(0, 1),-QQ(2, 1)],
  365. [QQ(1, 1),-QQ(1, 1), QQ(0, 1), QQ(6, 1)],
  366. [QQ(0, 1), QQ(2, 1), QQ(0, 1), QQ(3, 1)],
  367. [QQ(0, 1), QQ(0, 1), QQ(1, 1),-QQ(1, 1)]]]
  368. def test_groebner_lcm():
  369. R, x,y,z = ring("x,y,z", ZZ)
  370. assert groebner_lcm(x**2 - y**2, x - y) == x**2 - y**2
  371. assert groebner_lcm(2*x**2 - 2*y**2, 2*x - 2*y) == 2*x**2 - 2*y**2
  372. R, x,y,z = ring("x,y,z", QQ)
  373. assert groebner_lcm(x**2 - y**2, x - y) == x**2 - y**2
  374. assert groebner_lcm(2*x**2 - 2*y**2, 2*x - 2*y) == 2*x**2 - 2*y**2
  375. R, x,y = ring("x,y", ZZ)
  376. assert groebner_lcm(x**2*y, x*y**2) == x**2*y**2
  377. f = 2*x*y**5 - 3*x*y**4 - 2*x*y**3 + 3*x*y**2
  378. g = y**5 - 2*y**3 + y
  379. h = 2*x*y**7 - 3*x*y**6 - 4*x*y**5 + 6*x*y**4 + 2*x*y**3 - 3*x*y**2
  380. assert groebner_lcm(f, g) == h
  381. f = x**3 - 3*x**2*y - 9*x*y**2 - 5*y**3
  382. g = x**4 + 6*x**3*y + 12*x**2*y**2 + 10*x*y**3 + 3*y**4
  383. h = x**5 + x**4*y - 18*x**3*y**2 - 50*x**2*y**3 - 47*x*y**4 - 15*y**5
  384. assert groebner_lcm(f, g) == h
  385. def test_groebner_gcd():
  386. R, x,y,z = ring("x,y,z", ZZ)
  387. assert groebner_gcd(x**2 - y**2, x - y) == x - y
  388. assert groebner_gcd(2*x**2 - 2*y**2, 2*x - 2*y) == 2*x - 2*y
  389. R, x,y,z = ring("x,y,z", QQ)
  390. assert groebner_gcd(x**2 - y**2, x - y) == x - y
  391. assert groebner_gcd(2*x**2 - 2*y**2, 2*x - 2*y) == x - y
  392. def test_is_groebner():
  393. R, x,y = ring("x,y", QQ, grlex)
  394. valid_groebner = [x**2, x*y, -QQ(1,2)*x + y**2]
  395. invalid_groebner = [x**3, x*y, -QQ(1,2)*x + y**2]
  396. assert is_groebner(valid_groebner, R) is True
  397. assert is_groebner(invalid_groebner, R) is False
  398. def test_is_reduced():
  399. R, x, y = ring("x,y", QQ, lex)
  400. f = x**2 + 2*x*y**2
  401. g = x*y + 2*y**3 - 1
  402. assert is_reduced([f, g], R) == False
  403. G = groebner([f, g], R)
  404. assert is_reduced(G, R) == True