hyperbolic.py 52 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808
  1. from sympy.core.logic import FuzzyBool
  2. from sympy.core import S, sympify, cacheit, pi, I, Rational
  3. from sympy.core.add import Add
  4. from sympy.core.function import Function, ArgumentIndexError
  5. from sympy.functions.combinatorial.factorials import factorial, RisingFactorial
  6. from sympy.functions.elementary.exponential import exp, log, match_real_imag
  7. from sympy.functions.elementary.miscellaneous import sqrt
  8. from sympy.functions.elementary.integers import floor
  9. from sympy.core.logic import fuzzy_or, fuzzy_and
  10. def _rewrite_hyperbolics_as_exp(expr):
  11. expr = sympify(expr)
  12. return expr.xreplace({h: h.rewrite(exp)
  13. for h in expr.atoms(HyperbolicFunction)})
  14. ###############################################################################
  15. ########################### HYPERBOLIC FUNCTIONS ##############################
  16. ###############################################################################
  17. class HyperbolicFunction(Function):
  18. """
  19. Base class for hyperbolic functions.
  20. See Also
  21. ========
  22. sinh, cosh, tanh, coth
  23. """
  24. unbranched = True
  25. def _peeloff_ipi(arg):
  26. r"""
  27. Split ARG into two parts, a "rest" and a multiple of $I\pi$.
  28. This assumes ARG to be an ``Add``.
  29. The multiple of $I\pi$ returned in the second position is always a ``Rational``.
  30. Examples
  31. ========
  32. >>> from sympy.functions.elementary.hyperbolic import _peeloff_ipi as peel
  33. >>> from sympy import pi, I
  34. >>> from sympy.abc import x, y
  35. >>> peel(x + I*pi/2)
  36. (x, 1/2)
  37. >>> peel(x + I*2*pi/3 + I*pi*y)
  38. (x + I*pi*y + I*pi/6, 1/2)
  39. """
  40. ipi = S.Pi*S.ImaginaryUnit
  41. for a in Add.make_args(arg):
  42. if a == ipi:
  43. K = S.One
  44. break
  45. elif a.is_Mul:
  46. K, p = a.as_two_terms()
  47. if p == ipi and K.is_Rational:
  48. break
  49. else:
  50. return arg, S.Zero
  51. m1 = (K % S.Half)
  52. m2 = K - m1
  53. return arg - m2*ipi, m2
  54. class sinh(HyperbolicFunction):
  55. r"""
  56. ``sinh(x)`` is the hyperbolic sine of ``x``.
  57. The hyperbolic sine function is $\frac{e^x - e^{-x}}{2}$.
  58. Examples
  59. ========
  60. >>> from sympy import sinh
  61. >>> from sympy.abc import x
  62. >>> sinh(x)
  63. sinh(x)
  64. See Also
  65. ========
  66. cosh, tanh, asinh
  67. """
  68. def fdiff(self, argindex=1):
  69. """
  70. Returns the first derivative of this function.
  71. """
  72. if argindex == 1:
  73. return cosh(self.args[0])
  74. else:
  75. raise ArgumentIndexError(self, argindex)
  76. def inverse(self, argindex=1):
  77. """
  78. Returns the inverse of this function.
  79. """
  80. return asinh
  81. @classmethod
  82. def eval(cls, arg):
  83. from sympy.functions.elementary.trigonometric import sin
  84. arg = sympify(arg)
  85. if arg.is_Number:
  86. if arg is S.NaN:
  87. return S.NaN
  88. elif arg is S.Infinity:
  89. return S.Infinity
  90. elif arg is S.NegativeInfinity:
  91. return S.NegativeInfinity
  92. elif arg.is_zero:
  93. return S.Zero
  94. elif arg.is_negative:
  95. return -cls(-arg)
  96. else:
  97. if arg is S.ComplexInfinity:
  98. return S.NaN
  99. i_coeff = arg.as_coefficient(S.ImaginaryUnit)
  100. if i_coeff is not None:
  101. return S.ImaginaryUnit * sin(i_coeff)
  102. else:
  103. if arg.could_extract_minus_sign():
  104. return -cls(-arg)
  105. if arg.is_Add:
  106. x, m = _peeloff_ipi(arg)
  107. if m:
  108. m = m*S.Pi*S.ImaginaryUnit
  109. return sinh(m)*cosh(x) + cosh(m)*sinh(x)
  110. if arg.is_zero:
  111. return S.Zero
  112. if arg.func == asinh:
  113. return arg.args[0]
  114. if arg.func == acosh:
  115. x = arg.args[0]
  116. return sqrt(x - 1) * sqrt(x + 1)
  117. if arg.func == atanh:
  118. x = arg.args[0]
  119. return x/sqrt(1 - x**2)
  120. if arg.func == acoth:
  121. x = arg.args[0]
  122. return 1/(sqrt(x - 1) * sqrt(x + 1))
  123. @staticmethod
  124. @cacheit
  125. def taylor_term(n, x, *previous_terms):
  126. """
  127. Returns the next term in the Taylor series expansion.
  128. """
  129. if n < 0 or n % 2 == 0:
  130. return S.Zero
  131. else:
  132. x = sympify(x)
  133. if len(previous_terms) > 2:
  134. p = previous_terms[-2]
  135. return p * x**2 / (n*(n - 1))
  136. else:
  137. return x**(n) / factorial(n)
  138. def _eval_conjugate(self):
  139. return self.func(self.args[0].conjugate())
  140. def as_real_imag(self, deep=True, **hints):
  141. """
  142. Returns this function as a complex coordinate.
  143. """
  144. from sympy.functions.elementary.trigonometric import (cos, sin)
  145. if self.args[0].is_extended_real:
  146. if deep:
  147. hints['complex'] = False
  148. return (self.expand(deep, **hints), S.Zero)
  149. else:
  150. return (self, S.Zero)
  151. if deep:
  152. re, im = self.args[0].expand(deep, **hints).as_real_imag()
  153. else:
  154. re, im = self.args[0].as_real_imag()
  155. return (sinh(re)*cos(im), cosh(re)*sin(im))
  156. def _eval_expand_complex(self, deep=True, **hints):
  157. re_part, im_part = self.as_real_imag(deep=deep, **hints)
  158. return re_part + im_part*S.ImaginaryUnit
  159. def _eval_expand_trig(self, deep=True, **hints):
  160. if deep:
  161. arg = self.args[0].expand(deep, **hints)
  162. else:
  163. arg = self.args[0]
  164. x = None
  165. if arg.is_Add: # TODO, implement more if deep stuff here
  166. x, y = arg.as_two_terms()
  167. else:
  168. coeff, terms = arg.as_coeff_Mul(rational=True)
  169. if coeff is not S.One and coeff.is_Integer and terms is not S.One:
  170. x = terms
  171. y = (coeff - 1)*x
  172. if x is not None:
  173. return (sinh(x)*cosh(y) + sinh(y)*cosh(x)).expand(trig=True)
  174. return sinh(arg)
  175. def _eval_rewrite_as_tractable(self, arg, limitvar=None, **kwargs):
  176. return (exp(arg) - exp(-arg)) / 2
  177. def _eval_rewrite_as_exp(self, arg, **kwargs):
  178. return (exp(arg) - exp(-arg)) / 2
  179. def _eval_rewrite_as_cosh(self, arg, **kwargs):
  180. return -S.ImaginaryUnit*cosh(arg + S.Pi*S.ImaginaryUnit/2)
  181. def _eval_rewrite_as_tanh(self, arg, **kwargs):
  182. tanh_half = tanh(S.Half*arg)
  183. return 2*tanh_half/(1 - tanh_half**2)
  184. def _eval_rewrite_as_coth(self, arg, **kwargs):
  185. coth_half = coth(S.Half*arg)
  186. return 2*coth_half/(coth_half**2 - 1)
  187. def _eval_as_leading_term(self, x, logx=None, cdir=0):
  188. arg = self.args[0].as_leading_term(x, logx=logx, cdir=cdir)
  189. arg0 = arg.subs(x, 0)
  190. if arg0 is S.NaN:
  191. arg0 = arg.limit(x, 0, dir='-' if cdir.is_negative else '+')
  192. if arg0.is_zero:
  193. return arg
  194. elif arg0.is_finite:
  195. return self.func(arg0)
  196. else:
  197. return self
  198. def _eval_is_real(self):
  199. arg = self.args[0]
  200. if arg.is_real:
  201. return True
  202. # if `im` is of the form n*pi
  203. # else, check if it is a number
  204. re, im = arg.as_real_imag()
  205. return (im%pi).is_zero
  206. def _eval_is_extended_real(self):
  207. if self.args[0].is_extended_real:
  208. return True
  209. def _eval_is_positive(self):
  210. if self.args[0].is_extended_real:
  211. return self.args[0].is_positive
  212. def _eval_is_negative(self):
  213. if self.args[0].is_extended_real:
  214. return self.args[0].is_negative
  215. def _eval_is_finite(self):
  216. arg = self.args[0]
  217. return arg.is_finite
  218. def _eval_is_zero(self):
  219. rest, ipi_mult = _peeloff_ipi(self.args[0])
  220. if rest.is_zero:
  221. return ipi_mult.is_integer
  222. class cosh(HyperbolicFunction):
  223. r"""
  224. ``cosh(x)`` is the hyperbolic cosine of ``x``.
  225. The hyperbolic cosine function is $\frac{e^x + e^{-x}}{2}$.
  226. Examples
  227. ========
  228. >>> from sympy import cosh
  229. >>> from sympy.abc import x
  230. >>> cosh(x)
  231. cosh(x)
  232. See Also
  233. ========
  234. sinh, tanh, acosh
  235. """
  236. def fdiff(self, argindex=1):
  237. if argindex == 1:
  238. return sinh(self.args[0])
  239. else:
  240. raise ArgumentIndexError(self, argindex)
  241. @classmethod
  242. def eval(cls, arg):
  243. from sympy.functions.elementary.trigonometric import cos
  244. arg = sympify(arg)
  245. if arg.is_Number:
  246. if arg is S.NaN:
  247. return S.NaN
  248. elif arg is S.Infinity:
  249. return S.Infinity
  250. elif arg is S.NegativeInfinity:
  251. return S.Infinity
  252. elif arg.is_zero:
  253. return S.One
  254. elif arg.is_negative:
  255. return cls(-arg)
  256. else:
  257. if arg is S.ComplexInfinity:
  258. return S.NaN
  259. i_coeff = arg.as_coefficient(S.ImaginaryUnit)
  260. if i_coeff is not None:
  261. return cos(i_coeff)
  262. else:
  263. if arg.could_extract_minus_sign():
  264. return cls(-arg)
  265. if arg.is_Add:
  266. x, m = _peeloff_ipi(arg)
  267. if m:
  268. m = m*S.Pi*S.ImaginaryUnit
  269. return cosh(m)*cosh(x) + sinh(m)*sinh(x)
  270. if arg.is_zero:
  271. return S.One
  272. if arg.func == asinh:
  273. return sqrt(1 + arg.args[0]**2)
  274. if arg.func == acosh:
  275. return arg.args[0]
  276. if arg.func == atanh:
  277. return 1/sqrt(1 - arg.args[0]**2)
  278. if arg.func == acoth:
  279. x = arg.args[0]
  280. return x/(sqrt(x - 1) * sqrt(x + 1))
  281. @staticmethod
  282. @cacheit
  283. def taylor_term(n, x, *previous_terms):
  284. if n < 0 or n % 2 == 1:
  285. return S.Zero
  286. else:
  287. x = sympify(x)
  288. if len(previous_terms) > 2:
  289. p = previous_terms[-2]
  290. return p * x**2 / (n*(n - 1))
  291. else:
  292. return x**(n)/factorial(n)
  293. def _eval_conjugate(self):
  294. return self.func(self.args[0].conjugate())
  295. def as_real_imag(self, deep=True, **hints):
  296. from sympy.functions.elementary.trigonometric import (cos, sin)
  297. if self.args[0].is_extended_real:
  298. if deep:
  299. hints['complex'] = False
  300. return (self.expand(deep, **hints), S.Zero)
  301. else:
  302. return (self, S.Zero)
  303. if deep:
  304. re, im = self.args[0].expand(deep, **hints).as_real_imag()
  305. else:
  306. re, im = self.args[0].as_real_imag()
  307. return (cosh(re)*cos(im), sinh(re)*sin(im))
  308. def _eval_expand_complex(self, deep=True, **hints):
  309. re_part, im_part = self.as_real_imag(deep=deep, **hints)
  310. return re_part + im_part*S.ImaginaryUnit
  311. def _eval_expand_trig(self, deep=True, **hints):
  312. if deep:
  313. arg = self.args[0].expand(deep, **hints)
  314. else:
  315. arg = self.args[0]
  316. x = None
  317. if arg.is_Add: # TODO, implement more if deep stuff here
  318. x, y = arg.as_two_terms()
  319. else:
  320. coeff, terms = arg.as_coeff_Mul(rational=True)
  321. if coeff is not S.One and coeff.is_Integer and terms is not S.One:
  322. x = terms
  323. y = (coeff - 1)*x
  324. if x is not None:
  325. return (cosh(x)*cosh(y) + sinh(x)*sinh(y)).expand(trig=True)
  326. return cosh(arg)
  327. def _eval_rewrite_as_tractable(self, arg, limitvar=None, **kwargs):
  328. return (exp(arg) + exp(-arg)) / 2
  329. def _eval_rewrite_as_exp(self, arg, **kwargs):
  330. return (exp(arg) + exp(-arg)) / 2
  331. def _eval_rewrite_as_sinh(self, arg, **kwargs):
  332. return -S.ImaginaryUnit*sinh(arg + S.Pi*S.ImaginaryUnit/2)
  333. def _eval_rewrite_as_tanh(self, arg, **kwargs):
  334. tanh_half = tanh(S.Half*arg)**2
  335. return (1 + tanh_half)/(1 - tanh_half)
  336. def _eval_rewrite_as_coth(self, arg, **kwargs):
  337. coth_half = coth(S.Half*arg)**2
  338. return (coth_half + 1)/(coth_half - 1)
  339. def _eval_as_leading_term(self, x, logx=None, cdir=0):
  340. arg = self.args[0].as_leading_term(x, logx=logx, cdir=cdir)
  341. arg0 = arg.subs(x, 0)
  342. if arg0 is S.NaN:
  343. arg0 = arg.limit(x, 0, dir='-' if cdir.is_negative else '+')
  344. if arg0.is_zero:
  345. return S.One
  346. elif arg0.is_finite:
  347. return self.func(arg0)
  348. else:
  349. return self
  350. def _eval_is_real(self):
  351. arg = self.args[0]
  352. # `cosh(x)` is real for real OR purely imaginary `x`
  353. if arg.is_real or arg.is_imaginary:
  354. return True
  355. # cosh(a+ib) = cos(b)*cosh(a) + i*sin(b)*sinh(a)
  356. # the imaginary part can be an expression like n*pi
  357. # if not, check if the imaginary part is a number
  358. re, im = arg.as_real_imag()
  359. return (im%pi).is_zero
  360. def _eval_is_positive(self):
  361. # cosh(x+I*y) = cos(y)*cosh(x) + I*sin(y)*sinh(x)
  362. # cosh(z) is positive iff it is real and the real part is positive.
  363. # So we need sin(y)*sinh(x) = 0 which gives x=0 or y=n*pi
  364. # Case 1 (y=n*pi): cosh(z) = (-1)**n * cosh(x) -> positive for n even
  365. # Case 2 (x=0): cosh(z) = cos(y) -> positive when cos(y) is positive
  366. z = self.args[0]
  367. x, y = z.as_real_imag()
  368. ymod = y % (2*pi)
  369. yzero = ymod.is_zero
  370. # shortcut if ymod is zero
  371. if yzero:
  372. return True
  373. xzero = x.is_zero
  374. # shortcut x is not zero
  375. if xzero is False:
  376. return yzero
  377. return fuzzy_or([
  378. # Case 1:
  379. yzero,
  380. # Case 2:
  381. fuzzy_and([
  382. xzero,
  383. fuzzy_or([ymod < pi/2, ymod > 3*pi/2])
  384. ])
  385. ])
  386. def _eval_is_nonnegative(self):
  387. z = self.args[0]
  388. x, y = z.as_real_imag()
  389. ymod = y % (2*pi)
  390. yzero = ymod.is_zero
  391. # shortcut if ymod is zero
  392. if yzero:
  393. return True
  394. xzero = x.is_zero
  395. # shortcut x is not zero
  396. if xzero is False:
  397. return yzero
  398. return fuzzy_or([
  399. # Case 1:
  400. yzero,
  401. # Case 2:
  402. fuzzy_and([
  403. xzero,
  404. fuzzy_or([ymod <= pi/2, ymod >= 3*pi/2])
  405. ])
  406. ])
  407. def _eval_is_finite(self):
  408. arg = self.args[0]
  409. return arg.is_finite
  410. def _eval_is_zero(self):
  411. rest, ipi_mult = _peeloff_ipi(self.args[0])
  412. if ipi_mult and rest.is_zero:
  413. return (ipi_mult - S.Half).is_integer
  414. class tanh(HyperbolicFunction):
  415. r"""
  416. ``tanh(x)`` is the hyperbolic tangent of ``x``.
  417. The hyperbolic tangent function is $\frac{\sinh(x)}{\cosh(x)}$.
  418. Examples
  419. ========
  420. >>> from sympy import tanh
  421. >>> from sympy.abc import x
  422. >>> tanh(x)
  423. tanh(x)
  424. See Also
  425. ========
  426. sinh, cosh, atanh
  427. """
  428. def fdiff(self, argindex=1):
  429. if argindex == 1:
  430. return S.One - tanh(self.args[0])**2
  431. else:
  432. raise ArgumentIndexError(self, argindex)
  433. def inverse(self, argindex=1):
  434. """
  435. Returns the inverse of this function.
  436. """
  437. return atanh
  438. @classmethod
  439. def eval(cls, arg):
  440. from sympy.functions.elementary.trigonometric import tan
  441. arg = sympify(arg)
  442. if arg.is_Number:
  443. if arg is S.NaN:
  444. return S.NaN
  445. elif arg is S.Infinity:
  446. return S.One
  447. elif arg is S.NegativeInfinity:
  448. return S.NegativeOne
  449. elif arg.is_zero:
  450. return S.Zero
  451. elif arg.is_negative:
  452. return -cls(-arg)
  453. else:
  454. if arg is S.ComplexInfinity:
  455. return S.NaN
  456. i_coeff = arg.as_coefficient(S.ImaginaryUnit)
  457. if i_coeff is not None:
  458. if i_coeff.could_extract_minus_sign():
  459. return -S.ImaginaryUnit * tan(-i_coeff)
  460. return S.ImaginaryUnit * tan(i_coeff)
  461. else:
  462. if arg.could_extract_minus_sign():
  463. return -cls(-arg)
  464. if arg.is_Add:
  465. x, m = _peeloff_ipi(arg)
  466. if m:
  467. tanhm = tanh(m*S.Pi*S.ImaginaryUnit)
  468. if tanhm is S.ComplexInfinity:
  469. return coth(x)
  470. else: # tanhm == 0
  471. return tanh(x)
  472. if arg.is_zero:
  473. return S.Zero
  474. if arg.func == asinh:
  475. x = arg.args[0]
  476. return x/sqrt(1 + x**2)
  477. if arg.func == acosh:
  478. x = arg.args[0]
  479. return sqrt(x - 1) * sqrt(x + 1) / x
  480. if arg.func == atanh:
  481. return arg.args[0]
  482. if arg.func == acoth:
  483. return 1/arg.args[0]
  484. @staticmethod
  485. @cacheit
  486. def taylor_term(n, x, *previous_terms):
  487. from sympy.functions.combinatorial.numbers import bernoulli
  488. if n < 0 or n % 2 == 0:
  489. return S.Zero
  490. else:
  491. x = sympify(x)
  492. a = 2**(n + 1)
  493. B = bernoulli(n + 1)
  494. F = factorial(n + 1)
  495. return a*(a - 1) * B/F * x**n
  496. def _eval_conjugate(self):
  497. return self.func(self.args[0].conjugate())
  498. def as_real_imag(self, deep=True, **hints):
  499. from sympy.functions.elementary.trigonometric import (cos, sin)
  500. if self.args[0].is_extended_real:
  501. if deep:
  502. hints['complex'] = False
  503. return (self.expand(deep, **hints), S.Zero)
  504. else:
  505. return (self, S.Zero)
  506. if deep:
  507. re, im = self.args[0].expand(deep, **hints).as_real_imag()
  508. else:
  509. re, im = self.args[0].as_real_imag()
  510. denom = sinh(re)**2 + cos(im)**2
  511. return (sinh(re)*cosh(re)/denom, sin(im)*cos(im)/denom)
  512. def _eval_expand_trig(self, **hints):
  513. arg = self.args[0]
  514. if arg.is_Add:
  515. from sympy.polys.specialpolys import symmetric_poly
  516. n = len(arg.args)
  517. TX = [tanh(x, evaluate=False)._eval_expand_trig()
  518. for x in arg.args]
  519. p = [0, 0] # [den, num]
  520. for i in range(n + 1):
  521. p[i % 2] += symmetric_poly(i, TX)
  522. return p[1]/p[0]
  523. elif arg.is_Mul:
  524. from sympy.functions.combinatorial.numbers import nC
  525. coeff, terms = arg.as_coeff_Mul()
  526. if coeff.is_Integer and coeff > 1:
  527. n = []
  528. d = []
  529. T = tanh(terms)
  530. for k in range(1, coeff + 1, 2):
  531. n.append(nC(range(coeff), k)*T**k)
  532. for k in range(0, coeff + 1, 2):
  533. d.append(nC(range(coeff), k)*T**k)
  534. return Add(*n)/Add(*d)
  535. return tanh(arg)
  536. def _eval_rewrite_as_tractable(self, arg, limitvar=None, **kwargs):
  537. neg_exp, pos_exp = exp(-arg), exp(arg)
  538. return (pos_exp - neg_exp)/(pos_exp + neg_exp)
  539. def _eval_rewrite_as_exp(self, arg, **kwargs):
  540. neg_exp, pos_exp = exp(-arg), exp(arg)
  541. return (pos_exp - neg_exp)/(pos_exp + neg_exp)
  542. def _eval_rewrite_as_sinh(self, arg, **kwargs):
  543. return S.ImaginaryUnit*sinh(arg)/sinh(S.Pi*S.ImaginaryUnit/2 - arg)
  544. def _eval_rewrite_as_cosh(self, arg, **kwargs):
  545. return S.ImaginaryUnit*cosh(S.Pi*S.ImaginaryUnit/2 - arg)/cosh(arg)
  546. def _eval_rewrite_as_coth(self, arg, **kwargs):
  547. return 1/coth(arg)
  548. def _eval_as_leading_term(self, x, logx=None, cdir=0):
  549. from sympy.series.order import Order
  550. arg = self.args[0].as_leading_term(x)
  551. if x in arg.free_symbols and Order(1, x).contains(arg):
  552. return arg
  553. else:
  554. return self.func(arg)
  555. def _eval_is_real(self):
  556. arg = self.args[0]
  557. if arg.is_real:
  558. return True
  559. re, im = arg.as_real_imag()
  560. # if denom = 0, tanh(arg) = zoo
  561. if re == 0 and im % pi == pi/2:
  562. return None
  563. # check if im is of the form n*pi/2 to make sin(2*im) = 0
  564. # if not, im could be a number, return False in that case
  565. return (im % (pi/2)).is_zero
  566. def _eval_is_extended_real(self):
  567. if self.args[0].is_extended_real:
  568. return True
  569. def _eval_is_positive(self):
  570. if self.args[0].is_extended_real:
  571. return self.args[0].is_positive
  572. def _eval_is_negative(self):
  573. if self.args[0].is_extended_real:
  574. return self.args[0].is_negative
  575. def _eval_is_finite(self):
  576. from sympy.functions.elementary.trigonometric import cos
  577. arg = self.args[0]
  578. re, im = arg.as_real_imag()
  579. denom = cos(im)**2 + sinh(re)**2
  580. if denom == 0:
  581. return False
  582. elif denom.is_number:
  583. return True
  584. if arg.is_extended_real:
  585. return True
  586. def _eval_is_zero(self):
  587. arg = self.args[0]
  588. if arg.is_zero:
  589. return True
  590. class coth(HyperbolicFunction):
  591. r"""
  592. ``coth(x)`` is the hyperbolic cotangent of ``x``.
  593. The hyperbolic cotangent function is $\frac{\cosh(x)}{\sinh(x)}$.
  594. Examples
  595. ========
  596. >>> from sympy import coth
  597. >>> from sympy.abc import x
  598. >>> coth(x)
  599. coth(x)
  600. See Also
  601. ========
  602. sinh, cosh, acoth
  603. """
  604. def fdiff(self, argindex=1):
  605. if argindex == 1:
  606. return -1/sinh(self.args[0])**2
  607. else:
  608. raise ArgumentIndexError(self, argindex)
  609. def inverse(self, argindex=1):
  610. """
  611. Returns the inverse of this function.
  612. """
  613. return acoth
  614. @classmethod
  615. def eval(cls, arg):
  616. from sympy.functions.elementary.trigonometric import cot
  617. arg = sympify(arg)
  618. if arg.is_Number:
  619. if arg is S.NaN:
  620. return S.NaN
  621. elif arg is S.Infinity:
  622. return S.One
  623. elif arg is S.NegativeInfinity:
  624. return S.NegativeOne
  625. elif arg.is_zero:
  626. return S.ComplexInfinity
  627. elif arg.is_negative:
  628. return -cls(-arg)
  629. else:
  630. if arg is S.ComplexInfinity:
  631. return S.NaN
  632. i_coeff = arg.as_coefficient(S.ImaginaryUnit)
  633. if i_coeff is not None:
  634. if i_coeff.could_extract_minus_sign():
  635. return S.ImaginaryUnit * cot(-i_coeff)
  636. return -S.ImaginaryUnit * cot(i_coeff)
  637. else:
  638. if arg.could_extract_minus_sign():
  639. return -cls(-arg)
  640. if arg.is_Add:
  641. x, m = _peeloff_ipi(arg)
  642. if m:
  643. cothm = coth(m*S.Pi*S.ImaginaryUnit)
  644. if cothm is S.ComplexInfinity:
  645. return coth(x)
  646. else: # cothm == 0
  647. return tanh(x)
  648. if arg.is_zero:
  649. return S.ComplexInfinity
  650. if arg.func == asinh:
  651. x = arg.args[0]
  652. return sqrt(1 + x**2)/x
  653. if arg.func == acosh:
  654. x = arg.args[0]
  655. return x/(sqrt(x - 1) * sqrt(x + 1))
  656. if arg.func == atanh:
  657. return 1/arg.args[0]
  658. if arg.func == acoth:
  659. return arg.args[0]
  660. @staticmethod
  661. @cacheit
  662. def taylor_term(n, x, *previous_terms):
  663. from sympy.functions.combinatorial.numbers import bernoulli
  664. if n == 0:
  665. return 1 / sympify(x)
  666. elif n < 0 or n % 2 == 0:
  667. return S.Zero
  668. else:
  669. x = sympify(x)
  670. B = bernoulli(n + 1)
  671. F = factorial(n + 1)
  672. return 2**(n + 1) * B/F * x**n
  673. def _eval_conjugate(self):
  674. return self.func(self.args[0].conjugate())
  675. def as_real_imag(self, deep=True, **hints):
  676. from sympy.functions.elementary.trigonometric import (cos, sin)
  677. if self.args[0].is_extended_real:
  678. if deep:
  679. hints['complex'] = False
  680. return (self.expand(deep, **hints), S.Zero)
  681. else:
  682. return (self, S.Zero)
  683. if deep:
  684. re, im = self.args[0].expand(deep, **hints).as_real_imag()
  685. else:
  686. re, im = self.args[0].as_real_imag()
  687. denom = sinh(re)**2 + sin(im)**2
  688. return (sinh(re)*cosh(re)/denom, -sin(im)*cos(im)/denom)
  689. def _eval_rewrite_as_tractable(self, arg, limitvar=None, **kwargs):
  690. neg_exp, pos_exp = exp(-arg), exp(arg)
  691. return (pos_exp + neg_exp)/(pos_exp - neg_exp)
  692. def _eval_rewrite_as_exp(self, arg, **kwargs):
  693. neg_exp, pos_exp = exp(-arg), exp(arg)
  694. return (pos_exp + neg_exp)/(pos_exp - neg_exp)
  695. def _eval_rewrite_as_sinh(self, arg, **kwargs):
  696. return -S.ImaginaryUnit*sinh(S.Pi*S.ImaginaryUnit/2 - arg)/sinh(arg)
  697. def _eval_rewrite_as_cosh(self, arg, **kwargs):
  698. return -S.ImaginaryUnit*cosh(arg)/cosh(S.Pi*S.ImaginaryUnit/2 - arg)
  699. def _eval_rewrite_as_tanh(self, arg, **kwargs):
  700. return 1/tanh(arg)
  701. def _eval_is_positive(self):
  702. if self.args[0].is_extended_real:
  703. return self.args[0].is_positive
  704. def _eval_is_negative(self):
  705. if self.args[0].is_extended_real:
  706. return self.args[0].is_negative
  707. def _eval_as_leading_term(self, x, logx=None, cdir=0):
  708. from sympy.series.order import Order
  709. arg = self.args[0].as_leading_term(x)
  710. if x in arg.free_symbols and Order(1, x).contains(arg):
  711. return 1/arg
  712. else:
  713. return self.func(arg)
  714. def _eval_expand_trig(self, **hints):
  715. arg = self.args[0]
  716. if arg.is_Add:
  717. from sympy.polys.specialpolys import symmetric_poly
  718. CX = [coth(x, evaluate=False)._eval_expand_trig() for x in arg.args]
  719. p = [[], []]
  720. n = len(arg.args)
  721. for i in range(n, -1, -1):
  722. p[(n - i) % 2].append(symmetric_poly(i, CX))
  723. return Add(*p[0])/Add(*p[1])
  724. elif arg.is_Mul:
  725. from sympy.functions.combinatorial.factorials import binomial
  726. coeff, x = arg.as_coeff_Mul(rational=True)
  727. if coeff.is_Integer and coeff > 1:
  728. c = coth(x, evaluate=False)
  729. p = [[], []]
  730. for i in range(coeff, -1, -1):
  731. p[(coeff - i) % 2].append(binomial(coeff, i)*c**i)
  732. return Add(*p[0])/Add(*p[1])
  733. return coth(arg)
  734. class ReciprocalHyperbolicFunction(HyperbolicFunction):
  735. """Base class for reciprocal functions of hyperbolic functions. """
  736. #To be defined in class
  737. _reciprocal_of = None
  738. _is_even = None # type: FuzzyBool
  739. _is_odd = None # type: FuzzyBool
  740. @classmethod
  741. def eval(cls, arg):
  742. if arg.could_extract_minus_sign():
  743. if cls._is_even:
  744. return cls(-arg)
  745. if cls._is_odd:
  746. return -cls(-arg)
  747. t = cls._reciprocal_of.eval(arg)
  748. if hasattr(arg, 'inverse') and arg.inverse() == cls:
  749. return arg.args[0]
  750. return 1/t if t is not None else t
  751. def _call_reciprocal(self, method_name, *args, **kwargs):
  752. # Calls method_name on _reciprocal_of
  753. o = self._reciprocal_of(self.args[0])
  754. return getattr(o, method_name)(*args, **kwargs)
  755. def _calculate_reciprocal(self, method_name, *args, **kwargs):
  756. # If calling method_name on _reciprocal_of returns a value != None
  757. # then return the reciprocal of that value
  758. t = self._call_reciprocal(method_name, *args, **kwargs)
  759. return 1/t if t is not None else t
  760. def _rewrite_reciprocal(self, method_name, arg):
  761. # Special handling for rewrite functions. If reciprocal rewrite returns
  762. # unmodified expression, then return None
  763. t = self._call_reciprocal(method_name, arg)
  764. if t is not None and t != self._reciprocal_of(arg):
  765. return 1/t
  766. def _eval_rewrite_as_exp(self, arg, **kwargs):
  767. return self._rewrite_reciprocal("_eval_rewrite_as_exp", arg)
  768. def _eval_rewrite_as_tractable(self, arg, limitvar=None, **kwargs):
  769. return self._rewrite_reciprocal("_eval_rewrite_as_tractable", arg)
  770. def _eval_rewrite_as_tanh(self, arg, **kwargs):
  771. return self._rewrite_reciprocal("_eval_rewrite_as_tanh", arg)
  772. def _eval_rewrite_as_coth(self, arg, **kwargs):
  773. return self._rewrite_reciprocal("_eval_rewrite_as_coth", arg)
  774. def as_real_imag(self, deep = True, **hints):
  775. return (1 / self._reciprocal_of(self.args[0])).as_real_imag(deep, **hints)
  776. def _eval_conjugate(self):
  777. return self.func(self.args[0].conjugate())
  778. def _eval_expand_complex(self, deep=True, **hints):
  779. re_part, im_part = self.as_real_imag(deep=True, **hints)
  780. return re_part + S.ImaginaryUnit*im_part
  781. def _eval_expand_trig(self, **hints):
  782. return self._calculate_reciprocal("_eval_expand_trig", **hints)
  783. def _eval_as_leading_term(self, x, logx=None, cdir=0):
  784. return (1/self._reciprocal_of(self.args[0]))._eval_as_leading_term(x)
  785. def _eval_is_extended_real(self):
  786. return self._reciprocal_of(self.args[0]).is_extended_real
  787. def _eval_is_finite(self):
  788. return (1/self._reciprocal_of(self.args[0])).is_finite
  789. class csch(ReciprocalHyperbolicFunction):
  790. r"""
  791. ``csch(x)`` is the hyperbolic cosecant of ``x``.
  792. The hyperbolic cosecant function is $\frac{2}{e^x - e^{-x}}$
  793. Examples
  794. ========
  795. >>> from sympy import csch
  796. >>> from sympy.abc import x
  797. >>> csch(x)
  798. csch(x)
  799. See Also
  800. ========
  801. sinh, cosh, tanh, sech, asinh, acosh
  802. """
  803. _reciprocal_of = sinh
  804. _is_odd = True
  805. def fdiff(self, argindex=1):
  806. """
  807. Returns the first derivative of this function
  808. """
  809. if argindex == 1:
  810. return -coth(self.args[0]) * csch(self.args[0])
  811. else:
  812. raise ArgumentIndexError(self, argindex)
  813. @staticmethod
  814. @cacheit
  815. def taylor_term(n, x, *previous_terms):
  816. """
  817. Returns the next term in the Taylor series expansion
  818. """
  819. from sympy.functions.combinatorial.numbers import bernoulli
  820. if n == 0:
  821. return 1/sympify(x)
  822. elif n < 0 or n % 2 == 0:
  823. return S.Zero
  824. else:
  825. x = sympify(x)
  826. B = bernoulli(n + 1)
  827. F = factorial(n + 1)
  828. return 2 * (1 - 2**n) * B/F * x**n
  829. def _eval_rewrite_as_cosh(self, arg, **kwargs):
  830. return S.ImaginaryUnit / cosh(arg + S.ImaginaryUnit * S.Pi / 2)
  831. def _eval_is_positive(self):
  832. if self.args[0].is_extended_real:
  833. return self.args[0].is_positive
  834. def _eval_is_negative(self):
  835. if self.args[0].is_extended_real:
  836. return self.args[0].is_negative
  837. class sech(ReciprocalHyperbolicFunction):
  838. r"""
  839. ``sech(x)`` is the hyperbolic secant of ``x``.
  840. The hyperbolic secant function is $\frac{2}{e^x + e^{-x}}$
  841. Examples
  842. ========
  843. >>> from sympy import sech
  844. >>> from sympy.abc import x
  845. >>> sech(x)
  846. sech(x)
  847. See Also
  848. ========
  849. sinh, cosh, tanh, coth, csch, asinh, acosh
  850. """
  851. _reciprocal_of = cosh
  852. _is_even = True
  853. def fdiff(self, argindex=1):
  854. if argindex == 1:
  855. return - tanh(self.args[0])*sech(self.args[0])
  856. else:
  857. raise ArgumentIndexError(self, argindex)
  858. @staticmethod
  859. @cacheit
  860. def taylor_term(n, x, *previous_terms):
  861. from sympy.functions.combinatorial.numbers import euler
  862. if n < 0 or n % 2 == 1:
  863. return S.Zero
  864. else:
  865. x = sympify(x)
  866. return euler(n) / factorial(n) * x**(n)
  867. def _eval_rewrite_as_sinh(self, arg, **kwargs):
  868. return S.ImaginaryUnit / sinh(arg + S.ImaginaryUnit * S.Pi /2)
  869. def _eval_is_positive(self):
  870. if self.args[0].is_extended_real:
  871. return True
  872. ###############################################################################
  873. ############################# HYPERBOLIC INVERSES #############################
  874. ###############################################################################
  875. class InverseHyperbolicFunction(Function):
  876. """Base class for inverse hyperbolic functions."""
  877. pass
  878. class asinh(InverseHyperbolicFunction):
  879. """
  880. ``asinh(x)`` is the inverse hyperbolic sine of ``x``.
  881. The inverse hyperbolic sine function.
  882. Examples
  883. ========
  884. >>> from sympy import asinh
  885. >>> from sympy.abc import x
  886. >>> asinh(x).diff(x)
  887. 1/sqrt(x**2 + 1)
  888. >>> asinh(1)
  889. log(1 + sqrt(2))
  890. See Also
  891. ========
  892. acosh, atanh, sinh
  893. """
  894. def fdiff(self, argindex=1):
  895. if argindex == 1:
  896. return 1/sqrt(self.args[0]**2 + 1)
  897. else:
  898. raise ArgumentIndexError(self, argindex)
  899. @classmethod
  900. def eval(cls, arg):
  901. from sympy.functions.elementary.trigonometric import asin
  902. arg = sympify(arg)
  903. if arg.is_Number:
  904. if arg is S.NaN:
  905. return S.NaN
  906. elif arg is S.Infinity:
  907. return S.Infinity
  908. elif arg is S.NegativeInfinity:
  909. return S.NegativeInfinity
  910. elif arg.is_zero:
  911. return S.Zero
  912. elif arg is S.One:
  913. return log(sqrt(2) + 1)
  914. elif arg is S.NegativeOne:
  915. return log(sqrt(2) - 1)
  916. elif arg.is_negative:
  917. return -cls(-arg)
  918. else:
  919. if arg is S.ComplexInfinity:
  920. return S.ComplexInfinity
  921. if arg.is_zero:
  922. return S.Zero
  923. i_coeff = arg.as_coefficient(S.ImaginaryUnit)
  924. if i_coeff is not None:
  925. return S.ImaginaryUnit * asin(i_coeff)
  926. else:
  927. if arg.could_extract_minus_sign():
  928. return -cls(-arg)
  929. if isinstance(arg, sinh) and arg.args[0].is_number:
  930. z = arg.args[0]
  931. if z.is_real:
  932. return z
  933. r, i = match_real_imag(z)
  934. if r is not None and i is not None:
  935. f = floor((i + pi/2)/pi)
  936. m = z - I*pi*f
  937. even = f.is_even
  938. if even is True:
  939. return m
  940. elif even is False:
  941. return -m
  942. @staticmethod
  943. @cacheit
  944. def taylor_term(n, x, *previous_terms):
  945. if n < 0 or n % 2 == 0:
  946. return S.Zero
  947. else:
  948. x = sympify(x)
  949. if len(previous_terms) >= 2 and n > 2:
  950. p = previous_terms[-2]
  951. return -p * (n - 2)**2/(n*(n - 1)) * x**2
  952. else:
  953. k = (n - 1) // 2
  954. R = RisingFactorial(S.Half, k)
  955. F = factorial(k)
  956. return S.NegativeOne**k * R / F * x**n / n
  957. def _eval_as_leading_term(self, x, logx=None, cdir=0):
  958. from sympy.series.order import Order
  959. arg = self.args[0].as_leading_term(x)
  960. if x in arg.free_symbols and Order(1, x).contains(arg):
  961. return arg
  962. else:
  963. return self.func(arg)
  964. def _eval_rewrite_as_log(self, x, **kwargs):
  965. return log(x + sqrt(x**2 + 1))
  966. def inverse(self, argindex=1):
  967. """
  968. Returns the inverse of this function.
  969. """
  970. return sinh
  971. def _eval_is_zero(self):
  972. return self.args[0].is_zero
  973. class acosh(InverseHyperbolicFunction):
  974. """
  975. ``acosh(x)`` is the inverse hyperbolic cosine of ``x``.
  976. The inverse hyperbolic cosine function.
  977. Examples
  978. ========
  979. >>> from sympy import acosh
  980. >>> from sympy.abc import x
  981. >>> acosh(x).diff(x)
  982. 1/sqrt(x**2 - 1)
  983. >>> acosh(1)
  984. 0
  985. See Also
  986. ========
  987. asinh, atanh, cosh
  988. """
  989. def fdiff(self, argindex=1):
  990. if argindex == 1:
  991. return 1/sqrt(self.args[0]**2 - 1)
  992. else:
  993. raise ArgumentIndexError(self, argindex)
  994. @classmethod
  995. def eval(cls, arg):
  996. arg = sympify(arg)
  997. if arg.is_Number:
  998. if arg is S.NaN:
  999. return S.NaN
  1000. elif arg is S.Infinity:
  1001. return S.Infinity
  1002. elif arg is S.NegativeInfinity:
  1003. return S.Infinity
  1004. elif arg.is_zero:
  1005. return S.Pi*S.ImaginaryUnit / 2
  1006. elif arg is S.One:
  1007. return S.Zero
  1008. elif arg is S.NegativeOne:
  1009. return S.Pi*S.ImaginaryUnit
  1010. if arg.is_number:
  1011. cst_table = {
  1012. S.ImaginaryUnit: log(S.ImaginaryUnit*(1 + sqrt(2))),
  1013. -S.ImaginaryUnit: log(-S.ImaginaryUnit*(1 + sqrt(2))),
  1014. S.Half: S.Pi/3,
  1015. Rational(-1, 2): S.Pi*Rational(2, 3),
  1016. sqrt(2)/2: S.Pi/4,
  1017. -sqrt(2)/2: S.Pi*Rational(3, 4),
  1018. 1/sqrt(2): S.Pi/4,
  1019. -1/sqrt(2): S.Pi*Rational(3, 4),
  1020. sqrt(3)/2: S.Pi/6,
  1021. -sqrt(3)/2: S.Pi*Rational(5, 6),
  1022. (sqrt(3) - 1)/sqrt(2**3): S.Pi*Rational(5, 12),
  1023. -(sqrt(3) - 1)/sqrt(2**3): S.Pi*Rational(7, 12),
  1024. sqrt(2 + sqrt(2))/2: S.Pi/8,
  1025. -sqrt(2 + sqrt(2))/2: S.Pi*Rational(7, 8),
  1026. sqrt(2 - sqrt(2))/2: S.Pi*Rational(3, 8),
  1027. -sqrt(2 - sqrt(2))/2: S.Pi*Rational(5, 8),
  1028. (1 + sqrt(3))/(2*sqrt(2)): S.Pi/12,
  1029. -(1 + sqrt(3))/(2*sqrt(2)): S.Pi*Rational(11, 12),
  1030. (sqrt(5) + 1)/4: S.Pi/5,
  1031. -(sqrt(5) + 1)/4: S.Pi*Rational(4, 5)
  1032. }
  1033. if arg in cst_table:
  1034. if arg.is_extended_real:
  1035. return cst_table[arg]*S.ImaginaryUnit
  1036. return cst_table[arg]
  1037. if arg is S.ComplexInfinity:
  1038. return S.ComplexInfinity
  1039. if arg == S.ImaginaryUnit*S.Infinity:
  1040. return S.Infinity + S.ImaginaryUnit*S.Pi/2
  1041. if arg == -S.ImaginaryUnit*S.Infinity:
  1042. return S.Infinity - S.ImaginaryUnit*S.Pi/2
  1043. if arg.is_zero:
  1044. return S.Pi*S.ImaginaryUnit*S.Half
  1045. if isinstance(arg, cosh) and arg.args[0].is_number:
  1046. z = arg.args[0]
  1047. if z.is_real:
  1048. from sympy.functions.elementary.complexes import Abs
  1049. return Abs(z)
  1050. r, i = match_real_imag(z)
  1051. if r is not None and i is not None:
  1052. f = floor(i/pi)
  1053. m = z - I*pi*f
  1054. even = f.is_even
  1055. if even is True:
  1056. if r.is_nonnegative:
  1057. return m
  1058. elif r.is_negative:
  1059. return -m
  1060. elif even is False:
  1061. m -= I*pi
  1062. if r.is_nonpositive:
  1063. return -m
  1064. elif r.is_positive:
  1065. return m
  1066. @staticmethod
  1067. @cacheit
  1068. def taylor_term(n, x, *previous_terms):
  1069. if n == 0:
  1070. return S.Pi*S.ImaginaryUnit / 2
  1071. elif n < 0 or n % 2 == 0:
  1072. return S.Zero
  1073. else:
  1074. x = sympify(x)
  1075. if len(previous_terms) >= 2 and n > 2:
  1076. p = previous_terms[-2]
  1077. return p * (n - 2)**2/(n*(n - 1)) * x**2
  1078. else:
  1079. k = (n - 1) // 2
  1080. R = RisingFactorial(S.Half, k)
  1081. F = factorial(k)
  1082. return -R / F * S.ImaginaryUnit * x**n / n
  1083. def _eval_as_leading_term(self, x, logx=None, cdir=0):
  1084. from sympy.series.order import Order
  1085. arg = self.args[0].as_leading_term(x)
  1086. if x in arg.free_symbols and Order(1, x).contains(arg):
  1087. return S.ImaginaryUnit*S.Pi/2
  1088. else:
  1089. return self.func(arg)
  1090. def _eval_rewrite_as_log(self, x, **kwargs):
  1091. return log(x + sqrt(x + 1) * sqrt(x - 1))
  1092. def inverse(self, argindex=1):
  1093. """
  1094. Returns the inverse of this function.
  1095. """
  1096. return cosh
  1097. def _eval_is_zero(self):
  1098. if (self.args[0] - 1).is_zero:
  1099. return True
  1100. class atanh(InverseHyperbolicFunction):
  1101. """
  1102. ``atanh(x)`` is the inverse hyperbolic tangent of ``x``.
  1103. The inverse hyperbolic tangent function.
  1104. Examples
  1105. ========
  1106. >>> from sympy import atanh
  1107. >>> from sympy.abc import x
  1108. >>> atanh(x).diff(x)
  1109. 1/(1 - x**2)
  1110. See Also
  1111. ========
  1112. asinh, acosh, tanh
  1113. """
  1114. def fdiff(self, argindex=1):
  1115. if argindex == 1:
  1116. return 1/(1 - self.args[0]**2)
  1117. else:
  1118. raise ArgumentIndexError(self, argindex)
  1119. @classmethod
  1120. def eval(cls, arg):
  1121. from sympy.functions.elementary.trigonometric import atan
  1122. arg = sympify(arg)
  1123. if arg.is_Number:
  1124. if arg is S.NaN:
  1125. return S.NaN
  1126. elif arg.is_zero:
  1127. return S.Zero
  1128. elif arg is S.One:
  1129. return S.Infinity
  1130. elif arg is S.NegativeOne:
  1131. return S.NegativeInfinity
  1132. elif arg is S.Infinity:
  1133. return -S.ImaginaryUnit * atan(arg)
  1134. elif arg is S.NegativeInfinity:
  1135. return S.ImaginaryUnit * atan(-arg)
  1136. elif arg.is_negative:
  1137. return -cls(-arg)
  1138. else:
  1139. if arg is S.ComplexInfinity:
  1140. from sympy.calculus.accumulationbounds import AccumBounds
  1141. return S.ImaginaryUnit*AccumBounds(-S.Pi/2, S.Pi/2)
  1142. i_coeff = arg.as_coefficient(S.ImaginaryUnit)
  1143. if i_coeff is not None:
  1144. return S.ImaginaryUnit * atan(i_coeff)
  1145. else:
  1146. if arg.could_extract_minus_sign():
  1147. return -cls(-arg)
  1148. if arg.is_zero:
  1149. return S.Zero
  1150. if isinstance(arg, tanh) and arg.args[0].is_number:
  1151. z = arg.args[0]
  1152. if z.is_real:
  1153. return z
  1154. r, i = match_real_imag(z)
  1155. if r is not None and i is not None:
  1156. f = floor(2*i/pi)
  1157. even = f.is_even
  1158. m = z - I*f*pi/2
  1159. if even is True:
  1160. return m
  1161. elif even is False:
  1162. return m - I*pi/2
  1163. @staticmethod
  1164. @cacheit
  1165. def taylor_term(n, x, *previous_terms):
  1166. if n < 0 or n % 2 == 0:
  1167. return S.Zero
  1168. else:
  1169. x = sympify(x)
  1170. return x**n / n
  1171. def _eval_as_leading_term(self, x, logx=None, cdir=0):
  1172. from sympy.series.order import Order
  1173. arg = self.args[0].as_leading_term(x)
  1174. if x in arg.free_symbols and Order(1, x).contains(arg):
  1175. return arg
  1176. else:
  1177. return self.func(arg)
  1178. def _eval_rewrite_as_log(self, x, **kwargs):
  1179. return (log(1 + x) - log(1 - x)) / 2
  1180. def _eval_is_zero(self):
  1181. if self.args[0].is_zero:
  1182. return True
  1183. def _eval_is_imaginary(self):
  1184. return self.args[0].is_imaginary
  1185. def inverse(self, argindex=1):
  1186. """
  1187. Returns the inverse of this function.
  1188. """
  1189. return tanh
  1190. class acoth(InverseHyperbolicFunction):
  1191. """
  1192. ``acoth(x)`` is the inverse hyperbolic cotangent of ``x``.
  1193. The inverse hyperbolic cotangent function.
  1194. Examples
  1195. ========
  1196. >>> from sympy import acoth
  1197. >>> from sympy.abc import x
  1198. >>> acoth(x).diff(x)
  1199. 1/(1 - x**2)
  1200. See Also
  1201. ========
  1202. asinh, acosh, coth
  1203. """
  1204. def fdiff(self, argindex=1):
  1205. if argindex == 1:
  1206. return 1/(1 - self.args[0]**2)
  1207. else:
  1208. raise ArgumentIndexError(self, argindex)
  1209. @classmethod
  1210. def eval(cls, arg):
  1211. from sympy.functions.elementary.trigonometric import acot
  1212. arg = sympify(arg)
  1213. if arg.is_Number:
  1214. if arg is S.NaN:
  1215. return S.NaN
  1216. elif arg is S.Infinity:
  1217. return S.Zero
  1218. elif arg is S.NegativeInfinity:
  1219. return S.Zero
  1220. elif arg.is_zero:
  1221. return S.Pi*S.ImaginaryUnit / 2
  1222. elif arg is S.One:
  1223. return S.Infinity
  1224. elif arg is S.NegativeOne:
  1225. return S.NegativeInfinity
  1226. elif arg.is_negative:
  1227. return -cls(-arg)
  1228. else:
  1229. if arg is S.ComplexInfinity:
  1230. return S.Zero
  1231. i_coeff = arg.as_coefficient(S.ImaginaryUnit)
  1232. if i_coeff is not None:
  1233. return -S.ImaginaryUnit * acot(i_coeff)
  1234. else:
  1235. if arg.could_extract_minus_sign():
  1236. return -cls(-arg)
  1237. if arg.is_zero:
  1238. return S.Pi*S.ImaginaryUnit*S.Half
  1239. @staticmethod
  1240. @cacheit
  1241. def taylor_term(n, x, *previous_terms):
  1242. if n == 0:
  1243. return S.Pi*S.ImaginaryUnit / 2
  1244. elif n < 0 or n % 2 == 0:
  1245. return S.Zero
  1246. else:
  1247. x = sympify(x)
  1248. return x**n / n
  1249. def _eval_as_leading_term(self, x, logx=None, cdir=0):
  1250. from sympy.series.order import Order
  1251. arg = self.args[0].as_leading_term(x)
  1252. if x in arg.free_symbols and Order(1, x).contains(arg):
  1253. return S.ImaginaryUnit*S.Pi/2
  1254. else:
  1255. return self.func(arg)
  1256. def _eval_rewrite_as_log(self, x, **kwargs):
  1257. return (log(1 + 1/x) - log(1 - 1/x)) / 2
  1258. def inverse(self, argindex=1):
  1259. """
  1260. Returns the inverse of this function.
  1261. """
  1262. return coth
  1263. class asech(InverseHyperbolicFunction):
  1264. """
  1265. ``asech(x)`` is the inverse hyperbolic secant of ``x``.
  1266. The inverse hyperbolic secant function.
  1267. Examples
  1268. ========
  1269. >>> from sympy import asech, sqrt, S
  1270. >>> from sympy.abc import x
  1271. >>> asech(x).diff(x)
  1272. -1/(x*sqrt(1 - x**2))
  1273. >>> asech(1).diff(x)
  1274. 0
  1275. >>> asech(1)
  1276. 0
  1277. >>> asech(S(2))
  1278. I*pi/3
  1279. >>> asech(-sqrt(2))
  1280. 3*I*pi/4
  1281. >>> asech((sqrt(6) - sqrt(2)))
  1282. I*pi/12
  1283. See Also
  1284. ========
  1285. asinh, atanh, cosh, acoth
  1286. References
  1287. ==========
  1288. .. [1] https://en.wikipedia.org/wiki/Hyperbolic_function
  1289. .. [2] http://dlmf.nist.gov/4.37
  1290. .. [3] http://functions.wolfram.com/ElementaryFunctions/ArcSech/
  1291. """
  1292. def fdiff(self, argindex=1):
  1293. if argindex == 1:
  1294. z = self.args[0]
  1295. return -1/(z*sqrt(1 - z**2))
  1296. else:
  1297. raise ArgumentIndexError(self, argindex)
  1298. @classmethod
  1299. def eval(cls, arg):
  1300. arg = sympify(arg)
  1301. if arg.is_Number:
  1302. if arg is S.NaN:
  1303. return S.NaN
  1304. elif arg is S.Infinity:
  1305. return S.Pi*S.ImaginaryUnit / 2
  1306. elif arg is S.NegativeInfinity:
  1307. return S.Pi*S.ImaginaryUnit / 2
  1308. elif arg.is_zero:
  1309. return S.Infinity
  1310. elif arg is S.One:
  1311. return S.Zero
  1312. elif arg is S.NegativeOne:
  1313. return S.Pi*S.ImaginaryUnit
  1314. if arg.is_number:
  1315. cst_table = {
  1316. S.ImaginaryUnit: - (S.Pi*S.ImaginaryUnit / 2) + log(1 + sqrt(2)),
  1317. -S.ImaginaryUnit: (S.Pi*S.ImaginaryUnit / 2) + log(1 + sqrt(2)),
  1318. (sqrt(6) - sqrt(2)): S.Pi / 12,
  1319. (sqrt(2) - sqrt(6)): 11*S.Pi / 12,
  1320. sqrt(2 - 2/sqrt(5)): S.Pi / 10,
  1321. -sqrt(2 - 2/sqrt(5)): 9*S.Pi / 10,
  1322. 2 / sqrt(2 + sqrt(2)): S.Pi / 8,
  1323. -2 / sqrt(2 + sqrt(2)): 7*S.Pi / 8,
  1324. 2 / sqrt(3): S.Pi / 6,
  1325. -2 / sqrt(3): 5*S.Pi / 6,
  1326. (sqrt(5) - 1): S.Pi / 5,
  1327. (1 - sqrt(5)): 4*S.Pi / 5,
  1328. sqrt(2): S.Pi / 4,
  1329. -sqrt(2): 3*S.Pi / 4,
  1330. sqrt(2 + 2/sqrt(5)): 3*S.Pi / 10,
  1331. -sqrt(2 + 2/sqrt(5)): 7*S.Pi / 10,
  1332. S(2): S.Pi / 3,
  1333. -S(2): 2*S.Pi / 3,
  1334. sqrt(2*(2 + sqrt(2))): 3*S.Pi / 8,
  1335. -sqrt(2*(2 + sqrt(2))): 5*S.Pi / 8,
  1336. (1 + sqrt(5)): 2*S.Pi / 5,
  1337. (-1 - sqrt(5)): 3*S.Pi / 5,
  1338. (sqrt(6) + sqrt(2)): 5*S.Pi / 12,
  1339. (-sqrt(6) - sqrt(2)): 7*S.Pi / 12,
  1340. }
  1341. if arg in cst_table:
  1342. if arg.is_extended_real:
  1343. return cst_table[arg]*S.ImaginaryUnit
  1344. return cst_table[arg]
  1345. if arg is S.ComplexInfinity:
  1346. from sympy.calculus.accumulationbounds import AccumBounds
  1347. return S.ImaginaryUnit*AccumBounds(-S.Pi/2, S.Pi/2)
  1348. if arg.is_zero:
  1349. return S.Infinity
  1350. @staticmethod
  1351. @cacheit
  1352. def expansion_term(n, x, *previous_terms):
  1353. if n == 0:
  1354. return log(2 / x)
  1355. elif n < 0 or n % 2 == 1:
  1356. return S.Zero
  1357. else:
  1358. x = sympify(x)
  1359. if len(previous_terms) > 2 and n > 2:
  1360. p = previous_terms[-2]
  1361. return p * (n - 1)**2 // (n // 2)**2 * x**2 / 4
  1362. else:
  1363. k = n // 2
  1364. R = RisingFactorial(S.Half, k) * n
  1365. F = factorial(k) * n // 2 * n // 2
  1366. return -1 * R / F * x**n / 4
  1367. def inverse(self, argindex=1):
  1368. """
  1369. Returns the inverse of this function.
  1370. """
  1371. return sech
  1372. def _eval_rewrite_as_log(self, arg, **kwargs):
  1373. return log(1/arg + sqrt(1/arg - 1) * sqrt(1/arg + 1))
  1374. class acsch(InverseHyperbolicFunction):
  1375. """
  1376. ``acsch(x)`` is the inverse hyperbolic cosecant of ``x``.
  1377. The inverse hyperbolic cosecant function.
  1378. Examples
  1379. ========
  1380. >>> from sympy import acsch, sqrt, S
  1381. >>> from sympy.abc import x
  1382. >>> acsch(x).diff(x)
  1383. -1/(x**2*sqrt(1 + x**(-2)))
  1384. >>> acsch(1).diff(x)
  1385. 0
  1386. >>> acsch(1)
  1387. log(1 + sqrt(2))
  1388. >>> acsch(S.ImaginaryUnit)
  1389. -I*pi/2
  1390. >>> acsch(-2*S.ImaginaryUnit)
  1391. I*pi/6
  1392. >>> acsch(S.ImaginaryUnit*(sqrt(6) - sqrt(2)))
  1393. -5*I*pi/12
  1394. See Also
  1395. ========
  1396. asinh
  1397. References
  1398. ==========
  1399. .. [1] https://en.wikipedia.org/wiki/Hyperbolic_function
  1400. .. [2] http://dlmf.nist.gov/4.37
  1401. .. [3] http://functions.wolfram.com/ElementaryFunctions/ArcCsch/
  1402. """
  1403. def fdiff(self, argindex=1):
  1404. if argindex == 1:
  1405. z = self.args[0]
  1406. return -1/(z**2*sqrt(1 + 1/z**2))
  1407. else:
  1408. raise ArgumentIndexError(self, argindex)
  1409. @classmethod
  1410. def eval(cls, arg):
  1411. arg = sympify(arg)
  1412. if arg.is_Number:
  1413. if arg is S.NaN:
  1414. return S.NaN
  1415. elif arg is S.Infinity:
  1416. return S.Zero
  1417. elif arg is S.NegativeInfinity:
  1418. return S.Zero
  1419. elif arg.is_zero:
  1420. return S.ComplexInfinity
  1421. elif arg is S.One:
  1422. return log(1 + sqrt(2))
  1423. elif arg is S.NegativeOne:
  1424. return - log(1 + sqrt(2))
  1425. if arg.is_number:
  1426. cst_table = {
  1427. S.ImaginaryUnit: -S.Pi / 2,
  1428. S.ImaginaryUnit*(sqrt(2) + sqrt(6)): -S.Pi / 12,
  1429. S.ImaginaryUnit*(1 + sqrt(5)): -S.Pi / 10,
  1430. S.ImaginaryUnit*2 / sqrt(2 - sqrt(2)): -S.Pi / 8,
  1431. S.ImaginaryUnit*2: -S.Pi / 6,
  1432. S.ImaginaryUnit*sqrt(2 + 2/sqrt(5)): -S.Pi / 5,
  1433. S.ImaginaryUnit*sqrt(2): -S.Pi / 4,
  1434. S.ImaginaryUnit*(sqrt(5)-1): -3*S.Pi / 10,
  1435. S.ImaginaryUnit*2 / sqrt(3): -S.Pi / 3,
  1436. S.ImaginaryUnit*2 / sqrt(2 + sqrt(2)): -3*S.Pi / 8,
  1437. S.ImaginaryUnit*sqrt(2 - 2/sqrt(5)): -2*S.Pi / 5,
  1438. S.ImaginaryUnit*(sqrt(6) - sqrt(2)): -5*S.Pi / 12,
  1439. S(2): -S.ImaginaryUnit*log((1+sqrt(5))/2),
  1440. }
  1441. if arg in cst_table:
  1442. return cst_table[arg]*S.ImaginaryUnit
  1443. if arg is S.ComplexInfinity:
  1444. return S.Zero
  1445. if arg.is_zero:
  1446. return S.ComplexInfinity
  1447. if arg.could_extract_minus_sign():
  1448. return -cls(-arg)
  1449. def inverse(self, argindex=1):
  1450. """
  1451. Returns the inverse of this function.
  1452. """
  1453. return csch
  1454. def _eval_rewrite_as_log(self, arg, **kwargs):
  1455. return log(1/arg + sqrt(1/arg**2 + 1))
  1456. def _eval_is_zero(self):
  1457. return self.args[0].is_infinite