图片解析应用
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

82 lines
4.2 KiB

  1. from sympy.abc import theta, x
  2. from sympy.core import S
  3. from sympy.core.numbers import AlgebraicNumber
  4. from sympy.functions.elementary.miscellaneous import sqrt
  5. from sympy.polys import Poly, cyclotomic_poly
  6. from sympy.polys.domains import QQ
  7. from sympy.polys.matrices import DomainMatrix, DM
  8. from sympy.polys.numberfields.basis import round_two
  9. from sympy.testing.pytest import raises
  10. def test_round_two():
  11. # Poly must be monic, irreducible, and over ZZ:
  12. raises(ValueError, lambda: round_two(Poly(3 * x ** 2 + 1)))
  13. raises(ValueError, lambda: round_two(Poly(x ** 2 - 1)))
  14. raises(ValueError, lambda: round_two(Poly(x ** 2 + QQ(1, 2))))
  15. # Test on many fields:
  16. cases = (
  17. # A couple of cyclotomic fields:
  18. (cyclotomic_poly(5), DomainMatrix.eye(4, QQ), 125),
  19. (cyclotomic_poly(7), DomainMatrix.eye(6, QQ), -16807),
  20. # A couple of quadratic fields (one 1 mod 4, one 3 mod 4):
  21. (x ** 2 - 5, DM([[1, (1, 2)], [0, (1, 2)]], QQ), 5),
  22. (x ** 2 - 7, DM([[1, 0], [0, 1]], QQ), 28),
  23. # Dedekind's example of a field with 2 as essential disc divisor:
  24. (x ** 3 + x ** 2 - 2 * x + 8, DM([[1, 0, 0], [0, 1, 0], [0, (1, 2), (1, 2)]], QQ).transpose(), -503),
  25. # A bunch of cubics with various forms for F -- all of these require
  26. # second or third enlargements. (Five of them require a third, while the rest require just a second.)
  27. # F = 2^2
  28. (x**3 + 3 * x**2 - 4 * x + 4, DM([((1, 2), (1, 4), (1, 4)), (0, (1, 2), (1, 2)), (0, 0, 1)], QQ).transpose(), -83),
  29. # F = 2^2 * 3
  30. (x**3 + 3 * x**2 + 3 * x - 3, DM([((1, 2), 0, (1, 2)), (0, 1, 0), (0, 0, 1)], QQ).transpose(), -108),
  31. # F = 2^3
  32. (x**3 + 5 * x**2 - x + 3, DM([((1, 4), 0, (3, 4)), (0, (1, 2), (1, 2)), (0, 0, 1)], QQ).transpose(), -31),
  33. # F = 2^2 * 5
  34. (x**3 + 5 * x**2 - 5 * x - 5, DM([((1, 2), 0, (1, 2)), (0, 1, 0), (0, 0, 1)], QQ).transpose(), 1300),
  35. # F = 3^2
  36. (x**3 + 3 * x**2 + 5, DM([((1, 3), (1, 3), (1, 3)), (0, 1, 0), (0, 0, 1)], QQ).transpose(), -135),
  37. # F = 3^3
  38. (x**3 + 6 * x**2 + 3 * x - 1, DM([((1, 3), (1, 3), (1, 3)), (0, 1, 0), (0, 0, 1)], QQ).transpose(), 81),
  39. # F = 2^2 * 3^2
  40. (x**3 + 6 * x**2 + 4, DM([((1, 3), (2, 3), (1, 3)), (0, 1, 0), (0, 0, (1, 2))], QQ).transpose(), -108),
  41. # F = 2^3 * 7
  42. (x**3 + 7 * x**2 + 7 * x - 7, DM([((1, 4), 0, (3, 4)), (0, (1, 2), (1, 2)), (0, 0, 1)], QQ).transpose(), 49),
  43. # F = 2^2 * 13
  44. (x**3 + 7 * x**2 - x + 5, DM([((1, 2), 0, (1, 2)), (0, 1, 0), (0, 0, 1)], QQ).transpose(), -2028),
  45. # F = 2^4
  46. (x**3 + 7 * x**2 - 5 * x + 5, DM([((1, 4), 0, (3, 4)), (0, (1, 2), (1, 2)), (0, 0, 1)], QQ).transpose(), -140),
  47. # F = 5^2
  48. (x**3 + 4 * x**2 - 3 * x + 7, DM([((1, 5), (4, 5), (4, 5)), (0, 1, 0), (0, 0, 1)], QQ).transpose(), -175),
  49. # F = 7^2
  50. (x**3 + 8 * x**2 + 5 * x - 1, DM([((1, 7), (6, 7), (2, 7)), (0, 1, 0), (0, 0, 1)], QQ).transpose(), 49),
  51. # F = 2 * 5 * 7
  52. (x**3 + 8 * x**2 - 2 * x + 6, DM([(1, 0, 0), (0, 1, 0), (0, 0, 1)], QQ).transpose(), -14700),
  53. # F = 2^2 * 3 * 5
  54. (x**3 + 6 * x**2 - 3 * x + 8, DM([(1, 0, 0), (0, (1, 4), (1, 4)), (0, 0, 1)], QQ).transpose(), -675),
  55. # F = 2 * 3^2 * 7
  56. (x**3 + 9 * x**2 + 6 * x - 8, DM([(1, 0, 0), (0, (1, 2), (1, 2)), (0, 0, 1)], QQ).transpose(), 3969),
  57. # F = 2^2 * 3^2 * 7
  58. (x**3 + 15 * x**2 - 9 * x + 13, DM([((1, 6), (1, 3), (1, 6)), (0, 1, 0), (0, 0, 1)], QQ).transpose(), -5292),
  59. )
  60. for f, B_exp, d_exp in cases:
  61. K = QQ.algebraic_field((f, theta))
  62. B = K.maximal_order().QQ_matrix
  63. d = K.discriminant()
  64. assert d == d_exp
  65. # The computed basis need not equal the expected one, but their quotient
  66. # must be unimodular:
  67. assert (B.inv()*B_exp).det()**2 == 1
  68. def test_AlgebraicField_integral_basis():
  69. alpha = AlgebraicNumber(sqrt(5), alias='alpha')
  70. k = QQ.algebraic_field(alpha)
  71. B0 = k.integral_basis()
  72. B1 = k.integral_basis(fmt='sympy')
  73. B2 = k.integral_basis(fmt='alg')
  74. assert B0 == [k([1]), k([S.Half, S.Half])]
  75. assert B1 == [1, S.Half + alpha/2]
  76. assert B2 == [alpha.field_element([1]),
  77. alpha.field_element([S.Half, S.Half])]