sets.py 8.7 KB

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