test_fields.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. """Test sparse rational functions. """
  2. from sympy.polys.fields import field, sfield, FracField, FracElement
  3. from sympy.polys.rings import ring
  4. from sympy.polys.domains import ZZ, QQ
  5. from sympy.polys.orderings import lex
  6. from sympy.testing.pytest import raises, XFAIL
  7. from sympy.core import symbols, E
  8. from sympy.core.numbers import Rational
  9. from sympy.functions.elementary.exponential import (exp, log)
  10. from sympy.functions.elementary.miscellaneous import sqrt
  11. def test_FracField___init__():
  12. F1 = FracField("x,y", ZZ, lex)
  13. F2 = FracField("x,y", ZZ, lex)
  14. F3 = FracField("x,y,z", ZZ, lex)
  15. assert F1.x == F1.gens[0]
  16. assert F1.y == F1.gens[1]
  17. assert F1.x == F2.x
  18. assert F1.y == F2.y
  19. assert F1.x != F3.x
  20. assert F1.y != F3.y
  21. def test_FracField___hash__():
  22. F, x, y, z = field("x,y,z", QQ)
  23. assert hash(F)
  24. def test_FracField___eq__():
  25. assert field("x,y,z", QQ)[0] == field("x,y,z", QQ)[0]
  26. assert field("x,y,z", QQ)[0] is field("x,y,z", QQ)[0]
  27. assert field("x,y,z", QQ)[0] != field("x,y,z", ZZ)[0]
  28. assert field("x,y,z", QQ)[0] is not field("x,y,z", ZZ)[0]
  29. assert field("x,y,z", ZZ)[0] != field("x,y,z", QQ)[0]
  30. assert field("x,y,z", ZZ)[0] is not field("x,y,z", QQ)[0]
  31. assert field("x,y,z", QQ)[0] != field("x,y", QQ)[0]
  32. assert field("x,y,z", QQ)[0] is not field("x,y", QQ)[0]
  33. assert field("x,y", QQ)[0] != field("x,y,z", QQ)[0]
  34. assert field("x,y", QQ)[0] is not field("x,y,z", QQ)[0]
  35. def test_sfield():
  36. x = symbols("x")
  37. F = FracField((E, exp(exp(x)), exp(x)), ZZ, lex)
  38. e, exex, ex = F.gens
  39. assert sfield(exp(x)*exp(exp(x) + 1 + log(exp(x) + 3)/2)**2/(exp(x) + 3)) \
  40. == (F, e**2*exex**2*ex)
  41. F = FracField((x, exp(1/x), log(x), x**QQ(1, 3)), ZZ, lex)
  42. _, ex, lg, x3 = F.gens
  43. assert sfield(((x-3)*log(x)+4*x**2)*exp(1/x+log(x)/3)/x**2) == \
  44. (F, (4*F.x**2*ex + F.x*ex*lg - 3*ex*lg)/x3**5)
  45. F = FracField((x, log(x), sqrt(x + log(x))), ZZ, lex)
  46. _, lg, srt = F.gens
  47. assert sfield((x + 1) / (x * (x + log(x))**QQ(3, 2)) - 1/(x * log(x)**2)) \
  48. == (F, (F.x*lg**2 - F.x*srt + lg**2 - lg*srt)/
  49. (F.x**2*lg**2*srt + F.x*lg**3*srt))
  50. def test_FracElement___hash__():
  51. F, x, y, z = field("x,y,z", QQ)
  52. assert hash(x*y/z)
  53. def test_FracElement_copy():
  54. F, x, y, z = field("x,y,z", ZZ)
  55. f = x*y/3*z
  56. g = f.copy()
  57. assert f == g
  58. g.numer[(1, 1, 1)] = 7
  59. assert f != g
  60. def test_FracElement_as_expr():
  61. F, x, y, z = field("x,y,z", ZZ)
  62. f = (3*x**2*y - x*y*z)/(7*z**3 + 1)
  63. X, Y, Z = F.symbols
  64. g = (3*X**2*Y - X*Y*Z)/(7*Z**3 + 1)
  65. assert f != g
  66. assert f.as_expr() == g
  67. X, Y, Z = symbols("x,y,z")
  68. g = (3*X**2*Y - X*Y*Z)/(7*Z**3 + 1)
  69. assert f != g
  70. assert f.as_expr(X, Y, Z) == g
  71. raises(ValueError, lambda: f.as_expr(X))
  72. def test_FracElement_from_expr():
  73. x, y, z = symbols("x,y,z")
  74. F, X, Y, Z = field((x, y, z), ZZ)
  75. f = F.from_expr(1)
  76. assert f == 1 and isinstance(f, F.dtype)
  77. f = F.from_expr(Rational(3, 7))
  78. assert f == F(3)/7 and isinstance(f, F.dtype)
  79. f = F.from_expr(x)
  80. assert f == X and isinstance(f, F.dtype)
  81. f = F.from_expr(Rational(3,7)*x)
  82. assert f == X*Rational(3, 7) and isinstance(f, F.dtype)
  83. f = F.from_expr(1/x)
  84. assert f == 1/X and isinstance(f, F.dtype)
  85. f = F.from_expr(x*y*z)
  86. assert f == X*Y*Z and isinstance(f, F.dtype)
  87. f = F.from_expr(x*y/z)
  88. assert f == X*Y/Z and isinstance(f, F.dtype)
  89. f = F.from_expr(x*y*z + x*y + x)
  90. assert f == X*Y*Z + X*Y + X and isinstance(f, F.dtype)
  91. f = F.from_expr((x*y*z + x*y + x)/(x*y + 7))
  92. assert f == (X*Y*Z + X*Y + X)/(X*Y + 7) and isinstance(f, F.dtype)
  93. f = F.from_expr(x**3*y*z + x**2*y**7 + 1)
  94. assert f == X**3*Y*Z + X**2*Y**7 + 1 and isinstance(f, F.dtype)
  95. raises(ValueError, lambda: F.from_expr(2**x))
  96. raises(ValueError, lambda: F.from_expr(7*x + sqrt(2)))
  97. assert isinstance(ZZ[2**x].get_field().convert(2**(-x)),
  98. FracElement)
  99. assert isinstance(ZZ[x**2].get_field().convert(x**(-6)),
  100. FracElement)
  101. assert isinstance(ZZ[exp(Rational(1, 3))].get_field().convert(E),
  102. FracElement)
  103. def test_FracField_nested():
  104. a, b, x = symbols('a b x')
  105. F1 = ZZ.frac_field(a, b)
  106. F2 = F1.frac_field(x)
  107. frac = F2(a + b)
  108. assert frac.numer == F1.poly_ring(x)(a + b)
  109. assert frac.numer.coeffs() == [F1(a + b)]
  110. assert frac.denom == F1.poly_ring(x)(1)
  111. F3 = ZZ.poly_ring(a, b)
  112. F4 = F3.frac_field(x)
  113. frac = F4(a + b)
  114. assert frac.numer == F3.poly_ring(x)(a + b)
  115. assert frac.numer.coeffs() == [F3(a + b)]
  116. assert frac.denom == F3.poly_ring(x)(1)
  117. frac = F2(F3(a + b))
  118. assert frac.numer == F1.poly_ring(x)(a + b)
  119. assert frac.numer.coeffs() == [F1(a + b)]
  120. assert frac.denom == F1.poly_ring(x)(1)
  121. frac = F4(F1(a + b))
  122. assert frac.numer == F3.poly_ring(x)(a + b)
  123. assert frac.numer.coeffs() == [F3(a + b)]
  124. assert frac.denom == F3.poly_ring(x)(1)
  125. def test_FracElement__lt_le_gt_ge__():
  126. F, x, y = field("x,y", ZZ)
  127. assert F(1) < 1/x < 1/x**2 < 1/x**3
  128. assert F(1) <= 1/x <= 1/x**2 <= 1/x**3
  129. assert -7/x < 1/x < 3/x < y/x < 1/x**2
  130. assert -7/x <= 1/x <= 3/x <= y/x <= 1/x**2
  131. assert 1/x**3 > 1/x**2 > 1/x > F(1)
  132. assert 1/x**3 >= 1/x**2 >= 1/x >= F(1)
  133. assert 1/x**2 > y/x > 3/x > 1/x > -7/x
  134. assert 1/x**2 >= y/x >= 3/x >= 1/x >= -7/x
  135. def test_FracElement___neg__():
  136. F, x,y = field("x,y", QQ)
  137. f = (7*x - 9)/y
  138. g = (-7*x + 9)/y
  139. assert -f == g
  140. assert -g == f
  141. def test_FracElement___add__():
  142. F, x,y = field("x,y", QQ)
  143. f, g = 1/x, 1/y
  144. assert f + g == g + f == (x + y)/(x*y)
  145. assert x + F.ring.gens[0] == F.ring.gens[0] + x == 2*x
  146. F, x,y = field("x,y", ZZ)
  147. assert x + 3 == 3 + x
  148. assert x + QQ(3,7) == QQ(3,7) + x == (7*x + 3)/7
  149. Fuv, u,v = field("u,v", ZZ)
  150. Fxyzt, x,y,z,t = field("x,y,z,t", Fuv)
  151. f = (u*v + x)/(y + u*v)
  152. assert dict(f.numer) == {(1, 0, 0, 0): 1, (0, 0, 0, 0): u*v}
  153. assert dict(f.denom) == {(0, 1, 0, 0): 1, (0, 0, 0, 0): u*v}
  154. Ruv, u,v = ring("u,v", ZZ)
  155. Fxyzt, x,y,z,t = field("x,y,z,t", Ruv)
  156. f = (u*v + x)/(y + u*v)
  157. assert dict(f.numer) == {(1, 0, 0, 0): 1, (0, 0, 0, 0): u*v}
  158. assert dict(f.denom) == {(0, 1, 0, 0): 1, (0, 0, 0, 0): u*v}
  159. def test_FracElement___sub__():
  160. F, x,y = field("x,y", QQ)
  161. f, g = 1/x, 1/y
  162. assert f - g == (-x + y)/(x*y)
  163. assert x - F.ring.gens[0] == F.ring.gens[0] - x == 0
  164. F, x,y = field("x,y", ZZ)
  165. assert x - 3 == -(3 - x)
  166. assert x - QQ(3,7) == -(QQ(3,7) - x) == (7*x - 3)/7
  167. Fuv, u,v = field("u,v", ZZ)
  168. Fxyzt, x,y,z,t = field("x,y,z,t", Fuv)
  169. f = (u*v - x)/(y - u*v)
  170. assert dict(f.numer) == {(1, 0, 0, 0):-1, (0, 0, 0, 0): u*v}
  171. assert dict(f.denom) == {(0, 1, 0, 0): 1, (0, 0, 0, 0):-u*v}
  172. Ruv, u,v = ring("u,v", ZZ)
  173. Fxyzt, x,y,z,t = field("x,y,z,t", Ruv)
  174. f = (u*v - x)/(y - u*v)
  175. assert dict(f.numer) == {(1, 0, 0, 0):-1, (0, 0, 0, 0): u*v}
  176. assert dict(f.denom) == {(0, 1, 0, 0): 1, (0, 0, 0, 0):-u*v}
  177. def test_FracElement___mul__():
  178. F, x,y = field("x,y", QQ)
  179. f, g = 1/x, 1/y
  180. assert f*g == g*f == 1/(x*y)
  181. assert x*F.ring.gens[0] == F.ring.gens[0]*x == x**2
  182. F, x,y = field("x,y", ZZ)
  183. assert x*3 == 3*x
  184. assert x*QQ(3,7) == QQ(3,7)*x == x*Rational(3, 7)
  185. Fuv, u,v = field("u,v", ZZ)
  186. Fxyzt, x,y,z,t = field("x,y,z,t", Fuv)
  187. f = ((u + 1)*x*y + 1)/((v - 1)*z - t*u*v - 1)
  188. assert dict(f.numer) == {(1, 1, 0, 0): u + 1, (0, 0, 0, 0): 1}
  189. assert dict(f.denom) == {(0, 0, 1, 0): v - 1, (0, 0, 0, 1): -u*v, (0, 0, 0, 0): -1}
  190. Ruv, u,v = ring("u,v", ZZ)
  191. Fxyzt, x,y,z,t = field("x,y,z,t", Ruv)
  192. f = ((u + 1)*x*y + 1)/((v - 1)*z - t*u*v - 1)
  193. assert dict(f.numer) == {(1, 1, 0, 0): u + 1, (0, 0, 0, 0): 1}
  194. assert dict(f.denom) == {(0, 0, 1, 0): v - 1, (0, 0, 0, 1): -u*v, (0, 0, 0, 0): -1}
  195. def test_FracElement___truediv__():
  196. F, x,y = field("x,y", QQ)
  197. f, g = 1/x, 1/y
  198. assert f/g == y/x
  199. assert x/F.ring.gens[0] == F.ring.gens[0]/x == 1
  200. F, x,y = field("x,y", ZZ)
  201. assert x*3 == 3*x
  202. assert x/QQ(3,7) == (QQ(3,7)/x)**-1 == x*Rational(7, 3)
  203. raises(ZeroDivisionError, lambda: x/0)
  204. raises(ZeroDivisionError, lambda: 1/(x - x))
  205. raises(ZeroDivisionError, lambda: x/(x - x))
  206. Fuv, u,v = field("u,v", ZZ)
  207. Fxyzt, x,y,z,t = field("x,y,z,t", Fuv)
  208. f = (u*v)/(x*y)
  209. assert dict(f.numer) == {(0, 0, 0, 0): u*v}
  210. assert dict(f.denom) == {(1, 1, 0, 0): 1}
  211. g = (x*y)/(u*v)
  212. assert dict(g.numer) == {(1, 1, 0, 0): 1}
  213. assert dict(g.denom) == {(0, 0, 0, 0): u*v}
  214. Ruv, u,v = ring("u,v", ZZ)
  215. Fxyzt, x,y,z,t = field("x,y,z,t", Ruv)
  216. f = (u*v)/(x*y)
  217. assert dict(f.numer) == {(0, 0, 0, 0): u*v}
  218. assert dict(f.denom) == {(1, 1, 0, 0): 1}
  219. g = (x*y)/(u*v)
  220. assert dict(g.numer) == {(1, 1, 0, 0): 1}
  221. assert dict(g.denom) == {(0, 0, 0, 0): u*v}
  222. def test_FracElement___pow__():
  223. F, x,y = field("x,y", QQ)
  224. f, g = 1/x, 1/y
  225. assert f**3 == 1/x**3
  226. assert g**3 == 1/y**3
  227. assert (f*g)**3 == 1/(x**3*y**3)
  228. assert (f*g)**-3 == (x*y)**3
  229. raises(ZeroDivisionError, lambda: (x - x)**-3)
  230. def test_FracElement_diff():
  231. F, x,y,z = field("x,y,z", ZZ)
  232. assert ((x**2 + y)/(z + 1)).diff(x) == 2*x/(z + 1)
  233. @XFAIL
  234. def test_FracElement___call__():
  235. F, x,y,z = field("x,y,z", ZZ)
  236. f = (x**2 + 3*y)/z
  237. r = f(1, 1, 1)
  238. assert r == 4 and not isinstance(r, FracElement)
  239. raises(ZeroDivisionError, lambda: f(1, 1, 0))
  240. def test_FracElement_evaluate():
  241. F, x,y,z = field("x,y,z", ZZ)
  242. Fyz = field("y,z", ZZ)[0]
  243. f = (x**2 + 3*y)/z
  244. assert f.evaluate(x, 0) == 3*Fyz.y/Fyz.z
  245. raises(ZeroDivisionError, lambda: f.evaluate(z, 0))
  246. def test_FracElement_subs():
  247. F, x,y,z = field("x,y,z", ZZ)
  248. f = (x**2 + 3*y)/z
  249. assert f.subs(x, 0) == 3*y/z
  250. raises(ZeroDivisionError, lambda: f.subs(z, 0))
  251. def test_FracElement_compose():
  252. pass
  253. def test_FracField_index():
  254. a = symbols("a")
  255. F, x, y, z = field('x y z', QQ)
  256. assert F.index(x) == 0
  257. assert F.index(y) == 1
  258. raises(ValueError, lambda: F.index(1))
  259. raises(ValueError, lambda: F.index(a))
  260. pass