m2m模型翻译
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.

177 lines
5.7 KiB

7 months ago
  1. """
  2. test_pythonmpq.py
  3. Test the PythonMPQ class for consistency with gmpy2's mpq type. If gmpy2 is
  4. installed run the same tests for both.
  5. """
  6. from fractions import Fraction
  7. from decimal import Decimal
  8. import pickle
  9. from typing import Callable, List, Tuple, Type
  10. from sympy.testing.pytest import raises
  11. from sympy.external.pythonmpq import PythonMPQ
  12. #
  13. # If gmpy2 is installed then run the tests for both mpq and PythonMPQ.
  14. # That should ensure consistency between the implementation here and mpq.
  15. #
  16. rational_types: List[Tuple[Callable, Type, Callable, Type]]
  17. rational_types = [(PythonMPQ, PythonMPQ, int, int)]
  18. try:
  19. from gmpy2 import mpq, mpz
  20. rational_types.append((mpq, type(mpq(1)), mpz, type(mpz(1))))
  21. except ImportError:
  22. pass
  23. def test_PythonMPQ():
  24. #
  25. # Test PythonMPQ and also mpq if gmpy/gmpy2 is installed.
  26. #
  27. for Q, TQ, Z, TZ in rational_types:
  28. def check_Q(q):
  29. assert isinstance(q, TQ)
  30. assert isinstance(q.numerator, TZ)
  31. assert isinstance(q.denominator, TZ)
  32. return q.numerator, q.denominator
  33. # Check construction from different types
  34. assert check_Q(Q(3)) == (3, 1)
  35. assert check_Q(Q(3, 5)) == (3, 5)
  36. assert check_Q(Q(Q(3, 5))) == (3, 5)
  37. assert check_Q(Q(0.5)) == (1, 2)
  38. assert check_Q(Q('0.5')) == (1, 2)
  39. assert check_Q(Q(Fraction(3, 5))) == (3, 5)
  40. if Q is PythonMPQ:
  41. # This works in gmpy2 2.0.8 but not 2.1.0 or 2.1.1:
  42. # https://github.com/aleaxit/gmpy/issues/327
  43. assert check_Q(Q(Decimal('0.6'))) == (3, 5)
  44. # Invalid types
  45. raises(TypeError, lambda: Q([]))
  46. raises(TypeError, lambda: Q([], []))
  47. # Check normalisation of signs
  48. assert check_Q(Q(2, 3)) == (2, 3)
  49. assert check_Q(Q(-2, 3)) == (-2, 3)
  50. assert check_Q(Q(2, -3)) == (-2, 3)
  51. assert check_Q(Q(-2, -3)) == (2, 3)
  52. # Check gcd calculation
  53. assert check_Q(Q(12, 8)) == (3, 2)
  54. # __int__/__float__
  55. assert int(Q(5, 3)) == 1
  56. assert int(Q(-5, 3)) == -1
  57. assert float(Q(5, 2)) == 2.5
  58. assert float(Q(-5, 2)) == -2.5
  59. # __str__/__repr__
  60. assert str(Q(2, 1)) == "2"
  61. assert str(Q(1, 2)) == "1/2"
  62. if Q is PythonMPQ:
  63. assert repr(Q(2, 1)) == "MPQ(2,1)"
  64. assert repr(Q(1, 2)) == "MPQ(1,2)"
  65. else:
  66. assert repr(Q(2, 1)) == "mpq(2,1)"
  67. assert repr(Q(1, 2)) == "mpq(1,2)"
  68. # __bool__
  69. assert bool(Q(1, 2)) is True
  70. assert bool(Q(0)) is False
  71. # __eq__/__ne__
  72. assert (Q(2, 3) == Q(2, 3)) is True
  73. assert (Q(2, 3) == Q(2, 5)) is False
  74. assert (Q(2, 3) != Q(2, 3)) is False
  75. assert (Q(2, 3) != Q(2, 5)) is True
  76. # __hash__
  77. assert hash(Q(3, 5)) == hash(Fraction(3, 5))
  78. # __reduce__
  79. q = Q(2, 3)
  80. assert pickle.loads(pickle.dumps(q)) == q
  81. # __ge__/__gt__/__le__/__lt__
  82. assert (Q(1, 3) < Q(2, 3)) is True
  83. assert (Q(2, 3) < Q(2, 3)) is False
  84. assert (Q(2, 3) < Q(1, 3)) is False
  85. assert (Q(-2, 3) < Q(1, 3)) is True
  86. assert (Q(1, 3) < Q(-2, 3)) is False
  87. assert (Q(1, 3) <= Q(2, 3)) is True
  88. assert (Q(2, 3) <= Q(2, 3)) is True
  89. assert (Q(2, 3) <= Q(1, 3)) is False
  90. assert (Q(-2, 3) <= Q(1, 3)) is True
  91. assert (Q(1, 3) <= Q(-2, 3)) is False
  92. assert (Q(1, 3) > Q(2, 3)) is False
  93. assert (Q(2, 3) > Q(2, 3)) is False
  94. assert (Q(2, 3) > Q(1, 3)) is True
  95. assert (Q(-2, 3) > Q(1, 3)) is False
  96. assert (Q(1, 3) > Q(-2, 3)) is True
  97. assert (Q(1, 3) >= Q(2, 3)) is False
  98. assert (Q(2, 3) >= Q(2, 3)) is True
  99. assert (Q(2, 3) >= Q(1, 3)) is True
  100. assert (Q(-2, 3) >= Q(1, 3)) is False
  101. assert (Q(1, 3) >= Q(-2, 3)) is True
  102. # __abs__/__pos__/__neg__
  103. assert abs(Q(2, 3)) == abs(Q(-2, 3)) == Q(2, 3)
  104. assert +Q(2, 3) == Q(2, 3)
  105. assert -Q(2, 3) == Q(-2, 3)
  106. # __add__/__radd__
  107. assert Q(2, 3) + Q(5, 7) == Q(29, 21)
  108. assert Q(2, 3) + 1 == Q(5, 3)
  109. assert 1 + Q(2, 3) == Q(5, 3)
  110. raises(TypeError, lambda: [] + Q(1))
  111. raises(TypeError, lambda: Q(1) + [])
  112. # __sub__/__rsub__
  113. assert Q(2, 3) - Q(5, 7) == Q(-1, 21)
  114. assert Q(2, 3) - 1 == Q(-1, 3)
  115. assert 1 - Q(2, 3) == Q(1, 3)
  116. raises(TypeError, lambda: [] - Q(1))
  117. raises(TypeError, lambda: Q(1) - [])
  118. # __mul__/__rmul__
  119. assert Q(2, 3) * Q(5, 7) == Q(10, 21)
  120. assert Q(2, 3) * 1 == Q(2, 3)
  121. assert 1 * Q(2, 3) == Q(2, 3)
  122. raises(TypeError, lambda: [] * Q(1))
  123. raises(TypeError, lambda: Q(1) * [])
  124. # __pow__/__rpow__
  125. assert Q(2, 3) ** 2 == Q(4, 9)
  126. assert Q(2, 3) ** 1 == Q(2, 3)
  127. assert Q(-2, 3) ** 2 == Q(4, 9)
  128. assert Q(-2, 3) ** -1 == Q(-3, 2)
  129. if Q is PythonMPQ:
  130. raises(TypeError, lambda: 1 ** Q(2, 3))
  131. raises(TypeError, lambda: Q(1, 4) ** Q(1, 2))
  132. raises(TypeError, lambda: [] ** Q(1))
  133. raises(TypeError, lambda: Q(1) ** [])
  134. # __div__/__rdiv__
  135. assert Q(2, 3) / Q(5, 7) == Q(14, 15)
  136. assert Q(2, 3) / 1 == Q(2, 3)
  137. assert 1 / Q(2, 3) == Q(3, 2)
  138. raises(TypeError, lambda: [] / Q(1))
  139. raises(TypeError, lambda: Q(1) / [])
  140. raises(ZeroDivisionError, lambda: Q(1, 2) / Q(0))
  141. # __divmod__
  142. if Q is PythonMPQ:
  143. raises(TypeError, lambda: Q(2, 3) // Q(1, 3))
  144. raises(TypeError, lambda: Q(2, 3) % Q(1, 3))
  145. raises(TypeError, lambda: 1 // Q(1, 3))
  146. raises(TypeError, lambda: 1 % Q(1, 3))
  147. raises(TypeError, lambda: Q(2, 3) // 1)
  148. raises(TypeError, lambda: Q(2, 3) % 1)