sets.py 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. from sympy.assumptions import Predicate
  2. from sympy.multipledispatch import Dispatcher
  3. class IntegerPredicate(Predicate):
  4. """
  5. Integer predicate.
  6. Explanation
  7. ===========
  8. ``Q.integer(x)`` is true iff ``x`` belongs to the set of integer
  9. numbers.
  10. Examples
  11. ========
  12. >>> from sympy import Q, ask, S
  13. >>> ask(Q.integer(5))
  14. True
  15. >>> ask(Q.integer(S(1)/2))
  16. False
  17. References
  18. ==========
  19. .. [1] https://en.wikipedia.org/wiki/Integer
  20. """
  21. name = 'integer'
  22. handler = Dispatcher(
  23. "IntegerHandler",
  24. doc=("Handler for Q.integer.\n\n"
  25. "Test that an expression belongs to the field of integer numbers.")
  26. )
  27. class NonIntegerPredicate(Predicate):
  28. """
  29. Non-integer extended real predicate.
  30. """
  31. name = 'noninteger'
  32. handler = Dispatcher(
  33. "NonIntegerHandler",
  34. doc=("Handler for Q.noninteger.\n\n"
  35. "Test that an expression is a non-integer extended real number.")
  36. )
  37. class RationalPredicate(Predicate):
  38. """
  39. Rational number predicate.
  40. Explanation
  41. ===========
  42. ``Q.rational(x)`` is true iff ``x`` belongs to the set of
  43. rational numbers.
  44. Examples
  45. ========
  46. >>> from sympy import ask, Q, pi, S
  47. >>> ask(Q.rational(0))
  48. True
  49. >>> ask(Q.rational(S(1)/2))
  50. True
  51. >>> ask(Q.rational(pi))
  52. False
  53. References
  54. ==========
  55. .. [1] https://en.wikipedia.org/wiki/Rational_number
  56. """
  57. name = 'rational'
  58. handler = Dispatcher(
  59. "RationalHandler",
  60. doc=("Handler for Q.rational.\n\n"
  61. "Test that an expression belongs to the field of rational numbers.")
  62. )
  63. class IrrationalPredicate(Predicate):
  64. """
  65. Irrational number predicate.
  66. Explanation
  67. ===========
  68. ``Q.irrational(x)`` is true iff ``x`` is any real number that
  69. cannot be expressed as a ratio of integers.
  70. Examples
  71. ========
  72. >>> from sympy import ask, Q, pi, S, I
  73. >>> ask(Q.irrational(0))
  74. False
  75. >>> ask(Q.irrational(S(1)/2))
  76. False
  77. >>> ask(Q.irrational(pi))
  78. True
  79. >>> ask(Q.irrational(I))
  80. False
  81. References
  82. ==========
  83. .. [1] https://en.wikipedia.org/wiki/Irrational_number
  84. """
  85. name = 'irrational'
  86. handler = Dispatcher(
  87. "IrrationalHandler",
  88. doc=("Handler for Q.irrational.\n\n"
  89. "Test that an expression is irrational numbers.")
  90. )
  91. class RealPredicate(Predicate):
  92. r"""
  93. Real number predicate.
  94. Explanation
  95. ===========
  96. ``Q.real(x)`` is true iff ``x`` is a real number, i.e., it is in the
  97. interval `(-\infty, \infty)`. Note that, in particular the
  98. infinities are not real. Use ``Q.extended_real`` if you want to
  99. consider those as well.
  100. A few important facts about reals:
  101. - Every real number is positive, negative, or zero. Furthermore,
  102. because these sets are pairwise disjoint, each real number is
  103. exactly one of those three.
  104. - Every real number is also complex.
  105. - Every real number is finite.
  106. - Every real number is either rational or irrational.
  107. - Every real number is either algebraic or transcendental.
  108. - The facts ``Q.negative``, ``Q.zero``, ``Q.positive``,
  109. ``Q.nonnegative``, ``Q.nonpositive``, ``Q.nonzero``,
  110. ``Q.integer``, ``Q.rational``, and ``Q.irrational`` all imply
  111. ``Q.real``, as do all facts that imply those facts.
  112. - The facts ``Q.algebraic``, and ``Q.transcendental`` do not imply
  113. ``Q.real``; they imply ``Q.complex``. An algebraic or
  114. transcendental number may or may not be real.
  115. - The "non" facts (i.e., ``Q.nonnegative``, ``Q.nonzero``,
  116. ``Q.nonpositive`` and ``Q.noninteger``) are not equivalent to
  117. not the fact, but rather, not the fact *and* ``Q.real``.
  118. For example, ``Q.nonnegative`` means ``~Q.negative & Q.real``.
  119. So for example, ``I`` is not nonnegative, nonzero, or
  120. nonpositive.
  121. Examples
  122. ========
  123. >>> from sympy import Q, ask, symbols
  124. >>> x = symbols('x')
  125. >>> ask(Q.real(x), Q.positive(x))
  126. True
  127. >>> ask(Q.real(0))
  128. True
  129. References
  130. ==========
  131. .. [1] https://en.wikipedia.org/wiki/Real_number
  132. """
  133. name = 'real'
  134. handler = Dispatcher(
  135. "RealHandler",
  136. doc=("Handler for Q.real.\n\n"
  137. "Test that an expression belongs to the field of real numbers.")
  138. )
  139. class ExtendedRealPredicate(Predicate):
  140. r"""
  141. Extended real predicate.
  142. Explanation
  143. ===========
  144. ``Q.extended_real(x)`` is true iff ``x`` is a real number or
  145. `\{-\infty, \infty\}`.
  146. See documentation of ``Q.real`` for more information about related
  147. facts.
  148. Examples
  149. ========
  150. >>> from sympy import ask, Q, oo, I
  151. >>> ask(Q.extended_real(1))
  152. True
  153. >>> ask(Q.extended_real(I))
  154. False
  155. >>> ask(Q.extended_real(oo))
  156. True
  157. """
  158. name = 'extended_real'
  159. handler = Dispatcher(
  160. "ExtendedRealHandler",
  161. doc=("Handler for Q.extended_real.\n\n"
  162. "Test that an expression belongs to the field of extended real\n"
  163. "numbers, that is real numbers union {Infinity, -Infinity}.")
  164. )
  165. class HermitianPredicate(Predicate):
  166. """
  167. Hermitian predicate.
  168. Explanation
  169. ===========
  170. ``ask(Q.hermitian(x))`` is true iff ``x`` belongs to the set of
  171. Hermitian operators.
  172. References
  173. ==========
  174. .. [1] https://mathworld.wolfram.com/HermitianOperator.html
  175. """
  176. # TODO: Add examples
  177. name = 'hermitian'
  178. handler = Dispatcher(
  179. "HermitianHandler",
  180. doc=("Handler for Q.hermitian.\n\n"
  181. "Test that an expression belongs to the field of Hermitian operators.")
  182. )
  183. class ComplexPredicate(Predicate):
  184. """
  185. Complex number predicate.
  186. Explanation
  187. ===========
  188. ``Q.complex(x)`` is true iff ``x`` belongs to the set of complex
  189. numbers. Note that every complex number is finite.
  190. Examples
  191. ========
  192. >>> from sympy import Q, Symbol, ask, I, oo
  193. >>> x = Symbol('x')
  194. >>> ask(Q.complex(0))
  195. True
  196. >>> ask(Q.complex(2 + 3*I))
  197. True
  198. >>> ask(Q.complex(oo))
  199. False
  200. References
  201. ==========
  202. .. [1] https://en.wikipedia.org/wiki/Complex_number
  203. """
  204. name = 'complex'
  205. handler = Dispatcher(
  206. "ComplexHandler",
  207. doc=("Handler for Q.complex.\n\n"
  208. "Test that an expression belongs to the field of complex numbers.")
  209. )
  210. class ImaginaryPredicate(Predicate):
  211. """
  212. Imaginary number predicate.
  213. Explanation
  214. ===========
  215. ``Q.imaginary(x)`` is true iff ``x`` can be written as a real
  216. number multiplied by the imaginary unit ``I``. Please note that ``0``
  217. is not considered to be an imaginary number.
  218. Examples
  219. ========
  220. >>> from sympy import Q, ask, I
  221. >>> ask(Q.imaginary(3*I))
  222. True
  223. >>> ask(Q.imaginary(2 + 3*I))
  224. False
  225. >>> ask(Q.imaginary(0))
  226. False
  227. References
  228. ==========
  229. .. [1] https://en.wikipedia.org/wiki/Imaginary_number
  230. """
  231. name = 'imaginary'
  232. handler = Dispatcher(
  233. "ImaginaryHandler",
  234. doc=("Handler for Q.imaginary.\n\n"
  235. "Test that an expression belongs to the field of imaginary numbers,\n"
  236. "that is, numbers in the form x*I, where x is real.")
  237. )
  238. class AntihermitianPredicate(Predicate):
  239. """
  240. Antihermitian predicate.
  241. Explanation
  242. ===========
  243. ``Q.antihermitian(x)`` is true iff ``x`` belongs to the field of
  244. antihermitian operators, i.e., operators in the form ``x*I``, where
  245. ``x`` is Hermitian.
  246. References
  247. ==========
  248. .. [1] https://mathworld.wolfram.com/HermitianOperator.html
  249. """
  250. # TODO: Add examples
  251. name = 'antihermitian'
  252. handler = Dispatcher(
  253. "AntiHermitianHandler",
  254. doc=("Handler for Q.antihermitian.\n\n"
  255. "Test that an expression belongs to the field of anti-Hermitian\n"
  256. "operators, that is, operators in the form x*I, where x is Hermitian.")
  257. )
  258. class AlgebraicPredicate(Predicate):
  259. r"""
  260. Algebraic number predicate.
  261. Explanation
  262. ===========
  263. ``Q.algebraic(x)`` is true iff ``x`` belongs to the set of
  264. algebraic numbers. ``x`` is algebraic if there is some polynomial
  265. in ``p(x)\in \mathbb\{Q\}[x]`` such that ``p(x) = 0``.
  266. Examples
  267. ========
  268. >>> from sympy import ask, Q, sqrt, I, pi
  269. >>> ask(Q.algebraic(sqrt(2)))
  270. True
  271. >>> ask(Q.algebraic(I))
  272. True
  273. >>> ask(Q.algebraic(pi))
  274. False
  275. References
  276. ==========
  277. .. [1] https://en.wikipedia.org/wiki/Algebraic_number
  278. """
  279. name = 'algebraic'
  280. AlgebraicHandler = Dispatcher(
  281. "AlgebraicHandler",
  282. doc="""Handler for Q.algebraic key."""
  283. )
  284. class TranscendentalPredicate(Predicate):
  285. """
  286. Transcedental number predicate.
  287. Explanation
  288. ===========
  289. ``Q.transcendental(x)`` is true iff ``x`` belongs to the set of
  290. transcendental numbers. A transcendental number is a real
  291. or complex number that is not algebraic.
  292. """
  293. # TODO: Add examples
  294. name = 'transcendental'
  295. handler = Dispatcher(
  296. "Transcendental",
  297. doc="""Handler for Q.transcendental key."""
  298. )