test_subfield.py 12 KB

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