test_utilities.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. from sympy.abc import x
  2. from sympy.core.numbers import (I, Rational)
  3. from sympy.core.singleton import S
  4. from sympy.functions.elementary.miscellaneous import sqrt
  5. from sympy.polys import Poly, cyclotomic_poly
  6. from sympy.polys.domains import FF, QQ
  7. from sympy.polys.matrices import DomainMatrix, DM
  8. from sympy.polys.matrices.exceptions import DMRankError
  9. from sympy.polys.numberfields.utilities import (
  10. AlgIntPowers, coeff_search, extract_fundamental_discriminant,
  11. isolate, supplement_a_subspace,
  12. )
  13. from sympy.printing.lambdarepr import IntervalPrinter
  14. from sympy.testing.pytest import raises
  15. def test_AlgIntPowers_01():
  16. T = Poly(cyclotomic_poly(5))
  17. zeta_pow = AlgIntPowers(T)
  18. raises(ValueError, lambda: zeta_pow[-1])
  19. for e in range(10):
  20. a = e % 5
  21. if a < 4:
  22. c = zeta_pow[e]
  23. assert c[a] == 1 and all(c[i] == 0 for i in range(4) if i != a)
  24. else:
  25. assert zeta_pow[e] == [-1] * 4
  26. def test_AlgIntPowers_02():
  27. T = Poly(x**3 + 2*x**2 + 3*x + 4)
  28. m = 7
  29. theta_pow = AlgIntPowers(T, m)
  30. for e in range(10):
  31. computed = theta_pow[e]
  32. coeffs = (Poly(x)**e % T + Poly(x**3)).rep.rep[1:]
  33. expected = [c % m for c in reversed(coeffs)]
  34. assert computed == expected
  35. def test_coeff_search():
  36. C = []
  37. search = coeff_search(2, 1)
  38. for i, c in enumerate(search):
  39. C.append(c)
  40. if i == 12:
  41. break
  42. assert C == [[1, 1], [1, 0], [1, -1], [0, 1], [2, 2], [2, 1], [2, 0], [2, -1], [2, -2], [1, 2], [1, -2], [0, 2], [3, 3]]
  43. def test_extract_fundamental_discriminant():
  44. # To extract, integer must be 0 or 1 mod 4.
  45. raises(ValueError, lambda: extract_fundamental_discriminant(2))
  46. raises(ValueError, lambda: extract_fundamental_discriminant(3))
  47. # Try many cases, of different forms:
  48. cases = (
  49. (0, {}, {0: 1}),
  50. (1, {}, {}),
  51. (8, {2: 3}, {}),
  52. (-8, {2: 3, -1: 1}, {}),
  53. (12, {2: 2, 3: 1}, {}),
  54. (36, {}, {2: 1, 3: 1}),
  55. (45, {5: 1}, {3: 1}),
  56. (48, {2: 2, 3: 1}, {2: 1}),
  57. (1125, {5: 1}, {3: 1, 5: 1}),
  58. )
  59. for a, D_expected, F_expected in cases:
  60. D, F = extract_fundamental_discriminant(a)
  61. assert D == D_expected
  62. assert F == F_expected
  63. def test_supplement_a_subspace_1():
  64. M = DM([[1, 7, 0], [2, 3, 4]], QQ).transpose()
  65. # First supplement over QQ:
  66. B = supplement_a_subspace(M)
  67. assert B[:, :2] == M
  68. assert B[:, 2] == DomainMatrix.eye(3, QQ).to_dense()[:, 0]
  69. # Now supplement over FF(7):
  70. M = M.convert_to(FF(7))
  71. B = supplement_a_subspace(M)
  72. assert B[:, :2] == M
  73. # When we work mod 7, first col of M goes to [1, 0, 0],
  74. # so the supplementary vector cannot equal this, as it did
  75. # when we worked over QQ. Instead, we get the second std basis vector:
  76. assert B[:, 2] == DomainMatrix.eye(3, FF(7)).to_dense()[:, 1]
  77. def test_supplement_a_subspace_2():
  78. M = DM([[1, 0, 0], [2, 0, 0]], QQ).transpose()
  79. with raises(DMRankError):
  80. supplement_a_subspace(M)
  81. def test_IntervalPrinter():
  82. ip = IntervalPrinter()
  83. assert ip.doprint(x**Rational(1, 3)) == "x**(mpi('1/3'))"
  84. assert ip.doprint(sqrt(x)) == "x**(mpi('1/2'))"
  85. def test_isolate():
  86. assert isolate(1) == (1, 1)
  87. assert isolate(S.Half) == (S.Half, S.Half)
  88. assert isolate(sqrt(2)) == (1, 2)
  89. assert isolate(-sqrt(2)) == (-2, -1)
  90. assert isolate(sqrt(2), eps=Rational(1, 100)) == (Rational(24, 17), Rational(17, 12))
  91. assert isolate(-sqrt(2), eps=Rational(1, 100)) == (Rational(-17, 12), Rational(-24, 17))
  92. raises(NotImplementedError, lambda: isolate(I))