fancysets.py 47 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507
  1. from functools import reduce
  2. from itertools import product
  3. from sympy.core.basic import Basic
  4. from sympy.core.containers import Tuple
  5. from sympy.core.expr import Expr
  6. from sympy.core.function import Lambda
  7. from sympy.core.logic import fuzzy_not, fuzzy_or, fuzzy_and
  8. from sympy.core.mod import Mod
  9. from sympy.core.numbers import oo, igcd, Rational
  10. from sympy.core.relational import Eq, is_eq
  11. from sympy.core.singleton import Singleton, S
  12. from sympy.core.symbol import Dummy, symbols, Symbol
  13. from sympy.core.sympify import _sympify, sympify, _sympy_converter
  14. from sympy.logic.boolalg import And, Or
  15. from .sets import Set, Interval, Union, FiniteSet, ProductSet
  16. from sympy.utilities.misc import filldedent
  17. class Rationals(Set, metaclass=Singleton):
  18. """
  19. Represents the rational numbers. This set is also available as
  20. the singleton ``S.Rationals``.
  21. Examples
  22. ========
  23. >>> from sympy import S
  24. >>> S.Half in S.Rationals
  25. True
  26. >>> iterable = iter(S.Rationals)
  27. >>> [next(iterable) for i in range(12)]
  28. [0, 1, -1, 1/2, 2, -1/2, -2, 1/3, 3, -1/3, -3, 2/3]
  29. """
  30. is_iterable = True
  31. _inf = S.NegativeInfinity
  32. _sup = S.Infinity
  33. is_empty = False
  34. is_finite_set = False
  35. def _contains(self, other):
  36. if not isinstance(other, Expr):
  37. return False
  38. return other.is_rational
  39. def __iter__(self):
  40. yield S.Zero
  41. yield S.One
  42. yield S.NegativeOne
  43. d = 2
  44. while True:
  45. for n in range(d):
  46. if igcd(n, d) == 1:
  47. yield Rational(n, d)
  48. yield Rational(d, n)
  49. yield Rational(-n, d)
  50. yield Rational(-d, n)
  51. d += 1
  52. @property
  53. def _boundary(self):
  54. return S.Reals
  55. class Naturals(Set, metaclass=Singleton):
  56. """
  57. Represents the natural numbers (or counting numbers) which are all
  58. positive integers starting from 1. This set is also available as
  59. the singleton ``S.Naturals``.
  60. Examples
  61. ========
  62. >>> from sympy import S, Interval, pprint
  63. >>> 5 in S.Naturals
  64. True
  65. >>> iterable = iter(S.Naturals)
  66. >>> next(iterable)
  67. 1
  68. >>> next(iterable)
  69. 2
  70. >>> next(iterable)
  71. 3
  72. >>> pprint(S.Naturals.intersect(Interval(0, 10)))
  73. {1, 2, ..., 10}
  74. See Also
  75. ========
  76. Naturals0 : non-negative integers (i.e. includes 0, too)
  77. Integers : also includes negative integers
  78. """
  79. is_iterable = True
  80. _inf = S.One
  81. _sup = S.Infinity
  82. is_empty = False
  83. is_finite_set = False
  84. def _contains(self, other):
  85. if not isinstance(other, Expr):
  86. return False
  87. elif other.is_positive and other.is_integer:
  88. return True
  89. elif other.is_integer is False or other.is_positive is False:
  90. return False
  91. def _eval_is_subset(self, other):
  92. return Range(1, oo).is_subset(other)
  93. def _eval_is_superset(self, other):
  94. return Range(1, oo).is_superset(other)
  95. def __iter__(self):
  96. i = self._inf
  97. while True:
  98. yield i
  99. i = i + 1
  100. @property
  101. def _boundary(self):
  102. return self
  103. def as_relational(self, x):
  104. from sympy.functions.elementary.integers import floor
  105. return And(Eq(floor(x), x), x >= self.inf, x < oo)
  106. class Naturals0(Naturals):
  107. """Represents the whole numbers which are all the non-negative integers,
  108. inclusive of zero.
  109. See Also
  110. ========
  111. Naturals : positive integers; does not include 0
  112. Integers : also includes the negative integers
  113. """
  114. _inf = S.Zero
  115. def _contains(self, other):
  116. if not isinstance(other, Expr):
  117. return S.false
  118. elif other.is_integer and other.is_nonnegative:
  119. return S.true
  120. elif other.is_integer is False or other.is_nonnegative is False:
  121. return S.false
  122. def _eval_is_subset(self, other):
  123. return Range(oo).is_subset(other)
  124. def _eval_is_superset(self, other):
  125. return Range(oo).is_superset(other)
  126. class Integers(Set, metaclass=Singleton):
  127. """
  128. Represents all integers: positive, negative and zero. This set is also
  129. available as the singleton ``S.Integers``.
  130. Examples
  131. ========
  132. >>> from sympy import S, Interval, pprint
  133. >>> 5 in S.Naturals
  134. True
  135. >>> iterable = iter(S.Integers)
  136. >>> next(iterable)
  137. 0
  138. >>> next(iterable)
  139. 1
  140. >>> next(iterable)
  141. -1
  142. >>> next(iterable)
  143. 2
  144. >>> pprint(S.Integers.intersect(Interval(-4, 4)))
  145. {-4, -3, ..., 4}
  146. See Also
  147. ========
  148. Naturals0 : non-negative integers
  149. Integers : positive and negative integers and zero
  150. """
  151. is_iterable = True
  152. is_empty = False
  153. is_finite_set = False
  154. def _contains(self, other):
  155. if not isinstance(other, Expr):
  156. return S.false
  157. return other.is_integer
  158. def __iter__(self):
  159. yield S.Zero
  160. i = S.One
  161. while True:
  162. yield i
  163. yield -i
  164. i = i + 1
  165. @property
  166. def _inf(self):
  167. return S.NegativeInfinity
  168. @property
  169. def _sup(self):
  170. return S.Infinity
  171. @property
  172. def _boundary(self):
  173. return self
  174. def as_relational(self, x):
  175. from sympy.functions.elementary.integers import floor
  176. return And(Eq(floor(x), x), -oo < x, x < oo)
  177. def _eval_is_subset(self, other):
  178. return Range(-oo, oo).is_subset(other)
  179. def _eval_is_superset(self, other):
  180. return Range(-oo, oo).is_superset(other)
  181. class Reals(Interval, metaclass=Singleton):
  182. """
  183. Represents all real numbers
  184. from negative infinity to positive infinity,
  185. including all integer, rational and irrational numbers.
  186. This set is also available as the singleton ``S.Reals``.
  187. Examples
  188. ========
  189. >>> from sympy import S, Rational, pi, I
  190. >>> 5 in S.Reals
  191. True
  192. >>> Rational(-1, 2) in S.Reals
  193. True
  194. >>> pi in S.Reals
  195. True
  196. >>> 3*I in S.Reals
  197. False
  198. >>> S.Reals.contains(pi)
  199. True
  200. See Also
  201. ========
  202. ComplexRegion
  203. """
  204. @property
  205. def start(self):
  206. return S.NegativeInfinity
  207. @property
  208. def end(self):
  209. return S.Infinity
  210. @property
  211. def left_open(self):
  212. return True
  213. @property
  214. def right_open(self):
  215. return True
  216. def __eq__(self, other):
  217. return other == Interval(S.NegativeInfinity, S.Infinity)
  218. def __hash__(self):
  219. return hash(Interval(S.NegativeInfinity, S.Infinity))
  220. class ImageSet(Set):
  221. """
  222. Image of a set under a mathematical function. The transformation
  223. must be given as a Lambda function which has as many arguments
  224. as the elements of the set upon which it operates, e.g. 1 argument
  225. when acting on the set of integers or 2 arguments when acting on
  226. a complex region.
  227. This function is not normally called directly, but is called
  228. from ``imageset``.
  229. Examples
  230. ========
  231. >>> from sympy import Symbol, S, pi, Dummy, Lambda
  232. >>> from sympy import FiniteSet, ImageSet, Interval
  233. >>> x = Symbol('x')
  234. >>> N = S.Naturals
  235. >>> squares = ImageSet(Lambda(x, x**2), N) # {x**2 for x in N}
  236. >>> 4 in squares
  237. True
  238. >>> 5 in squares
  239. False
  240. >>> FiniteSet(0, 1, 2, 3, 4, 5, 6, 7, 9, 10).intersect(squares)
  241. {1, 4, 9}
  242. >>> square_iterable = iter(squares)
  243. >>> for i in range(4):
  244. ... next(square_iterable)
  245. 1
  246. 4
  247. 9
  248. 16
  249. If you want to get value for `x` = 2, 1/2 etc. (Please check whether the
  250. `x` value is in ``base_set`` or not before passing it as args)
  251. >>> squares.lamda(2)
  252. 4
  253. >>> squares.lamda(S(1)/2)
  254. 1/4
  255. >>> n = Dummy('n')
  256. >>> solutions = ImageSet(Lambda(n, n*pi), S.Integers) # solutions of sin(x) = 0
  257. >>> dom = Interval(-1, 1)
  258. >>> dom.intersect(solutions)
  259. {0}
  260. See Also
  261. ========
  262. sympy.sets.sets.imageset
  263. """
  264. def __new__(cls, flambda, *sets):
  265. if not isinstance(flambda, Lambda):
  266. raise ValueError('First argument must be a Lambda')
  267. signature = flambda.signature
  268. if len(signature) != len(sets):
  269. raise ValueError('Incompatible signature')
  270. sets = [_sympify(s) for s in sets]
  271. if not all(isinstance(s, Set) for s in sets):
  272. raise TypeError("Set arguments to ImageSet should of type Set")
  273. if not all(cls._check_sig(sg, st) for sg, st in zip(signature, sets)):
  274. raise ValueError("Signature %s does not match sets %s" % (signature, sets))
  275. if flambda is S.IdentityFunction and len(sets) == 1:
  276. return sets[0]
  277. if not set(flambda.variables) & flambda.expr.free_symbols:
  278. is_empty = fuzzy_or(s.is_empty for s in sets)
  279. if is_empty == True:
  280. return S.EmptySet
  281. elif is_empty == False:
  282. return FiniteSet(flambda.expr)
  283. return Basic.__new__(cls, flambda, *sets)
  284. lamda = property(lambda self: self.args[0])
  285. base_sets = property(lambda self: self.args[1:])
  286. @property
  287. def base_set(self):
  288. # XXX: Maybe deprecate this? It is poorly defined in handling
  289. # the multivariate case...
  290. sets = self.base_sets
  291. if len(sets) == 1:
  292. return sets[0]
  293. else:
  294. return ProductSet(*sets).flatten()
  295. @property
  296. def base_pset(self):
  297. return ProductSet(*self.base_sets)
  298. @classmethod
  299. def _check_sig(cls, sig_i, set_i):
  300. if sig_i.is_symbol:
  301. return True
  302. elif isinstance(set_i, ProductSet):
  303. sets = set_i.sets
  304. if len(sig_i) != len(sets):
  305. return False
  306. # Recurse through the signature for nested tuples:
  307. return all(cls._check_sig(ts, ps) for ts, ps in zip(sig_i, sets))
  308. else:
  309. # XXX: Need a better way of checking whether a set is a set of
  310. # Tuples or not. For example a FiniteSet can contain Tuples
  311. # but so can an ImageSet or a ConditionSet. Others like
  312. # Integers, Reals etc can not contain Tuples. We could just
  313. # list the possibilities here... Current code for e.g.
  314. # _contains probably only works for ProductSet.
  315. return True # Give the benefit of the doubt
  316. def __iter__(self):
  317. already_seen = set()
  318. for i in self.base_pset:
  319. val = self.lamda(*i)
  320. if val in already_seen:
  321. continue
  322. else:
  323. already_seen.add(val)
  324. yield val
  325. def _is_multivariate(self):
  326. return len(self.lamda.variables) > 1
  327. def _contains(self, other):
  328. from sympy.solvers.solveset import _solveset_multi
  329. def get_symsetmap(signature, base_sets):
  330. '''Attempt to get a map of symbols to base_sets'''
  331. queue = list(zip(signature, base_sets))
  332. symsetmap = {}
  333. for sig, base_set in queue:
  334. if sig.is_symbol:
  335. symsetmap[sig] = base_set
  336. elif base_set.is_ProductSet:
  337. sets = base_set.sets
  338. if len(sig) != len(sets):
  339. raise ValueError("Incompatible signature")
  340. # Recurse
  341. queue.extend(zip(sig, sets))
  342. else:
  343. # If we get here then we have something like sig = (x, y) and
  344. # base_set = {(1, 2), (3, 4)}. For now we give up.
  345. return None
  346. return symsetmap
  347. def get_equations(expr, candidate):
  348. '''Find the equations relating symbols in expr and candidate.'''
  349. queue = [(expr, candidate)]
  350. for e, c in queue:
  351. if not isinstance(e, Tuple):
  352. yield Eq(e, c)
  353. elif not isinstance(c, Tuple) or len(e) != len(c):
  354. yield False
  355. return
  356. else:
  357. queue.extend(zip(e, c))
  358. # Get the basic objects together:
  359. other = _sympify(other)
  360. expr = self.lamda.expr
  361. sig = self.lamda.signature
  362. variables = self.lamda.variables
  363. base_sets = self.base_sets
  364. # Use dummy symbols for ImageSet parameters so they don't match
  365. # anything in other
  366. rep = {v: Dummy(v.name) for v in variables}
  367. variables = [v.subs(rep) for v in variables]
  368. sig = sig.subs(rep)
  369. expr = expr.subs(rep)
  370. # Map the parts of other to those in the Lambda expr
  371. equations = []
  372. for eq in get_equations(expr, other):
  373. # Unsatisfiable equation?
  374. if eq is False:
  375. return False
  376. equations.append(eq)
  377. # Map the symbols in the signature to the corresponding domains
  378. symsetmap = get_symsetmap(sig, base_sets)
  379. if symsetmap is None:
  380. # Can't factor the base sets to a ProductSet
  381. return None
  382. # Which of the variables in the Lambda signature need to be solved for?
  383. symss = (eq.free_symbols for eq in equations)
  384. variables = set(variables) & reduce(set.union, symss, set())
  385. # Use internal multivariate solveset
  386. variables = tuple(variables)
  387. base_sets = [symsetmap[v] for v in variables]
  388. solnset = _solveset_multi(equations, variables, base_sets)
  389. if solnset is None:
  390. return None
  391. return fuzzy_not(solnset.is_empty)
  392. @property
  393. def is_iterable(self):
  394. return all(s.is_iterable for s in self.base_sets)
  395. def doit(self, **kwargs):
  396. from sympy.sets.setexpr import SetExpr
  397. f = self.lamda
  398. sig = f.signature
  399. if len(sig) == 1 and sig[0].is_symbol and isinstance(f.expr, Expr):
  400. base_set = self.base_sets[0]
  401. return SetExpr(base_set)._eval_func(f).set
  402. if all(s.is_FiniteSet for s in self.base_sets):
  403. return FiniteSet(*(f(*a) for a in product(*self.base_sets)))
  404. return self
  405. class Range(Set):
  406. """
  407. Represents a range of integers. Can be called as ``Range(stop)``,
  408. ``Range(start, stop)``, or ``Range(start, stop, step)``; when ``step`` is
  409. not given it defaults to 1.
  410. ``Range(stop)`` is the same as ``Range(0, stop, 1)`` and the stop value
  411. (just as for Python ranges) is not included in the Range values.
  412. >>> from sympy import Range
  413. >>> list(Range(3))
  414. [0, 1, 2]
  415. The step can also be negative:
  416. >>> list(Range(10, 0, -2))
  417. [10, 8, 6, 4, 2]
  418. The stop value is made canonical so equivalent ranges always
  419. have the same args:
  420. >>> Range(0, 10, 3)
  421. Range(0, 12, 3)
  422. Infinite ranges are allowed. ``oo`` and ``-oo`` are never included in the
  423. set (``Range`` is always a subset of ``Integers``). If the starting point
  424. is infinite, then the final value is ``stop - step``. To iterate such a
  425. range, it needs to be reversed:
  426. >>> from sympy import oo
  427. >>> r = Range(-oo, 1)
  428. >>> r[-1]
  429. 0
  430. >>> next(iter(r))
  431. Traceback (most recent call last):
  432. ...
  433. TypeError: Cannot iterate over Range with infinite start
  434. >>> next(iter(r.reversed))
  435. 0
  436. Although ``Range`` is a :class:`Set` (and supports the normal set
  437. operations) it maintains the order of the elements and can
  438. be used in contexts where ``range`` would be used.
  439. >>> from sympy import Interval
  440. >>> Range(0, 10, 2).intersect(Interval(3, 7))
  441. Range(4, 8, 2)
  442. >>> list(_)
  443. [4, 6]
  444. Although slicing of a Range will always return a Range -- possibly
  445. empty -- an empty set will be returned from any intersection that
  446. is empty:
  447. >>> Range(3)[:0]
  448. Range(0, 0, 1)
  449. >>> Range(3).intersect(Interval(4, oo))
  450. EmptySet
  451. >>> Range(3).intersect(Range(4, oo))
  452. EmptySet
  453. Range will accept symbolic arguments but has very limited support
  454. for doing anything other than displaying the Range:
  455. >>> from sympy import Symbol, pprint
  456. >>> from sympy.abc import i, j, k
  457. >>> Range(i, j, k).start
  458. i
  459. >>> Range(i, j, k).inf
  460. Traceback (most recent call last):
  461. ...
  462. ValueError: invalid method for symbolic range
  463. Better success will be had when using integer symbols:
  464. >>> n = Symbol('n', integer=True)
  465. >>> r = Range(n, n + 20, 3)
  466. >>> r.inf
  467. n
  468. >>> pprint(r)
  469. {n, n + 3, ..., n + 18}
  470. """
  471. def __new__(cls, *args):
  472. from sympy.functions.elementary.integers import ceiling
  473. if len(args) == 1:
  474. if isinstance(args[0], range):
  475. raise TypeError(
  476. 'use sympify(%s) to convert range to Range' % args[0])
  477. # expand range
  478. slc = slice(*args)
  479. if slc.step == 0:
  480. raise ValueError("step cannot be 0")
  481. start, stop, step = slc.start or 0, slc.stop, slc.step or 1
  482. try:
  483. ok = []
  484. for w in (start, stop, step):
  485. w = sympify(w)
  486. if w in [S.NegativeInfinity, S.Infinity] or (
  487. w.has(Symbol) and w.is_integer != False):
  488. ok.append(w)
  489. elif not w.is_Integer:
  490. if w.is_infinite:
  491. raise ValueError('infinite symbols not allowed')
  492. raise ValueError
  493. else:
  494. ok.append(w)
  495. except ValueError:
  496. raise ValueError(filldedent('''
  497. Finite arguments to Range must be integers; `imageset` can define
  498. other cases, e.g. use `imageset(i, i/10, Range(3))` to give
  499. [0, 1/10, 1/5].'''))
  500. start, stop, step = ok
  501. null = False
  502. if any(i.has(Symbol) for i in (start, stop, step)):
  503. dif = stop - start
  504. n = dif/step
  505. if n.is_Rational:
  506. from sympy.functions.elementary.integers import floor
  507. if dif == 0:
  508. null = True
  509. else: # (x, x + 5, 2) or (x, 3*x, x)
  510. n = floor(n)
  511. end = start + n*step
  512. if dif.is_Rational: # (x, x + 5, 2)
  513. if (end - stop).is_negative:
  514. end += step
  515. else: # (x, 3*x, x)
  516. if (end/stop - 1).is_negative:
  517. end += step
  518. elif n.is_extended_negative:
  519. null = True
  520. else:
  521. end = stop # other methods like sup and reversed must fail
  522. elif start.is_infinite:
  523. span = step*(stop - start)
  524. if span is S.NaN or span <= 0:
  525. null = True
  526. elif step.is_Integer and stop.is_infinite and abs(step) != 1:
  527. raise ValueError(filldedent('''
  528. Step size must be %s in this case.''' % (1 if step > 0 else -1)))
  529. else:
  530. end = stop
  531. else:
  532. oostep = step.is_infinite
  533. if oostep:
  534. step = S.One if step > 0 else S.NegativeOne
  535. n = ceiling((stop - start)/step)
  536. if n <= 0:
  537. null = True
  538. elif oostep:
  539. step = S.One # make it canonical
  540. end = start + step
  541. else:
  542. end = start + n*step
  543. if null:
  544. start = end = S.Zero
  545. step = S.One
  546. return Basic.__new__(cls, start, end, step)
  547. start = property(lambda self: self.args[0])
  548. stop = property(lambda self: self.args[1])
  549. step = property(lambda self: self.args[2])
  550. @property
  551. def reversed(self):
  552. """Return an equivalent Range in the opposite order.
  553. Examples
  554. ========
  555. >>> from sympy import Range
  556. >>> Range(10).reversed
  557. Range(9, -1, -1)
  558. """
  559. if self.has(Symbol):
  560. n = (self.stop - self.start)/self.step
  561. if not n.is_extended_positive or not all(
  562. i.is_integer or i.is_infinite for i in self.args):
  563. raise ValueError('invalid method for symbolic range')
  564. if self.start == self.stop:
  565. return self
  566. return self.func(
  567. self.stop - self.step, self.start - self.step, -self.step)
  568. def _contains(self, other):
  569. if self.start == self.stop:
  570. return S.false
  571. if other.is_infinite:
  572. return S.false
  573. if not other.is_integer:
  574. return other.is_integer
  575. if self.has(Symbol):
  576. n = (self.stop - self.start)/self.step
  577. if not n.is_extended_positive or not all(
  578. i.is_integer or i.is_infinite for i in self.args):
  579. return
  580. else:
  581. n = self.size
  582. if self.start.is_finite:
  583. ref = self.start
  584. elif self.stop.is_finite:
  585. ref = self.stop
  586. else: # both infinite; step is +/- 1 (enforced by __new__)
  587. return S.true
  588. if n == 1:
  589. return Eq(other, self[0])
  590. res = (ref - other) % self.step
  591. if res == S.Zero:
  592. if self.has(Symbol):
  593. d = Dummy('i')
  594. return self.as_relational(d).subs(d, other)
  595. return And(other >= self.inf, other <= self.sup)
  596. elif res.is_Integer: # off sequence
  597. return S.false
  598. else: # symbolic/unsimplified residue modulo step
  599. return None
  600. def __iter__(self):
  601. n = self.size # validate
  602. if not (n.has(S.Infinity) or n.has(S.NegativeInfinity) or n.is_Integer):
  603. raise TypeError("Cannot iterate over symbolic Range")
  604. if self.start in [S.NegativeInfinity, S.Infinity]:
  605. raise TypeError("Cannot iterate over Range with infinite start")
  606. elif self.start != self.stop:
  607. i = self.start
  608. if n.is_infinite:
  609. while True:
  610. yield i
  611. i += self.step
  612. else:
  613. for _ in range(n):
  614. yield i
  615. i += self.step
  616. @property
  617. def is_iterable(self):
  618. # Check that size can be determined, used by __iter__
  619. dif = self.stop - self.start
  620. n = dif/self.step
  621. if not (n.has(S.Infinity) or n.has(S.NegativeInfinity) or n.is_Integer):
  622. return False
  623. if self.start in [S.NegativeInfinity, S.Infinity]:
  624. return False
  625. if not (n.is_extended_nonnegative and all(i.is_integer for i in self.args)):
  626. return False
  627. return True
  628. def __len__(self):
  629. rv = self.size
  630. if rv is S.Infinity:
  631. raise ValueError('Use .size to get the length of an infinite Range')
  632. return int(rv)
  633. @property
  634. def size(self):
  635. if self.start == self.stop:
  636. return S.Zero
  637. dif = self.stop - self.start
  638. n = dif/self.step
  639. if n.is_infinite:
  640. return S.Infinity
  641. if n.is_extended_nonnegative and all(i.is_integer for i in self.args):
  642. from sympy.functions.elementary.integers import floor
  643. return abs(floor(n))
  644. raise ValueError('Invalid method for symbolic Range')
  645. @property
  646. def is_finite_set(self):
  647. if self.start.is_integer and self.stop.is_integer:
  648. return True
  649. return self.size.is_finite
  650. @property
  651. def is_empty(self):
  652. try:
  653. return self.size.is_zero
  654. except ValueError:
  655. return None
  656. def __bool__(self):
  657. # this only distinguishes between definite null range
  658. # and non-null/unknown null; getting True doesn't mean
  659. # that it actually is not null
  660. b = is_eq(self.start, self.stop)
  661. if b is None:
  662. raise ValueError('cannot tell if Range is null or not')
  663. return not bool(b)
  664. def __getitem__(self, i):
  665. from sympy.functions.elementary.integers import ceiling
  666. ooslice = "cannot slice from the end with an infinite value"
  667. zerostep = "slice step cannot be zero"
  668. infinite = "slicing not possible on range with infinite start"
  669. # if we had to take every other element in the following
  670. # oo, ..., 6, 4, 2, 0
  671. # we might get oo, ..., 4, 0 or oo, ..., 6, 2
  672. ambiguous = "cannot unambiguously re-stride from the end " + \
  673. "with an infinite value"
  674. if isinstance(i, slice):
  675. if self.size.is_finite: # validates, too
  676. if self.start == self.stop:
  677. return Range(0)
  678. start, stop, step = i.indices(self.size)
  679. n = ceiling((stop - start)/step)
  680. if n <= 0:
  681. return Range(0)
  682. canonical_stop = start + n*step
  683. end = canonical_stop - step
  684. ss = step*self.step
  685. return Range(self[start], self[end] + ss, ss)
  686. else: # infinite Range
  687. start = i.start
  688. stop = i.stop
  689. if i.step == 0:
  690. raise ValueError(zerostep)
  691. step = i.step or 1
  692. ss = step*self.step
  693. #---------------------
  694. # handle infinite Range
  695. # i.e. Range(-oo, oo) or Range(oo, -oo, -1)
  696. # --------------------
  697. if self.start.is_infinite and self.stop.is_infinite:
  698. raise ValueError(infinite)
  699. #---------------------
  700. # handle infinite on right
  701. # e.g. Range(0, oo) or Range(0, -oo, -1)
  702. # --------------------
  703. if self.stop.is_infinite:
  704. # start and stop are not interdependent --
  705. # they only depend on step --so we use the
  706. # equivalent reversed values
  707. return self.reversed[
  708. stop if stop is None else -stop + 1:
  709. start if start is None else -start:
  710. step].reversed
  711. #---------------------
  712. # handle infinite on the left
  713. # e.g. Range(oo, 0, -1) or Range(-oo, 0)
  714. # --------------------
  715. # consider combinations of
  716. # start/stop {== None, < 0, == 0, > 0} and
  717. # step {< 0, > 0}
  718. if start is None:
  719. if stop is None:
  720. if step < 0:
  721. return Range(self[-1], self.start, ss)
  722. elif step > 1:
  723. raise ValueError(ambiguous)
  724. else: # == 1
  725. return self
  726. elif stop < 0:
  727. if step < 0:
  728. return Range(self[-1], self[stop], ss)
  729. else: # > 0
  730. return Range(self.start, self[stop], ss)
  731. elif stop == 0:
  732. if step > 0:
  733. return Range(0)
  734. else: # < 0
  735. raise ValueError(ooslice)
  736. elif stop == 1:
  737. if step > 0:
  738. raise ValueError(ooslice) # infinite singleton
  739. else: # < 0
  740. raise ValueError(ooslice)
  741. else: # > 1
  742. raise ValueError(ooslice)
  743. elif start < 0:
  744. if stop is None:
  745. if step < 0:
  746. return Range(self[start], self.start, ss)
  747. else: # > 0
  748. return Range(self[start], self.stop, ss)
  749. elif stop < 0:
  750. return Range(self[start], self[stop], ss)
  751. elif stop == 0:
  752. if step < 0:
  753. raise ValueError(ooslice)
  754. else: # > 0
  755. return Range(0)
  756. elif stop > 0:
  757. raise ValueError(ooslice)
  758. elif start == 0:
  759. if stop is None:
  760. if step < 0:
  761. raise ValueError(ooslice) # infinite singleton
  762. elif step > 1:
  763. raise ValueError(ambiguous)
  764. else: # == 1
  765. return self
  766. elif stop < 0:
  767. if step > 1:
  768. raise ValueError(ambiguous)
  769. elif step == 1:
  770. return Range(self.start, self[stop], ss)
  771. else: # < 0
  772. return Range(0)
  773. else: # >= 0
  774. raise ValueError(ooslice)
  775. elif start > 0:
  776. raise ValueError(ooslice)
  777. else:
  778. if self.start == self.stop:
  779. raise IndexError('Range index out of range')
  780. if not (all(i.is_integer or i.is_infinite
  781. for i in self.args) and ((self.stop - self.start)/
  782. self.step).is_extended_positive):
  783. raise ValueError('Invalid method for symbolic Range')
  784. if i == 0:
  785. if self.start.is_infinite:
  786. raise ValueError(ooslice)
  787. return self.start
  788. if i == -1:
  789. if self.stop.is_infinite:
  790. raise ValueError(ooslice)
  791. return self.stop - self.step
  792. n = self.size # must be known for any other index
  793. rv = (self.stop if i < 0 else self.start) + i*self.step
  794. if rv.is_infinite:
  795. raise ValueError(ooslice)
  796. val = (rv - self.start)/self.step
  797. rel = fuzzy_or([val.is_infinite,
  798. fuzzy_and([val.is_nonnegative, (n-val).is_nonnegative])])
  799. if rel:
  800. return rv
  801. if rel is None:
  802. raise ValueError('Invalid method for symbolic Range')
  803. raise IndexError("Range index out of range")
  804. @property
  805. def _inf(self):
  806. if not self:
  807. return S.EmptySet.inf
  808. if self.has(Symbol):
  809. if all(i.is_integer or i.is_infinite for i in self.args):
  810. dif = self.stop - self.start
  811. if self.step.is_positive and dif.is_positive:
  812. return self.start
  813. elif self.step.is_negative and dif.is_negative:
  814. return self.stop - self.step
  815. raise ValueError('invalid method for symbolic range')
  816. if self.step > 0:
  817. return self.start
  818. else:
  819. return self.stop - self.step
  820. @property
  821. def _sup(self):
  822. if not self:
  823. return S.EmptySet.sup
  824. if self.has(Symbol):
  825. if all(i.is_integer or i.is_infinite for i in self.args):
  826. dif = self.stop - self.start
  827. if self.step.is_positive and dif.is_positive:
  828. return self.stop - self.step
  829. elif self.step.is_negative and dif.is_negative:
  830. return self.start
  831. raise ValueError('invalid method for symbolic range')
  832. if self.step > 0:
  833. return self.stop - self.step
  834. else:
  835. return self.start
  836. @property
  837. def _boundary(self):
  838. return self
  839. def as_relational(self, x):
  840. """Rewrite a Range in terms of equalities and logic operators. """
  841. if self.start.is_infinite:
  842. assert not self.stop.is_infinite # by instantiation
  843. a = self.reversed.start
  844. else:
  845. a = self.start
  846. step = self.step
  847. in_seq = Eq(Mod(x - a, step), 0)
  848. ints = And(Eq(Mod(a, 1), 0), Eq(Mod(step, 1), 0))
  849. n = (self.stop - self.start)/self.step
  850. if n == 0:
  851. return S.EmptySet.as_relational(x)
  852. if n == 1:
  853. return And(Eq(x, a), ints)
  854. try:
  855. a, b = self.inf, self.sup
  856. except ValueError:
  857. a = None
  858. if a is not None:
  859. range_cond = And(
  860. x > a if a.is_infinite else x >= a,
  861. x < b if b.is_infinite else x <= b)
  862. else:
  863. a, b = self.start, self.stop - self.step
  864. range_cond = Or(
  865. And(self.step >= 1, x > a if a.is_infinite else x >= a,
  866. x < b if b.is_infinite else x <= b),
  867. And(self.step <= -1, x < a if a.is_infinite else x <= a,
  868. x > b if b.is_infinite else x >= b))
  869. return And(in_seq, ints, range_cond)
  870. _sympy_converter[range] = lambda r: Range(r.start, r.stop, r.step)
  871. def normalize_theta_set(theta):
  872. r"""
  873. Normalize a Real Set `theta` in the interval `[0, 2\pi)`. It returns
  874. a normalized value of theta in the Set. For Interval, a maximum of
  875. one cycle $[0, 2\pi]$, is returned i.e. for theta equal to $[0, 10\pi]$,
  876. returned normalized value would be $[0, 2\pi)$. As of now intervals
  877. with end points as non-multiples of ``pi`` is not supported.
  878. Raises
  879. ======
  880. NotImplementedError
  881. The algorithms for Normalizing theta Set are not yet
  882. implemented.
  883. ValueError
  884. The input is not valid, i.e. the input is not a real set.
  885. RuntimeError
  886. It is a bug, please report to the github issue tracker.
  887. Examples
  888. ========
  889. >>> from sympy.sets.fancysets import normalize_theta_set
  890. >>> from sympy import Interval, FiniteSet, pi
  891. >>> normalize_theta_set(Interval(9*pi/2, 5*pi))
  892. Interval(pi/2, pi)
  893. >>> normalize_theta_set(Interval(-3*pi/2, pi/2))
  894. Interval.Ropen(0, 2*pi)
  895. >>> normalize_theta_set(Interval(-pi/2, pi/2))
  896. Union(Interval(0, pi/2), Interval.Ropen(3*pi/2, 2*pi))
  897. >>> normalize_theta_set(Interval(-4*pi, 3*pi))
  898. Interval.Ropen(0, 2*pi)
  899. >>> normalize_theta_set(Interval(-3*pi/2, -pi/2))
  900. Interval(pi/2, 3*pi/2)
  901. >>> normalize_theta_set(FiniteSet(0, pi, 3*pi))
  902. {0, pi}
  903. """
  904. from sympy.functions.elementary.trigonometric import _pi_coeff as coeff
  905. if theta.is_Interval:
  906. interval_len = theta.measure
  907. # one complete circle
  908. if interval_len >= 2*S.Pi:
  909. if interval_len == 2*S.Pi and theta.left_open and theta.right_open:
  910. k = coeff(theta.start)
  911. return Union(Interval(0, k*S.Pi, False, True),
  912. Interval(k*S.Pi, 2*S.Pi, True, True))
  913. return Interval(0, 2*S.Pi, False, True)
  914. k_start, k_end = coeff(theta.start), coeff(theta.end)
  915. if k_start is None or k_end is None:
  916. raise NotImplementedError("Normalizing theta without pi as coefficient is "
  917. "not yet implemented")
  918. new_start = k_start*S.Pi
  919. new_end = k_end*S.Pi
  920. if new_start > new_end:
  921. return Union(Interval(S.Zero, new_end, False, theta.right_open),
  922. Interval(new_start, 2*S.Pi, theta.left_open, True))
  923. else:
  924. return Interval(new_start, new_end, theta.left_open, theta.right_open)
  925. elif theta.is_FiniteSet:
  926. new_theta = []
  927. for element in theta:
  928. k = coeff(element)
  929. if k is None:
  930. raise NotImplementedError('Normalizing theta without pi as '
  931. 'coefficient, is not Implemented.')
  932. else:
  933. new_theta.append(k*S.Pi)
  934. return FiniteSet(*new_theta)
  935. elif theta.is_Union:
  936. return Union(*[normalize_theta_set(interval) for interval in theta.args])
  937. elif theta.is_subset(S.Reals):
  938. raise NotImplementedError("Normalizing theta when, it is of type %s is not "
  939. "implemented" % type(theta))
  940. else:
  941. raise ValueError(" %s is not a real set" % (theta))
  942. class ComplexRegion(Set):
  943. r"""
  944. Represents the Set of all Complex Numbers. It can represent a
  945. region of Complex Plane in both the standard forms Polar and
  946. Rectangular coordinates.
  947. * Polar Form
  948. Input is in the form of the ProductSet or Union of ProductSets
  949. of the intervals of ``r`` and ``theta``, and use the flag ``polar=True``.
  950. .. math:: Z = \{z \in \mathbb{C} \mid z = r\times (\cos(\theta) + I\sin(\theta)), r \in [\texttt{r}], \theta \in [\texttt{theta}]\}
  951. * Rectangular Form
  952. Input is in the form of the ProductSet or Union of ProductSets
  953. of interval of x and y, the real and imaginary parts of the Complex numbers in a plane.
  954. Default input type is in rectangular form.
  955. .. math:: Z = \{z \in \mathbb{C} \mid z = x + Iy, x \in [\operatorname{re}(z)], y \in [\operatorname{im}(z)]\}
  956. Examples
  957. ========
  958. >>> from sympy import ComplexRegion, Interval, S, I, Union
  959. >>> a = Interval(2, 3)
  960. >>> b = Interval(4, 6)
  961. >>> c1 = ComplexRegion(a*b) # Rectangular Form
  962. >>> c1
  963. CartesianComplexRegion(ProductSet(Interval(2, 3), Interval(4, 6)))
  964. * c1 represents the rectangular region in complex plane
  965. surrounded by the coordinates (2, 4), (3, 4), (3, 6) and
  966. (2, 6), of the four vertices.
  967. >>> c = Interval(1, 8)
  968. >>> c2 = ComplexRegion(Union(a*b, b*c))
  969. >>> c2
  970. CartesianComplexRegion(Union(ProductSet(Interval(2, 3), Interval(4, 6)), ProductSet(Interval(4, 6), Interval(1, 8))))
  971. * c2 represents the Union of two rectangular regions in complex
  972. plane. One of them surrounded by the coordinates of c1 and
  973. other surrounded by the coordinates (4, 1), (6, 1), (6, 8) and
  974. (4, 8).
  975. >>> 2.5 + 4.5*I in c1
  976. True
  977. >>> 2.5 + 6.5*I in c1
  978. False
  979. >>> r = Interval(0, 1)
  980. >>> theta = Interval(0, 2*S.Pi)
  981. >>> c2 = ComplexRegion(r*theta, polar=True) # Polar Form
  982. >>> c2 # unit Disk
  983. PolarComplexRegion(ProductSet(Interval(0, 1), Interval.Ropen(0, 2*pi)))
  984. * c2 represents the region in complex plane inside the
  985. Unit Disk centered at the origin.
  986. >>> 0.5 + 0.5*I in c2
  987. True
  988. >>> 1 + 2*I in c2
  989. False
  990. >>> unit_disk = ComplexRegion(Interval(0, 1)*Interval(0, 2*S.Pi), polar=True)
  991. >>> upper_half_unit_disk = ComplexRegion(Interval(0, 1)*Interval(0, S.Pi), polar=True)
  992. >>> intersection = unit_disk.intersect(upper_half_unit_disk)
  993. >>> intersection
  994. PolarComplexRegion(ProductSet(Interval(0, 1), Interval(0, pi)))
  995. >>> intersection == upper_half_unit_disk
  996. True
  997. See Also
  998. ========
  999. CartesianComplexRegion
  1000. PolarComplexRegion
  1001. Complexes
  1002. """
  1003. is_ComplexRegion = True
  1004. def __new__(cls, sets, polar=False):
  1005. if polar is False:
  1006. return CartesianComplexRegion(sets)
  1007. elif polar is True:
  1008. return PolarComplexRegion(sets)
  1009. else:
  1010. raise ValueError("polar should be either True or False")
  1011. @property
  1012. def sets(self):
  1013. """
  1014. Return raw input sets to the self.
  1015. Examples
  1016. ========
  1017. >>> from sympy import Interval, ComplexRegion, Union
  1018. >>> a = Interval(2, 3)
  1019. >>> b = Interval(4, 5)
  1020. >>> c = Interval(1, 7)
  1021. >>> C1 = ComplexRegion(a*b)
  1022. >>> C1.sets
  1023. ProductSet(Interval(2, 3), Interval(4, 5))
  1024. >>> C2 = ComplexRegion(Union(a*b, b*c))
  1025. >>> C2.sets
  1026. Union(ProductSet(Interval(2, 3), Interval(4, 5)), ProductSet(Interval(4, 5), Interval(1, 7)))
  1027. """
  1028. return self.args[0]
  1029. @property
  1030. def psets(self):
  1031. """
  1032. Return a tuple of sets (ProductSets) input of the self.
  1033. Examples
  1034. ========
  1035. >>> from sympy import Interval, ComplexRegion, Union
  1036. >>> a = Interval(2, 3)
  1037. >>> b = Interval(4, 5)
  1038. >>> c = Interval(1, 7)
  1039. >>> C1 = ComplexRegion(a*b)
  1040. >>> C1.psets
  1041. (ProductSet(Interval(2, 3), Interval(4, 5)),)
  1042. >>> C2 = ComplexRegion(Union(a*b, b*c))
  1043. >>> C2.psets
  1044. (ProductSet(Interval(2, 3), Interval(4, 5)), ProductSet(Interval(4, 5), Interval(1, 7)))
  1045. """
  1046. if self.sets.is_ProductSet:
  1047. psets = ()
  1048. psets = psets + (self.sets, )
  1049. else:
  1050. psets = self.sets.args
  1051. return psets
  1052. @property
  1053. def a_interval(self):
  1054. """
  1055. Return the union of intervals of `x` when, self is in
  1056. rectangular form, or the union of intervals of `r` when
  1057. self is in polar form.
  1058. Examples
  1059. ========
  1060. >>> from sympy import Interval, ComplexRegion, Union
  1061. >>> a = Interval(2, 3)
  1062. >>> b = Interval(4, 5)
  1063. >>> c = Interval(1, 7)
  1064. >>> C1 = ComplexRegion(a*b)
  1065. >>> C1.a_interval
  1066. Interval(2, 3)
  1067. >>> C2 = ComplexRegion(Union(a*b, b*c))
  1068. >>> C2.a_interval
  1069. Union(Interval(2, 3), Interval(4, 5))
  1070. """
  1071. a_interval = []
  1072. for element in self.psets:
  1073. a_interval.append(element.args[0])
  1074. a_interval = Union(*a_interval)
  1075. return a_interval
  1076. @property
  1077. def b_interval(self):
  1078. """
  1079. Return the union of intervals of `y` when, self is in
  1080. rectangular form, or the union of intervals of `theta`
  1081. when self is in polar form.
  1082. Examples
  1083. ========
  1084. >>> from sympy import Interval, ComplexRegion, Union
  1085. >>> a = Interval(2, 3)
  1086. >>> b = Interval(4, 5)
  1087. >>> c = Interval(1, 7)
  1088. >>> C1 = ComplexRegion(a*b)
  1089. >>> C1.b_interval
  1090. Interval(4, 5)
  1091. >>> C2 = ComplexRegion(Union(a*b, b*c))
  1092. >>> C2.b_interval
  1093. Interval(1, 7)
  1094. """
  1095. b_interval = []
  1096. for element in self.psets:
  1097. b_interval.append(element.args[1])
  1098. b_interval = Union(*b_interval)
  1099. return b_interval
  1100. @property
  1101. def _measure(self):
  1102. """
  1103. The measure of self.sets.
  1104. Examples
  1105. ========
  1106. >>> from sympy import Interval, ComplexRegion, S
  1107. >>> a, b = Interval(2, 5), Interval(4, 8)
  1108. >>> c = Interval(0, 2*S.Pi)
  1109. >>> c1 = ComplexRegion(a*b)
  1110. >>> c1.measure
  1111. 12
  1112. >>> c2 = ComplexRegion(a*c, polar=True)
  1113. >>> c2.measure
  1114. 6*pi
  1115. """
  1116. return self.sets._measure
  1117. @classmethod
  1118. def from_real(cls, sets):
  1119. """
  1120. Converts given subset of real numbers to a complex region.
  1121. Examples
  1122. ========
  1123. >>> from sympy import Interval, ComplexRegion
  1124. >>> unit = Interval(0,1)
  1125. >>> ComplexRegion.from_real(unit)
  1126. CartesianComplexRegion(ProductSet(Interval(0, 1), {0}))
  1127. """
  1128. if not sets.is_subset(S.Reals):
  1129. raise ValueError("sets must be a subset of the real line")
  1130. return CartesianComplexRegion(sets * FiniteSet(0))
  1131. def _contains(self, other):
  1132. from sympy.functions import arg, Abs
  1133. other = sympify(other)
  1134. isTuple = isinstance(other, Tuple)
  1135. if isTuple and len(other) != 2:
  1136. raise ValueError('expecting Tuple of length 2')
  1137. # If the other is not an Expression, and neither a Tuple
  1138. if not isinstance(other, (Expr, Tuple)):
  1139. return S.false
  1140. # self in rectangular form
  1141. if not self.polar:
  1142. re, im = other if isTuple else other.as_real_imag()
  1143. return fuzzy_or(fuzzy_and([
  1144. pset.args[0]._contains(re),
  1145. pset.args[1]._contains(im)])
  1146. for pset in self.psets)
  1147. # self in polar form
  1148. elif self.polar:
  1149. if other.is_zero:
  1150. # ignore undefined complex argument
  1151. return fuzzy_or(pset.args[0]._contains(S.Zero)
  1152. for pset in self.psets)
  1153. if isTuple:
  1154. r, theta = other
  1155. else:
  1156. r, theta = Abs(other), arg(other)
  1157. if theta.is_real and theta.is_number:
  1158. # angles in psets are normalized to [0, 2pi)
  1159. theta %= 2*S.Pi
  1160. return fuzzy_or(fuzzy_and([
  1161. pset.args[0]._contains(r),
  1162. pset.args[1]._contains(theta)])
  1163. for pset in self.psets)
  1164. class CartesianComplexRegion(ComplexRegion):
  1165. r"""
  1166. Set representing a square region of the complex plane.
  1167. .. math:: Z = \{z \in \mathbb{C} \mid z = x + Iy, x \in [\operatorname{re}(z)], y \in [\operatorname{im}(z)]\}
  1168. Examples
  1169. ========
  1170. >>> from sympy import ComplexRegion, I, Interval
  1171. >>> region = ComplexRegion(Interval(1, 3) * Interval(4, 6))
  1172. >>> 2 + 5*I in region
  1173. True
  1174. >>> 5*I in region
  1175. False
  1176. See also
  1177. ========
  1178. ComplexRegion
  1179. PolarComplexRegion
  1180. Complexes
  1181. """
  1182. polar = False
  1183. variables = symbols('x, y', cls=Dummy)
  1184. def __new__(cls, sets):
  1185. if sets == S.Reals*S.Reals:
  1186. return S.Complexes
  1187. if all(_a.is_FiniteSet for _a in sets.args) and (len(sets.args) == 2):
  1188. # ** ProductSet of FiniteSets in the Complex Plane. **
  1189. # For Cases like ComplexRegion({2, 4}*{3}), It
  1190. # would return {2 + 3*I, 4 + 3*I}
  1191. # FIXME: This should probably be handled with something like:
  1192. # return ImageSet(Lambda((x, y), x+I*y), sets).rewrite(FiniteSet)
  1193. complex_num = []
  1194. for x in sets.args[0]:
  1195. for y in sets.args[1]:
  1196. complex_num.append(x + S.ImaginaryUnit*y)
  1197. return FiniteSet(*complex_num)
  1198. else:
  1199. return Set.__new__(cls, sets)
  1200. @property
  1201. def expr(self):
  1202. x, y = self.variables
  1203. return x + S.ImaginaryUnit*y
  1204. class PolarComplexRegion(ComplexRegion):
  1205. r"""
  1206. Set representing a polar region of the complex plane.
  1207. .. math:: Z = \{z \in \mathbb{C} \mid z = r\times (\cos(\theta) + I\sin(\theta)), r \in [\texttt{r}], \theta \in [\texttt{theta}]\}
  1208. Examples
  1209. ========
  1210. >>> from sympy import ComplexRegion, Interval, oo, pi, I
  1211. >>> rset = Interval(0, oo)
  1212. >>> thetaset = Interval(0, pi)
  1213. >>> upper_half_plane = ComplexRegion(rset * thetaset, polar=True)
  1214. >>> 1 + I in upper_half_plane
  1215. True
  1216. >>> 1 - I in upper_half_plane
  1217. False
  1218. See also
  1219. ========
  1220. ComplexRegion
  1221. CartesianComplexRegion
  1222. Complexes
  1223. """
  1224. polar = True
  1225. variables = symbols('r, theta', cls=Dummy)
  1226. def __new__(cls, sets):
  1227. new_sets = []
  1228. # sets is Union of ProductSets
  1229. if not sets.is_ProductSet:
  1230. for k in sets.args:
  1231. new_sets.append(k)
  1232. # sets is ProductSets
  1233. else:
  1234. new_sets.append(sets)
  1235. # Normalize input theta
  1236. for k, v in enumerate(new_sets):
  1237. new_sets[k] = ProductSet(v.args[0],
  1238. normalize_theta_set(v.args[1]))
  1239. sets = Union(*new_sets)
  1240. return Set.__new__(cls, sets)
  1241. @property
  1242. def expr(self):
  1243. from sympy.functions.elementary.trigonometric import sin, cos
  1244. r, theta = self.variables
  1245. return r*(cos(theta) + S.ImaginaryUnit*sin(theta))
  1246. class Complexes(CartesianComplexRegion, metaclass=Singleton):
  1247. """
  1248. The :class:`Set` of all complex numbers
  1249. Examples
  1250. ========
  1251. >>> from sympy import S, I
  1252. >>> S.Complexes
  1253. Complexes
  1254. >>> 1 + I in S.Complexes
  1255. True
  1256. See also
  1257. ========
  1258. Reals
  1259. ComplexRegion
  1260. """
  1261. is_empty = False
  1262. is_finite_set = False
  1263. # Override property from superclass since Complexes has no args
  1264. @property
  1265. def sets(self):
  1266. return ProductSet(S.Reals, S.Reals)
  1267. def __new__(cls):
  1268. return Set.__new__(cls)