test_galoistools.py 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867
  1. from sympy.polys.galoistools import (
  2. gf_crt, gf_crt1, gf_crt2, gf_int,
  3. gf_degree, gf_strip, gf_trunc, gf_normal,
  4. gf_from_dict, gf_to_dict,
  5. gf_from_int_poly, gf_to_int_poly,
  6. gf_neg, gf_add_ground, gf_sub_ground, gf_mul_ground,
  7. gf_add, gf_sub, gf_add_mul, gf_sub_mul, gf_mul, gf_sqr,
  8. gf_div, gf_rem, gf_quo, gf_exquo,
  9. gf_lshift, gf_rshift, gf_expand,
  10. gf_pow, gf_pow_mod,
  11. gf_gcdex, gf_gcd, gf_lcm, gf_cofactors,
  12. gf_LC, gf_TC, gf_monic,
  13. gf_eval, gf_multi_eval,
  14. gf_compose, gf_compose_mod,
  15. gf_trace_map,
  16. gf_diff,
  17. gf_irreducible, gf_irreducible_p,
  18. gf_irred_p_ben_or, gf_irred_p_rabin,
  19. gf_sqf_list, gf_sqf_part, gf_sqf_p,
  20. gf_Qmatrix, gf_Qbasis,
  21. gf_ddf_zassenhaus, gf_ddf_shoup,
  22. gf_edf_zassenhaus, gf_edf_shoup,
  23. gf_berlekamp,
  24. gf_factor_sqf, gf_factor,
  25. gf_value, linear_congruence, csolve_prime, gf_csolve,
  26. gf_frobenius_map, gf_frobenius_monomial_base
  27. )
  28. from sympy.polys.polyerrors import (
  29. ExactQuotientFailed,
  30. )
  31. from sympy.polys import polyconfig as config
  32. from sympy.polys.domains import ZZ
  33. from sympy.core.numbers import pi
  34. from sympy.ntheory.generate import nextprime
  35. from sympy.testing.pytest import raises
  36. def test_gf_crt():
  37. U = [49, 76, 65]
  38. M = [99, 97, 95]
  39. p = 912285
  40. u = 639985
  41. assert gf_crt(U, M, ZZ) == u
  42. E = [9215, 9405, 9603]
  43. S = [62, 24, 12]
  44. assert gf_crt1(M, ZZ) == (p, E, S)
  45. assert gf_crt2(U, M, p, E, S, ZZ) == u
  46. def test_gf_int():
  47. assert gf_int(0, 5) == 0
  48. assert gf_int(1, 5) == 1
  49. assert gf_int(2, 5) == 2
  50. assert gf_int(3, 5) == -2
  51. assert gf_int(4, 5) == -1
  52. assert gf_int(5, 5) == 0
  53. def test_gf_degree():
  54. assert gf_degree([]) == -1
  55. assert gf_degree([1]) == 0
  56. assert gf_degree([1, 0]) == 1
  57. assert gf_degree([1, 0, 0, 0, 1]) == 4
  58. def test_gf_strip():
  59. assert gf_strip([]) == []
  60. assert gf_strip([0]) == []
  61. assert gf_strip([0, 0, 0]) == []
  62. assert gf_strip([1]) == [1]
  63. assert gf_strip([0, 1]) == [1]
  64. assert gf_strip([0, 0, 0, 1]) == [1]
  65. assert gf_strip([1, 2, 0]) == [1, 2, 0]
  66. assert gf_strip([0, 1, 2, 0]) == [1, 2, 0]
  67. assert gf_strip([0, 0, 0, 1, 2, 0]) == [1, 2, 0]
  68. def test_gf_trunc():
  69. assert gf_trunc([], 11) == []
  70. assert gf_trunc([1], 11) == [1]
  71. assert gf_trunc([22], 11) == []
  72. assert gf_trunc([12], 11) == [1]
  73. assert gf_trunc([11, 22, 17, 1, 0], 11) == [6, 1, 0]
  74. assert gf_trunc([12, 23, 17, 1, 0], 11) == [1, 1, 6, 1, 0]
  75. def test_gf_normal():
  76. assert gf_normal([11, 22, 17, 1, 0], 11, ZZ) == [6, 1, 0]
  77. def test_gf_from_to_dict():
  78. f = {11: 12, 6: 2, 0: 25}
  79. F = {11: 1, 6: 2, 0: 3}
  80. g = [1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 3]
  81. assert gf_from_dict(f, 11, ZZ) == g
  82. assert gf_to_dict(g, 11) == F
  83. f = {11: -5, 4: 0, 3: 1, 0: 12}
  84. F = {11: -5, 3: 1, 0: 1}
  85. g = [6, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1]
  86. assert gf_from_dict(f, 11, ZZ) == g
  87. assert gf_to_dict(g, 11) == F
  88. assert gf_to_dict([10], 11, symmetric=True) == {0: -1}
  89. assert gf_to_dict([10], 11, symmetric=False) == {0: 10}
  90. def test_gf_from_to_int_poly():
  91. assert gf_from_int_poly([1, 0, 7, 2, 20], 5) == [1, 0, 2, 2, 0]
  92. assert gf_to_int_poly([1, 0, 4, 2, 3], 5) == [1, 0, -1, 2, -2]
  93. assert gf_to_int_poly([10], 11, symmetric=True) == [-1]
  94. assert gf_to_int_poly([10], 11, symmetric=False) == [10]
  95. def test_gf_LC():
  96. assert gf_LC([], ZZ) == 0
  97. assert gf_LC([1], ZZ) == 1
  98. assert gf_LC([1, 2], ZZ) == 1
  99. def test_gf_TC():
  100. assert gf_TC([], ZZ) == 0
  101. assert gf_TC([1], ZZ) == 1
  102. assert gf_TC([1, 2], ZZ) == 2
  103. def test_gf_monic():
  104. assert gf_monic(ZZ.map([]), 11, ZZ) == (0, [])
  105. assert gf_monic(ZZ.map([1]), 11, ZZ) == (1, [1])
  106. assert gf_monic(ZZ.map([2]), 11, ZZ) == (2, [1])
  107. assert gf_monic(ZZ.map([1, 2, 3, 4]), 11, ZZ) == (1, [1, 2, 3, 4])
  108. assert gf_monic(ZZ.map([2, 3, 4, 5]), 11, ZZ) == (2, [1, 7, 2, 8])
  109. def test_gf_arith():
  110. assert gf_neg([], 11, ZZ) == []
  111. assert gf_neg([1], 11, ZZ) == [10]
  112. assert gf_neg([1, 2, 3], 11, ZZ) == [10, 9, 8]
  113. assert gf_add_ground([], 0, 11, ZZ) == []
  114. assert gf_sub_ground([], 0, 11, ZZ) == []
  115. assert gf_add_ground([], 3, 11, ZZ) == [3]
  116. assert gf_sub_ground([], 3, 11, ZZ) == [8]
  117. assert gf_add_ground([1], 3, 11, ZZ) == [4]
  118. assert gf_sub_ground([1], 3, 11, ZZ) == [9]
  119. assert gf_add_ground([8], 3, 11, ZZ) == []
  120. assert gf_sub_ground([3], 3, 11, ZZ) == []
  121. assert gf_add_ground([1, 2, 3], 3, 11, ZZ) == [1, 2, 6]
  122. assert gf_sub_ground([1, 2, 3], 3, 11, ZZ) == [1, 2, 0]
  123. assert gf_mul_ground([], 0, 11, ZZ) == []
  124. assert gf_mul_ground([], 1, 11, ZZ) == []
  125. assert gf_mul_ground([1], 0, 11, ZZ) == []
  126. assert gf_mul_ground([1], 1, 11, ZZ) == [1]
  127. assert gf_mul_ground([1, 2, 3], 0, 11, ZZ) == []
  128. assert gf_mul_ground([1, 2, 3], 1, 11, ZZ) == [1, 2, 3]
  129. assert gf_mul_ground([1, 2, 3], 7, 11, ZZ) == [7, 3, 10]
  130. assert gf_add([], [], 11, ZZ) == []
  131. assert gf_add([1], [], 11, ZZ) == [1]
  132. assert gf_add([], [1], 11, ZZ) == [1]
  133. assert gf_add([1], [1], 11, ZZ) == [2]
  134. assert gf_add([1], [2], 11, ZZ) == [3]
  135. assert gf_add([1, 2], [1], 11, ZZ) == [1, 3]
  136. assert gf_add([1], [1, 2], 11, ZZ) == [1, 3]
  137. assert gf_add([1, 2, 3], [8, 9, 10], 11, ZZ) == [9, 0, 2]
  138. assert gf_sub([], [], 11, ZZ) == []
  139. assert gf_sub([1], [], 11, ZZ) == [1]
  140. assert gf_sub([], [1], 11, ZZ) == [10]
  141. assert gf_sub([1], [1], 11, ZZ) == []
  142. assert gf_sub([1], [2], 11, ZZ) == [10]
  143. assert gf_sub([1, 2], [1], 11, ZZ) == [1, 1]
  144. assert gf_sub([1], [1, 2], 11, ZZ) == [10, 10]
  145. assert gf_sub([3, 2, 1], [8, 9, 10], 11, ZZ) == [6, 4, 2]
  146. assert gf_add_mul(
  147. [1, 5, 6], [7, 3], [8, 0, 6, 1], 11, ZZ) == [1, 2, 10, 8, 9]
  148. assert gf_sub_mul(
  149. [1, 5, 6], [7, 3], [8, 0, 6, 1], 11, ZZ) == [10, 9, 3, 2, 3]
  150. assert gf_mul([], [], 11, ZZ) == []
  151. assert gf_mul([], [1], 11, ZZ) == []
  152. assert gf_mul([1], [], 11, ZZ) == []
  153. assert gf_mul([1], [1], 11, ZZ) == [1]
  154. assert gf_mul([5], [7], 11, ZZ) == [2]
  155. assert gf_mul([3, 0, 0, 6, 1, 2], [4, 0, 1, 0], 11, ZZ) == [1, 0,
  156. 3, 2, 4, 3, 1, 2, 0]
  157. assert gf_mul([4, 0, 1, 0], [3, 0, 0, 6, 1, 2], 11, ZZ) == [1, 0,
  158. 3, 2, 4, 3, 1, 2, 0]
  159. assert gf_mul([2, 0, 0, 1, 7], [2, 0, 0, 1, 7], 11, ZZ) == [4, 0,
  160. 0, 4, 6, 0, 1, 3, 5]
  161. assert gf_sqr([], 11, ZZ) == []
  162. assert gf_sqr([2], 11, ZZ) == [4]
  163. assert gf_sqr([1, 2], 11, ZZ) == [1, 4, 4]
  164. assert gf_sqr([2, 0, 0, 1, 7], 11, ZZ) == [4, 0, 0, 4, 6, 0, 1, 3, 5]
  165. def test_gf_division():
  166. raises(ZeroDivisionError, lambda: gf_div([1, 2, 3], [], 11, ZZ))
  167. raises(ZeroDivisionError, lambda: gf_rem([1, 2, 3], [], 11, ZZ))
  168. raises(ZeroDivisionError, lambda: gf_quo([1, 2, 3], [], 11, ZZ))
  169. raises(ZeroDivisionError, lambda: gf_quo([1, 2, 3], [], 11, ZZ))
  170. assert gf_div([1], [1, 2, 3], 7, ZZ) == ([], [1])
  171. assert gf_rem([1], [1, 2, 3], 7, ZZ) == [1]
  172. assert gf_quo([1], [1, 2, 3], 7, ZZ) == []
  173. f = ZZ.map([5, 4, 3, 2, 1, 0])
  174. g = ZZ.map([1, 2, 3])
  175. q = [5, 1, 0, 6]
  176. r = [3, 3]
  177. assert gf_div(f, g, 7, ZZ) == (q, r)
  178. assert gf_rem(f, g, 7, ZZ) == r
  179. assert gf_quo(f, g, 7, ZZ) == q
  180. raises(ExactQuotientFailed, lambda: gf_exquo(f, g, 7, ZZ))
  181. f = ZZ.map([5, 4, 3, 2, 1, 0])
  182. g = ZZ.map([1, 2, 3, 0])
  183. q = [5, 1, 0]
  184. r = [6, 1, 0]
  185. assert gf_div(f, g, 7, ZZ) == (q, r)
  186. assert gf_rem(f, g, 7, ZZ) == r
  187. assert gf_quo(f, g, 7, ZZ) == q
  188. raises(ExactQuotientFailed, lambda: gf_exquo(f, g, 7, ZZ))
  189. assert gf_quo(ZZ.map([1, 2, 1]), ZZ.map([1, 1]), 11, ZZ) == [1, 1]
  190. def test_gf_shift():
  191. f = [1, 2, 3, 4, 5]
  192. assert gf_lshift([], 5, ZZ) == []
  193. assert gf_rshift([], 5, ZZ) == ([], [])
  194. assert gf_lshift(f, 1, ZZ) == [1, 2, 3, 4, 5, 0]
  195. assert gf_lshift(f, 2, ZZ) == [1, 2, 3, 4, 5, 0, 0]
  196. assert gf_rshift(f, 0, ZZ) == (f, [])
  197. assert gf_rshift(f, 1, ZZ) == ([1, 2, 3, 4], [5])
  198. assert gf_rshift(f, 3, ZZ) == ([1, 2], [3, 4, 5])
  199. assert gf_rshift(f, 5, ZZ) == ([], f)
  200. def test_gf_expand():
  201. F = [([1, 1], 2), ([1, 2], 3)]
  202. assert gf_expand(F, 11, ZZ) == [1, 8, 3, 5, 6, 8]
  203. assert gf_expand((4, F), 11, ZZ) == [4, 10, 1, 9, 2, 10]
  204. def test_gf_powering():
  205. assert gf_pow([1, 0, 0, 1, 8], 0, 11, ZZ) == [1]
  206. assert gf_pow([1, 0, 0, 1, 8], 1, 11, ZZ) == [1, 0, 0, 1, 8]
  207. assert gf_pow([1, 0, 0, 1, 8], 2, 11, ZZ) == [1, 0, 0, 2, 5, 0, 1, 5, 9]
  208. assert gf_pow([1, 0, 0, 1, 8], 5, 11, ZZ) == \
  209. [1, 0, 0, 5, 7, 0, 10, 6, 2, 10, 9, 6, 10, 6, 6, 0, 5, 2, 5, 9, 10]
  210. assert gf_pow([1, 0, 0, 1, 8], 8, 11, ZZ) == \
  211. [1, 0, 0, 8, 9, 0, 6, 8, 10, 1, 2, 5, 10, 7, 7, 9, 1, 2, 0, 0, 6, 2,
  212. 5, 2, 5, 7, 7, 9, 10, 10, 7, 5, 5]
  213. assert gf_pow([1, 0, 0, 1, 8], 45, 11, ZZ) == \
  214. [ 1, 0, 0, 1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  215. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 4, 10, 0, 0, 0, 0, 0, 0,
  216. 10, 0, 0, 10, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  217. 6, 0, 0, 6, 4, 0, 0, 0, 0, 0, 0, 8, 0, 0, 8, 9, 0, 0, 0, 0, 0, 0,
  218. 10, 0, 0, 10, 3, 0, 0, 0, 0, 0, 0, 4, 0, 0, 4, 10, 0, 0, 0, 0, 0, 0,
  219. 8, 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 9, 0, 0, 9, 6, 0, 0, 0, 0, 0, 0,
  220. 3, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 3, 0, 0, 0, 0, 0, 0,
  221. 10, 0, 0, 10, 3, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 5, 0, 0, 0, 0, 0, 0,
  222. 4, 0, 0, 4, 10]
  223. assert gf_pow_mod(ZZ.map([1, 0, 0, 1, 8]), 0, ZZ.map([2, 0, 7]), 11, ZZ) == [1]
  224. assert gf_pow_mod(ZZ.map([1, 0, 0, 1, 8]), 1, ZZ.map([2, 0, 7]), 11, ZZ) == [1, 1]
  225. assert gf_pow_mod(ZZ.map([1, 0, 0, 1, 8]), 2, ZZ.map([2, 0, 7]), 11, ZZ) == [2, 3]
  226. assert gf_pow_mod(ZZ.map([1, 0, 0, 1, 8]), 5, ZZ.map([2, 0, 7]), 11, ZZ) == [7, 8]
  227. assert gf_pow_mod(ZZ.map([1, 0, 0, 1, 8]), 8, ZZ.map([2, 0, 7]), 11, ZZ) == [1, 5]
  228. assert gf_pow_mod(ZZ.map([1, 0, 0, 1, 8]), 45, ZZ.map([2, 0, 7]), 11, ZZ) == [5, 4]
  229. def test_gf_gcdex():
  230. assert gf_gcdex(ZZ.map([]), ZZ.map([]), 11, ZZ) == ([1], [], [])
  231. assert gf_gcdex(ZZ.map([2]), ZZ.map([]), 11, ZZ) == ([6], [], [1])
  232. assert gf_gcdex(ZZ.map([]), ZZ.map([2]), 11, ZZ) == ([], [6], [1])
  233. assert gf_gcdex(ZZ.map([2]), ZZ.map([2]), 11, ZZ) == ([], [6], [1])
  234. assert gf_gcdex(ZZ.map([]), ZZ.map([3, 0]), 11, ZZ) == ([], [4], [1, 0])
  235. assert gf_gcdex(ZZ.map([3, 0]), ZZ.map([]), 11, ZZ) == ([4], [], [1, 0])
  236. assert gf_gcdex(ZZ.map([3, 0]), ZZ.map([3, 0]), 11, ZZ) == ([], [4], [1, 0])
  237. assert gf_gcdex(ZZ.map([1, 8, 7]), ZZ.map([1, 7, 1, 7]), 11, ZZ) == ([5, 6], [6], [1, 7])
  238. def test_gf_gcd():
  239. assert gf_gcd(ZZ.map([]), ZZ.map([]), 11, ZZ) == []
  240. assert gf_gcd(ZZ.map([2]), ZZ.map([]), 11, ZZ) == [1]
  241. assert gf_gcd(ZZ.map([]), ZZ.map([2]), 11, ZZ) == [1]
  242. assert gf_gcd(ZZ.map([2]), ZZ.map([2]), 11, ZZ) == [1]
  243. assert gf_gcd(ZZ.map([]), ZZ.map([1, 0]), 11, ZZ) == [1, 0]
  244. assert gf_gcd(ZZ.map([1, 0]), ZZ.map([]), 11, ZZ) == [1, 0]
  245. assert gf_gcd(ZZ.map([3, 0]), ZZ.map([3, 0]), 11, ZZ) == [1, 0]
  246. assert gf_gcd(ZZ.map([1, 8, 7]), ZZ.map([1, 7, 1, 7]), 11, ZZ) == [1, 7]
  247. def test_gf_lcm():
  248. assert gf_lcm(ZZ.map([]), ZZ.map([]), 11, ZZ) == []
  249. assert gf_lcm(ZZ.map([2]), ZZ.map([]), 11, ZZ) == []
  250. assert gf_lcm(ZZ.map([]), ZZ.map([2]), 11, ZZ) == []
  251. assert gf_lcm(ZZ.map([2]), ZZ.map([2]), 11, ZZ) == [1]
  252. assert gf_lcm(ZZ.map([]), ZZ.map([1, 0]), 11, ZZ) == []
  253. assert gf_lcm(ZZ.map([1, 0]), ZZ.map([]), 11, ZZ) == []
  254. assert gf_lcm(ZZ.map([3, 0]), ZZ.map([3, 0]), 11, ZZ) == [1, 0]
  255. assert gf_lcm(ZZ.map([1, 8, 7]), ZZ.map([1, 7, 1, 7]), 11, ZZ) == [1, 8, 8, 8, 7]
  256. def test_gf_cofactors():
  257. assert gf_cofactors(ZZ.map([]), ZZ.map([]), 11, ZZ) == ([], [], [])
  258. assert gf_cofactors(ZZ.map([2]), ZZ.map([]), 11, ZZ) == ([1], [2], [])
  259. assert gf_cofactors(ZZ.map([]), ZZ.map([2]), 11, ZZ) == ([1], [], [2])
  260. assert gf_cofactors(ZZ.map([2]), ZZ.map([2]), 11, ZZ) == ([1], [2], [2])
  261. assert gf_cofactors(ZZ.map([]), ZZ.map([1, 0]), 11, ZZ) == ([1, 0], [], [1])
  262. assert gf_cofactors(ZZ.map([1, 0]), ZZ.map([]), 11, ZZ) == ([1, 0], [1], [])
  263. assert gf_cofactors(ZZ.map([3, 0]), ZZ.map([3, 0]), 11, ZZ) == (
  264. [1, 0], [3], [3])
  265. assert gf_cofactors(ZZ.map([1, 8, 7]), ZZ.map([1, 7, 1, 7]), 11, ZZ) == (
  266. ([1, 7], [1, 1], [1, 0, 1]))
  267. def test_gf_diff():
  268. assert gf_diff([], 11, ZZ) == []
  269. assert gf_diff([7], 11, ZZ) == []
  270. assert gf_diff([7, 3], 11, ZZ) == [7]
  271. assert gf_diff([7, 3, 1], 11, ZZ) == [3, 3]
  272. assert gf_diff([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 11, ZZ) == []
  273. def test_gf_eval():
  274. assert gf_eval([], 4, 11, ZZ) == 0
  275. assert gf_eval([], 27, 11, ZZ) == 0
  276. assert gf_eval([7], 4, 11, ZZ) == 7
  277. assert gf_eval([7], 27, 11, ZZ) == 7
  278. assert gf_eval([1, 0, 3, 2, 4, 3, 1, 2, 0], 0, 11, ZZ) == 0
  279. assert gf_eval([1, 0, 3, 2, 4, 3, 1, 2, 0], 4, 11, ZZ) == 9
  280. assert gf_eval([1, 0, 3, 2, 4, 3, 1, 2, 0], 27, 11, ZZ) == 5
  281. assert gf_eval([4, 0, 0, 4, 6, 0, 1, 3, 5], 0, 11, ZZ) == 5
  282. assert gf_eval([4, 0, 0, 4, 6, 0, 1, 3, 5], 4, 11, ZZ) == 3
  283. assert gf_eval([4, 0, 0, 4, 6, 0, 1, 3, 5], 27, 11, ZZ) == 9
  284. assert gf_multi_eval([3, 2, 1], [0, 1, 2, 3], 11, ZZ) == [1, 6, 6, 1]
  285. def test_gf_compose():
  286. assert gf_compose([], [1, 0], 11, ZZ) == []
  287. assert gf_compose_mod([], [1, 0], [1, 0], 11, ZZ) == []
  288. assert gf_compose([1], [], 11, ZZ) == [1]
  289. assert gf_compose([1, 0], [], 11, ZZ) == []
  290. assert gf_compose([1, 0], [1, 0], 11, ZZ) == [1, 0]
  291. f = ZZ.map([1, 1, 4, 9, 1])
  292. g = ZZ.map([1, 1, 1])
  293. h = ZZ.map([1, 0, 0, 2])
  294. assert gf_compose(g, h, 11, ZZ) == [1, 0, 0, 5, 0, 0, 7]
  295. assert gf_compose_mod(g, h, f, 11, ZZ) == [3, 9, 6, 10]
  296. def test_gf_trace_map():
  297. f = ZZ.map([1, 1, 4, 9, 1])
  298. a = [1, 1, 1]
  299. c = ZZ.map([1, 0])
  300. b = gf_pow_mod(c, 11, f, 11, ZZ)
  301. assert gf_trace_map(a, b, c, 0, f, 11, ZZ) == \
  302. ([1, 1, 1], [1, 1, 1])
  303. assert gf_trace_map(a, b, c, 1, f, 11, ZZ) == \
  304. ([5, 2, 10, 3], [5, 3, 0, 4])
  305. assert gf_trace_map(a, b, c, 2, f, 11, ZZ) == \
  306. ([5, 9, 5, 3], [10, 1, 5, 7])
  307. assert gf_trace_map(a, b, c, 3, f, 11, ZZ) == \
  308. ([1, 10, 6, 0], [7])
  309. assert gf_trace_map(a, b, c, 4, f, 11, ZZ) == \
  310. ([1, 1, 1], [1, 1, 8])
  311. assert gf_trace_map(a, b, c, 5, f, 11, ZZ) == \
  312. ([5, 2, 10, 3], [5, 3, 0, 0])
  313. assert gf_trace_map(a, b, c, 11, f, 11, ZZ) == \
  314. ([1, 10, 6, 0], [10])
  315. def test_gf_irreducible():
  316. assert gf_irreducible_p(gf_irreducible(1, 11, ZZ), 11, ZZ) is True
  317. assert gf_irreducible_p(gf_irreducible(2, 11, ZZ), 11, ZZ) is True
  318. assert gf_irreducible_p(gf_irreducible(3, 11, ZZ), 11, ZZ) is True
  319. assert gf_irreducible_p(gf_irreducible(4, 11, ZZ), 11, ZZ) is True
  320. assert gf_irreducible_p(gf_irreducible(5, 11, ZZ), 11, ZZ) is True
  321. assert gf_irreducible_p(gf_irreducible(6, 11, ZZ), 11, ZZ) is True
  322. assert gf_irreducible_p(gf_irreducible(7, 11, ZZ), 11, ZZ) is True
  323. def test_gf_irreducible_p():
  324. assert gf_irred_p_ben_or(ZZ.map([7]), 11, ZZ) is True
  325. assert gf_irred_p_ben_or(ZZ.map([7, 3]), 11, ZZ) is True
  326. assert gf_irred_p_ben_or(ZZ.map([7, 3, 1]), 11, ZZ) is False
  327. assert gf_irred_p_rabin(ZZ.map([7]), 11, ZZ) is True
  328. assert gf_irred_p_rabin(ZZ.map([7, 3]), 11, ZZ) is True
  329. assert gf_irred_p_rabin(ZZ.map([7, 3, 1]), 11, ZZ) is False
  330. config.setup('GF_IRRED_METHOD', 'ben-or')
  331. assert gf_irreducible_p(ZZ.map([7]), 11, ZZ) is True
  332. assert gf_irreducible_p(ZZ.map([7, 3]), 11, ZZ) is True
  333. assert gf_irreducible_p(ZZ.map([7, 3, 1]), 11, ZZ) is False
  334. config.setup('GF_IRRED_METHOD', 'rabin')
  335. assert gf_irreducible_p(ZZ.map([7]), 11, ZZ) is True
  336. assert gf_irreducible_p(ZZ.map([7, 3]), 11, ZZ) is True
  337. assert gf_irreducible_p(ZZ.map([7, 3, 1]), 11, ZZ) is False
  338. config.setup('GF_IRRED_METHOD', 'other')
  339. raises(KeyError, lambda: gf_irreducible_p([7], 11, ZZ))
  340. config.setup('GF_IRRED_METHOD')
  341. f = ZZ.map([1, 9, 9, 13, 16, 15, 6, 7, 7, 7, 10])
  342. g = ZZ.map([1, 7, 16, 7, 15, 13, 13, 11, 16, 10, 9])
  343. h = gf_mul(f, g, 17, ZZ)
  344. assert gf_irred_p_ben_or(f, 17, ZZ) is True
  345. assert gf_irred_p_ben_or(g, 17, ZZ) is True
  346. assert gf_irred_p_ben_or(h, 17, ZZ) is False
  347. assert gf_irred_p_rabin(f, 17, ZZ) is True
  348. assert gf_irred_p_rabin(g, 17, ZZ) is True
  349. assert gf_irred_p_rabin(h, 17, ZZ) is False
  350. def test_gf_squarefree():
  351. assert gf_sqf_list([], 11, ZZ) == (0, [])
  352. assert gf_sqf_list([1], 11, ZZ) == (1, [])
  353. assert gf_sqf_list([1, 1], 11, ZZ) == (1, [([1, 1], 1)])
  354. assert gf_sqf_p([], 11, ZZ) is True
  355. assert gf_sqf_p([1], 11, ZZ) is True
  356. assert gf_sqf_p([1, 1], 11, ZZ) is True
  357. f = gf_from_dict({11: 1, 0: 1}, 11, ZZ)
  358. assert gf_sqf_p(f, 11, ZZ) is False
  359. assert gf_sqf_list(f, 11, ZZ) == \
  360. (1, [([1, 1], 11)])
  361. f = [1, 5, 8, 4]
  362. assert gf_sqf_p(f, 11, ZZ) is False
  363. assert gf_sqf_list(f, 11, ZZ) == \
  364. (1, [([1, 1], 1),
  365. ([1, 2], 2)])
  366. assert gf_sqf_part(f, 11, ZZ) == [1, 3, 2]
  367. f = [1, 0, 0, 2, 0, 0, 2, 0, 0, 1, 0]
  368. assert gf_sqf_list(f, 3, ZZ) == \
  369. (1, [([1, 0], 1),
  370. ([1, 1], 3),
  371. ([1, 2], 6)])
  372. def test_gf_frobenius_map():
  373. f = ZZ.map([2, 0, 1, 0, 2, 2, 0, 2, 2, 2])
  374. g = ZZ.map([1,1,0,2,0,1,0,2,0,1])
  375. p = 3
  376. b = gf_frobenius_monomial_base(g, p, ZZ)
  377. h = gf_frobenius_map(f, g, b, p, ZZ)
  378. h1 = gf_pow_mod(f, p, g, p, ZZ)
  379. assert h == h1
  380. def test_gf_berlekamp():
  381. f = gf_from_int_poly([1, -3, 1, -3, -1, -3, 1], 11)
  382. Q = [[1, 0, 0, 0, 0, 0],
  383. [3, 5, 8, 8, 6, 5],
  384. [3, 6, 6, 1, 10, 0],
  385. [9, 4, 10, 3, 7, 9],
  386. [7, 8, 10, 0, 0, 8],
  387. [8, 10, 7, 8, 10, 8]]
  388. V = [[1, 0, 0, 0, 0, 0],
  389. [0, 1, 1, 1, 1, 0],
  390. [0, 0, 7, 9, 0, 1]]
  391. assert gf_Qmatrix(f, 11, ZZ) == Q
  392. assert gf_Qbasis(Q, 11, ZZ) == V
  393. assert gf_berlekamp(f, 11, ZZ) == \
  394. [[1, 1], [1, 5, 3], [1, 2, 3, 4]]
  395. f = ZZ.map([1, 0, 1, 0, 10, 10, 8, 2, 8])
  396. Q = ZZ.map([[1, 0, 0, 0, 0, 0, 0, 0],
  397. [2, 1, 7, 11, 10, 12, 5, 11],
  398. [3, 6, 4, 3, 0, 4, 7, 2],
  399. [4, 3, 6, 5, 1, 6, 2, 3],
  400. [2, 11, 8, 8, 3, 1, 3, 11],
  401. [6, 11, 8, 6, 2, 7, 10, 9],
  402. [5, 11, 7, 10, 0, 11, 7, 12],
  403. [3, 3, 12, 5, 0, 11, 9, 12]])
  404. V = [[1, 0, 0, 0, 0, 0, 0, 0],
  405. [0, 5, 5, 0, 9, 5, 1, 0],
  406. [0, 9, 11, 9, 10, 12, 0, 1]]
  407. assert gf_Qmatrix(f, 13, ZZ) == Q
  408. assert gf_Qbasis(Q, 13, ZZ) == V
  409. assert gf_berlekamp(f, 13, ZZ) == \
  410. [[1, 3], [1, 8, 4, 12], [1, 2, 3, 4, 6]]
  411. def test_gf_ddf():
  412. f = gf_from_dict({15: ZZ(1), 0: ZZ(-1)}, 11, ZZ)
  413. g = [([1, 0, 0, 0, 0, 10], 1),
  414. ([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2)]
  415. assert gf_ddf_zassenhaus(f, 11, ZZ) == g
  416. assert gf_ddf_shoup(f, 11, ZZ) == g
  417. f = gf_from_dict({63: ZZ(1), 0: ZZ(1)}, 2, ZZ)
  418. g = [([1, 1], 1),
  419. ([1, 1, 1], 2),
  420. ([1, 1, 1, 1, 1, 1, 1], 3),
  421. ([1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0,
  422. 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0,
  423. 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1], 6)]
  424. assert gf_ddf_zassenhaus(f, 2, ZZ) == g
  425. assert gf_ddf_shoup(f, 2, ZZ) == g
  426. f = gf_from_dict({6: ZZ(1), 5: ZZ(-1), 4: ZZ(1), 3: ZZ(1), 1: ZZ(-1)}, 3, ZZ)
  427. g = [([1, 1, 0], 1),
  428. ([1, 1, 0, 1, 2], 2)]
  429. assert gf_ddf_zassenhaus(f, 3, ZZ) == g
  430. assert gf_ddf_shoup(f, 3, ZZ) == g
  431. f = ZZ.map([1, 2, 5, 26, 677, 436, 791, 325, 456, 24, 577])
  432. g = [([1, 701], 1),
  433. ([1, 110, 559, 532, 694, 151, 110, 70, 735, 122], 9)]
  434. assert gf_ddf_zassenhaus(f, 809, ZZ) == g
  435. assert gf_ddf_shoup(f, 809, ZZ) == g
  436. p = ZZ(nextprime(int((2**15 * pi).evalf())))
  437. f = gf_from_dict({15: 1, 1: 1, 0: 1}, p, ZZ)
  438. g = [([1, 22730, 68144], 2),
  439. ([1, 64876, 83977, 10787, 12561, 68608, 52650, 88001, 84356], 4),
  440. ([1, 15347, 95022, 84569, 94508, 92335], 5)]
  441. assert gf_ddf_zassenhaus(f, p, ZZ) == g
  442. assert gf_ddf_shoup(f, p, ZZ) == g
  443. def test_gf_edf():
  444. f = ZZ.map([1, 1, 0, 1, 2])
  445. g = ZZ.map([[1, 0, 1], [1, 1, 2]])
  446. assert gf_edf_zassenhaus(f, 2, 3, ZZ) == g
  447. assert gf_edf_shoup(f, 2, 3, ZZ) == g
  448. def test_issue_23174():
  449. f = ZZ.map([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
  450. g = ZZ.map([[1, 0, 0, 1, 1, 1, 0, 0, 1], [1, 1, 1, 0, 1, 0, 1, 1, 1]])
  451. assert gf_edf_zassenhaus(f, 8, 2, ZZ) == g
  452. def test_gf_factor():
  453. assert gf_factor([], 11, ZZ) == (0, [])
  454. assert gf_factor([1], 11, ZZ) == (1, [])
  455. assert gf_factor([1, 1], 11, ZZ) == (1, [([1, 1], 1)])
  456. assert gf_factor_sqf([], 11, ZZ) == (0, [])
  457. assert gf_factor_sqf([1], 11, ZZ) == (1, [])
  458. assert gf_factor_sqf([1, 1], 11, ZZ) == (1, [[1, 1]])
  459. config.setup('GF_FACTOR_METHOD', 'berlekamp')
  460. assert gf_factor_sqf([], 11, ZZ) == (0, [])
  461. assert gf_factor_sqf([1], 11, ZZ) == (1, [])
  462. assert gf_factor_sqf([1, 1], 11, ZZ) == (1, [[1, 1]])
  463. config.setup('GF_FACTOR_METHOD', 'zassenhaus')
  464. assert gf_factor_sqf([], 11, ZZ) == (0, [])
  465. assert gf_factor_sqf([1], 11, ZZ) == (1, [])
  466. assert gf_factor_sqf([1, 1], 11, ZZ) == (1, [[1, 1]])
  467. config.setup('GF_FACTOR_METHOD', 'shoup')
  468. assert gf_factor_sqf(ZZ.map([]), 11, ZZ) == (0, [])
  469. assert gf_factor_sqf(ZZ.map([1]), 11, ZZ) == (1, [])
  470. assert gf_factor_sqf(ZZ.map([1, 1]), 11, ZZ) == (1, [[1, 1]])
  471. f, p = ZZ.map([1, 0, 0, 1, 0]), 2
  472. g = (1, [([1, 0], 1),
  473. ([1, 1], 1),
  474. ([1, 1, 1], 1)])
  475. config.setup('GF_FACTOR_METHOD', 'berlekamp')
  476. assert gf_factor(f, p, ZZ) == g
  477. config.setup('GF_FACTOR_METHOD', 'zassenhaus')
  478. assert gf_factor(f, p, ZZ) == g
  479. config.setup('GF_FACTOR_METHOD', 'shoup')
  480. assert gf_factor(f, p, ZZ) == g
  481. g = (1, [[1, 0],
  482. [1, 1],
  483. [1, 1, 1]])
  484. config.setup('GF_FACTOR_METHOD', 'berlekamp')
  485. assert gf_factor_sqf(f, p, ZZ) == g
  486. config.setup('GF_FACTOR_METHOD', 'zassenhaus')
  487. assert gf_factor_sqf(f, p, ZZ) == g
  488. config.setup('GF_FACTOR_METHOD', 'shoup')
  489. assert gf_factor_sqf(f, p, ZZ) == g
  490. f, p = gf_from_int_poly([1, -3, 1, -3, -1, -3, 1], 11), 11
  491. g = (1, [([1, 1], 1),
  492. ([1, 5, 3], 1),
  493. ([1, 2, 3, 4], 1)])
  494. config.setup('GF_FACTOR_METHOD', 'berlekamp')
  495. assert gf_factor(f, p, ZZ) == g
  496. config.setup('GF_FACTOR_METHOD', 'zassenhaus')
  497. assert gf_factor(f, p, ZZ) == g
  498. config.setup('GF_FACTOR_METHOD', 'shoup')
  499. assert gf_factor(f, p, ZZ) == g
  500. f, p = [1, 5, 8, 4], 11
  501. g = (1, [([1, 1], 1), ([1, 2], 2)])
  502. config.setup('GF_FACTOR_METHOD', 'berlekamp')
  503. assert gf_factor(f, p, ZZ) == g
  504. config.setup('GF_FACTOR_METHOD', 'zassenhaus')
  505. assert gf_factor(f, p, ZZ) == g
  506. config.setup('GF_FACTOR_METHOD', 'shoup')
  507. assert gf_factor(f, p, ZZ) == g
  508. f, p = [1, 1, 10, 1, 0, 10, 10, 10, 0, 0], 11
  509. g = (1, [([1, 0], 2), ([1, 9, 5], 1), ([1, 3, 0, 8, 5, 2], 1)])
  510. config.setup('GF_FACTOR_METHOD', 'berlekamp')
  511. assert gf_factor(f, p, ZZ) == g
  512. config.setup('GF_FACTOR_METHOD', 'zassenhaus')
  513. assert gf_factor(f, p, ZZ) == g
  514. config.setup('GF_FACTOR_METHOD', 'shoup')
  515. assert gf_factor(f, p, ZZ) == g
  516. f, p = gf_from_dict({32: 1, 0: 1}, 11, ZZ), 11
  517. g = (1, [([1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 10], 1),
  518. ([1, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 10], 1)])
  519. config.setup('GF_FACTOR_METHOD', 'berlekamp')
  520. assert gf_factor(f, p, ZZ) == g
  521. config.setup('GF_FACTOR_METHOD', 'zassenhaus')
  522. assert gf_factor(f, p, ZZ) == g
  523. config.setup('GF_FACTOR_METHOD', 'shoup')
  524. assert gf_factor(f, p, ZZ) == g
  525. f, p = gf_from_dict({32: ZZ(8), 0: ZZ(5)}, 11, ZZ), 11
  526. g = (8, [([1, 3], 1),
  527. ([1, 8], 1),
  528. ([1, 0, 9], 1),
  529. ([1, 2, 2], 1),
  530. ([1, 9, 2], 1),
  531. ([1, 0, 5, 0, 7], 1),
  532. ([1, 0, 6, 0, 7], 1),
  533. ([1, 0, 0, 0, 1, 0, 0, 0, 6], 1),
  534. ([1, 0, 0, 0, 10, 0, 0, 0, 6], 1)])
  535. config.setup('GF_FACTOR_METHOD', 'berlekamp')
  536. assert gf_factor(f, p, ZZ) == g
  537. config.setup('GF_FACTOR_METHOD', 'zassenhaus')
  538. assert gf_factor(f, p, ZZ) == g
  539. config.setup('GF_FACTOR_METHOD', 'shoup')
  540. assert gf_factor(f, p, ZZ) == g
  541. f, p = gf_from_dict({63: ZZ(8), 0: ZZ(5)}, 11, ZZ), 11
  542. g = (8, [([1, 7], 1),
  543. ([1, 4, 5], 1),
  544. ([1, 6, 8, 2], 1),
  545. ([1, 9, 9, 2], 1),
  546. ([1, 0, 0, 9, 0, 0, 4], 1),
  547. ([1, 2, 0, 8, 4, 6, 4], 1),
  548. ([1, 2, 3, 8, 0, 6, 4], 1),
  549. ([1, 2, 6, 0, 8, 4, 4], 1),
  550. ([1, 3, 3, 1, 6, 8, 4], 1),
  551. ([1, 5, 6, 0, 8, 6, 4], 1),
  552. ([1, 6, 2, 7, 9, 8, 4], 1),
  553. ([1, 10, 4, 7, 10, 7, 4], 1),
  554. ([1, 10, 10, 1, 4, 9, 4], 1)])
  555. config.setup('GF_FACTOR_METHOD', 'berlekamp')
  556. assert gf_factor(f, p, ZZ) == g
  557. config.setup('GF_FACTOR_METHOD', 'zassenhaus')
  558. assert gf_factor(f, p, ZZ) == g
  559. config.setup('GF_FACTOR_METHOD', 'shoup')
  560. assert gf_factor(f, p, ZZ) == g
  561. # Gathen polynomials: x**n + x + 1 (mod p > 2**n * pi)
  562. p = ZZ(nextprime(int((2**15 * pi).evalf())))
  563. f = gf_from_dict({15: 1, 1: 1, 0: 1}, p, ZZ)
  564. assert gf_sqf_p(f, p, ZZ) is True
  565. g = (1, [([1, 22730, 68144], 1),
  566. ([1, 81553, 77449, 86810, 4724], 1),
  567. ([1, 86276, 56779, 14859, 31575], 1),
  568. ([1, 15347, 95022, 84569, 94508, 92335], 1)])
  569. config.setup('GF_FACTOR_METHOD', 'zassenhaus')
  570. assert gf_factor(f, p, ZZ) == g
  571. config.setup('GF_FACTOR_METHOD', 'shoup')
  572. assert gf_factor(f, p, ZZ) == g
  573. g = (1, [[1, 22730, 68144],
  574. [1, 81553, 77449, 86810, 4724],
  575. [1, 86276, 56779, 14859, 31575],
  576. [1, 15347, 95022, 84569, 94508, 92335]])
  577. config.setup('GF_FACTOR_METHOD', 'zassenhaus')
  578. assert gf_factor_sqf(f, p, ZZ) == g
  579. config.setup('GF_FACTOR_METHOD', 'shoup')
  580. assert gf_factor_sqf(f, p, ZZ) == g
  581. # Shoup polynomials: f = a_0 x**n + a_1 x**(n-1) + ... + a_n
  582. # (mod p > 2**(n-2) * pi), where a_n = a_{n-1}**2 + 1, a_0 = 1
  583. p = ZZ(nextprime(int((2**4 * pi).evalf())))
  584. f = ZZ.map([1, 2, 5, 26, 41, 39, 38])
  585. assert gf_sqf_p(f, p, ZZ) is True
  586. g = (1, [([1, 44, 26], 1),
  587. ([1, 11, 25, 18, 30], 1)])
  588. config.setup('GF_FACTOR_METHOD', 'zassenhaus')
  589. assert gf_factor(f, p, ZZ) == g
  590. config.setup('GF_FACTOR_METHOD', 'shoup')
  591. assert gf_factor(f, p, ZZ) == g
  592. g = (1, [[1, 44, 26],
  593. [1, 11, 25, 18, 30]])
  594. config.setup('GF_FACTOR_METHOD', 'zassenhaus')
  595. assert gf_factor_sqf(f, p, ZZ) == g
  596. config.setup('GF_FACTOR_METHOD', 'shoup')
  597. assert gf_factor_sqf(f, p, ZZ) == g
  598. config.setup('GF_FACTOR_METHOD', 'other')
  599. raises(KeyError, lambda: gf_factor([1, 1], 11, ZZ))
  600. config.setup('GF_FACTOR_METHOD')
  601. def test_gf_csolve():
  602. assert gf_value([1, 7, 2, 4], 11) == 2204
  603. assert linear_congruence(4, 3, 5) == [2]
  604. assert linear_congruence(0, 3, 5) == []
  605. assert linear_congruence(6, 1, 4) == []
  606. assert linear_congruence(0, 5, 5) == [0, 1, 2, 3, 4]
  607. assert linear_congruence(3, 12, 15) == [4, 9, 14]
  608. assert linear_congruence(6, 0, 18) == [0, 3, 6, 9, 12, 15]
  609. # with power = 1
  610. assert csolve_prime([1, 3, 2, 17], 7) == [3]
  611. assert csolve_prime([1, 3, 1, 5], 5) == [0, 1]
  612. assert csolve_prime([3, 6, 9, 3], 3) == [0, 1, 2]
  613. # with power > 1
  614. assert csolve_prime(
  615. [1, 1, 223], 3, 4) == [4, 13, 22, 31, 40, 49, 58, 67, 76]
  616. assert csolve_prime([3, 5, 2, 25], 5, 3) == [16, 50, 99]
  617. assert csolve_prime([3, 2, 2, 49], 7, 3) == [147, 190, 234]
  618. assert gf_csolve([1, 1, 7], 189) == [13, 49, 76, 112, 139, 175]
  619. assert gf_csolve([1, 3, 4, 1, 30], 60) == [10, 30]
  620. assert gf_csolve([1, 1, 7], 15) == []