fancysets.py 47 KB

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