complexes.py 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465
  1. from typing import Tuple as tTuple
  2. from sympy.core import S, Add, Mul, sympify, Symbol, Dummy, Basic
  3. from sympy.core.expr import Expr
  4. from sympy.core.exprtools import factor_terms
  5. from sympy.core.function import (Function, Derivative, ArgumentIndexError,
  6. AppliedUndef, expand_mul)
  7. from sympy.core.logic import fuzzy_not, fuzzy_or
  8. from sympy.core.numbers import pi, I, oo
  9. from sympy.core.power import Pow
  10. from sympy.core.relational import Eq
  11. from sympy.functions.elementary.miscellaneous import sqrt
  12. from sympy.functions.elementary.piecewise import Piecewise
  13. ###############################################################################
  14. ######################### REAL and IMAGINARY PARTS ############################
  15. ###############################################################################
  16. class re(Function):
  17. """
  18. Returns real part of expression. This function performs only
  19. elementary analysis and so it will fail to decompose properly
  20. more complicated expressions. If completely simplified result
  21. is needed then use ``Basic.as_real_imag()`` or perform complex
  22. expansion on instance of this function.
  23. Examples
  24. ========
  25. >>> from sympy import re, im, I, E, symbols
  26. >>> x, y = symbols('x y', real=True)
  27. >>> re(2*E)
  28. 2*E
  29. >>> re(2*I + 17)
  30. 17
  31. >>> re(2*I)
  32. 0
  33. >>> re(im(x) + x*I + 2)
  34. 2
  35. >>> re(5 + I + 2)
  36. 7
  37. Parameters
  38. ==========
  39. arg : Expr
  40. Real or complex expression.
  41. Returns
  42. =======
  43. expr : Expr
  44. Real part of expression.
  45. See Also
  46. ========
  47. im
  48. """
  49. args: tTuple[Expr]
  50. is_extended_real = True
  51. unbranched = True # implicitly works on the projection to C
  52. _singularities = True # non-holomorphic
  53. @classmethod
  54. def eval(cls, arg):
  55. if arg is S.NaN:
  56. return S.NaN
  57. elif arg is S.ComplexInfinity:
  58. return S.NaN
  59. elif arg.is_extended_real:
  60. return arg
  61. elif arg.is_imaginary or (I*arg).is_extended_real:
  62. return S.Zero
  63. elif arg.is_Matrix:
  64. return arg.as_real_imag()[0]
  65. elif arg.is_Function and isinstance(arg, conjugate):
  66. return re(arg.args[0])
  67. else:
  68. included, reverted, excluded = [], [], []
  69. args = Add.make_args(arg)
  70. for term in args:
  71. coeff = term.as_coefficient(I)
  72. if coeff is not None:
  73. if not coeff.is_extended_real:
  74. reverted.append(coeff)
  75. elif not term.has(I) and term.is_extended_real:
  76. excluded.append(term)
  77. else:
  78. # Try to do some advanced expansion. If
  79. # impossible, don't try to do re(arg) again
  80. # (because this is what we are trying to do now).
  81. real_imag = term.as_real_imag(ignore=arg)
  82. if real_imag:
  83. excluded.append(real_imag[0])
  84. else:
  85. included.append(term)
  86. if len(args) != len(included):
  87. a, b, c = (Add(*xs) for xs in [included, reverted, excluded])
  88. return cls(a) - im(b) + c
  89. def as_real_imag(self, deep=True, **hints):
  90. """
  91. Returns the real number with a zero imaginary part.
  92. """
  93. return (self, S.Zero)
  94. def _eval_derivative(self, x):
  95. if x.is_extended_real or self.args[0].is_extended_real:
  96. return re(Derivative(self.args[0], x, evaluate=True))
  97. if x.is_imaginary or self.args[0].is_imaginary:
  98. return -I \
  99. * im(Derivative(self.args[0], x, evaluate=True))
  100. def _eval_rewrite_as_im(self, arg, **kwargs):
  101. return self.args[0] - I*im(self.args[0])
  102. def _eval_is_algebraic(self):
  103. return self.args[0].is_algebraic
  104. def _eval_is_zero(self):
  105. # is_imaginary implies nonzero
  106. return fuzzy_or([self.args[0].is_imaginary, self.args[0].is_zero])
  107. def _eval_is_finite(self):
  108. if self.args[0].is_finite:
  109. return True
  110. def _eval_is_complex(self):
  111. if self.args[0].is_finite:
  112. return True
  113. class im(Function):
  114. """
  115. Returns imaginary part of expression. This function performs only
  116. elementary analysis and so it will fail to decompose properly more
  117. complicated expressions. If completely simplified result is needed then
  118. use ``Basic.as_real_imag()`` or perform complex expansion on instance of
  119. this function.
  120. Examples
  121. ========
  122. >>> from sympy import re, im, E, I
  123. >>> from sympy.abc import x, y
  124. >>> im(2*E)
  125. 0
  126. >>> im(2*I + 17)
  127. 2
  128. >>> im(x*I)
  129. re(x)
  130. >>> im(re(x) + y)
  131. im(y)
  132. >>> im(2 + 3*I)
  133. 3
  134. Parameters
  135. ==========
  136. arg : Expr
  137. Real or complex expression.
  138. Returns
  139. =======
  140. expr : Expr
  141. Imaginary part of expression.
  142. See Also
  143. ========
  144. re
  145. """
  146. args: tTuple[Expr]
  147. is_extended_real = True
  148. unbranched = True # implicitly works on the projection to C
  149. _singularities = True # non-holomorphic
  150. @classmethod
  151. def eval(cls, arg):
  152. if arg is S.NaN:
  153. return S.NaN
  154. elif arg is S.ComplexInfinity:
  155. return S.NaN
  156. elif arg.is_extended_real:
  157. return S.Zero
  158. elif arg.is_imaginary or (I*arg).is_extended_real:
  159. return -I * arg
  160. elif arg.is_Matrix:
  161. return arg.as_real_imag()[1]
  162. elif arg.is_Function and isinstance(arg, conjugate):
  163. return -im(arg.args[0])
  164. else:
  165. included, reverted, excluded = [], [], []
  166. args = Add.make_args(arg)
  167. for term in args:
  168. coeff = term.as_coefficient(I)
  169. if coeff is not None:
  170. if not coeff.is_extended_real:
  171. reverted.append(coeff)
  172. else:
  173. excluded.append(coeff)
  174. elif term.has(I) or not term.is_extended_real:
  175. # Try to do some advanced expansion. If
  176. # impossible, don't try to do im(arg) again
  177. # (because this is what we are trying to do now).
  178. real_imag = term.as_real_imag(ignore=arg)
  179. if real_imag:
  180. excluded.append(real_imag[1])
  181. else:
  182. included.append(term)
  183. if len(args) != len(included):
  184. a, b, c = (Add(*xs) for xs in [included, reverted, excluded])
  185. return cls(a) + re(b) + c
  186. def as_real_imag(self, deep=True, **hints):
  187. """
  188. Return the imaginary part with a zero real part.
  189. """
  190. return (self, S.Zero)
  191. def _eval_derivative(self, x):
  192. if x.is_extended_real or self.args[0].is_extended_real:
  193. return im(Derivative(self.args[0], x, evaluate=True))
  194. if x.is_imaginary or self.args[0].is_imaginary:
  195. return -I \
  196. * re(Derivative(self.args[0], x, evaluate=True))
  197. def _eval_rewrite_as_re(self, arg, **kwargs):
  198. return -I*(self.args[0] - re(self.args[0]))
  199. def _eval_is_algebraic(self):
  200. return self.args[0].is_algebraic
  201. def _eval_is_zero(self):
  202. return self.args[0].is_extended_real
  203. def _eval_is_finite(self):
  204. if self.args[0].is_finite:
  205. return True
  206. def _eval_is_complex(self):
  207. if self.args[0].is_finite:
  208. return True
  209. ###############################################################################
  210. ############### SIGN, ABSOLUTE VALUE, ARGUMENT and CONJUGATION ################
  211. ###############################################################################
  212. class sign(Function):
  213. """
  214. Returns the complex sign of an expression:
  215. Explanation
  216. ===========
  217. If the expression is real the sign will be:
  218. * $1$ if expression is positive
  219. * $0$ if expression is equal to zero
  220. * $-1$ if expression is negative
  221. If the expression is imaginary the sign will be:
  222. * $I$ if im(expression) is positive
  223. * $-I$ if im(expression) is negative
  224. Otherwise an unevaluated expression will be returned. When evaluated, the
  225. result (in general) will be ``cos(arg(expr)) + I*sin(arg(expr))``.
  226. Examples
  227. ========
  228. >>> from sympy import sign, I
  229. >>> sign(-1)
  230. -1
  231. >>> sign(0)
  232. 0
  233. >>> sign(-3*I)
  234. -I
  235. >>> sign(1 + I)
  236. sign(1 + I)
  237. >>> _.evalf()
  238. 0.707106781186548 + 0.707106781186548*I
  239. Parameters
  240. ==========
  241. arg : Expr
  242. Real or imaginary expression.
  243. Returns
  244. =======
  245. expr : Expr
  246. Complex sign of expression.
  247. See Also
  248. ========
  249. Abs, conjugate
  250. """
  251. is_complex = True
  252. _singularities = True
  253. def doit(self, **hints):
  254. s = super().doit()
  255. if s == self and self.args[0].is_zero is False:
  256. return self.args[0] / Abs(self.args[0])
  257. return s
  258. @classmethod
  259. def eval(cls, arg):
  260. # handle what we can
  261. if arg.is_Mul:
  262. c, args = arg.as_coeff_mul()
  263. unk = []
  264. s = sign(c)
  265. for a in args:
  266. if a.is_extended_negative:
  267. s = -s
  268. elif a.is_extended_positive:
  269. pass
  270. else:
  271. if a.is_imaginary:
  272. ai = im(a)
  273. if ai.is_comparable: # i.e. a = I*real
  274. s *= I
  275. if ai.is_extended_negative:
  276. # can't use sign(ai) here since ai might not be
  277. # a Number
  278. s = -s
  279. else:
  280. unk.append(a)
  281. else:
  282. unk.append(a)
  283. if c is S.One and len(unk) == len(args):
  284. return None
  285. return s * cls(arg._new_rawargs(*unk))
  286. if arg is S.NaN:
  287. return S.NaN
  288. if arg.is_zero: # it may be an Expr that is zero
  289. return S.Zero
  290. if arg.is_extended_positive:
  291. return S.One
  292. if arg.is_extended_negative:
  293. return S.NegativeOne
  294. if arg.is_Function:
  295. if isinstance(arg, sign):
  296. return arg
  297. if arg.is_imaginary:
  298. if arg.is_Pow and arg.exp is S.Half:
  299. # we catch this because non-trivial sqrt args are not expanded
  300. # e.g. sqrt(1-sqrt(2)) --x--> to I*sqrt(sqrt(2) - 1)
  301. return I
  302. arg2 = -I * arg
  303. if arg2.is_extended_positive:
  304. return I
  305. if arg2.is_extended_negative:
  306. return -I
  307. def _eval_Abs(self):
  308. if fuzzy_not(self.args[0].is_zero):
  309. return S.One
  310. def _eval_conjugate(self):
  311. return sign(conjugate(self.args[0]))
  312. def _eval_derivative(self, x):
  313. if self.args[0].is_extended_real:
  314. from sympy.functions.special.delta_functions import DiracDelta
  315. return 2 * Derivative(self.args[0], x, evaluate=True) \
  316. * DiracDelta(self.args[0])
  317. elif self.args[0].is_imaginary:
  318. from sympy.functions.special.delta_functions import DiracDelta
  319. return 2 * Derivative(self.args[0], x, evaluate=True) \
  320. * DiracDelta(-I * self.args[0])
  321. def _eval_is_nonnegative(self):
  322. if self.args[0].is_nonnegative:
  323. return True
  324. def _eval_is_nonpositive(self):
  325. if self.args[0].is_nonpositive:
  326. return True
  327. def _eval_is_imaginary(self):
  328. return self.args[0].is_imaginary
  329. def _eval_is_integer(self):
  330. return self.args[0].is_extended_real
  331. def _eval_is_zero(self):
  332. return self.args[0].is_zero
  333. def _eval_power(self, other):
  334. if (
  335. fuzzy_not(self.args[0].is_zero) and
  336. other.is_integer and
  337. other.is_even
  338. ):
  339. return S.One
  340. def _eval_nseries(self, x, n, logx, cdir=0):
  341. arg0 = self.args[0]
  342. x0 = arg0.subs(x, 0)
  343. if x0 != 0:
  344. return self.func(x0)
  345. if cdir != 0:
  346. cdir = arg0.dir(x, cdir)
  347. return -S.One if re(cdir) < 0 else S.One
  348. def _eval_rewrite_as_Piecewise(self, arg, **kwargs):
  349. if arg.is_extended_real:
  350. return Piecewise((1, arg > 0), (-1, arg < 0), (0, True))
  351. def _eval_rewrite_as_Heaviside(self, arg, **kwargs):
  352. from sympy.functions.special.delta_functions import Heaviside
  353. if arg.is_extended_real:
  354. return Heaviside(arg) * 2 - 1
  355. def _eval_rewrite_as_Abs(self, arg, **kwargs):
  356. return Piecewise((0, Eq(arg, 0)), (arg / Abs(arg), True))
  357. def _eval_simplify(self, **kwargs):
  358. return self.func(factor_terms(self.args[0])) # XXX include doit?
  359. class Abs(Function):
  360. """
  361. Return the absolute value of the argument.
  362. Explanation
  363. ===========
  364. This is an extension of the built-in function ``abs()`` to accept symbolic
  365. values. If you pass a SymPy expression to the built-in ``abs()``, it will
  366. pass it automatically to ``Abs()``.
  367. Examples
  368. ========
  369. >>> from sympy import Abs, Symbol, S, I
  370. >>> Abs(-1)
  371. 1
  372. >>> x = Symbol('x', real=True)
  373. >>> Abs(-x)
  374. Abs(x)
  375. >>> Abs(x**2)
  376. x**2
  377. >>> abs(-x) # The Python built-in
  378. Abs(x)
  379. >>> Abs(3*x + 2*I)
  380. sqrt(9*x**2 + 4)
  381. >>> Abs(8*I)
  382. 8
  383. Note that the Python built-in will return either an Expr or int depending on
  384. the argument::
  385. >>> type(abs(-1))
  386. <... 'int'>
  387. >>> type(abs(S.NegativeOne))
  388. <class 'sympy.core.numbers.One'>
  389. Abs will always return a SymPy object.
  390. Parameters
  391. ==========
  392. arg : Expr
  393. Real or complex expression.
  394. Returns
  395. =======
  396. expr : Expr
  397. Absolute value returned can be an expression or integer depending on
  398. input arg.
  399. See Also
  400. ========
  401. sign, conjugate
  402. """
  403. args: tTuple[Expr]
  404. is_extended_real = True
  405. is_extended_negative = False
  406. is_extended_nonnegative = True
  407. unbranched = True
  408. _singularities = True # non-holomorphic
  409. def fdiff(self, argindex=1):
  410. """
  411. Get the first derivative of the argument to Abs().
  412. """
  413. if argindex == 1:
  414. return sign(self.args[0])
  415. else:
  416. raise ArgumentIndexError(self, argindex)
  417. @classmethod
  418. def eval(cls, arg):
  419. from sympy.simplify.simplify import signsimp
  420. if hasattr(arg, '_eval_Abs'):
  421. obj = arg._eval_Abs()
  422. if obj is not None:
  423. return obj
  424. if not isinstance(arg, Expr):
  425. raise TypeError("Bad argument type for Abs(): %s" % type(arg))
  426. # handle what we can
  427. arg = signsimp(arg, evaluate=False)
  428. n, d = arg.as_numer_denom()
  429. if d.free_symbols and not n.free_symbols:
  430. return cls(n)/cls(d)
  431. if arg.is_Mul:
  432. known = []
  433. unk = []
  434. for t in arg.args:
  435. if t.is_Pow and t.exp.is_integer and t.exp.is_negative:
  436. bnew = cls(t.base)
  437. if isinstance(bnew, cls):
  438. unk.append(t)
  439. else:
  440. known.append(Pow(bnew, t.exp))
  441. else:
  442. tnew = cls(t)
  443. if isinstance(tnew, cls):
  444. unk.append(t)
  445. else:
  446. known.append(tnew)
  447. known = Mul(*known)
  448. unk = cls(Mul(*unk), evaluate=False) if unk else S.One
  449. return known*unk
  450. if arg is S.NaN:
  451. return S.NaN
  452. if arg is S.ComplexInfinity:
  453. return oo
  454. from sympy.functions.elementary.exponential import exp, log
  455. if arg.is_Pow:
  456. base, exponent = arg.as_base_exp()
  457. if base.is_extended_real:
  458. if exponent.is_integer:
  459. if exponent.is_even:
  460. return arg
  461. if base is S.NegativeOne:
  462. return S.One
  463. return Abs(base)**exponent
  464. if base.is_extended_nonnegative:
  465. return base**re(exponent)
  466. if base.is_extended_negative:
  467. return (-base)**re(exponent)*exp(-pi*im(exponent))
  468. return
  469. elif not base.has(Symbol): # complex base
  470. # express base**exponent as exp(exponent*log(base))
  471. a, b = log(base).as_real_imag()
  472. z = a + I*b
  473. return exp(re(exponent*z))
  474. if isinstance(arg, exp):
  475. return exp(re(arg.args[0]))
  476. if isinstance(arg, AppliedUndef):
  477. if arg.is_positive:
  478. return arg
  479. elif arg.is_negative:
  480. return -arg
  481. return
  482. if arg.is_Add and arg.has(oo, S.NegativeInfinity):
  483. if any(a.is_infinite for a in arg.as_real_imag()):
  484. return oo
  485. if arg.is_zero:
  486. return S.Zero
  487. if arg.is_extended_nonnegative:
  488. return arg
  489. if arg.is_extended_nonpositive:
  490. return -arg
  491. if arg.is_imaginary:
  492. arg2 = -I * arg
  493. if arg2.is_extended_nonnegative:
  494. return arg2
  495. if arg.is_extended_real:
  496. return
  497. # reject result if all new conjugates are just wrappers around
  498. # an expression that was already in the arg
  499. conj = signsimp(arg.conjugate(), evaluate=False)
  500. new_conj = conj.atoms(conjugate) - arg.atoms(conjugate)
  501. if new_conj and all(arg.has(i.args[0]) for i in new_conj):
  502. return
  503. if arg != conj and arg != -conj:
  504. ignore = arg.atoms(Abs)
  505. abs_free_arg = arg.xreplace({i: Dummy(real=True) for i in ignore})
  506. unk = [a for a in abs_free_arg.free_symbols if a.is_extended_real is None]
  507. if not unk or not all(conj.has(conjugate(u)) for u in unk):
  508. return sqrt(expand_mul(arg*conj))
  509. def _eval_is_real(self):
  510. if self.args[0].is_finite:
  511. return True
  512. def _eval_is_integer(self):
  513. if self.args[0].is_extended_real:
  514. return self.args[0].is_integer
  515. def _eval_is_extended_nonzero(self):
  516. return fuzzy_not(self._args[0].is_zero)
  517. def _eval_is_zero(self):
  518. return self._args[0].is_zero
  519. def _eval_is_extended_positive(self):
  520. return fuzzy_not(self._args[0].is_zero)
  521. def _eval_is_rational(self):
  522. if self.args[0].is_extended_real:
  523. return self.args[0].is_rational
  524. def _eval_is_even(self):
  525. if self.args[0].is_extended_real:
  526. return self.args[0].is_even
  527. def _eval_is_odd(self):
  528. if self.args[0].is_extended_real:
  529. return self.args[0].is_odd
  530. def _eval_is_algebraic(self):
  531. return self.args[0].is_algebraic
  532. def _eval_power(self, exponent):
  533. if self.args[0].is_extended_real and exponent.is_integer:
  534. if exponent.is_even:
  535. return self.args[0]**exponent
  536. elif exponent is not S.NegativeOne and exponent.is_Integer:
  537. return self.args[0]**(exponent - 1)*self
  538. return
  539. def _eval_nseries(self, x, n, logx, cdir=0):
  540. from sympy.functions.elementary.exponential import log
  541. direction = self.args[0].leadterm(x)[0]
  542. if direction.has(log(x)):
  543. direction = direction.subs(log(x), logx)
  544. s = self.args[0]._eval_nseries(x, n=n, logx=logx)
  545. return (sign(direction)*s).expand()
  546. def _eval_derivative(self, x):
  547. if self.args[0].is_extended_real or self.args[0].is_imaginary:
  548. return Derivative(self.args[0], x, evaluate=True) \
  549. * sign(conjugate(self.args[0]))
  550. rv = (re(self.args[0]) * Derivative(re(self.args[0]), x,
  551. evaluate=True) + im(self.args[0]) * Derivative(im(self.args[0]),
  552. x, evaluate=True)) / Abs(self.args[0])
  553. return rv.rewrite(sign)
  554. def _eval_rewrite_as_Heaviside(self, arg, **kwargs):
  555. # Note this only holds for real arg (since Heaviside is not defined
  556. # for complex arguments).
  557. from sympy.functions.special.delta_functions import Heaviside
  558. if arg.is_extended_real:
  559. return arg*(Heaviside(arg) - Heaviside(-arg))
  560. def _eval_rewrite_as_Piecewise(self, arg, **kwargs):
  561. if arg.is_extended_real:
  562. return Piecewise((arg, arg >= 0), (-arg, True))
  563. elif arg.is_imaginary:
  564. return Piecewise((I*arg, I*arg >= 0), (-I*arg, True))
  565. def _eval_rewrite_as_sign(self, arg, **kwargs):
  566. return arg/sign(arg)
  567. def _eval_rewrite_as_conjugate(self, arg, **kwargs):
  568. return sqrt(arg*conjugate(arg))
  569. class arg(Function):
  570. r"""
  571. Returns the argument (in radians) of a complex number. The argument is
  572. evaluated in consistent convention with ``atan2`` where the branch-cut is
  573. taken along the negative real axis and ``arg(z)`` is in the interval
  574. $(-\pi,\pi]$. For a positive number, the argument is always 0; the
  575. argument of a negative number is $\pi$; and the argument of 0
  576. is undefined and returns ``nan``. So the ``arg`` function will never nest
  577. greater than 3 levels since at the 4th application, the result must be
  578. nan; for a real number, nan is returned on the 3rd application.
  579. Examples
  580. ========
  581. >>> from sympy import arg, I, sqrt, Dummy
  582. >>> from sympy.abc import x
  583. >>> arg(2.0)
  584. 0
  585. >>> arg(I)
  586. pi/2
  587. >>> arg(sqrt(2) + I*sqrt(2))
  588. pi/4
  589. >>> arg(sqrt(3)/2 + I/2)
  590. pi/6
  591. >>> arg(4 + 3*I)
  592. atan(3/4)
  593. >>> arg(0.8 + 0.6*I)
  594. 0.643501108793284
  595. >>> arg(arg(arg(arg(x))))
  596. nan
  597. >>> real = Dummy(real=True)
  598. >>> arg(arg(arg(real)))
  599. nan
  600. Parameters
  601. ==========
  602. arg : Expr
  603. Real or complex expression.
  604. Returns
  605. =======
  606. value : Expr
  607. Returns arc tangent of arg measured in radians.
  608. """
  609. is_extended_real = True
  610. is_real = True
  611. is_finite = True
  612. _singularities = True # non-holomorphic
  613. @classmethod
  614. def eval(cls, arg):
  615. a = arg
  616. for i in range(3):
  617. if isinstance(a, cls):
  618. a = a.args[0]
  619. else:
  620. if i == 2 and a.is_extended_real:
  621. return S.NaN
  622. break
  623. else:
  624. return S.NaN
  625. from sympy.functions.elementary.exponential import exp_polar
  626. if isinstance(arg, exp_polar):
  627. return periodic_argument(arg, oo)
  628. if not arg.is_Atom:
  629. c, arg_ = factor_terms(arg).as_coeff_Mul()
  630. if arg_.is_Mul:
  631. arg_ = Mul(*[a if (sign(a) not in (-1, 1)) else
  632. sign(a) for a in arg_.args])
  633. arg_ = sign(c)*arg_
  634. else:
  635. arg_ = arg
  636. if any(i.is_extended_positive is None for i in arg_.atoms(AppliedUndef)):
  637. return
  638. from sympy.functions.elementary.trigonometric import atan2
  639. x, y = arg_.as_real_imag()
  640. rv = atan2(y, x)
  641. if rv.is_number:
  642. return rv
  643. if arg_ != arg:
  644. return cls(arg_, evaluate=False)
  645. def _eval_derivative(self, t):
  646. x, y = self.args[0].as_real_imag()
  647. return (x * Derivative(y, t, evaluate=True) - y *
  648. Derivative(x, t, evaluate=True)) / (x**2 + y**2)
  649. def _eval_rewrite_as_atan2(self, arg, **kwargs):
  650. from sympy.functions.elementary.trigonometric import atan2
  651. x, y = self.args[0].as_real_imag()
  652. return atan2(y, x)
  653. class conjugate(Function):
  654. """
  655. Returns the *complex conjugate* [1]_ of an argument.
  656. In mathematics, the complex conjugate of a complex number
  657. is given by changing the sign of the imaginary part.
  658. Thus, the conjugate of the complex number
  659. :math:`a + ib` (where $a$ and $b$ are real numbers) is :math:`a - ib`
  660. Examples
  661. ========
  662. >>> from sympy import conjugate, I
  663. >>> conjugate(2)
  664. 2
  665. >>> conjugate(I)
  666. -I
  667. >>> conjugate(3 + 2*I)
  668. 3 - 2*I
  669. >>> conjugate(5 - I)
  670. 5 + I
  671. Parameters
  672. ==========
  673. arg : Expr
  674. Real or complex expression.
  675. Returns
  676. =======
  677. arg : Expr
  678. Complex conjugate of arg as real, imaginary or mixed expression.
  679. See Also
  680. ========
  681. sign, Abs
  682. References
  683. ==========
  684. .. [1] https://en.wikipedia.org/wiki/Complex_conjugation
  685. """
  686. _singularities = True # non-holomorphic
  687. @classmethod
  688. def eval(cls, arg):
  689. obj = arg._eval_conjugate()
  690. if obj is not None:
  691. return obj
  692. def inverse(self):
  693. return conjugate
  694. def _eval_Abs(self):
  695. return Abs(self.args[0], evaluate=True)
  696. def _eval_adjoint(self):
  697. return transpose(self.args[0])
  698. def _eval_conjugate(self):
  699. return self.args[0]
  700. def _eval_derivative(self, x):
  701. if x.is_real:
  702. return conjugate(Derivative(self.args[0], x, evaluate=True))
  703. elif x.is_imaginary:
  704. return -conjugate(Derivative(self.args[0], x, evaluate=True))
  705. def _eval_transpose(self):
  706. return adjoint(self.args[0])
  707. def _eval_is_algebraic(self):
  708. return self.args[0].is_algebraic
  709. class transpose(Function):
  710. """
  711. Linear map transposition.
  712. Examples
  713. ========
  714. >>> from sympy import transpose, Matrix, MatrixSymbol
  715. >>> A = MatrixSymbol('A', 25, 9)
  716. >>> transpose(A)
  717. A.T
  718. >>> B = MatrixSymbol('B', 9, 22)
  719. >>> transpose(B)
  720. B.T
  721. >>> transpose(A*B)
  722. B.T*A.T
  723. >>> M = Matrix([[4, 5], [2, 1], [90, 12]])
  724. >>> M
  725. Matrix([
  726. [ 4, 5],
  727. [ 2, 1],
  728. [90, 12]])
  729. >>> transpose(M)
  730. Matrix([
  731. [4, 2, 90],
  732. [5, 1, 12]])
  733. Parameters
  734. ==========
  735. arg : Matrix
  736. Matrix or matrix expression to take the transpose of.
  737. Returns
  738. =======
  739. value : Matrix
  740. Transpose of arg.
  741. """
  742. @classmethod
  743. def eval(cls, arg):
  744. obj = arg._eval_transpose()
  745. if obj is not None:
  746. return obj
  747. def _eval_adjoint(self):
  748. return conjugate(self.args[0])
  749. def _eval_conjugate(self):
  750. return adjoint(self.args[0])
  751. def _eval_transpose(self):
  752. return self.args[0]
  753. class adjoint(Function):
  754. """
  755. Conjugate transpose or Hermite conjugation.
  756. Examples
  757. ========
  758. >>> from sympy import adjoint, MatrixSymbol
  759. >>> A = MatrixSymbol('A', 10, 5)
  760. >>> adjoint(A)
  761. Adjoint(A)
  762. Parameters
  763. ==========
  764. arg : Matrix
  765. Matrix or matrix expression to take the adjoint of.
  766. Returns
  767. =======
  768. value : Matrix
  769. Represents the conjugate transpose or Hermite
  770. conjugation of arg.
  771. """
  772. @classmethod
  773. def eval(cls, arg):
  774. obj = arg._eval_adjoint()
  775. if obj is not None:
  776. return obj
  777. obj = arg._eval_transpose()
  778. if obj is not None:
  779. return conjugate(obj)
  780. def _eval_adjoint(self):
  781. return self.args[0]
  782. def _eval_conjugate(self):
  783. return transpose(self.args[0])
  784. def _eval_transpose(self):
  785. return conjugate(self.args[0])
  786. def _latex(self, printer, exp=None, *args):
  787. arg = printer._print(self.args[0])
  788. tex = r'%s^{\dagger}' % arg
  789. if exp:
  790. tex = r'\left(%s\right)^{%s}' % (tex, exp)
  791. return tex
  792. def _pretty(self, printer, *args):
  793. from sympy.printing.pretty.stringpict import prettyForm
  794. pform = printer._print(self.args[0], *args)
  795. if printer._use_unicode:
  796. pform = pform**prettyForm('\N{DAGGER}')
  797. else:
  798. pform = pform**prettyForm('+')
  799. return pform
  800. ###############################################################################
  801. ############### HANDLING OF POLAR NUMBERS #####################################
  802. ###############################################################################
  803. class polar_lift(Function):
  804. """
  805. Lift argument to the Riemann surface of the logarithm, using the
  806. standard branch.
  807. Examples
  808. ========
  809. >>> from sympy import Symbol, polar_lift, I
  810. >>> p = Symbol('p', polar=True)
  811. >>> x = Symbol('x')
  812. >>> polar_lift(4)
  813. 4*exp_polar(0)
  814. >>> polar_lift(-4)
  815. 4*exp_polar(I*pi)
  816. >>> polar_lift(-I)
  817. exp_polar(-I*pi/2)
  818. >>> polar_lift(I + 2)
  819. polar_lift(2 + I)
  820. >>> polar_lift(4*x)
  821. 4*polar_lift(x)
  822. >>> polar_lift(4*p)
  823. 4*p
  824. Parameters
  825. ==========
  826. arg : Expr
  827. Real or complex expression.
  828. See Also
  829. ========
  830. sympy.functions.elementary.exponential.exp_polar
  831. periodic_argument
  832. """
  833. is_polar = True
  834. is_comparable = False # Cannot be evalf'd.
  835. @classmethod
  836. def eval(cls, arg):
  837. from sympy.functions.elementary.complexes import arg as argument
  838. if arg.is_number:
  839. ar = argument(arg)
  840. # In general we want to affirm that something is known,
  841. # e.g. `not ar.has(argument) and not ar.has(atan)`
  842. # but for now we will just be more restrictive and
  843. # see that it has evaluated to one of the known values.
  844. if ar in (0, pi/2, -pi/2, pi):
  845. from sympy.functions.elementary.exponential import exp_polar
  846. return exp_polar(I*ar)*abs(arg)
  847. if arg.is_Mul:
  848. args = arg.args
  849. else:
  850. args = [arg]
  851. included = []
  852. excluded = []
  853. positive = []
  854. for arg in args:
  855. if arg.is_polar:
  856. included += [arg]
  857. elif arg.is_positive:
  858. positive += [arg]
  859. else:
  860. excluded += [arg]
  861. if len(excluded) < len(args):
  862. if excluded:
  863. return Mul(*(included + positive))*polar_lift(Mul(*excluded))
  864. elif included:
  865. return Mul(*(included + positive))
  866. else:
  867. from sympy.functions.elementary.exponential import exp_polar
  868. return Mul(*positive)*exp_polar(0)
  869. def _eval_evalf(self, prec):
  870. """ Careful! any evalf of polar numbers is flaky """
  871. return self.args[0]._eval_evalf(prec)
  872. def _eval_Abs(self):
  873. return Abs(self.args[0], evaluate=True)
  874. class periodic_argument(Function):
  875. r"""
  876. Represent the argument on a quotient of the Riemann surface of the
  877. logarithm. That is, given a period $P$, always return a value in
  878. $(-P/2, P/2]$, by using $\exp(PI) = 1$.
  879. Examples
  880. ========
  881. >>> from sympy import exp_polar, periodic_argument
  882. >>> from sympy import I, pi
  883. >>> periodic_argument(exp_polar(10*I*pi), 2*pi)
  884. 0
  885. >>> periodic_argument(exp_polar(5*I*pi), 4*pi)
  886. pi
  887. >>> from sympy import exp_polar, periodic_argument
  888. >>> from sympy import I, pi
  889. >>> periodic_argument(exp_polar(5*I*pi), 2*pi)
  890. pi
  891. >>> periodic_argument(exp_polar(5*I*pi), 3*pi)
  892. -pi
  893. >>> periodic_argument(exp_polar(5*I*pi), pi)
  894. 0
  895. Parameters
  896. ==========
  897. ar : Expr
  898. A polar number.
  899. period : Expr
  900. The period $P$.
  901. See Also
  902. ========
  903. sympy.functions.elementary.exponential.exp_polar
  904. polar_lift : Lift argument to the Riemann surface of the logarithm
  905. principal_branch
  906. """
  907. @classmethod
  908. def _getunbranched(cls, ar):
  909. from sympy.functions.elementary.exponential import exp_polar, log
  910. if ar.is_Mul:
  911. args = ar.args
  912. else:
  913. args = [ar]
  914. unbranched = 0
  915. for a in args:
  916. if not a.is_polar:
  917. unbranched += arg(a)
  918. elif isinstance(a, exp_polar):
  919. unbranched += a.exp.as_real_imag()[1]
  920. elif a.is_Pow:
  921. re, im = a.exp.as_real_imag()
  922. unbranched += re*unbranched_argument(
  923. a.base) + im*log(abs(a.base))
  924. elif isinstance(a, polar_lift):
  925. unbranched += arg(a.args[0])
  926. else:
  927. return None
  928. return unbranched
  929. @classmethod
  930. def eval(cls, ar, period):
  931. # Our strategy is to evaluate the argument on the Riemann surface of the
  932. # logarithm, and then reduce.
  933. # NOTE evidently this means it is a rather bad idea to use this with
  934. # period != 2*pi and non-polar numbers.
  935. if not period.is_extended_positive:
  936. return None
  937. if period == oo and isinstance(ar, principal_branch):
  938. return periodic_argument(*ar.args)
  939. if isinstance(ar, polar_lift) and period >= 2*pi:
  940. return periodic_argument(ar.args[0], period)
  941. if ar.is_Mul:
  942. newargs = [x for x in ar.args if not x.is_positive]
  943. if len(newargs) != len(ar.args):
  944. return periodic_argument(Mul(*newargs), period)
  945. unbranched = cls._getunbranched(ar)
  946. if unbranched is None:
  947. return None
  948. from sympy.functions.elementary.trigonometric import atan, atan2
  949. if unbranched.has(periodic_argument, atan2, atan):
  950. return None
  951. if period == oo:
  952. return unbranched
  953. if period != oo:
  954. from sympy.functions.elementary.integers import ceiling
  955. n = ceiling(unbranched/period - S.Half)*period
  956. if not n.has(ceiling):
  957. return unbranched - n
  958. def _eval_evalf(self, prec):
  959. z, period = self.args
  960. if period == oo:
  961. unbranched = periodic_argument._getunbranched(z)
  962. if unbranched is None:
  963. return self
  964. return unbranched._eval_evalf(prec)
  965. ub = periodic_argument(z, oo)._eval_evalf(prec)
  966. from sympy.functions.elementary.integers import ceiling
  967. return (ub - ceiling(ub/period - S.Half)*period)._eval_evalf(prec)
  968. def unbranched_argument(arg):
  969. '''
  970. Returns periodic argument of arg with period as infinity.
  971. Examples
  972. ========
  973. >>> from sympy import exp_polar, unbranched_argument
  974. >>> from sympy import I, pi
  975. >>> unbranched_argument(exp_polar(15*I*pi))
  976. 15*pi
  977. >>> unbranched_argument(exp_polar(7*I*pi))
  978. 7*pi
  979. See also
  980. ========
  981. periodic_argument
  982. '''
  983. return periodic_argument(arg, oo)
  984. class principal_branch(Function):
  985. """
  986. Represent a polar number reduced to its principal branch on a quotient
  987. of the Riemann surface of the logarithm.
  988. Explanation
  989. ===========
  990. This is a function of two arguments. The first argument is a polar
  991. number `z`, and the second one a positive real number or infinity, `p`.
  992. The result is ``z mod exp_polar(I*p)``.
  993. Examples
  994. ========
  995. >>> from sympy import exp_polar, principal_branch, oo, I, pi
  996. >>> from sympy.abc import z
  997. >>> principal_branch(z, oo)
  998. z
  999. >>> principal_branch(exp_polar(2*pi*I)*3, 2*pi)
  1000. 3*exp_polar(0)
  1001. >>> principal_branch(exp_polar(2*pi*I)*3*z, 2*pi)
  1002. 3*principal_branch(z, 2*pi)
  1003. Parameters
  1004. ==========
  1005. x : Expr
  1006. A polar number.
  1007. period : Expr
  1008. Positive real number or infinity.
  1009. See Also
  1010. ========
  1011. sympy.functions.elementary.exponential.exp_polar
  1012. polar_lift : Lift argument to the Riemann surface of the logarithm
  1013. periodic_argument
  1014. """
  1015. is_polar = True
  1016. is_comparable = False # cannot always be evalf'd
  1017. @classmethod
  1018. def eval(self, x, period):
  1019. from sympy.functions.elementary.exponential import exp_polar
  1020. if isinstance(x, polar_lift):
  1021. return principal_branch(x.args[0], period)
  1022. if period == oo:
  1023. return x
  1024. ub = periodic_argument(x, oo)
  1025. barg = periodic_argument(x, period)
  1026. if ub != barg and not ub.has(periodic_argument) \
  1027. and not barg.has(periodic_argument):
  1028. pl = polar_lift(x)
  1029. def mr(expr):
  1030. if not isinstance(expr, Symbol):
  1031. return polar_lift(expr)
  1032. return expr
  1033. pl = pl.replace(polar_lift, mr)
  1034. # Recompute unbranched argument
  1035. ub = periodic_argument(pl, oo)
  1036. if not pl.has(polar_lift):
  1037. if ub != barg:
  1038. res = exp_polar(I*(barg - ub))*pl
  1039. else:
  1040. res = pl
  1041. if not res.is_polar and not res.has(exp_polar):
  1042. res *= exp_polar(0)
  1043. return res
  1044. if not x.free_symbols:
  1045. c, m = x, ()
  1046. else:
  1047. c, m = x.as_coeff_mul(*x.free_symbols)
  1048. others = []
  1049. for y in m:
  1050. if y.is_positive:
  1051. c *= y
  1052. else:
  1053. others += [y]
  1054. m = tuple(others)
  1055. arg = periodic_argument(c, period)
  1056. if arg.has(periodic_argument):
  1057. return None
  1058. if arg.is_number and (unbranched_argument(c) != arg or
  1059. (arg == 0 and m != () and c != 1)):
  1060. if arg == 0:
  1061. return abs(c)*principal_branch(Mul(*m), period)
  1062. return principal_branch(exp_polar(I*arg)*Mul(*m), period)*abs(c)
  1063. if arg.is_number and ((abs(arg) < period/2) == True or arg == period/2) \
  1064. and m == ():
  1065. return exp_polar(arg*I)*abs(c)
  1066. def _eval_evalf(self, prec):
  1067. z, period = self.args
  1068. p = periodic_argument(z, period)._eval_evalf(prec)
  1069. if abs(p) > pi or p == -pi:
  1070. return self # Cannot evalf for this argument.
  1071. from sympy.functions.elementary.exponential import exp
  1072. return (abs(z)*exp(I*p))._eval_evalf(prec)
  1073. def _polarify(eq, lift, pause=False):
  1074. from sympy.integrals.integrals import Integral
  1075. if eq.is_polar:
  1076. return eq
  1077. if eq.is_number and not pause:
  1078. return polar_lift(eq)
  1079. if isinstance(eq, Symbol) and not pause and lift:
  1080. return polar_lift(eq)
  1081. elif eq.is_Atom:
  1082. return eq
  1083. elif eq.is_Add:
  1084. r = eq.func(*[_polarify(arg, lift, pause=True) for arg in eq.args])
  1085. if lift:
  1086. return polar_lift(r)
  1087. return r
  1088. elif eq.is_Pow and eq.base == S.Exp1:
  1089. return eq.func(S.Exp1, _polarify(eq.exp, lift, pause=False))
  1090. elif eq.is_Function:
  1091. return eq.func(*[_polarify(arg, lift, pause=False) for arg in eq.args])
  1092. elif isinstance(eq, Integral):
  1093. # Don't lift the integration variable
  1094. func = _polarify(eq.function, lift, pause=pause)
  1095. limits = []
  1096. for limit in eq.args[1:]:
  1097. var = _polarify(limit[0], lift=False, pause=pause)
  1098. rest = _polarify(limit[1:], lift=lift, pause=pause)
  1099. limits.append((var,) + rest)
  1100. return Integral(*((func,) + tuple(limits)))
  1101. else:
  1102. return eq.func(*[_polarify(arg, lift, pause=pause)
  1103. if isinstance(arg, Expr) else arg for arg in eq.args])
  1104. def polarify(eq, subs=True, lift=False):
  1105. """
  1106. Turn all numbers in eq into their polar equivalents (under the standard
  1107. choice of argument).
  1108. Note that no attempt is made to guess a formal convention of adding
  1109. polar numbers, expressions like $1 + x$ will generally not be altered.
  1110. Note also that this function does not promote ``exp(x)`` to ``exp_polar(x)``.
  1111. If ``subs`` is ``True``, all symbols which are not already polar will be
  1112. substituted for polar dummies; in this case the function behaves much
  1113. like :func:`~.posify`.
  1114. If ``lift`` is ``True``, both addition statements and non-polar symbols are
  1115. changed to their ``polar_lift()``ed versions.
  1116. Note that ``lift=True`` implies ``subs=False``.
  1117. Examples
  1118. ========
  1119. >>> from sympy import polarify, sin, I
  1120. >>> from sympy.abc import x, y
  1121. >>> expr = (-x)**y
  1122. >>> expr.expand()
  1123. (-x)**y
  1124. >>> polarify(expr)
  1125. ((_x*exp_polar(I*pi))**_y, {_x: x, _y: y})
  1126. >>> polarify(expr)[0].expand()
  1127. _x**_y*exp_polar(_y*I*pi)
  1128. >>> polarify(x, lift=True)
  1129. polar_lift(x)
  1130. >>> polarify(x*(1+y), lift=True)
  1131. polar_lift(x)*polar_lift(y + 1)
  1132. Adds are treated carefully:
  1133. >>> polarify(1 + sin((1 + I)*x))
  1134. (sin(_x*polar_lift(1 + I)) + 1, {_x: x})
  1135. """
  1136. if lift:
  1137. subs = False
  1138. eq = _polarify(sympify(eq), lift)
  1139. if not subs:
  1140. return eq
  1141. reps = {s: Dummy(s.name, polar=True) for s in eq.free_symbols}
  1142. eq = eq.subs(reps)
  1143. return eq, {r: s for s, r in reps.items()}
  1144. def _unpolarify(eq, exponents_only, pause=False):
  1145. if not isinstance(eq, Basic) or eq.is_Atom:
  1146. return eq
  1147. if not pause:
  1148. from sympy.functions.elementary.exponential import exp, exp_polar
  1149. if isinstance(eq, exp_polar):
  1150. return exp(_unpolarify(eq.exp, exponents_only))
  1151. if isinstance(eq, principal_branch) and eq.args[1] == 2*pi:
  1152. return _unpolarify(eq.args[0], exponents_only)
  1153. if (
  1154. eq.is_Add or eq.is_Mul or eq.is_Boolean or
  1155. eq.is_Relational and (
  1156. eq.rel_op in ('==', '!=') and 0 in eq.args or
  1157. eq.rel_op not in ('==', '!='))
  1158. ):
  1159. return eq.func(*[_unpolarify(x, exponents_only) for x in eq.args])
  1160. if isinstance(eq, polar_lift):
  1161. return _unpolarify(eq.args[0], exponents_only)
  1162. if eq.is_Pow:
  1163. expo = _unpolarify(eq.exp, exponents_only)
  1164. base = _unpolarify(eq.base, exponents_only,
  1165. not (expo.is_integer and not pause))
  1166. return base**expo
  1167. if eq.is_Function and getattr(eq.func, 'unbranched', False):
  1168. return eq.func(*[_unpolarify(x, exponents_only, exponents_only)
  1169. for x in eq.args])
  1170. return eq.func(*[_unpolarify(x, exponents_only, True) for x in eq.args])
  1171. def unpolarify(eq, subs=None, exponents_only=False):
  1172. """
  1173. If `p` denotes the projection from the Riemann surface of the logarithm to
  1174. the complex line, return a simplified version `eq'` of `eq` such that
  1175. `p(eq') = p(eq)`.
  1176. Also apply the substitution subs in the end. (This is a convenience, since
  1177. ``unpolarify``, in a certain sense, undoes :func:`polarify`.)
  1178. Examples
  1179. ========
  1180. >>> from sympy import unpolarify, polar_lift, sin, I
  1181. >>> unpolarify(polar_lift(I + 2))
  1182. 2 + I
  1183. >>> unpolarify(sin(polar_lift(I + 7)))
  1184. sin(7 + I)
  1185. """
  1186. if isinstance(eq, bool):
  1187. return eq
  1188. eq = sympify(eq)
  1189. if subs is not None:
  1190. return unpolarify(eq.subs(subs))
  1191. changed = True
  1192. pause = False
  1193. if exponents_only:
  1194. pause = True
  1195. while changed:
  1196. changed = False
  1197. res = _unpolarify(eq, exponents_only, pause)
  1198. if res != eq:
  1199. changed = True
  1200. eq = res
  1201. if isinstance(res, bool):
  1202. return res
  1203. # Finally, replacing Exp(0) by 1 is always correct.
  1204. # So is polar_lift(0) -> 0.
  1205. from sympy.functions.elementary.exponential import exp_polar
  1206. return res.subs({exp_polar(0): 1, polar_lift(0): 0})