hyperbolic.py 65 KB

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