test_subfield.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. """Tests for the subfield problem and allied problems. """
  2. from sympy.core.numbers import (AlgebraicNumber, I, pi, Rational)
  3. from sympy.core.singleton import S
  4. from sympy.functions.elementary.exponential import exp
  5. from sympy.functions.elementary.miscellaneous import sqrt
  6. from sympy.external.gmpy import MPQ
  7. from sympy.polys.numberfields.subfield import (
  8. is_isomorphism_possible,
  9. field_isomorphism_pslq,
  10. field_isomorphism,
  11. primitive_element,
  12. to_number_field,
  13. )
  14. from sympy.polys.domains import QQ
  15. from sympy.polys.polyerrors import IsomorphismFailed
  16. from sympy.polys.polytools import Poly
  17. from sympy.polys.rootoftools import CRootOf
  18. from sympy.testing.pytest import raises
  19. from sympy.abc import x
  20. Q = Rational
  21. def test_field_isomorphism_pslq():
  22. a = AlgebraicNumber(I)
  23. b = AlgebraicNumber(I*sqrt(3))
  24. raises(NotImplementedError, lambda: field_isomorphism_pslq(a, b))
  25. a = AlgebraicNumber(sqrt(2))
  26. b = AlgebraicNumber(sqrt(3))
  27. c = AlgebraicNumber(sqrt(7))
  28. d = AlgebraicNumber(sqrt(2) + sqrt(3))
  29. e = AlgebraicNumber(sqrt(2) + sqrt(3) + sqrt(7))
  30. assert field_isomorphism_pslq(a, a) == [1, 0]
  31. assert field_isomorphism_pslq(a, b) is None
  32. assert field_isomorphism_pslq(a, c) is None
  33. assert field_isomorphism_pslq(a, d) == [Q(1, 2), 0, -Q(9, 2), 0]
  34. assert field_isomorphism_pslq(
  35. a, e) == [Q(1, 80), 0, -Q(1, 2), 0, Q(59, 20), 0]
  36. assert field_isomorphism_pslq(b, a) is None
  37. assert field_isomorphism_pslq(b, b) == [1, 0]
  38. assert field_isomorphism_pslq(b, c) is None
  39. assert field_isomorphism_pslq(b, d) == [-Q(1, 2), 0, Q(11, 2), 0]
  40. assert field_isomorphism_pslq(b, e) == [-Q(
  41. 3, 640), 0, Q(67, 320), 0, -Q(297, 160), 0, Q(313, 80), 0]
  42. assert field_isomorphism_pslq(c, a) is None
  43. assert field_isomorphism_pslq(c, b) is None
  44. assert field_isomorphism_pslq(c, c) == [1, 0]
  45. assert field_isomorphism_pslq(c, d) is None
  46. assert field_isomorphism_pslq(c, e) == [Q(
  47. 3, 640), 0, -Q(71, 320), 0, Q(377, 160), 0, -Q(469, 80), 0]
  48. assert field_isomorphism_pslq(d, a) is None
  49. assert field_isomorphism_pslq(d, b) is None
  50. assert field_isomorphism_pslq(d, c) is None
  51. assert field_isomorphism_pslq(d, d) == [1, 0]
  52. assert field_isomorphism_pslq(d, e) == [-Q(
  53. 3, 640), 0, Q(71, 320), 0, -Q(377, 160), 0, Q(549, 80), 0]
  54. assert field_isomorphism_pslq(e, a) is None
  55. assert field_isomorphism_pslq(e, b) is None
  56. assert field_isomorphism_pslq(e, c) is None
  57. assert field_isomorphism_pslq(e, d) is None
  58. assert field_isomorphism_pslq(e, e) == [1, 0]
  59. f = AlgebraicNumber(3*sqrt(2) + 8*sqrt(7) - 5)
  60. assert field_isomorphism_pslq(
  61. f, e) == [Q(3, 80), 0, -Q(139, 80), 0, Q(347, 20), 0, -Q(761, 20), -5]
  62. def test_field_isomorphism():
  63. assert field_isomorphism(3, sqrt(2)) == [3]
  64. assert field_isomorphism( I*sqrt(3), I*sqrt(3)/2) == [ 2, 0]
  65. assert field_isomorphism(-I*sqrt(3), I*sqrt(3)/2) == [-2, 0]
  66. assert field_isomorphism( I*sqrt(3), -I*sqrt(3)/2) == [-2, 0]
  67. assert field_isomorphism(-I*sqrt(3), -I*sqrt(3)/2) == [ 2, 0]
  68. assert field_isomorphism( 2*I*sqrt(3)/7, 5*I*sqrt(3)/3) == [ Rational(6, 35), 0]
  69. assert field_isomorphism(-2*I*sqrt(3)/7, 5*I*sqrt(3)/3) == [Rational(-6, 35), 0]
  70. assert field_isomorphism( 2*I*sqrt(3)/7, -5*I*sqrt(3)/3) == [Rational(-6, 35), 0]
  71. assert field_isomorphism(-2*I*sqrt(3)/7, -5*I*sqrt(3)/3) == [ Rational(6, 35), 0]
  72. assert field_isomorphism(
  73. 2*I*sqrt(3)/7 + 27, 5*I*sqrt(3)/3) == [ Rational(6, 35), 27]
  74. assert field_isomorphism(
  75. -2*I*sqrt(3)/7 + 27, 5*I*sqrt(3)/3) == [Rational(-6, 35), 27]
  76. assert field_isomorphism(
  77. 2*I*sqrt(3)/7 + 27, -5*I*sqrt(3)/3) == [Rational(-6, 35), 27]
  78. assert field_isomorphism(
  79. -2*I*sqrt(3)/7 + 27, -5*I*sqrt(3)/3) == [ Rational(6, 35), 27]
  80. p = AlgebraicNumber( sqrt(2) + sqrt(3))
  81. q = AlgebraicNumber(-sqrt(2) + sqrt(3))
  82. r = AlgebraicNumber( sqrt(2) - sqrt(3))
  83. s = AlgebraicNumber(-sqrt(2) - sqrt(3))
  84. pos_coeffs = [ S.Half, S.Zero, Rational(-9, 2), S.Zero]
  85. neg_coeffs = [Rational(-1, 2), S.Zero, Rational(9, 2), S.Zero]
  86. a = AlgebraicNumber(sqrt(2))
  87. assert is_isomorphism_possible(a, p) is True
  88. assert is_isomorphism_possible(a, q) is True
  89. assert is_isomorphism_possible(a, r) is True
  90. assert is_isomorphism_possible(a, s) is True
  91. assert field_isomorphism(a, p, fast=True) == pos_coeffs
  92. assert field_isomorphism(a, q, fast=True) == neg_coeffs
  93. assert field_isomorphism(a, r, fast=True) == pos_coeffs
  94. assert field_isomorphism(a, s, fast=True) == neg_coeffs
  95. assert field_isomorphism(a, p, fast=False) == pos_coeffs
  96. assert field_isomorphism(a, q, fast=False) == neg_coeffs
  97. assert field_isomorphism(a, r, fast=False) == pos_coeffs
  98. assert field_isomorphism(a, s, fast=False) == neg_coeffs
  99. a = AlgebraicNumber(-sqrt(2))
  100. assert is_isomorphism_possible(a, p) is True
  101. assert is_isomorphism_possible(a, q) is True
  102. assert is_isomorphism_possible(a, r) is True
  103. assert is_isomorphism_possible(a, s) is True
  104. assert field_isomorphism(a, p, fast=True) == neg_coeffs
  105. assert field_isomorphism(a, q, fast=True) == pos_coeffs
  106. assert field_isomorphism(a, r, fast=True) == neg_coeffs
  107. assert field_isomorphism(a, s, fast=True) == pos_coeffs
  108. assert field_isomorphism(a, p, fast=False) == neg_coeffs
  109. assert field_isomorphism(a, q, fast=False) == pos_coeffs
  110. assert field_isomorphism(a, r, fast=False) == neg_coeffs
  111. assert field_isomorphism(a, s, fast=False) == pos_coeffs
  112. pos_coeffs = [ S.Half, S.Zero, Rational(-11, 2), S.Zero]
  113. neg_coeffs = [Rational(-1, 2), S.Zero, Rational(11, 2), S.Zero]
  114. a = AlgebraicNumber(sqrt(3))
  115. assert is_isomorphism_possible(a, p) is True
  116. assert is_isomorphism_possible(a, q) is True
  117. assert is_isomorphism_possible(a, r) is True
  118. assert is_isomorphism_possible(a, s) is True
  119. assert field_isomorphism(a, p, fast=True) == neg_coeffs
  120. assert field_isomorphism(a, q, fast=True) == neg_coeffs
  121. assert field_isomorphism(a, r, fast=True) == pos_coeffs
  122. assert field_isomorphism(a, s, fast=True) == pos_coeffs
  123. assert field_isomorphism(a, p, fast=False) == neg_coeffs
  124. assert field_isomorphism(a, q, fast=False) == neg_coeffs
  125. assert field_isomorphism(a, r, fast=False) == pos_coeffs
  126. assert field_isomorphism(a, s, fast=False) == pos_coeffs
  127. a = AlgebraicNumber(-sqrt(3))
  128. assert is_isomorphism_possible(a, p) is True
  129. assert is_isomorphism_possible(a, q) is True
  130. assert is_isomorphism_possible(a, r) is True
  131. assert is_isomorphism_possible(a, s) is True
  132. assert field_isomorphism(a, p, fast=True) == pos_coeffs
  133. assert field_isomorphism(a, q, fast=True) == pos_coeffs
  134. assert field_isomorphism(a, r, fast=True) == neg_coeffs
  135. assert field_isomorphism(a, s, fast=True) == neg_coeffs
  136. assert field_isomorphism(a, p, fast=False) == pos_coeffs
  137. assert field_isomorphism(a, q, fast=False) == pos_coeffs
  138. assert field_isomorphism(a, r, fast=False) == neg_coeffs
  139. assert field_isomorphism(a, s, fast=False) == neg_coeffs
  140. pos_coeffs = [ Rational(3, 2), S.Zero, Rational(-33, 2), -S(8)]
  141. neg_coeffs = [Rational(-3, 2), S.Zero, Rational(33, 2), -S(8)]
  142. a = AlgebraicNumber(3*sqrt(3) - 8)
  143. assert is_isomorphism_possible(a, p) is True
  144. assert is_isomorphism_possible(a, q) is True
  145. assert is_isomorphism_possible(a, r) is True
  146. assert is_isomorphism_possible(a, s) is True
  147. assert field_isomorphism(a, p, fast=True) == neg_coeffs
  148. assert field_isomorphism(a, q, fast=True) == neg_coeffs
  149. assert field_isomorphism(a, r, fast=True) == pos_coeffs
  150. assert field_isomorphism(a, s, fast=True) == pos_coeffs
  151. assert field_isomorphism(a, p, fast=False) == neg_coeffs
  152. assert field_isomorphism(a, q, fast=False) == neg_coeffs
  153. assert field_isomorphism(a, r, fast=False) == pos_coeffs
  154. assert field_isomorphism(a, s, fast=False) == pos_coeffs
  155. a = AlgebraicNumber(3*sqrt(2) + 2*sqrt(3) + 1)
  156. pos_1_coeffs = [ S.Half, S.Zero, Rational(-5, 2), S.One]
  157. neg_5_coeffs = [Rational(-5, 2), S.Zero, Rational(49, 2), S.One]
  158. pos_5_coeffs = [ Rational(5, 2), S.Zero, Rational(-49, 2), S.One]
  159. neg_1_coeffs = [Rational(-1, 2), S.Zero, Rational(5, 2), S.One]
  160. assert is_isomorphism_possible(a, p) is True
  161. assert is_isomorphism_possible(a, q) is True
  162. assert is_isomorphism_possible(a, r) is True
  163. assert is_isomorphism_possible(a, s) is True
  164. assert field_isomorphism(a, p, fast=True) == pos_1_coeffs
  165. assert field_isomorphism(a, q, fast=True) == neg_5_coeffs
  166. assert field_isomorphism(a, r, fast=True) == pos_5_coeffs
  167. assert field_isomorphism(a, s, fast=True) == neg_1_coeffs
  168. assert field_isomorphism(a, p, fast=False) == pos_1_coeffs
  169. assert field_isomorphism(a, q, fast=False) == neg_5_coeffs
  170. assert field_isomorphism(a, r, fast=False) == pos_5_coeffs
  171. assert field_isomorphism(a, s, fast=False) == neg_1_coeffs
  172. a = AlgebraicNumber(sqrt(2))
  173. b = AlgebraicNumber(sqrt(3))
  174. c = AlgebraicNumber(sqrt(7))
  175. assert is_isomorphism_possible(a, b) is True
  176. assert is_isomorphism_possible(b, a) is True
  177. assert is_isomorphism_possible(c, p) is False
  178. assert field_isomorphism(sqrt(2), sqrt(3), fast=True) is None
  179. assert field_isomorphism(sqrt(3), sqrt(2), fast=True) is None
  180. assert field_isomorphism(sqrt(2), sqrt(3), fast=False) is None
  181. assert field_isomorphism(sqrt(3), sqrt(2), fast=False) is None
  182. a = AlgebraicNumber(sqrt(2))
  183. b = AlgebraicNumber(2 ** (S(1) / 3))
  184. assert is_isomorphism_possible(a, b) is False
  185. assert field_isomorphism(a, b) is None
  186. def test_primitive_element():
  187. assert primitive_element([sqrt(2)], x) == (x**2 - 2, [1])
  188. assert primitive_element(
  189. [sqrt(2), sqrt(3)], x) == (x**4 - 10*x**2 + 1, [1, 1])
  190. assert primitive_element([sqrt(2)], x, polys=True) == (Poly(x**2 - 2, domain='QQ'), [1])
  191. assert primitive_element([sqrt(
  192. 2), sqrt(3)], x, polys=True) == (Poly(x**4 - 10*x**2 + 1, domain='QQ'), [1, 1])
  193. assert primitive_element(
  194. [sqrt(2)], x, ex=True) == (x**2 - 2, [1], [[1, 0]])
  195. assert primitive_element([sqrt(2), sqrt(3)], x, ex=True) == \
  196. (x**4 - 10*x**2 + 1, [1, 1], [[Q(1, 2), 0, -Q(9, 2), 0], [-
  197. Q(1, 2), 0, Q(11, 2), 0]])
  198. assert primitive_element(
  199. [sqrt(2)], x, ex=True, polys=True) == (Poly(x**2 - 2, domain='QQ'), [1], [[1, 0]])
  200. assert primitive_element([sqrt(2), sqrt(3)], x, ex=True, polys=True) == \
  201. (Poly(x**4 - 10*x**2 + 1, domain='QQ'), [1, 1], [[Q(1, 2), 0, -Q(9, 2),
  202. 0], [-Q(1, 2), 0, Q(11, 2), 0]])
  203. assert primitive_element([sqrt(2)], polys=True) == (Poly(x**2 - 2), [1])
  204. raises(ValueError, lambda: primitive_element([], x, ex=False))
  205. raises(ValueError, lambda: primitive_element([], x, ex=True))
  206. # Issue 14117
  207. a, b = I*sqrt(2*sqrt(2) + 3), I*sqrt(-2*sqrt(2) + 3)
  208. assert primitive_element([a, b, I], x) == (x**4 + 6*x**2 + 1, [1, 0, 0])
  209. assert primitive_element([sqrt(2), 0], x) == (x**2 - 2, [1, 0])
  210. assert primitive_element([0, sqrt(2)], x) == (x**2 - 2, [1, 1])
  211. assert primitive_element([sqrt(2), 0], x, ex=True) == (x**2 - 2, [1, 0], [[MPQ(1,1), MPQ(0,1)], []])
  212. assert primitive_element([0, sqrt(2)], x, ex=True) == (x**2 - 2, [1, 1], [[], [MPQ(1,1), MPQ(0,1)]])
  213. def test_to_number_field():
  214. assert to_number_field(sqrt(2)) == AlgebraicNumber(sqrt(2))
  215. assert to_number_field(
  216. [sqrt(2), sqrt(3)]) == AlgebraicNumber(sqrt(2) + sqrt(3))
  217. a = AlgebraicNumber(sqrt(2) + sqrt(3), [S.Half, S.Zero, Rational(-9, 2), S.Zero])
  218. assert to_number_field(sqrt(2), sqrt(2) + sqrt(3)) == a
  219. assert to_number_field(sqrt(2), AlgebraicNumber(sqrt(2) + sqrt(3))) == a
  220. raises(IsomorphismFailed, lambda: to_number_field(sqrt(2), sqrt(3)))
  221. def test_issue_22561():
  222. a = to_number_field(sqrt(2), sqrt(2) + sqrt(3))
  223. b = to_number_field(sqrt(2), sqrt(2) + sqrt(5))
  224. assert field_isomorphism(a, b) == [1, 0]
  225. def test_issue_22736():
  226. a = CRootOf(x**4 + x**3 + x**2 + x + 1, -1)
  227. a._reset()
  228. b = exp(2*I*pi/5)
  229. assert field_isomorphism(a, b) == [1, 0]
  230. def test_issue_27798():
  231. # https://github.com/sympy/sympy/issues/27798
  232. a, b = CRootOf(49*x**3 - 49*x**2 + 14*x - 1, 2), CRootOf(49*x**3 - 49*x**2 + 14*x - 1, 0)
  233. assert primitive_element([a, b], polys=True)[0].primitive()[0] == 1
  234. assert primitive_element([a, b], polys=True, ex=True)[0].primitive()[0] == 1
  235. f1, f2 = QQ.algebraic_field(a), QQ.algebraic_field(b)
  236. f3 = f1.unify(f2)
  237. assert f3.mod.primitive()[0] == 1
  238. assert Poly(x, x, domain=f1) + Poly(x, x, domain=f2) == Poly(2*x, x, domain=f3)