trigonometric.py 108 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490
  1. from typing import Tuple as tTuple
  2. from sympy.core.add import Add
  3. from sympy.core.basic import sympify, cacheit
  4. from sympy.core.expr import Expr
  5. from sympy.core.function import Function, ArgumentIndexError, PoleError, expand_mul
  6. from sympy.core.logic import fuzzy_not, fuzzy_or, FuzzyBool, fuzzy_and
  7. from sympy.core.numbers import igcdex, Rational, pi, Integer
  8. from sympy.core.relational import Ne
  9. from sympy.core.singleton import S
  10. from sympy.core.symbol import Symbol, Dummy
  11. from sympy.functions.combinatorial.factorials import factorial, RisingFactorial
  12. from sympy.functions.elementary.exponential import log, exp
  13. from sympy.functions.elementary.integers import floor
  14. from sympy.functions.elementary.hyperbolic import (acoth, asinh, atanh, cosh,
  15. coth, HyperbolicFunction, sinh, tanh)
  16. from sympy.functions.elementary.miscellaneous import sqrt, Min, Max
  17. from sympy.functions.elementary.piecewise import Piecewise
  18. from sympy.sets.setexpr import SetExpr
  19. from sympy.sets.sets import FiniteSet
  20. from sympy.utilities.iterables import numbered_symbols
  21. ###############################################################################
  22. ########################## TRIGONOMETRIC FUNCTIONS ############################
  23. ###############################################################################
  24. class TrigonometricFunction(Function):
  25. """Base class for trigonometric functions. """
  26. unbranched = True
  27. _singularities = (S.ComplexInfinity,)
  28. def _eval_is_rational(self):
  29. s = self.func(*self.args)
  30. if s.func == self.func:
  31. if s.args[0].is_rational and fuzzy_not(s.args[0].is_zero):
  32. return False
  33. else:
  34. return s.is_rational
  35. def _eval_is_algebraic(self):
  36. s = self.func(*self.args)
  37. if s.func == self.func:
  38. if fuzzy_not(self.args[0].is_zero) and self.args[0].is_algebraic:
  39. return False
  40. pi_coeff = _pi_coeff(self.args[0])
  41. if pi_coeff is not None and pi_coeff.is_rational:
  42. return True
  43. else:
  44. return s.is_algebraic
  45. def _eval_expand_complex(self, deep=True, **hints):
  46. re_part, im_part = self.as_real_imag(deep=deep, **hints)
  47. return re_part + im_part*S.ImaginaryUnit
  48. def _as_real_imag(self, deep=True, **hints):
  49. if self.args[0].is_extended_real:
  50. if deep:
  51. hints['complex'] = False
  52. return (self.args[0].expand(deep, **hints), S.Zero)
  53. else:
  54. return (self.args[0], S.Zero)
  55. if deep:
  56. re, im = self.args[0].expand(deep, **hints).as_real_imag()
  57. else:
  58. re, im = self.args[0].as_real_imag()
  59. return (re, im)
  60. def _period(self, general_period, symbol=None):
  61. f = expand_mul(self.args[0])
  62. if symbol is None:
  63. symbol = tuple(f.free_symbols)[0]
  64. if not f.has(symbol):
  65. return S.Zero
  66. if f == symbol:
  67. return general_period
  68. if symbol in f.free_symbols:
  69. if f.is_Mul:
  70. g, h = f.as_independent(symbol)
  71. if h == symbol:
  72. return general_period/abs(g)
  73. if f.is_Add:
  74. a, h = f.as_independent(symbol)
  75. g, h = h.as_independent(symbol, as_Add=False)
  76. if h == symbol:
  77. return general_period/abs(g)
  78. raise NotImplementedError("Use the periodicity function instead.")
  79. def _peeloff_pi(arg):
  80. r"""
  81. Split ARG into two parts, a "rest" and a multiple of $\pi$.
  82. This assumes ARG to be an Add.
  83. The multiple of $\pi$ returned in the second position is always a Rational.
  84. Examples
  85. ========
  86. >>> from sympy.functions.elementary.trigonometric import _peeloff_pi
  87. >>> from sympy import pi
  88. >>> from sympy.abc import x, y
  89. >>> _peeloff_pi(x + pi/2)
  90. (x, 1/2)
  91. >>> _peeloff_pi(x + 2*pi/3 + pi*y)
  92. (x + pi*y + pi/6, 1/2)
  93. """
  94. pi_coeff = S.Zero
  95. rest_terms = []
  96. for a in Add.make_args(arg):
  97. K = a.coeff(S.Pi)
  98. if K and K.is_rational:
  99. pi_coeff += K
  100. else:
  101. rest_terms.append(a)
  102. if pi_coeff is S.Zero:
  103. return arg, S.Zero
  104. m1 = (pi_coeff % S.Half)
  105. m2 = pi_coeff - m1
  106. if m2.is_integer or ((2*m2).is_integer and m2.is_even is False):
  107. return Add(*(rest_terms + [m1*pi])), m2
  108. return arg, S.Zero
  109. def _pi_coeff(arg, cycles=1):
  110. r"""
  111. When arg is a Number times $\pi$ (e.g. $3\pi/2$) then return the Number
  112. normalized to be in the range $[0, 2]$, else `None`.
  113. When an even multiple of $\pi$ is encountered, if it is multiplying
  114. something with known parity then the multiple is returned as 0 otherwise
  115. as 2.
  116. Examples
  117. ========
  118. >>> from sympy.functions.elementary.trigonometric import _pi_coeff
  119. >>> from sympy import pi, Dummy
  120. >>> from sympy.abc import x
  121. >>> _pi_coeff(3*x*pi)
  122. 3*x
  123. >>> _pi_coeff(11*pi/7)
  124. 11/7
  125. >>> _pi_coeff(-11*pi/7)
  126. 3/7
  127. >>> _pi_coeff(4*pi)
  128. 0
  129. >>> _pi_coeff(5*pi)
  130. 1
  131. >>> _pi_coeff(5.0*pi)
  132. 1
  133. >>> _pi_coeff(5.5*pi)
  134. 3/2
  135. >>> _pi_coeff(2 + pi)
  136. >>> _pi_coeff(2*Dummy(integer=True)*pi)
  137. 2
  138. >>> _pi_coeff(2*Dummy(even=True)*pi)
  139. 0
  140. """
  141. arg = sympify(arg)
  142. if arg is S.Pi:
  143. return S.One
  144. elif not arg:
  145. return S.Zero
  146. elif arg.is_Mul:
  147. cx = arg.coeff(S.Pi)
  148. if cx:
  149. c, x = cx.as_coeff_Mul() # pi is not included as coeff
  150. if c.is_Float:
  151. # recast exact binary fractions to Rationals
  152. f = abs(c) % 1
  153. if f != 0:
  154. p = -int(round(log(f, 2).evalf()))
  155. m = 2**p
  156. cm = c*m
  157. i = int(cm)
  158. if i == cm:
  159. c = Rational(i, m)
  160. cx = c*x
  161. else:
  162. c = Rational(int(c))
  163. cx = c*x
  164. if x.is_integer:
  165. c2 = c % 2
  166. if c2 == 1:
  167. return x
  168. elif not c2:
  169. if x.is_even is not None: # known parity
  170. return S.Zero
  171. return Integer(2)
  172. else:
  173. return c2*x
  174. return cx
  175. elif arg.is_zero:
  176. return S.Zero
  177. class sin(TrigonometricFunction):
  178. r"""
  179. The sine function.
  180. Returns the sine of x (measured in radians).
  181. Explanation
  182. ===========
  183. This function will evaluate automatically in the
  184. case $x/\pi$ is some rational number [4]_. For example,
  185. if $x$ is a multiple of $\pi$, $\pi/2$, $\pi/3$, $\pi/4$, and $\pi/6$.
  186. Examples
  187. ========
  188. >>> from sympy import sin, pi
  189. >>> from sympy.abc import x
  190. >>> sin(x**2).diff(x)
  191. 2*x*cos(x**2)
  192. >>> sin(1).diff(x)
  193. 0
  194. >>> sin(pi)
  195. 0
  196. >>> sin(pi/2)
  197. 1
  198. >>> sin(pi/6)
  199. 1/2
  200. >>> sin(pi/12)
  201. -sqrt(2)/4 + sqrt(6)/4
  202. See Also
  203. ========
  204. csc, cos, sec, tan, cot
  205. asin, acsc, acos, asec, atan, acot, atan2
  206. References
  207. ==========
  208. .. [1] https://en.wikipedia.org/wiki/Trigonometric_functions
  209. .. [2] http://dlmf.nist.gov/4.14
  210. .. [3] http://functions.wolfram.com/ElementaryFunctions/Sin
  211. .. [4] http://mathworld.wolfram.com/TrigonometryAngles.html
  212. """
  213. def period(self, symbol=None):
  214. return self._period(2*pi, symbol)
  215. def fdiff(self, argindex=1):
  216. if argindex == 1:
  217. return cos(self.args[0])
  218. else:
  219. raise ArgumentIndexError(self, argindex)
  220. @classmethod
  221. def eval(cls, arg):
  222. from sympy.calculus.accumulationbounds import AccumBounds
  223. if arg.is_Number:
  224. if arg is S.NaN:
  225. return S.NaN
  226. elif arg.is_zero:
  227. return S.Zero
  228. elif arg in (S.Infinity, S.NegativeInfinity):
  229. return AccumBounds(-1, 1)
  230. if arg is S.ComplexInfinity:
  231. return S.NaN
  232. if isinstance(arg, AccumBounds):
  233. min, max = arg.min, arg.max
  234. d = floor(min/(2*S.Pi))
  235. if min is not S.NegativeInfinity:
  236. min = min - d*2*S.Pi
  237. if max is not S.Infinity:
  238. max = max - d*2*S.Pi
  239. if AccumBounds(min, max).intersection(FiniteSet(S.Pi/2, S.Pi*Rational(5, 2))) \
  240. is not S.EmptySet and \
  241. AccumBounds(min, max).intersection(FiniteSet(S.Pi*Rational(3, 2),
  242. S.Pi*Rational(7, 2))) is not S.EmptySet:
  243. return AccumBounds(-1, 1)
  244. elif AccumBounds(min, max).intersection(FiniteSet(S.Pi/2, S.Pi*Rational(5, 2))) \
  245. is not S.EmptySet:
  246. return AccumBounds(Min(sin(min), sin(max)), 1)
  247. elif AccumBounds(min, max).intersection(FiniteSet(S.Pi*Rational(3, 2), S.Pi*Rational(8, 2))) \
  248. is not S.EmptySet:
  249. return AccumBounds(-1, Max(sin(min), sin(max)))
  250. else:
  251. return AccumBounds(Min(sin(min), sin(max)),
  252. Max(sin(min), sin(max)))
  253. elif isinstance(arg, SetExpr):
  254. return arg._eval_func(cls)
  255. if arg.could_extract_minus_sign():
  256. return -cls(-arg)
  257. i_coeff = arg.as_coefficient(S.ImaginaryUnit)
  258. if i_coeff is not None:
  259. return S.ImaginaryUnit*sinh(i_coeff)
  260. pi_coeff = _pi_coeff(arg)
  261. if pi_coeff is not None:
  262. if pi_coeff.is_integer:
  263. return S.Zero
  264. if (2*pi_coeff).is_integer:
  265. # is_even-case handled above as then pi_coeff.is_integer,
  266. # so check if known to be not even
  267. if pi_coeff.is_even is False:
  268. return S.NegativeOne**(pi_coeff - S.Half)
  269. if not pi_coeff.is_Rational:
  270. narg = pi_coeff*S.Pi
  271. if narg != arg:
  272. return cls(narg)
  273. return None
  274. # https://github.com/sympy/sympy/issues/6048
  275. # transform a sine to a cosine, to avoid redundant code
  276. if pi_coeff.is_Rational:
  277. x = pi_coeff % 2
  278. if x > 1:
  279. return -cls((x % 1)*S.Pi)
  280. if 2*x > 1:
  281. return cls((1 - x)*S.Pi)
  282. narg = ((pi_coeff + Rational(3, 2)) % 2)*S.Pi
  283. result = cos(narg)
  284. if not isinstance(result, cos):
  285. return result
  286. if pi_coeff*S.Pi != arg:
  287. return cls(pi_coeff*S.Pi)
  288. return None
  289. if arg.is_Add:
  290. x, m = _peeloff_pi(arg)
  291. if m:
  292. m = m*S.Pi
  293. return sin(m)*cos(x) + cos(m)*sin(x)
  294. if arg.is_zero:
  295. return S.Zero
  296. if isinstance(arg, asin):
  297. return arg.args[0]
  298. if isinstance(arg, atan):
  299. x = arg.args[0]
  300. return x/sqrt(1 + x**2)
  301. if isinstance(arg, atan2):
  302. y, x = arg.args
  303. return y/sqrt(x**2 + y**2)
  304. if isinstance(arg, acos):
  305. x = arg.args[0]
  306. return sqrt(1 - x**2)
  307. if isinstance(arg, acot):
  308. x = arg.args[0]
  309. return 1/(sqrt(1 + 1/x**2)*x)
  310. if isinstance(arg, acsc):
  311. x = arg.args[0]
  312. return 1/x
  313. if isinstance(arg, asec):
  314. x = arg.args[0]
  315. return sqrt(1 - 1/x**2)
  316. @staticmethod
  317. @cacheit
  318. def taylor_term(n, x, *previous_terms):
  319. if n < 0 or n % 2 == 0:
  320. return S.Zero
  321. else:
  322. x = sympify(x)
  323. if len(previous_terms) > 2:
  324. p = previous_terms[-2]
  325. return -p*x**2/(n*(n - 1))
  326. else:
  327. return S.NegativeOne**(n//2)*x**n/factorial(n)
  328. def _eval_nseries(self, x, n, logx, cdir=0):
  329. arg = self.args[0]
  330. if logx is not None:
  331. arg = arg.subs(log(x), logx)
  332. if arg.subs(x, 0).has(S.NaN, S.ComplexInfinity):
  333. raise PoleError("Cannot expand %s around 0" % (self))
  334. return Function._eval_nseries(self, x, n=n, logx=logx, cdir=cdir)
  335. def _eval_rewrite_as_exp(self, arg, **kwargs):
  336. I = S.ImaginaryUnit
  337. if isinstance(arg, (TrigonometricFunction, HyperbolicFunction)):
  338. arg = arg.func(arg.args[0]).rewrite(exp)
  339. return (exp(arg*I) - exp(-arg*I))/(2*I)
  340. def _eval_rewrite_as_Pow(self, arg, **kwargs):
  341. if isinstance(arg, log):
  342. I = S.ImaginaryUnit
  343. x = arg.args[0]
  344. return I*x**-I/2 - I*x**I /2
  345. def _eval_rewrite_as_cos(self, arg, **kwargs):
  346. return cos(arg - S.Pi/2, evaluate=False)
  347. def _eval_rewrite_as_tan(self, arg, **kwargs):
  348. tan_half = tan(S.Half*arg)
  349. return 2*tan_half/(1 + tan_half**2)
  350. def _eval_rewrite_as_sincos(self, arg, **kwargs):
  351. return sin(arg)*cos(arg)/cos(arg)
  352. def _eval_rewrite_as_cot(self, arg, **kwargs):
  353. cot_half = cot(S.Half*arg)
  354. return 2*cot_half/(1 + cot_half**2)
  355. def _eval_rewrite_as_pow(self, arg, **kwargs):
  356. return self.rewrite(cos).rewrite(pow)
  357. def _eval_rewrite_as_sqrt(self, arg, **kwargs):
  358. return self.rewrite(cos).rewrite(sqrt)
  359. def _eval_rewrite_as_csc(self, arg, **kwargs):
  360. return 1/csc(arg)
  361. def _eval_rewrite_as_sec(self, arg, **kwargs):
  362. return 1/sec(arg - S.Pi/2, evaluate=False)
  363. def _eval_rewrite_as_sinc(self, arg, **kwargs):
  364. return arg*sinc(arg)
  365. def _eval_conjugate(self):
  366. return self.func(self.args[0].conjugate())
  367. def as_real_imag(self, deep=True, **hints):
  368. re, im = self._as_real_imag(deep=deep, **hints)
  369. return (sin(re)*cosh(im), cos(re)*sinh(im))
  370. def _eval_expand_trig(self, **hints):
  371. from sympy.functions.special.polynomials import chebyshevt, chebyshevu
  372. arg = self.args[0]
  373. x = None
  374. if arg.is_Add: # TODO, implement more if deep stuff here
  375. # TODO: Do this more efficiently for more than two terms
  376. x, y = arg.as_two_terms()
  377. sx = sin(x, evaluate=False)._eval_expand_trig()
  378. sy = sin(y, evaluate=False)._eval_expand_trig()
  379. cx = cos(x, evaluate=False)._eval_expand_trig()
  380. cy = cos(y, evaluate=False)._eval_expand_trig()
  381. return sx*cy + sy*cx
  382. elif arg.is_Mul:
  383. n, x = arg.as_coeff_Mul(rational=True)
  384. if n.is_Integer: # n will be positive because of .eval
  385. # canonicalization
  386. # See http://mathworld.wolfram.com/Multiple-AngleFormulas.html
  387. if n.is_odd:
  388. return S.NegativeOne**((n - 1)/2)*chebyshevt(n, sin(x))
  389. else:
  390. return expand_mul(S.NegativeOne**(n/2 - 1)*cos(x)*
  391. chebyshevu(n - 1, sin(x)), deep=False)
  392. pi_coeff = _pi_coeff(arg)
  393. if pi_coeff is not None:
  394. if pi_coeff.is_Rational:
  395. return self.rewrite(sqrt)
  396. return sin(arg)
  397. def _eval_as_leading_term(self, x, logx=None, cdir=0):
  398. from sympy.functions.elementary.complexes import re
  399. from sympy.calculus.accumulationbounds import AccumBounds
  400. arg = self.args[0]
  401. x0 = arg.subs(x, 0).cancel()
  402. n = x0/S.Pi
  403. if n.is_integer:
  404. lt = (arg - n*S.Pi).as_leading_term(x)
  405. return (S.NegativeOne**n)*lt
  406. if x0 is S.ComplexInfinity:
  407. x0 = arg.limit(x, 0, dir='-' if re(cdir).is_negative else '+')
  408. if x0 in [S.Infinity, S.NegativeInfinity]:
  409. return AccumBounds(-1, 1)
  410. return self.func(x0) if x0.is_finite else self
  411. def _eval_is_extended_real(self):
  412. if self.args[0].is_extended_real:
  413. return True
  414. def _eval_is_finite(self):
  415. arg = self.args[0]
  416. if arg.is_extended_real:
  417. return True
  418. def _eval_is_zero(self):
  419. rest, pi_mult = _peeloff_pi(self.args[0])
  420. if rest.is_zero:
  421. return pi_mult.is_integer
  422. def _eval_is_complex(self):
  423. if self.args[0].is_extended_real \
  424. or self.args[0].is_complex:
  425. return True
  426. class cos(TrigonometricFunction):
  427. """
  428. The cosine function.
  429. Returns the cosine of x (measured in radians).
  430. Explanation
  431. ===========
  432. See :func:`sin` for notes about automatic evaluation.
  433. Examples
  434. ========
  435. >>> from sympy import cos, pi
  436. >>> from sympy.abc import x
  437. >>> cos(x**2).diff(x)
  438. -2*x*sin(x**2)
  439. >>> cos(1).diff(x)
  440. 0
  441. >>> cos(pi)
  442. -1
  443. >>> cos(pi/2)
  444. 0
  445. >>> cos(2*pi/3)
  446. -1/2
  447. >>> cos(pi/12)
  448. sqrt(2)/4 + sqrt(6)/4
  449. See Also
  450. ========
  451. sin, csc, sec, tan, cot
  452. asin, acsc, acos, asec, atan, acot, atan2
  453. References
  454. ==========
  455. .. [1] https://en.wikipedia.org/wiki/Trigonometric_functions
  456. .. [2] http://dlmf.nist.gov/4.14
  457. .. [3] http://functions.wolfram.com/ElementaryFunctions/Cos
  458. """
  459. def period(self, symbol=None):
  460. return self._period(2*pi, symbol)
  461. def fdiff(self, argindex=1):
  462. if argindex == 1:
  463. return -sin(self.args[0])
  464. else:
  465. raise ArgumentIndexError(self, argindex)
  466. @classmethod
  467. def eval(cls, arg):
  468. from sympy.functions.special.polynomials import chebyshevt
  469. from sympy.calculus.accumulationbounds import AccumBounds
  470. if arg.is_Number:
  471. if arg is S.NaN:
  472. return S.NaN
  473. elif arg.is_zero:
  474. return S.One
  475. elif arg in (S.Infinity, S.NegativeInfinity):
  476. # In this case it is better to return AccumBounds(-1, 1)
  477. # rather than returning S.NaN, since AccumBounds(-1, 1)
  478. # preserves the information that sin(oo) is between
  479. # -1 and 1, where S.NaN does not do that.
  480. return AccumBounds(-1, 1)
  481. if arg is S.ComplexInfinity:
  482. return S.NaN
  483. if isinstance(arg, AccumBounds):
  484. return sin(arg + S.Pi/2)
  485. elif isinstance(arg, SetExpr):
  486. return arg._eval_func(cls)
  487. if arg.is_extended_real and arg.is_finite is False:
  488. return AccumBounds(-1, 1)
  489. if arg.could_extract_minus_sign():
  490. return cls(-arg)
  491. i_coeff = arg.as_coefficient(S.ImaginaryUnit)
  492. if i_coeff is not None:
  493. return cosh(i_coeff)
  494. pi_coeff = _pi_coeff(arg)
  495. if pi_coeff is not None:
  496. if pi_coeff.is_integer:
  497. return (S.NegativeOne)**pi_coeff
  498. if (2*pi_coeff).is_integer:
  499. # is_even-case handled above as then pi_coeff.is_integer,
  500. # so check if known to be not even
  501. if pi_coeff.is_even is False:
  502. return S.Zero
  503. if not pi_coeff.is_Rational:
  504. narg = pi_coeff*S.Pi
  505. if narg != arg:
  506. return cls(narg)
  507. return None
  508. # cosine formula #####################
  509. # https://github.com/sympy/sympy/issues/6048
  510. # explicit calculations are performed for
  511. # cos(k pi/n) for n = 8,10,12,15,20,24,30,40,60,120
  512. # Some other exact values like cos(k pi/240) can be
  513. # calculated using a partial-fraction decomposition
  514. # by calling cos( X ).rewrite(sqrt)
  515. cst_table_some = {
  516. 3: S.Half,
  517. 5: (sqrt(5) + 1)/4,
  518. }
  519. if pi_coeff.is_Rational:
  520. q = pi_coeff.q
  521. p = pi_coeff.p % (2*q)
  522. if p > q:
  523. narg = (pi_coeff - 1)*S.Pi
  524. return -cls(narg)
  525. if 2*p > q:
  526. narg = (1 - pi_coeff)*S.Pi
  527. return -cls(narg)
  528. # If nested sqrt's are worse than un-evaluation
  529. # you can require q to be in (1, 2, 3, 4, 6, 12)
  530. # q <= 12, q=15, q=20, q=24, q=30, q=40, q=60, q=120 return
  531. # expressions with 2 or fewer sqrt nestings.
  532. table2 = {
  533. 12: (3, 4),
  534. 20: (4, 5),
  535. 30: (5, 6),
  536. 15: (6, 10),
  537. 24: (6, 8),
  538. 40: (8, 10),
  539. 60: (20, 30),
  540. 120: (40, 60)
  541. }
  542. if q in table2:
  543. a, b = p*S.Pi/table2[q][0], p*S.Pi/table2[q][1]
  544. nvala, nvalb = cls(a), cls(b)
  545. if None in (nvala, nvalb):
  546. return None
  547. return nvala*nvalb + cls(S.Pi/2 - a)*cls(S.Pi/2 - b)
  548. if q > 12:
  549. return None
  550. if q in cst_table_some:
  551. cts = cst_table_some[pi_coeff.q]
  552. return chebyshevt(pi_coeff.p, cts).expand()
  553. if 0 == q % 2:
  554. narg = (pi_coeff*2)*S.Pi
  555. nval = cls(narg)
  556. if None == nval:
  557. return None
  558. x = (2*pi_coeff + 1)/2
  559. sign_cos = (-1)**((-1 if x < 0 else 1)*int(abs(x)))
  560. return sign_cos*sqrt( (1 + nval)/2 )
  561. return None
  562. if arg.is_Add:
  563. x, m = _peeloff_pi(arg)
  564. if m:
  565. m = m*S.Pi
  566. return cos(m)*cos(x) - sin(m)*sin(x)
  567. if arg.is_zero:
  568. return S.One
  569. if isinstance(arg, acos):
  570. return arg.args[0]
  571. if isinstance(arg, atan):
  572. x = arg.args[0]
  573. return 1/sqrt(1 + x**2)
  574. if isinstance(arg, atan2):
  575. y, x = arg.args
  576. return x/sqrt(x**2 + y**2)
  577. if isinstance(arg, asin):
  578. x = arg.args[0]
  579. return sqrt(1 - x ** 2)
  580. if isinstance(arg, acot):
  581. x = arg.args[0]
  582. return 1/sqrt(1 + 1/x**2)
  583. if isinstance(arg, acsc):
  584. x = arg.args[0]
  585. return sqrt(1 - 1/x**2)
  586. if isinstance(arg, asec):
  587. x = arg.args[0]
  588. return 1/x
  589. @staticmethod
  590. @cacheit
  591. def taylor_term(n, x, *previous_terms):
  592. if n < 0 or n % 2 == 1:
  593. return S.Zero
  594. else:
  595. x = sympify(x)
  596. if len(previous_terms) > 2:
  597. p = previous_terms[-2]
  598. return -p*x**2/(n*(n - 1))
  599. else:
  600. return S.NegativeOne**(n//2)*x**n/factorial(n)
  601. def _eval_nseries(self, x, n, logx, cdir=0):
  602. arg = self.args[0]
  603. if logx is not None:
  604. arg = arg.subs(log(x), logx)
  605. if arg.subs(x, 0).has(S.NaN, S.ComplexInfinity):
  606. raise PoleError("Cannot expand %s around 0" % (self))
  607. return Function._eval_nseries(self, x, n=n, logx=logx, cdir=cdir)
  608. def _eval_rewrite_as_exp(self, arg, **kwargs):
  609. I = S.ImaginaryUnit
  610. if isinstance(arg, (TrigonometricFunction, HyperbolicFunction)):
  611. arg = arg.func(arg.args[0]).rewrite(exp)
  612. return (exp(arg*I) + exp(-arg*I))/2
  613. def _eval_rewrite_as_Pow(self, arg, **kwargs):
  614. if isinstance(arg, log):
  615. I = S.ImaginaryUnit
  616. x = arg.args[0]
  617. return x**I/2 + x**-I/2
  618. def _eval_rewrite_as_sin(self, arg, **kwargs):
  619. return sin(arg + S.Pi/2, evaluate=False)
  620. def _eval_rewrite_as_tan(self, arg, **kwargs):
  621. tan_half = tan(S.Half*arg)**2
  622. return (1 - tan_half)/(1 + tan_half)
  623. def _eval_rewrite_as_sincos(self, arg, **kwargs):
  624. return sin(arg)*cos(arg)/sin(arg)
  625. def _eval_rewrite_as_cot(self, arg, **kwargs):
  626. cot_half = cot(S.Half*arg)**2
  627. return (cot_half - 1)/(cot_half + 1)
  628. def _eval_rewrite_as_pow(self, arg, **kwargs):
  629. return self._eval_rewrite_as_sqrt(arg)
  630. def _eval_rewrite_as_sqrt(self, arg, **kwargs):
  631. from sympy.functions.special.polynomials import chebyshevt
  632. def migcdex(x):
  633. # recursive calcuation of gcd and linear combination
  634. # for a sequence of integers.
  635. # Given (x1, x2, x3)
  636. # Returns (y1, y1, y3, g)
  637. # such that g is the gcd and x1*y1+x2*y2+x3*y3 - g = 0
  638. # Note, that this is only one such linear combination.
  639. if len(x) == 1:
  640. return (1, x[0])
  641. if len(x) == 2:
  642. return igcdex(x[0], x[-1])
  643. g = migcdex(x[1:])
  644. u, v, h = igcdex(x[0], g[-1])
  645. return tuple([u] + [v*i for i in g[0:-1] ] + [h])
  646. def ipartfrac(r, factors=None):
  647. from sympy.ntheory import factorint
  648. if isinstance(r, int):
  649. return r
  650. if not isinstance(r, Rational):
  651. raise TypeError("r is not rational")
  652. n = r.q
  653. if 2 > r.q*r.q:
  654. return r.q
  655. if None == factors:
  656. a = [n//x**y for x, y in factorint(r.q).items()]
  657. else:
  658. a = [n//x for x in factors]
  659. if len(a) == 1:
  660. return [ r ]
  661. h = migcdex(a)
  662. ans = [ r.p*Rational(i*j, r.q) for i, j in zip(h[:-1], a) ]
  663. assert r == sum(ans)
  664. return ans
  665. pi_coeff = _pi_coeff(arg)
  666. if pi_coeff is None:
  667. return None
  668. if pi_coeff.is_integer:
  669. # it was unevaluated
  670. return self.func(pi_coeff*S.Pi)
  671. if not pi_coeff.is_Rational:
  672. return None
  673. def _cospi257():
  674. """ Express cos(pi/257) explicitly as a function of radicals
  675. Based upon the equations in
  676. http://math.stackexchange.com/questions/516142/how-does-cos2-pi-257-look-like-in-real-radicals
  677. See also http://www.susqu.edu/brakke/constructions/257-gon.m.txt
  678. """
  679. def f1(a, b):
  680. return (a + sqrt(a**2 + b))/2, (a - sqrt(a**2 + b))/2
  681. def f2(a, b):
  682. return (a - sqrt(a**2 + b))/2
  683. t1, t2 = f1(-1, 256)
  684. z1, z3 = f1(t1, 64)
  685. z2, z4 = f1(t2, 64)
  686. y1, y5 = f1(z1, 4*(5 + t1 + 2*z1))
  687. y6, y2 = f1(z2, 4*(5 + t2 + 2*z2))
  688. y3, y7 = f1(z3, 4*(5 + t1 + 2*z3))
  689. y8, y4 = f1(z4, 4*(5 + t2 + 2*z4))
  690. x1, x9 = f1(y1, -4*(t1 + y1 + y3 + 2*y6))
  691. x2, x10 = f1(y2, -4*(t2 + y2 + y4 + 2*y7))
  692. x3, x11 = f1(y3, -4*(t1 + y3 + y5 + 2*y8))
  693. x4, x12 = f1(y4, -4*(t2 + y4 + y6 + 2*y1))
  694. x5, x13 = f1(y5, -4*(t1 + y5 + y7 + 2*y2))
  695. x6, x14 = f1(y6, -4*(t2 + y6 + y8 + 2*y3))
  696. x15, x7 = f1(y7, -4*(t1 + y7 + y1 + 2*y4))
  697. x8, x16 = f1(y8, -4*(t2 + y8 + y2 + 2*y5))
  698. v1 = f2(x1, -4*(x1 + x2 + x3 + x6))
  699. v2 = f2(x2, -4*(x2 + x3 + x4 + x7))
  700. v3 = f2(x8, -4*(x8 + x9 + x10 + x13))
  701. v4 = f2(x9, -4*(x9 + x10 + x11 + x14))
  702. v5 = f2(x10, -4*(x10 + x11 + x12 + x15))
  703. v6 = f2(x16, -4*(x16 + x1 + x2 + x5))
  704. u1 = -f2(-v1, -4*(v2 + v3))
  705. u2 = -f2(-v4, -4*(v5 + v6))
  706. w1 = -2*f2(-u1, -4*u2)
  707. return sqrt(sqrt(2)*sqrt(w1 + 4)/8 + S.Half)
  708. cst_table_some = {
  709. 3: S.Half,
  710. 5: (sqrt(5) + 1)/4,
  711. 17: sqrt((15 + sqrt(17))/32 + sqrt(2)*(sqrt(17 - sqrt(17)) +
  712. sqrt(sqrt(2)*(-8*sqrt(17 + sqrt(17)) - (1 - sqrt(17))
  713. *sqrt(17 - sqrt(17))) + 6*sqrt(17) + 34))/32),
  714. 257: _cospi257()
  715. # 65537 is the only other known Fermat prime and the very
  716. # large expression is intentionally omitted from SymPy; see
  717. # http://www.susqu.edu/brakke/constructions/65537-gon.m.txt
  718. }
  719. def _fermatCoords(n):
  720. # if n can be factored in terms of Fermat primes with
  721. # multiplicity of each being 1, return those primes, else
  722. # False
  723. primes = []
  724. for p_i in cst_table_some:
  725. quotient, remainder = divmod(n, p_i)
  726. if remainder == 0:
  727. n = quotient
  728. primes.append(p_i)
  729. if n == 1:
  730. return tuple(primes)
  731. return False
  732. if pi_coeff.q in cst_table_some:
  733. rv = chebyshevt(pi_coeff.p, cst_table_some[pi_coeff.q])
  734. if pi_coeff.q < 257:
  735. rv = rv.expand()
  736. return rv
  737. if not pi_coeff.q % 2: # recursively remove factors of 2
  738. pico2 = pi_coeff*2
  739. nval = cos(pico2*S.Pi).rewrite(sqrt)
  740. x = (pico2 + 1)/2
  741. sign_cos = -1 if int(x) % 2 else 1
  742. return sign_cos*sqrt( (1 + nval)/2 )
  743. FC = _fermatCoords(pi_coeff.q)
  744. if FC:
  745. decomp = ipartfrac(pi_coeff, FC)
  746. X = [(x[1], x[0]*S.Pi) for x in zip(decomp, numbered_symbols('z'))]
  747. pcls = cos(sum([x[0] for x in X]))._eval_expand_trig().subs(X)
  748. return pcls.rewrite(sqrt)
  749. else:
  750. decomp = ipartfrac(pi_coeff)
  751. X = [(x[1], x[0]*S.Pi) for x in zip(decomp, numbered_symbols('z'))]
  752. pcls = cos(sum([x[0] for x in X]))._eval_expand_trig().subs(X)
  753. return pcls
  754. def _eval_rewrite_as_sec(self, arg, **kwargs):
  755. return 1/sec(arg)
  756. def _eval_rewrite_as_csc(self, arg, **kwargs):
  757. return 1/sec(arg).rewrite(csc)
  758. def _eval_conjugate(self):
  759. return self.func(self.args[0].conjugate())
  760. def as_real_imag(self, deep=True, **hints):
  761. re, im = self._as_real_imag(deep=deep, **hints)
  762. return (cos(re)*cosh(im), -sin(re)*sinh(im))
  763. def _eval_expand_trig(self, **hints):
  764. from sympy.functions.special.polynomials import chebyshevt
  765. arg = self.args[0]
  766. x = None
  767. if arg.is_Add: # TODO: Do this more efficiently for more than two terms
  768. x, y = arg.as_two_terms()
  769. sx = sin(x, evaluate=False)._eval_expand_trig()
  770. sy = sin(y, evaluate=False)._eval_expand_trig()
  771. cx = cos(x, evaluate=False)._eval_expand_trig()
  772. cy = cos(y, evaluate=False)._eval_expand_trig()
  773. return cx*cy - sx*sy
  774. elif arg.is_Mul:
  775. coeff, terms = arg.as_coeff_Mul(rational=True)
  776. if coeff.is_Integer:
  777. return chebyshevt(coeff, cos(terms))
  778. pi_coeff = _pi_coeff(arg)
  779. if pi_coeff is not None:
  780. if pi_coeff.is_Rational:
  781. return self.rewrite(sqrt)
  782. return cos(arg)
  783. def _eval_as_leading_term(self, x, logx=None, cdir=0):
  784. from sympy.functions.elementary.complexes import re
  785. from sympy.calculus.accumulationbounds import AccumBounds
  786. arg = self.args[0]
  787. x0 = arg.subs(x, 0).cancel()
  788. n = (x0 + S.Pi/2)/S.Pi
  789. if n.is_integer:
  790. lt = (arg - n*S.Pi + S.Pi/2).as_leading_term(x)
  791. return (S.NegativeOne**n)*lt
  792. if x0 is S.ComplexInfinity:
  793. x0 = arg.limit(x, 0, dir='-' if re(cdir).is_negative else '+')
  794. if x0 in [S.Infinity, S.NegativeInfinity]:
  795. return AccumBounds(-1, 1)
  796. return self.func(x0) if x0.is_finite else self
  797. def _eval_is_extended_real(self):
  798. if self.args[0].is_extended_real:
  799. return True
  800. def _eval_is_finite(self):
  801. arg = self.args[0]
  802. if arg.is_extended_real:
  803. return True
  804. def _eval_is_complex(self):
  805. if self.args[0].is_extended_real \
  806. or self.args[0].is_complex:
  807. return True
  808. def _eval_is_zero(self):
  809. rest, pi_mult = _peeloff_pi(self.args[0])
  810. if pi_mult:
  811. return fuzzy_and([(pi_mult - S.Half).is_integer, rest.is_zero])
  812. else:
  813. return rest.is_zero
  814. class tan(TrigonometricFunction):
  815. """
  816. The tangent function.
  817. Returns the tangent of x (measured in radians).
  818. Explanation
  819. ===========
  820. See :class:`sin` for notes about automatic evaluation.
  821. Examples
  822. ========
  823. >>> from sympy import tan, pi
  824. >>> from sympy.abc import x
  825. >>> tan(x**2).diff(x)
  826. 2*x*(tan(x**2)**2 + 1)
  827. >>> tan(1).diff(x)
  828. 0
  829. >>> tan(pi/8).expand()
  830. -1 + sqrt(2)
  831. See Also
  832. ========
  833. sin, csc, cos, sec, cot
  834. asin, acsc, acos, asec, atan, acot, atan2
  835. References
  836. ==========
  837. .. [1] https://en.wikipedia.org/wiki/Trigonometric_functions
  838. .. [2] http://dlmf.nist.gov/4.14
  839. .. [3] http://functions.wolfram.com/ElementaryFunctions/Tan
  840. """
  841. def period(self, symbol=None):
  842. return self._period(pi, symbol)
  843. def fdiff(self, argindex=1):
  844. if argindex == 1:
  845. return S.One + self**2
  846. else:
  847. raise ArgumentIndexError(self, argindex)
  848. def inverse(self, argindex=1):
  849. """
  850. Returns the inverse of this function.
  851. """
  852. return atan
  853. @classmethod
  854. def eval(cls, arg):
  855. from sympy.calculus.accumulationbounds import AccumBounds
  856. if arg.is_Number:
  857. if arg is S.NaN:
  858. return S.NaN
  859. elif arg.is_zero:
  860. return S.Zero
  861. elif arg in (S.Infinity, S.NegativeInfinity):
  862. return AccumBounds(S.NegativeInfinity, S.Infinity)
  863. if arg is S.ComplexInfinity:
  864. return S.NaN
  865. if isinstance(arg, AccumBounds):
  866. min, max = arg.min, arg.max
  867. d = floor(min/S.Pi)
  868. if min is not S.NegativeInfinity:
  869. min = min - d*S.Pi
  870. if max is not S.Infinity:
  871. max = max - d*S.Pi
  872. if AccumBounds(min, max).intersection(FiniteSet(S.Pi/2, S.Pi*Rational(3, 2))):
  873. return AccumBounds(S.NegativeInfinity, S.Infinity)
  874. else:
  875. return AccumBounds(tan(min), tan(max))
  876. if arg.could_extract_minus_sign():
  877. return -cls(-arg)
  878. i_coeff = arg.as_coefficient(S.ImaginaryUnit)
  879. if i_coeff is not None:
  880. return S.ImaginaryUnit*tanh(i_coeff)
  881. pi_coeff = _pi_coeff(arg, 2)
  882. if pi_coeff is not None:
  883. if pi_coeff.is_integer:
  884. return S.Zero
  885. if not pi_coeff.is_Rational:
  886. narg = pi_coeff*S.Pi
  887. if narg != arg:
  888. return cls(narg)
  889. return None
  890. if pi_coeff.is_Rational:
  891. q = pi_coeff.q
  892. p = pi_coeff.p % q
  893. # ensure simplified results are returned for n*pi/5, n*pi/10
  894. table10 = {
  895. 1: sqrt(1 - 2*sqrt(5)/5),
  896. 2: sqrt(5 - 2*sqrt(5)),
  897. 3: sqrt(1 + 2*sqrt(5)/5),
  898. 4: sqrt(5 + 2*sqrt(5))
  899. }
  900. if q in (5, 10):
  901. n = 10*p/q
  902. if n > 5:
  903. n = 10 - n
  904. return -table10[n]
  905. else:
  906. return table10[n]
  907. if not pi_coeff.q % 2:
  908. narg = pi_coeff*S.Pi*2
  909. cresult, sresult = cos(narg), cos(narg - S.Pi/2)
  910. if not isinstance(cresult, cos) \
  911. and not isinstance(sresult, cos):
  912. if sresult == 0:
  913. return S.ComplexInfinity
  914. return 1/sresult - cresult/sresult
  915. table2 = {
  916. 12: (3, 4),
  917. 20: (4, 5),
  918. 30: (5, 6),
  919. 15: (6, 10),
  920. 24: (6, 8),
  921. 40: (8, 10),
  922. 60: (20, 30),
  923. 120: (40, 60)
  924. }
  925. if q in table2:
  926. nvala, nvalb = cls(p*S.Pi/table2[q][0]), cls(p*S.Pi/table2[q][1])
  927. if None in (nvala, nvalb):
  928. return None
  929. return (nvala - nvalb)/(1 + nvala*nvalb)
  930. narg = ((pi_coeff + S.Half) % 1 - S.Half)*S.Pi
  931. # see cos() to specify which expressions should be
  932. # expanded automatically in terms of radicals
  933. cresult, sresult = cos(narg), cos(narg - S.Pi/2)
  934. if not isinstance(cresult, cos) \
  935. and not isinstance(sresult, cos):
  936. if cresult == 0:
  937. return S.ComplexInfinity
  938. return (sresult/cresult)
  939. if narg != arg:
  940. return cls(narg)
  941. if arg.is_Add:
  942. x, m = _peeloff_pi(arg)
  943. if m:
  944. tanm = tan(m*S.Pi)
  945. if tanm is S.ComplexInfinity:
  946. return -cot(x)
  947. else: # tanm == 0
  948. return tan(x)
  949. if arg.is_zero:
  950. return S.Zero
  951. if isinstance(arg, atan):
  952. return arg.args[0]
  953. if isinstance(arg, atan2):
  954. y, x = arg.args
  955. return y/x
  956. if isinstance(arg, asin):
  957. x = arg.args[0]
  958. return x/sqrt(1 - x**2)
  959. if isinstance(arg, acos):
  960. x = arg.args[0]
  961. return sqrt(1 - x**2)/x
  962. if isinstance(arg, acot):
  963. x = arg.args[0]
  964. return 1/x
  965. if isinstance(arg, acsc):
  966. x = arg.args[0]
  967. return 1/(sqrt(1 - 1/x**2)*x)
  968. if isinstance(arg, asec):
  969. x = arg.args[0]
  970. return sqrt(1 - 1/x**2)*x
  971. @staticmethod
  972. @cacheit
  973. def taylor_term(n, x, *previous_terms):
  974. from sympy.functions.combinatorial.numbers import bernoulli
  975. if n < 0 or n % 2 == 0:
  976. return S.Zero
  977. else:
  978. x = sympify(x)
  979. a, b = ((n - 1)//2), 2**(n + 1)
  980. B = bernoulli(n + 1)
  981. F = factorial(n + 1)
  982. return S.NegativeOne**a*b*(b - 1)*B/F*x**n
  983. def _eval_nseries(self, x, n, logx, cdir=0):
  984. i = self.args[0].limit(x, 0)*2/S.Pi
  985. if i and i.is_Integer:
  986. return self.rewrite(cos)._eval_nseries(x, n=n, logx=logx)
  987. return Function._eval_nseries(self, x, n=n, logx=logx)
  988. def _eval_rewrite_as_Pow(self, arg, **kwargs):
  989. if isinstance(arg, log):
  990. I = S.ImaginaryUnit
  991. x = arg.args[0]
  992. return I*(x**-I - x**I)/(x**-I + x**I)
  993. def _eval_conjugate(self):
  994. return self.func(self.args[0].conjugate())
  995. def as_real_imag(self, deep=True, **hints):
  996. re, im = self._as_real_imag(deep=deep, **hints)
  997. if im:
  998. denom = cos(2*re) + cosh(2*im)
  999. return (sin(2*re)/denom, sinh(2*im)/denom)
  1000. else:
  1001. return (self.func(re), S.Zero)
  1002. def _eval_expand_trig(self, **hints):
  1003. from sympy.functions.elementary.complexes import (im, re)
  1004. arg = self.args[0]
  1005. x = None
  1006. if arg.is_Add:
  1007. from sympy.polys.specialpolys import symmetric_poly
  1008. n = len(arg.args)
  1009. TX = []
  1010. for x in arg.args:
  1011. tx = tan(x, evaluate=False)._eval_expand_trig()
  1012. TX.append(tx)
  1013. Yg = numbered_symbols('Y')
  1014. Y = [ next(Yg) for i in range(n) ]
  1015. p = [0, 0]
  1016. for i in range(n + 1):
  1017. p[1 - i % 2] += symmetric_poly(i, Y)*(-1)**((i % 4)//2)
  1018. return (p[0]/p[1]).subs(list(zip(Y, TX)))
  1019. elif arg.is_Mul:
  1020. coeff, terms = arg.as_coeff_Mul(rational=True)
  1021. if coeff.is_Integer and coeff > 1:
  1022. I = S.ImaginaryUnit
  1023. z = Symbol('dummy', real=True)
  1024. P = ((1 + I*z)**coeff).expand()
  1025. return (im(P)/re(P)).subs([(z, tan(terms))])
  1026. return tan(arg)
  1027. def _eval_rewrite_as_exp(self, arg, **kwargs):
  1028. I = S.ImaginaryUnit
  1029. if isinstance(arg, (TrigonometricFunction, HyperbolicFunction)):
  1030. arg = arg.func(arg.args[0]).rewrite(exp)
  1031. neg_exp, pos_exp = exp(-arg*I), exp(arg*I)
  1032. return I*(neg_exp - pos_exp)/(neg_exp + pos_exp)
  1033. def _eval_rewrite_as_sin(self, x, **kwargs):
  1034. return 2*sin(x)**2/sin(2*x)
  1035. def _eval_rewrite_as_cos(self, x, **kwargs):
  1036. return cos(x - S.Pi/2, evaluate=False)/cos(x)
  1037. def _eval_rewrite_as_sincos(self, arg, **kwargs):
  1038. return sin(arg)/cos(arg)
  1039. def _eval_rewrite_as_cot(self, arg, **kwargs):
  1040. return 1/cot(arg)
  1041. def _eval_rewrite_as_sec(self, arg, **kwargs):
  1042. sin_in_sec_form = sin(arg).rewrite(sec)
  1043. cos_in_sec_form = cos(arg).rewrite(sec)
  1044. return sin_in_sec_form/cos_in_sec_form
  1045. def _eval_rewrite_as_csc(self, arg, **kwargs):
  1046. sin_in_csc_form = sin(arg).rewrite(csc)
  1047. cos_in_csc_form = cos(arg).rewrite(csc)
  1048. return sin_in_csc_form/cos_in_csc_form
  1049. def _eval_rewrite_as_pow(self, arg, **kwargs):
  1050. y = self.rewrite(cos).rewrite(pow)
  1051. if y.has(cos):
  1052. return None
  1053. return y
  1054. def _eval_rewrite_as_sqrt(self, arg, **kwargs):
  1055. y = self.rewrite(cos).rewrite(sqrt)
  1056. if y.has(cos):
  1057. return None
  1058. return y
  1059. def _eval_as_leading_term(self, x, logx=None, cdir=0):
  1060. arg = self.args[0]
  1061. x0 = arg.subs(x, 0).cancel()
  1062. n = 2*x0/S.Pi
  1063. if n.is_integer:
  1064. lt = (arg - n*S.Pi/2).as_leading_term(x)
  1065. return lt if n.is_even else -1/lt
  1066. return self.func(x0) if x0.is_finite else self
  1067. def _eval_is_extended_real(self):
  1068. # FIXME: currently tan(pi/2) return zoo
  1069. return self.args[0].is_extended_real
  1070. def _eval_is_real(self):
  1071. arg = self.args[0]
  1072. if arg.is_real and (arg/pi - S.Half).is_integer is False:
  1073. return True
  1074. def _eval_is_finite(self):
  1075. arg = self.args[0]
  1076. if arg.is_real and (arg/pi - S.Half).is_integer is False:
  1077. return True
  1078. if arg.is_imaginary:
  1079. return True
  1080. def _eval_is_zero(self):
  1081. rest, pi_mult = _peeloff_pi(self.args[0])
  1082. if rest.is_zero:
  1083. return pi_mult.is_integer
  1084. def _eval_is_complex(self):
  1085. arg = self.args[0]
  1086. if arg.is_real and (arg/pi - S.Half).is_integer is False:
  1087. return True
  1088. class cot(TrigonometricFunction):
  1089. """
  1090. The cotangent function.
  1091. Returns the cotangent of x (measured in radians).
  1092. Explanation
  1093. ===========
  1094. See :class:`sin` for notes about automatic evaluation.
  1095. Examples
  1096. ========
  1097. >>> from sympy import cot, pi
  1098. >>> from sympy.abc import x
  1099. >>> cot(x**2).diff(x)
  1100. 2*x*(-cot(x**2)**2 - 1)
  1101. >>> cot(1).diff(x)
  1102. 0
  1103. >>> cot(pi/12)
  1104. sqrt(3) + 2
  1105. See Also
  1106. ========
  1107. sin, csc, cos, sec, tan
  1108. asin, acsc, acos, asec, atan, acot, atan2
  1109. References
  1110. ==========
  1111. .. [1] https://en.wikipedia.org/wiki/Trigonometric_functions
  1112. .. [2] http://dlmf.nist.gov/4.14
  1113. .. [3] http://functions.wolfram.com/ElementaryFunctions/Cot
  1114. """
  1115. def period(self, symbol=None):
  1116. return self._period(pi, symbol)
  1117. def fdiff(self, argindex=1):
  1118. if argindex == 1:
  1119. return S.NegativeOne - self**2
  1120. else:
  1121. raise ArgumentIndexError(self, argindex)
  1122. def inverse(self, argindex=1):
  1123. """
  1124. Returns the inverse of this function.
  1125. """
  1126. return acot
  1127. @classmethod
  1128. def eval(cls, arg):
  1129. from sympy.calculus.accumulationbounds import AccumBounds
  1130. if arg.is_Number:
  1131. if arg is S.NaN:
  1132. return S.NaN
  1133. if arg.is_zero:
  1134. return S.ComplexInfinity
  1135. if arg is S.ComplexInfinity:
  1136. return S.NaN
  1137. if isinstance(arg, AccumBounds):
  1138. return -tan(arg + S.Pi/2)
  1139. if arg.could_extract_minus_sign():
  1140. return -cls(-arg)
  1141. i_coeff = arg.as_coefficient(S.ImaginaryUnit)
  1142. if i_coeff is not None:
  1143. return -S.ImaginaryUnit*coth(i_coeff)
  1144. pi_coeff = _pi_coeff(arg, 2)
  1145. if pi_coeff is not None:
  1146. if pi_coeff.is_integer:
  1147. return S.ComplexInfinity
  1148. if not pi_coeff.is_Rational:
  1149. narg = pi_coeff*S.Pi
  1150. if narg != arg:
  1151. return cls(narg)
  1152. return None
  1153. if pi_coeff.is_Rational:
  1154. if pi_coeff.q in (5, 10):
  1155. return tan(S.Pi/2 - arg)
  1156. if pi_coeff.q > 2 and not pi_coeff.q % 2:
  1157. narg = pi_coeff*S.Pi*2
  1158. cresult, sresult = cos(narg), cos(narg - S.Pi/2)
  1159. if not isinstance(cresult, cos) \
  1160. and not isinstance(sresult, cos):
  1161. return 1/sresult + cresult/sresult
  1162. table2 = {
  1163. 12: (3, 4),
  1164. 20: (4, 5),
  1165. 30: (5, 6),
  1166. 15: (6, 10),
  1167. 24: (6, 8),
  1168. 40: (8, 10),
  1169. 60: (20, 30),
  1170. 120: (40, 60)
  1171. }
  1172. q = pi_coeff.q
  1173. p = pi_coeff.p % q
  1174. if q in table2:
  1175. nvala, nvalb = cls(p*S.Pi/table2[q][0]), cls(p*S.Pi/table2[q][1])
  1176. if None in (nvala, nvalb):
  1177. return None
  1178. return (1 + nvala*nvalb)/(nvalb - nvala)
  1179. narg = (((pi_coeff + S.Half) % 1) - S.Half)*S.Pi
  1180. # see cos() to specify which expressions should be
  1181. # expanded automatically in terms of radicals
  1182. cresult, sresult = cos(narg), cos(narg - S.Pi/2)
  1183. if not isinstance(cresult, cos) \
  1184. and not isinstance(sresult, cos):
  1185. if sresult == 0:
  1186. return S.ComplexInfinity
  1187. return cresult/sresult
  1188. if narg != arg:
  1189. return cls(narg)
  1190. if arg.is_Add:
  1191. x, m = _peeloff_pi(arg)
  1192. if m:
  1193. cotm = cot(m*S.Pi)
  1194. if cotm is S.ComplexInfinity:
  1195. return cot(x)
  1196. else: # cotm == 0
  1197. return -tan(x)
  1198. if arg.is_zero:
  1199. return S.ComplexInfinity
  1200. if isinstance(arg, acot):
  1201. return arg.args[0]
  1202. if isinstance(arg, atan):
  1203. x = arg.args[0]
  1204. return 1/x
  1205. if isinstance(arg, atan2):
  1206. y, x = arg.args
  1207. return x/y
  1208. if isinstance(arg, asin):
  1209. x = arg.args[0]
  1210. return sqrt(1 - x**2)/x
  1211. if isinstance(arg, acos):
  1212. x = arg.args[0]
  1213. return x/sqrt(1 - x**2)
  1214. if isinstance(arg, acsc):
  1215. x = arg.args[0]
  1216. return sqrt(1 - 1/x**2)*x
  1217. if isinstance(arg, asec):
  1218. x = arg.args[0]
  1219. return 1/(sqrt(1 - 1/x**2)*x)
  1220. @staticmethod
  1221. @cacheit
  1222. def taylor_term(n, x, *previous_terms):
  1223. from sympy.functions.combinatorial.numbers import bernoulli
  1224. if n == 0:
  1225. return 1/sympify(x)
  1226. elif n < 0 or n % 2 == 0:
  1227. return S.Zero
  1228. else:
  1229. x = sympify(x)
  1230. B = bernoulli(n + 1)
  1231. F = factorial(n + 1)
  1232. return S.NegativeOne**((n + 1)//2)*2**(n + 1)*B/F*x**n
  1233. def _eval_nseries(self, x, n, logx, cdir=0):
  1234. i = self.args[0].limit(x, 0)/S.Pi
  1235. if i and i.is_Integer:
  1236. return self.rewrite(cos)._eval_nseries(x, n=n, logx=logx)
  1237. return self.rewrite(tan)._eval_nseries(x, n=n, logx=logx)
  1238. def _eval_conjugate(self):
  1239. return self.func(self.args[0].conjugate())
  1240. def as_real_imag(self, deep=True, **hints):
  1241. re, im = self._as_real_imag(deep=deep, **hints)
  1242. if im:
  1243. denom = cos(2*re) - cosh(2*im)
  1244. return (-sin(2*re)/denom, sinh(2*im)/denom)
  1245. else:
  1246. return (self.func(re), S.Zero)
  1247. def _eval_rewrite_as_exp(self, arg, **kwargs):
  1248. I = S.ImaginaryUnit
  1249. if isinstance(arg, (TrigonometricFunction, HyperbolicFunction)):
  1250. arg = arg.func(arg.args[0]).rewrite(exp)
  1251. neg_exp, pos_exp = exp(-arg*I), exp(arg*I)
  1252. return I*(pos_exp + neg_exp)/(pos_exp - neg_exp)
  1253. def _eval_rewrite_as_Pow(self, arg, **kwargs):
  1254. if isinstance(arg, log):
  1255. I = S.ImaginaryUnit
  1256. x = arg.args[0]
  1257. return -I*(x**-I + x**I)/(x**-I - x**I)
  1258. def _eval_rewrite_as_sin(self, x, **kwargs):
  1259. return sin(2*x)/(2*(sin(x)**2))
  1260. def _eval_rewrite_as_cos(self, x, **kwargs):
  1261. return cos(x)/cos(x - S.Pi/2, evaluate=False)
  1262. def _eval_rewrite_as_sincos(self, arg, **kwargs):
  1263. return cos(arg)/sin(arg)
  1264. def _eval_rewrite_as_tan(self, arg, **kwargs):
  1265. return 1/tan(arg)
  1266. def _eval_rewrite_as_sec(self, arg, **kwargs):
  1267. cos_in_sec_form = cos(arg).rewrite(sec)
  1268. sin_in_sec_form = sin(arg).rewrite(sec)
  1269. return cos_in_sec_form/sin_in_sec_form
  1270. def _eval_rewrite_as_csc(self, arg, **kwargs):
  1271. cos_in_csc_form = cos(arg).rewrite(csc)
  1272. sin_in_csc_form = sin(arg).rewrite(csc)
  1273. return cos_in_csc_form/sin_in_csc_form
  1274. def _eval_rewrite_as_pow(self, arg, **kwargs):
  1275. y = self.rewrite(cos).rewrite(pow)
  1276. if y.has(cos):
  1277. return None
  1278. return y
  1279. def _eval_rewrite_as_sqrt(self, arg, **kwargs):
  1280. y = self.rewrite(cos).rewrite(sqrt)
  1281. if y.has(cos):
  1282. return None
  1283. return y
  1284. def _eval_as_leading_term(self, x, logx=None, cdir=0):
  1285. arg = self.args[0]
  1286. x0 = arg.subs(x, 0).cancel()
  1287. n = 2*x0/S.Pi
  1288. if n.is_integer:
  1289. lt = (arg - n*S.Pi/2).as_leading_term(x)
  1290. return 1/lt if n.is_even else -lt
  1291. return self.func(x0) if x0.is_finite else self
  1292. def _eval_is_extended_real(self):
  1293. return self.args[0].is_extended_real
  1294. def _eval_expand_trig(self, **hints):
  1295. from sympy.functions.elementary.complexes import (im, re)
  1296. arg = self.args[0]
  1297. x = None
  1298. if arg.is_Add:
  1299. from sympy.polys.specialpolys import symmetric_poly
  1300. n = len(arg.args)
  1301. CX = []
  1302. for x in arg.args:
  1303. cx = cot(x, evaluate=False)._eval_expand_trig()
  1304. CX.append(cx)
  1305. Yg = numbered_symbols('Y')
  1306. Y = [ next(Yg) for i in range(n) ]
  1307. p = [0, 0]
  1308. for i in range(n, -1, -1):
  1309. p[(n - i) % 2] += symmetric_poly(i, Y)*(-1)**(((n - i) % 4)//2)
  1310. return (p[0]/p[1]).subs(list(zip(Y, CX)))
  1311. elif arg.is_Mul:
  1312. coeff, terms = arg.as_coeff_Mul(rational=True)
  1313. if coeff.is_Integer and coeff > 1:
  1314. I = S.ImaginaryUnit
  1315. z = Symbol('dummy', real=True)
  1316. P = ((z + I)**coeff).expand()
  1317. return (re(P)/im(P)).subs([(z, cot(terms))])
  1318. return cot(arg) # XXX sec and csc return 1/cos and 1/sin
  1319. def _eval_is_finite(self):
  1320. arg = self.args[0]
  1321. if arg.is_real and (arg/pi).is_integer is False:
  1322. return True
  1323. if arg.is_imaginary:
  1324. return True
  1325. def _eval_is_real(self):
  1326. arg = self.args[0]
  1327. if arg.is_real and (arg/pi).is_integer is False:
  1328. return True
  1329. def _eval_is_complex(self):
  1330. arg = self.args[0]
  1331. if arg.is_real and (arg/pi).is_integer is False:
  1332. return True
  1333. def _eval_is_zero(self):
  1334. rest, pimult = _peeloff_pi(self.args[0])
  1335. if pimult and rest.is_zero:
  1336. return (pimult - S.Half).is_integer
  1337. def _eval_subs(self, old, new):
  1338. arg = self.args[0]
  1339. argnew = arg.subs(old, new)
  1340. if arg != argnew and (argnew/S.Pi).is_integer:
  1341. return S.ComplexInfinity
  1342. return cot(argnew)
  1343. class ReciprocalTrigonometricFunction(TrigonometricFunction):
  1344. """Base class for reciprocal functions of trigonometric functions. """
  1345. _reciprocal_of = None # mandatory, to be defined in subclass
  1346. _singularities = (S.ComplexInfinity,)
  1347. # _is_even and _is_odd are used for correct evaluation of csc(-x), sec(-x)
  1348. # TODO refactor into TrigonometricFunction common parts of
  1349. # trigonometric functions eval() like even/odd, func(x+2*k*pi), etc.
  1350. # optional, to be defined in subclasses:
  1351. _is_even = None # type: FuzzyBool
  1352. _is_odd = None # type: FuzzyBool
  1353. @classmethod
  1354. def eval(cls, arg):
  1355. if arg.could_extract_minus_sign():
  1356. if cls._is_even:
  1357. return cls(-arg)
  1358. if cls._is_odd:
  1359. return -cls(-arg)
  1360. pi_coeff = _pi_coeff(arg)
  1361. if (pi_coeff is not None
  1362. and not (2*pi_coeff).is_integer
  1363. and pi_coeff.is_Rational):
  1364. q = pi_coeff.q
  1365. p = pi_coeff.p % (2*q)
  1366. if p > q:
  1367. narg = (pi_coeff - 1)*S.Pi
  1368. return -cls(narg)
  1369. if 2*p > q:
  1370. narg = (1 - pi_coeff)*S.Pi
  1371. if cls._is_odd:
  1372. return cls(narg)
  1373. elif cls._is_even:
  1374. return -cls(narg)
  1375. if hasattr(arg, 'inverse') and arg.inverse() == cls:
  1376. return arg.args[0]
  1377. t = cls._reciprocal_of.eval(arg)
  1378. if t is None:
  1379. return t
  1380. elif any(isinstance(i, cos) for i in (t, -t)):
  1381. return (1/t).rewrite(sec)
  1382. elif any(isinstance(i, sin) for i in (t, -t)):
  1383. return (1/t).rewrite(csc)
  1384. else:
  1385. return 1/t
  1386. def _call_reciprocal(self, method_name, *args, **kwargs):
  1387. # Calls method_name on _reciprocal_of
  1388. o = self._reciprocal_of(self.args[0])
  1389. return getattr(o, method_name)(*args, **kwargs)
  1390. def _calculate_reciprocal(self, method_name, *args, **kwargs):
  1391. # If calling method_name on _reciprocal_of returns a value != None
  1392. # then return the reciprocal of that value
  1393. t = self._call_reciprocal(method_name, *args, **kwargs)
  1394. return 1/t if t is not None else t
  1395. def _rewrite_reciprocal(self, method_name, arg):
  1396. # Special handling for rewrite functions. If reciprocal rewrite returns
  1397. # unmodified expression, then return None
  1398. t = self._call_reciprocal(method_name, arg)
  1399. if t is not None and t != self._reciprocal_of(arg):
  1400. return 1/t
  1401. def _period(self, symbol):
  1402. f = expand_mul(self.args[0])
  1403. return self._reciprocal_of(f).period(symbol)
  1404. def fdiff(self, argindex=1):
  1405. return -self._calculate_reciprocal("fdiff", argindex)/self**2
  1406. def _eval_rewrite_as_exp(self, arg, **kwargs):
  1407. return self._rewrite_reciprocal("_eval_rewrite_as_exp", arg)
  1408. def _eval_rewrite_as_Pow(self, arg, **kwargs):
  1409. return self._rewrite_reciprocal("_eval_rewrite_as_Pow", arg)
  1410. def _eval_rewrite_as_sin(self, arg, **kwargs):
  1411. return self._rewrite_reciprocal("_eval_rewrite_as_sin", arg)
  1412. def _eval_rewrite_as_cos(self, arg, **kwargs):
  1413. return self._rewrite_reciprocal("_eval_rewrite_as_cos", arg)
  1414. def _eval_rewrite_as_tan(self, arg, **kwargs):
  1415. return self._rewrite_reciprocal("_eval_rewrite_as_tan", arg)
  1416. def _eval_rewrite_as_pow(self, arg, **kwargs):
  1417. return self._rewrite_reciprocal("_eval_rewrite_as_pow", arg)
  1418. def _eval_rewrite_as_sqrt(self, arg, **kwargs):
  1419. return self._rewrite_reciprocal("_eval_rewrite_as_sqrt", arg)
  1420. def _eval_conjugate(self):
  1421. return self.func(self.args[0].conjugate())
  1422. def as_real_imag(self, deep=True, **hints):
  1423. return (1/self._reciprocal_of(self.args[0])).as_real_imag(deep,
  1424. **hints)
  1425. def _eval_expand_trig(self, **hints):
  1426. return self._calculate_reciprocal("_eval_expand_trig", **hints)
  1427. def _eval_is_extended_real(self):
  1428. return self._reciprocal_of(self.args[0])._eval_is_extended_real()
  1429. def _eval_as_leading_term(self, x, logx=None, cdir=0):
  1430. return (1/self._reciprocal_of(self.args[0]))._eval_as_leading_term(x)
  1431. def _eval_is_finite(self):
  1432. return (1/self._reciprocal_of(self.args[0])).is_finite
  1433. def _eval_nseries(self, x, n, logx, cdir=0):
  1434. return (1/self._reciprocal_of(self.args[0]))._eval_nseries(x, n, logx)
  1435. class sec(ReciprocalTrigonometricFunction):
  1436. """
  1437. The secant function.
  1438. Returns the secant of x (measured in radians).
  1439. Explanation
  1440. ===========
  1441. See :class:`sin` for notes about automatic evaluation.
  1442. Examples
  1443. ========
  1444. >>> from sympy import sec
  1445. >>> from sympy.abc import x
  1446. >>> sec(x**2).diff(x)
  1447. 2*x*tan(x**2)*sec(x**2)
  1448. >>> sec(1).diff(x)
  1449. 0
  1450. See Also
  1451. ========
  1452. sin, csc, cos, tan, cot
  1453. asin, acsc, acos, asec, atan, acot, atan2
  1454. References
  1455. ==========
  1456. .. [1] https://en.wikipedia.org/wiki/Trigonometric_functions
  1457. .. [2] http://dlmf.nist.gov/4.14
  1458. .. [3] http://functions.wolfram.com/ElementaryFunctions/Sec
  1459. """
  1460. _reciprocal_of = cos
  1461. _is_even = True
  1462. def period(self, symbol=None):
  1463. return self._period(symbol)
  1464. def _eval_rewrite_as_cot(self, arg, **kwargs):
  1465. cot_half_sq = cot(arg/2)**2
  1466. return (cot_half_sq + 1)/(cot_half_sq - 1)
  1467. def _eval_rewrite_as_cos(self, arg, **kwargs):
  1468. return (1/cos(arg))
  1469. def _eval_rewrite_as_sincos(self, arg, **kwargs):
  1470. return sin(arg)/(cos(arg)*sin(arg))
  1471. def _eval_rewrite_as_sin(self, arg, **kwargs):
  1472. return (1/cos(arg).rewrite(sin))
  1473. def _eval_rewrite_as_tan(self, arg, **kwargs):
  1474. return (1/cos(arg).rewrite(tan))
  1475. def _eval_rewrite_as_csc(self, arg, **kwargs):
  1476. return csc(pi/2 - arg, evaluate=False)
  1477. def fdiff(self, argindex=1):
  1478. if argindex == 1:
  1479. return tan(self.args[0])*sec(self.args[0])
  1480. else:
  1481. raise ArgumentIndexError(self, argindex)
  1482. def _eval_is_complex(self):
  1483. arg = self.args[0]
  1484. if arg.is_complex and (arg/pi - S.Half).is_integer is False:
  1485. return True
  1486. @staticmethod
  1487. @cacheit
  1488. def taylor_term(n, x, *previous_terms):
  1489. # Reference Formula:
  1490. # http://functions.wolfram.com/ElementaryFunctions/Sec/06/01/02/01/
  1491. from sympy.functions.combinatorial.numbers import euler
  1492. if n < 0 or n % 2 == 1:
  1493. return S.Zero
  1494. else:
  1495. x = sympify(x)
  1496. k = n//2
  1497. return S.NegativeOne**k*euler(2*k)/factorial(2*k)*x**(2*k)
  1498. def _eval_as_leading_term(self, x, logx=None, cdir=0):
  1499. arg = self.args[0]
  1500. x0 = arg.subs(x, 0).cancel()
  1501. n = (x0 + S.Pi/2)/S.Pi
  1502. if n.is_integer:
  1503. lt = (arg - n*S.Pi + S.Pi/2).as_leading_term(x)
  1504. return (S.NegativeOne**n)/lt
  1505. return self.func(x0)
  1506. class csc(ReciprocalTrigonometricFunction):
  1507. """
  1508. The cosecant function.
  1509. Returns the cosecant of x (measured in radians).
  1510. Explanation
  1511. ===========
  1512. See :func:`sin` for notes about automatic evaluation.
  1513. Examples
  1514. ========
  1515. >>> from sympy import csc
  1516. >>> from sympy.abc import x
  1517. >>> csc(x**2).diff(x)
  1518. -2*x*cot(x**2)*csc(x**2)
  1519. >>> csc(1).diff(x)
  1520. 0
  1521. See Also
  1522. ========
  1523. sin, cos, sec, tan, cot
  1524. asin, acsc, acos, asec, atan, acot, atan2
  1525. References
  1526. ==========
  1527. .. [1] https://en.wikipedia.org/wiki/Trigonometric_functions
  1528. .. [2] http://dlmf.nist.gov/4.14
  1529. .. [3] http://functions.wolfram.com/ElementaryFunctions/Csc
  1530. """
  1531. _reciprocal_of = sin
  1532. _is_odd = True
  1533. def period(self, symbol=None):
  1534. return self._period(symbol)
  1535. def _eval_rewrite_as_sin(self, arg, **kwargs):
  1536. return (1/sin(arg))
  1537. def _eval_rewrite_as_sincos(self, arg, **kwargs):
  1538. return cos(arg)/(sin(arg)*cos(arg))
  1539. def _eval_rewrite_as_cot(self, arg, **kwargs):
  1540. cot_half = cot(arg/2)
  1541. return (1 + cot_half**2)/(2*cot_half)
  1542. def _eval_rewrite_as_cos(self, arg, **kwargs):
  1543. return 1/sin(arg).rewrite(cos)
  1544. def _eval_rewrite_as_sec(self, arg, **kwargs):
  1545. return sec(pi/2 - arg, evaluate=False)
  1546. def _eval_rewrite_as_tan(self, arg, **kwargs):
  1547. return (1/sin(arg).rewrite(tan))
  1548. def fdiff(self, argindex=1):
  1549. if argindex == 1:
  1550. return -cot(self.args[0])*csc(self.args[0])
  1551. else:
  1552. raise ArgumentIndexError(self, argindex)
  1553. def _eval_is_complex(self):
  1554. arg = self.args[0]
  1555. if arg.is_real and (arg/pi).is_integer is False:
  1556. return True
  1557. @staticmethod
  1558. @cacheit
  1559. def taylor_term(n, x, *previous_terms):
  1560. from sympy.functions.combinatorial.numbers import bernoulli
  1561. if n == 0:
  1562. return 1/sympify(x)
  1563. elif n < 0 or n % 2 == 0:
  1564. return S.Zero
  1565. else:
  1566. x = sympify(x)
  1567. k = n//2 + 1
  1568. return (S.NegativeOne**(k - 1)*2*(2**(2*k - 1) - 1)*
  1569. bernoulli(2*k)*x**(2*k - 1)/factorial(2*k))
  1570. class sinc(Function):
  1571. r"""
  1572. Represents an unnormalized sinc function:
  1573. .. math::
  1574. \operatorname{sinc}(x) =
  1575. \begin{cases}
  1576. \frac{\sin x}{x} & \qquad x \neq 0 \\
  1577. 1 & \qquad x = 0
  1578. \end{cases}
  1579. Examples
  1580. ========
  1581. >>> from sympy import sinc, oo, jn
  1582. >>> from sympy.abc import x
  1583. >>> sinc(x)
  1584. sinc(x)
  1585. * Automated Evaluation
  1586. >>> sinc(0)
  1587. 1
  1588. >>> sinc(oo)
  1589. 0
  1590. * Differentiation
  1591. >>> sinc(x).diff()
  1592. cos(x)/x - sin(x)/x**2
  1593. * Series Expansion
  1594. >>> sinc(x).series()
  1595. 1 - x**2/6 + x**4/120 + O(x**6)
  1596. * As zero'th order spherical Bessel Function
  1597. >>> sinc(x).rewrite(jn)
  1598. jn(0, x)
  1599. See also
  1600. ========
  1601. sin
  1602. References
  1603. ==========
  1604. .. [1] https://en.wikipedia.org/wiki/Sinc_function
  1605. """
  1606. _singularities = (S.ComplexInfinity,)
  1607. def fdiff(self, argindex=1):
  1608. x = self.args[0]
  1609. if argindex == 1:
  1610. # We would like to return the Piecewise here, but Piecewise.diff
  1611. # currently can't handle removable singularities, meaning things
  1612. # like sinc(x).diff(x, 2) give the wrong answer at x = 0. See
  1613. # https://github.com/sympy/sympy/issues/11402.
  1614. #
  1615. # return Piecewise(((x*cos(x) - sin(x))/x**2, Ne(x, S.Zero)), (S.Zero, S.true))
  1616. return cos(x)/x - sin(x)/x**2
  1617. else:
  1618. raise ArgumentIndexError(self, argindex)
  1619. @classmethod
  1620. def eval(cls, arg):
  1621. if arg.is_zero:
  1622. return S.One
  1623. if arg.is_Number:
  1624. if arg in [S.Infinity, S.NegativeInfinity]:
  1625. return S.Zero
  1626. elif arg is S.NaN:
  1627. return S.NaN
  1628. if arg is S.ComplexInfinity:
  1629. return S.NaN
  1630. if arg.could_extract_minus_sign():
  1631. return cls(-arg)
  1632. pi_coeff = _pi_coeff(arg)
  1633. if pi_coeff is not None:
  1634. if pi_coeff.is_integer:
  1635. if fuzzy_not(arg.is_zero):
  1636. return S.Zero
  1637. elif (2*pi_coeff).is_integer:
  1638. return S.NegativeOne**(pi_coeff - S.Half)/arg
  1639. def _eval_nseries(self, x, n, logx, cdir=0):
  1640. x = self.args[0]
  1641. return (sin(x)/x)._eval_nseries(x, n, logx)
  1642. def _eval_rewrite_as_jn(self, arg, **kwargs):
  1643. from sympy.functions.special.bessel import jn
  1644. return jn(0, arg)
  1645. def _eval_rewrite_as_sin(self, arg, **kwargs):
  1646. return Piecewise((sin(arg)/arg, Ne(arg, S.Zero)), (S.One, S.true))
  1647. def _eval_is_zero(self):
  1648. if self.args[0].is_infinite:
  1649. return True
  1650. rest, pi_mult = _peeloff_pi(self.args[0])
  1651. if rest.is_zero:
  1652. return fuzzy_and([pi_mult.is_integer, pi_mult.is_nonzero])
  1653. if rest.is_Number and pi_mult.is_integer:
  1654. return False
  1655. def _eval_is_real(self):
  1656. if self.args[0].is_extended_real or self.args[0].is_imaginary:
  1657. return True
  1658. _eval_is_finite = _eval_is_real
  1659. ###############################################################################
  1660. ########################### TRIGONOMETRIC INVERSES ############################
  1661. ###############################################################################
  1662. class InverseTrigonometricFunction(Function):
  1663. """Base class for inverse trigonometric functions."""
  1664. _singularities = (S.One, S.NegativeOne, S.Zero, S.ComplexInfinity) # type: tTuple[Expr, ...]
  1665. @staticmethod
  1666. def _asin_table():
  1667. # Only keys with could_extract_minus_sign() == False
  1668. # are actually needed.
  1669. return {
  1670. sqrt(3)/2: S.Pi/3,
  1671. sqrt(2)/2: S.Pi/4,
  1672. 1/sqrt(2): S.Pi/4,
  1673. sqrt((5 - sqrt(5))/8): S.Pi/5,
  1674. sqrt(2)*sqrt(5 - sqrt(5))/4: S.Pi/5,
  1675. sqrt((5 + sqrt(5))/8): S.Pi*Rational(2, 5),
  1676. sqrt(2)*sqrt(5 + sqrt(5))/4: S.Pi*Rational(2, 5),
  1677. S.Half: S.Pi/6,
  1678. sqrt(2 - sqrt(2))/2: S.Pi/8,
  1679. sqrt(S.Half - sqrt(2)/4): S.Pi/8,
  1680. sqrt(2 + sqrt(2))/2: S.Pi*Rational(3, 8),
  1681. sqrt(S.Half + sqrt(2)/4): S.Pi*Rational(3, 8),
  1682. (sqrt(5) - 1)/4: S.Pi/10,
  1683. (1 - sqrt(5))/4: -S.Pi/10,
  1684. (sqrt(5) + 1)/4: S.Pi*Rational(3, 10),
  1685. sqrt(6)/4 - sqrt(2)/4: S.Pi/12,
  1686. -sqrt(6)/4 + sqrt(2)/4: -S.Pi/12,
  1687. (sqrt(3) - 1)/sqrt(8): S.Pi/12,
  1688. (1 - sqrt(3))/sqrt(8): -S.Pi/12,
  1689. sqrt(6)/4 + sqrt(2)/4: S.Pi*Rational(5, 12),
  1690. (1 + sqrt(3))/sqrt(8): S.Pi*Rational(5, 12)
  1691. }
  1692. @staticmethod
  1693. def _atan_table():
  1694. # Only keys with could_extract_minus_sign() == False
  1695. # are actually needed.
  1696. return {
  1697. sqrt(3)/3: S.Pi/6,
  1698. 1/sqrt(3): S.Pi/6,
  1699. sqrt(3): S.Pi/3,
  1700. sqrt(2) - 1: S.Pi/8,
  1701. 1 - sqrt(2): -S.Pi/8,
  1702. 1 + sqrt(2): S.Pi*Rational(3, 8),
  1703. sqrt(5 - 2*sqrt(5)): S.Pi/5,
  1704. sqrt(5 + 2*sqrt(5)): S.Pi*Rational(2, 5),
  1705. sqrt(1 - 2*sqrt(5)/5): S.Pi/10,
  1706. sqrt(1 + 2*sqrt(5)/5): S.Pi*Rational(3, 10),
  1707. 2 - sqrt(3): S.Pi/12,
  1708. -2 + sqrt(3): -S.Pi/12,
  1709. 2 + sqrt(3): S.Pi*Rational(5, 12)
  1710. }
  1711. @staticmethod
  1712. def _acsc_table():
  1713. # Keys for which could_extract_minus_sign()
  1714. # will obviously return True are omitted.
  1715. return {
  1716. 2*sqrt(3)/3: S.Pi/3,
  1717. sqrt(2): S.Pi/4,
  1718. sqrt(2 + 2*sqrt(5)/5): S.Pi/5,
  1719. 1/sqrt(Rational(5, 8) - sqrt(5)/8): S.Pi/5,
  1720. sqrt(2 - 2*sqrt(5)/5): S.Pi*Rational(2, 5),
  1721. 1/sqrt(Rational(5, 8) + sqrt(5)/8): S.Pi*Rational(2, 5),
  1722. 2: S.Pi/6,
  1723. sqrt(4 + 2*sqrt(2)): S.Pi/8,
  1724. 2/sqrt(2 - sqrt(2)): S.Pi/8,
  1725. sqrt(4 - 2*sqrt(2)): S.Pi*Rational(3, 8),
  1726. 2/sqrt(2 + sqrt(2)): S.Pi*Rational(3, 8),
  1727. 1 + sqrt(5): S.Pi/10,
  1728. sqrt(5) - 1: S.Pi*Rational(3, 10),
  1729. -(sqrt(5) - 1): S.Pi*Rational(-3, 10),
  1730. sqrt(6) + sqrt(2): S.Pi/12,
  1731. sqrt(6) - sqrt(2): S.Pi*Rational(5, 12),
  1732. -(sqrt(6) - sqrt(2)): S.Pi*Rational(-5, 12)
  1733. }
  1734. class asin(InverseTrigonometricFunction):
  1735. r"""
  1736. The inverse sine function.
  1737. Returns the arcsine of x in radians.
  1738. Explanation
  1739. ===========
  1740. ``asin(x)`` will evaluate automatically in the cases
  1741. $x \in \{\infty, -\infty, 0, 1, -1\}$ and for some instances when the
  1742. result is a rational multiple of $\pi$ (see the ``eval`` class method).
  1743. A purely imaginary argument will lead to an asinh expression.
  1744. Examples
  1745. ========
  1746. >>> from sympy import asin, oo
  1747. >>> asin(1)
  1748. pi/2
  1749. >>> asin(-1)
  1750. -pi/2
  1751. >>> asin(-oo)
  1752. oo*I
  1753. >>> asin(oo)
  1754. -oo*I
  1755. See Also
  1756. ========
  1757. sin, csc, cos, sec, tan, cot
  1758. acsc, acos, asec, atan, acot, atan2
  1759. References
  1760. ==========
  1761. .. [1] https://en.wikipedia.org/wiki/Inverse_trigonometric_functions
  1762. .. [2] http://dlmf.nist.gov/4.23
  1763. .. [3] http://functions.wolfram.com/ElementaryFunctions/ArcSin
  1764. """
  1765. def fdiff(self, argindex=1):
  1766. if argindex == 1:
  1767. return 1/sqrt(1 - self.args[0]**2)
  1768. else:
  1769. raise ArgumentIndexError(self, argindex)
  1770. def _eval_is_rational(self):
  1771. s = self.func(*self.args)
  1772. if s.func == self.func:
  1773. if s.args[0].is_rational:
  1774. return False
  1775. else:
  1776. return s.is_rational
  1777. def _eval_is_positive(self):
  1778. return self._eval_is_extended_real() and self.args[0].is_positive
  1779. def _eval_is_negative(self):
  1780. return self._eval_is_extended_real() and self.args[0].is_negative
  1781. @classmethod
  1782. def eval(cls, arg):
  1783. if arg.is_Number:
  1784. if arg is S.NaN:
  1785. return S.NaN
  1786. elif arg is S.Infinity:
  1787. return S.NegativeInfinity*S.ImaginaryUnit
  1788. elif arg is S.NegativeInfinity:
  1789. return S.Infinity*S.ImaginaryUnit
  1790. elif arg.is_zero:
  1791. return S.Zero
  1792. elif arg is S.One:
  1793. return S.Pi/2
  1794. elif arg is S.NegativeOne:
  1795. return -S.Pi/2
  1796. if arg is S.ComplexInfinity:
  1797. return S.ComplexInfinity
  1798. if arg.could_extract_minus_sign():
  1799. return -cls(-arg)
  1800. if arg.is_number:
  1801. asin_table = cls._asin_table()
  1802. if arg in asin_table:
  1803. return asin_table[arg]
  1804. i_coeff = arg.as_coefficient(S.ImaginaryUnit)
  1805. if i_coeff is not None:
  1806. return S.ImaginaryUnit*asinh(i_coeff)
  1807. if arg.is_zero:
  1808. return S.Zero
  1809. if isinstance(arg, sin):
  1810. ang = arg.args[0]
  1811. if ang.is_comparable:
  1812. ang %= 2*pi # restrict to [0,2*pi)
  1813. if ang > pi: # restrict to (-pi,pi]
  1814. ang = pi - ang
  1815. # restrict to [-pi/2,pi/2]
  1816. if ang > pi/2:
  1817. ang = pi - ang
  1818. if ang < -pi/2:
  1819. ang = -pi - ang
  1820. return ang
  1821. if isinstance(arg, cos): # acos(x) + asin(x) = pi/2
  1822. ang = arg.args[0]
  1823. if ang.is_comparable:
  1824. return pi/2 - acos(arg)
  1825. @staticmethod
  1826. @cacheit
  1827. def taylor_term(n, x, *previous_terms):
  1828. if n < 0 or n % 2 == 0:
  1829. return S.Zero
  1830. else:
  1831. x = sympify(x)
  1832. if len(previous_terms) >= 2 and n > 2:
  1833. p = previous_terms[-2]
  1834. return p*(n - 2)**2/(n*(n - 1))*x**2
  1835. else:
  1836. k = (n - 1) // 2
  1837. R = RisingFactorial(S.Half, k)
  1838. F = factorial(k)
  1839. return R/F*x**n/n
  1840. def _eval_as_leading_term(self, x, logx=None, cdir=0):
  1841. from sympy.functions.elementary.complexes import im
  1842. arg = self.args[0]
  1843. x0 = arg.subs(x, 0).cancel()
  1844. if x0.is_zero:
  1845. return arg.as_leading_term(x)
  1846. if x0 is S.ComplexInfinity:
  1847. return S.ImaginaryUnit*log(arg.as_leading_term(x))
  1848. if cdir != 0:
  1849. cdir = arg.dir(x, cdir)
  1850. if im(cdir) < 0 and x0.is_real and x0 < S.NegativeOne:
  1851. return -S.Pi - self.func(x0)
  1852. elif im(cdir) > 0 and x0.is_real and x0 > S.One:
  1853. return S.Pi - self.func(x0)
  1854. return self.func(x0)
  1855. def _eval_nseries(self, x, n, logx, cdir=0): # asin
  1856. from sympy.functions.elementary.complexes import im
  1857. from sympy.series.order import O
  1858. arg0 = self.args[0].subs(x, 0)
  1859. if arg0 is S.One:
  1860. t = Dummy('t', positive=True)
  1861. ser = asin(S.One - t**2).rewrite(log).nseries(t, 0, 2*n)
  1862. arg1 = S.One - self.args[0]
  1863. f = arg1.as_leading_term(x)
  1864. g = (arg1 - f)/ f
  1865. if not g.is_meromorphic(x, 0): # cannot be expanded
  1866. return O(1) if n == 0 else S.Pi/2 + O(sqrt(x))
  1867. res1 = sqrt(S.One + g)._eval_nseries(x, n=n, logx=logx)
  1868. res = (res1.removeO()*sqrt(f)).expand()
  1869. return ser.removeO().subs(t, res).expand().powsimp() + O(x**n, x)
  1870. if arg0 is S.NegativeOne:
  1871. t = Dummy('t', positive=True)
  1872. ser = asin(S.NegativeOne + t**2).rewrite(log).nseries(t, 0, 2*n)
  1873. arg1 = S.One + self.args[0]
  1874. f = arg1.as_leading_term(x)
  1875. g = (arg1 - f)/ f
  1876. if not g.is_meromorphic(x, 0): # cannot be expanded
  1877. return O(1) if n == 0 else -S.Pi/2 + O(sqrt(x))
  1878. res1 = sqrt(S.One + g)._eval_nseries(x, n=n, logx=logx)
  1879. res = (res1.removeO()*sqrt(f)).expand()
  1880. return ser.removeO().subs(t, res).expand().powsimp() + O(x**n, x)
  1881. res = Function._eval_nseries(self, x, n=n, logx=logx)
  1882. if arg0 is S.ComplexInfinity:
  1883. return res
  1884. if cdir != 0:
  1885. cdir = self.args[0].dir(x, cdir)
  1886. if im(cdir) < 0 and arg0.is_real and arg0 < S.NegativeOne:
  1887. return -S.Pi - res
  1888. elif im(cdir) > 0 and arg0.is_real and arg0 > S.One:
  1889. return S.Pi - res
  1890. return res
  1891. def _eval_rewrite_as_acos(self, x, **kwargs):
  1892. return S.Pi/2 - acos(x)
  1893. def _eval_rewrite_as_atan(self, x, **kwargs):
  1894. return 2*atan(x/(1 + sqrt(1 - x**2)))
  1895. def _eval_rewrite_as_log(self, x, **kwargs):
  1896. return -S.ImaginaryUnit*log(S.ImaginaryUnit*x + sqrt(1 - x**2))
  1897. def _eval_rewrite_as_acot(self, arg, **kwargs):
  1898. return 2*acot((1 + sqrt(1 - arg**2))/arg)
  1899. def _eval_rewrite_as_asec(self, arg, **kwargs):
  1900. return S.Pi/2 - asec(1/arg)
  1901. def _eval_rewrite_as_acsc(self, arg, **kwargs):
  1902. return acsc(1/arg)
  1903. def _eval_is_extended_real(self):
  1904. x = self.args[0]
  1905. return x.is_extended_real and (1 - abs(x)).is_nonnegative
  1906. def inverse(self, argindex=1):
  1907. """
  1908. Returns the inverse of this function.
  1909. """
  1910. return sin
  1911. class acos(InverseTrigonometricFunction):
  1912. r"""
  1913. The inverse cosine function.
  1914. Returns the arc cosine of x (measured in radians).
  1915. Examples
  1916. ========
  1917. ``acos(x)`` will evaluate automatically in the cases
  1918. $x \in \{\infty, -\infty, 0, 1, -1\}$ and for some instances when
  1919. the result is a rational multiple of $\pi$ (see the eval class method).
  1920. ``acos(zoo)`` evaluates to ``zoo``
  1921. (see note in :class:`sympy.functions.elementary.trigonometric.asec`)
  1922. A purely imaginary argument will be rewritten to asinh.
  1923. Examples
  1924. ========
  1925. >>> from sympy import acos, oo
  1926. >>> acos(1)
  1927. 0
  1928. >>> acos(0)
  1929. pi/2
  1930. >>> acos(oo)
  1931. oo*I
  1932. See Also
  1933. ========
  1934. sin, csc, cos, sec, tan, cot
  1935. asin, acsc, asec, atan, acot, atan2
  1936. References
  1937. ==========
  1938. .. [1] https://en.wikipedia.org/wiki/Inverse_trigonometric_functions
  1939. .. [2] http://dlmf.nist.gov/4.23
  1940. .. [3] http://functions.wolfram.com/ElementaryFunctions/ArcCos
  1941. """
  1942. def fdiff(self, argindex=1):
  1943. if argindex == 1:
  1944. return -1/sqrt(1 - self.args[0]**2)
  1945. else:
  1946. raise ArgumentIndexError(self, argindex)
  1947. def _eval_is_rational(self):
  1948. s = self.func(*self.args)
  1949. if s.func == self.func:
  1950. if s.args[0].is_rational:
  1951. return False
  1952. else:
  1953. return s.is_rational
  1954. @classmethod
  1955. def eval(cls, arg):
  1956. if arg.is_Number:
  1957. if arg is S.NaN:
  1958. return S.NaN
  1959. elif arg is S.Infinity:
  1960. return S.Infinity*S.ImaginaryUnit
  1961. elif arg is S.NegativeInfinity:
  1962. return S.NegativeInfinity*S.ImaginaryUnit
  1963. elif arg.is_zero:
  1964. return S.Pi/2
  1965. elif arg is S.One:
  1966. return S.Zero
  1967. elif arg is S.NegativeOne:
  1968. return S.Pi
  1969. if arg is S.ComplexInfinity:
  1970. return S.ComplexInfinity
  1971. if arg.is_number:
  1972. asin_table = cls._asin_table()
  1973. if arg in asin_table:
  1974. return pi/2 - asin_table[arg]
  1975. elif -arg in asin_table:
  1976. return pi/2 + asin_table[-arg]
  1977. i_coeff = arg.as_coefficient(S.ImaginaryUnit)
  1978. if i_coeff is not None:
  1979. return pi/2 - asin(arg)
  1980. if isinstance(arg, cos):
  1981. ang = arg.args[0]
  1982. if ang.is_comparable:
  1983. ang %= 2*pi # restrict to [0,2*pi)
  1984. if ang > pi: # restrict to [0,pi]
  1985. ang = 2*pi - ang
  1986. return ang
  1987. if isinstance(arg, sin): # acos(x) + asin(x) = pi/2
  1988. ang = arg.args[0]
  1989. if ang.is_comparable:
  1990. return pi/2 - asin(arg)
  1991. @staticmethod
  1992. @cacheit
  1993. def taylor_term(n, x, *previous_terms):
  1994. if n == 0:
  1995. return S.Pi/2
  1996. elif n < 0 or n % 2 == 0:
  1997. return S.Zero
  1998. else:
  1999. x = sympify(x)
  2000. if len(previous_terms) >= 2 and n > 2:
  2001. p = previous_terms[-2]
  2002. return p*(n - 2)**2/(n*(n - 1))*x**2
  2003. else:
  2004. k = (n - 1) // 2
  2005. R = RisingFactorial(S.Half, k)
  2006. F = factorial(k)
  2007. return -R/F*x**n/n
  2008. def _eval_as_leading_term(self, x, logx=None, cdir=0):
  2009. from sympy.functions.elementary.complexes import im
  2010. arg = self.args[0]
  2011. x0 = arg.subs(x, 0).cancel()
  2012. if x0 == 1:
  2013. return sqrt(2)*sqrt((S.One - arg).as_leading_term(x))
  2014. if x0 is S.ComplexInfinity:
  2015. return S.ImaginaryUnit*log(arg.as_leading_term(x))
  2016. if cdir != 0:
  2017. cdir = arg.dir(x, cdir)
  2018. if im(cdir) < 0 and x0.is_real and x0 < S.NegativeOne:
  2019. return 2*S.Pi - self.func(x0)
  2020. elif im(cdir) > 0 and x0.is_real and x0 > S.One:
  2021. return -self.func(x0)
  2022. return self.func(x0)
  2023. def _eval_is_extended_real(self):
  2024. x = self.args[0]
  2025. return x.is_extended_real and (1 - abs(x)).is_nonnegative
  2026. def _eval_is_nonnegative(self):
  2027. return self._eval_is_extended_real()
  2028. def _eval_nseries(self, x, n, logx, cdir=0): # acos
  2029. from sympy.functions.elementary.complexes import im
  2030. from sympy.series.order import O
  2031. arg0 = self.args[0].subs(x, 0)
  2032. if arg0 is S.One:
  2033. t = Dummy('t', positive=True)
  2034. ser = acos(S.One - t**2).rewrite(log).nseries(t, 0, 2*n)
  2035. arg1 = S.One - self.args[0]
  2036. f = arg1.as_leading_term(x)
  2037. g = (arg1 - f)/ f
  2038. if not g.is_meromorphic(x, 0): # cannot be expanded
  2039. return O(1) if n == 0 else O(sqrt(x))
  2040. res1 = sqrt(S.One + g)._eval_nseries(x, n=n, logx=logx)
  2041. res = (res1.removeO()*sqrt(f)).expand()
  2042. return ser.removeO().subs(t, res).expand().powsimp() + O(x**n, x)
  2043. if arg0 is S.NegativeOne:
  2044. t = Dummy('t', positive=True)
  2045. ser = acos(S.NegativeOne + t**2).rewrite(log).nseries(t, 0, 2*n)
  2046. arg1 = S.One + self.args[0]
  2047. f = arg1.as_leading_term(x)
  2048. g = (arg1 - f)/ f
  2049. if not g.is_meromorphic(x, 0): # cannot be expanded
  2050. return O(1) if n == 0 else S.Pi + O(sqrt(x))
  2051. res1 = sqrt(S.One + g)._eval_nseries(x, n=n, logx=logx)
  2052. res = (res1.removeO()*sqrt(f)).expand()
  2053. return ser.removeO().subs(t, res).expand().powsimp() + O(x**n, x)
  2054. res = Function._eval_nseries(self, x, n=n, logx=logx)
  2055. if arg0 is S.ComplexInfinity:
  2056. return res
  2057. if cdir != 0:
  2058. cdir = self.args[0].dir(x, cdir)
  2059. if im(cdir) < 0 and arg0.is_real and arg0 < S.NegativeOne:
  2060. return 2*S.Pi - res
  2061. elif im(cdir) > 0 and arg0.is_real and arg0 > S.One:
  2062. return -res
  2063. return res
  2064. def _eval_rewrite_as_log(self, x, **kwargs):
  2065. return S.Pi/2 + S.ImaginaryUnit*\
  2066. log(S.ImaginaryUnit*x + sqrt(1 - x**2))
  2067. def _eval_rewrite_as_asin(self, x, **kwargs):
  2068. return S.Pi/2 - asin(x)
  2069. def _eval_rewrite_as_atan(self, x, **kwargs):
  2070. return atan(sqrt(1 - x**2)/x) + (S.Pi/2)*(1 - x*sqrt(1/x**2))
  2071. def inverse(self, argindex=1):
  2072. """
  2073. Returns the inverse of this function.
  2074. """
  2075. return cos
  2076. def _eval_rewrite_as_acot(self, arg, **kwargs):
  2077. return S.Pi/2 - 2*acot((1 + sqrt(1 - arg**2))/arg)
  2078. def _eval_rewrite_as_asec(self, arg, **kwargs):
  2079. return asec(1/arg)
  2080. def _eval_rewrite_as_acsc(self, arg, **kwargs):
  2081. return S.Pi/2 - acsc(1/arg)
  2082. def _eval_conjugate(self):
  2083. z = self.args[0]
  2084. r = self.func(self.args[0].conjugate())
  2085. if z.is_extended_real is False:
  2086. return r
  2087. elif z.is_extended_real and (z + 1).is_nonnegative and (z - 1).is_nonpositive:
  2088. return r
  2089. class atan(InverseTrigonometricFunction):
  2090. r"""
  2091. The inverse tangent function.
  2092. Returns the arc tangent of x (measured in radians).
  2093. Explanation
  2094. ===========
  2095. ``atan(x)`` will evaluate automatically in the cases
  2096. $x \in \{\infty, -\infty, 0, 1, -1\}$ and for some instances when the
  2097. result is a rational multiple of $\pi$ (see the eval class method).
  2098. Examples
  2099. ========
  2100. >>> from sympy import atan, oo
  2101. >>> atan(0)
  2102. 0
  2103. >>> atan(1)
  2104. pi/4
  2105. >>> atan(oo)
  2106. pi/2
  2107. See Also
  2108. ========
  2109. sin, csc, cos, sec, tan, cot
  2110. asin, acsc, acos, asec, acot, atan2
  2111. References
  2112. ==========
  2113. .. [1] https://en.wikipedia.org/wiki/Inverse_trigonometric_functions
  2114. .. [2] http://dlmf.nist.gov/4.23
  2115. .. [3] http://functions.wolfram.com/ElementaryFunctions/ArcTan
  2116. """
  2117. args: tTuple[Expr]
  2118. _singularities = (S.ImaginaryUnit, -S.ImaginaryUnit)
  2119. def fdiff(self, argindex=1):
  2120. if argindex == 1:
  2121. return 1/(1 + self.args[0]**2)
  2122. else:
  2123. raise ArgumentIndexError(self, argindex)
  2124. def _eval_is_rational(self):
  2125. s = self.func(*self.args)
  2126. if s.func == self.func:
  2127. if s.args[0].is_rational:
  2128. return False
  2129. else:
  2130. return s.is_rational
  2131. def _eval_is_positive(self):
  2132. return self.args[0].is_extended_positive
  2133. def _eval_is_nonnegative(self):
  2134. return self.args[0].is_extended_nonnegative
  2135. def _eval_is_zero(self):
  2136. return self.args[0].is_zero
  2137. def _eval_is_real(self):
  2138. return self.args[0].is_extended_real
  2139. @classmethod
  2140. def eval(cls, arg):
  2141. if arg.is_Number:
  2142. if arg is S.NaN:
  2143. return S.NaN
  2144. elif arg is S.Infinity:
  2145. return S.Pi/2
  2146. elif arg is S.NegativeInfinity:
  2147. return -S.Pi/2
  2148. elif arg.is_zero:
  2149. return S.Zero
  2150. elif arg is S.One:
  2151. return S.Pi/4
  2152. elif arg is S.NegativeOne:
  2153. return -S.Pi/4
  2154. if arg is S.ComplexInfinity:
  2155. from sympy.calculus.accumulationbounds import AccumBounds
  2156. return AccumBounds(-S.Pi/2, S.Pi/2)
  2157. if arg.could_extract_minus_sign():
  2158. return -cls(-arg)
  2159. if arg.is_number:
  2160. atan_table = cls._atan_table()
  2161. if arg in atan_table:
  2162. return atan_table[arg]
  2163. i_coeff = arg.as_coefficient(S.ImaginaryUnit)
  2164. if i_coeff is not None:
  2165. return S.ImaginaryUnit*atanh(i_coeff)
  2166. if arg.is_zero:
  2167. return S.Zero
  2168. if isinstance(arg, tan):
  2169. ang = arg.args[0]
  2170. if ang.is_comparable:
  2171. ang %= pi # restrict to [0,pi)
  2172. if ang > pi/2: # restrict to [-pi/2,pi/2]
  2173. ang -= pi
  2174. return ang
  2175. if isinstance(arg, cot): # atan(x) + acot(x) = pi/2
  2176. ang = arg.args[0]
  2177. if ang.is_comparable:
  2178. ang = pi/2 - acot(arg)
  2179. if ang > pi/2: # restrict to [-pi/2,pi/2]
  2180. ang -= pi
  2181. return ang
  2182. @staticmethod
  2183. @cacheit
  2184. def taylor_term(n, x, *previous_terms):
  2185. if n < 0 or n % 2 == 0:
  2186. return S.Zero
  2187. else:
  2188. x = sympify(x)
  2189. return S.NegativeOne**((n - 1)//2)*x**n/n
  2190. def _eval_as_leading_term(self, x, logx=None, cdir=0):
  2191. from sympy.functions.elementary.complexes import (im, re)
  2192. arg = self.args[0]
  2193. x0 = arg.subs(x, 0).cancel()
  2194. if x0.is_zero:
  2195. return arg.as_leading_term(x)
  2196. if x0 is S.ComplexInfinity:
  2197. return acot(1/arg)._eval_as_leading_term(x, cdir=cdir)
  2198. if cdir != 0:
  2199. cdir = arg.dir(x, cdir)
  2200. if re(cdir) < 0 and re(x0).is_zero and im(x0) > S.One:
  2201. return self.func(x0) - S.Pi
  2202. elif re(cdir) > 0 and re(x0).is_zero and im(x0) < S.NegativeOne:
  2203. return self.func(x0) + S.Pi
  2204. return self.func(x0)
  2205. def _eval_nseries(self, x, n, logx, cdir=0): # atan
  2206. from sympy.functions.elementary.complexes import (im, re)
  2207. arg0 = self.args[0].subs(x, 0)
  2208. res = Function._eval_nseries(self, x, n=n, logx=logx)
  2209. if cdir != 0:
  2210. cdir = self.args[0].dir(x, cdir)
  2211. if arg0 is S.ComplexInfinity:
  2212. if re(cdir) > 0:
  2213. return res - S.Pi
  2214. return res
  2215. if re(cdir) < 0 and re(arg0).is_zero and im(arg0) > S.One:
  2216. return res - S.Pi
  2217. elif re(cdir) > 0 and re(arg0).is_zero and im(arg0) < S.NegativeOne:
  2218. return res + S.Pi
  2219. return res
  2220. def _eval_rewrite_as_log(self, x, **kwargs):
  2221. return S.ImaginaryUnit/2*(log(S.One - S.ImaginaryUnit*x)
  2222. - log(S.One + S.ImaginaryUnit*x))
  2223. def _eval_aseries(self, n, args0, x, logx):
  2224. if args0[0] is S.Infinity:
  2225. return (S.Pi/2 - atan(1/self.args[0]))._eval_nseries(x, n, logx)
  2226. elif args0[0] is S.NegativeInfinity:
  2227. return (-S.Pi/2 - atan(1/self.args[0]))._eval_nseries(x, n, logx)
  2228. else:
  2229. return super()._eval_aseries(n, args0, x, logx)
  2230. def inverse(self, argindex=1):
  2231. """
  2232. Returns the inverse of this function.
  2233. """
  2234. return tan
  2235. def _eval_rewrite_as_asin(self, arg, **kwargs):
  2236. return sqrt(arg**2)/arg*(S.Pi/2 - asin(1/sqrt(1 + arg**2)))
  2237. def _eval_rewrite_as_acos(self, arg, **kwargs):
  2238. return sqrt(arg**2)/arg*acos(1/sqrt(1 + arg**2))
  2239. def _eval_rewrite_as_acot(self, arg, **kwargs):
  2240. return acot(1/arg)
  2241. def _eval_rewrite_as_asec(self, arg, **kwargs):
  2242. return sqrt(arg**2)/arg*asec(sqrt(1 + arg**2))
  2243. def _eval_rewrite_as_acsc(self, arg, **kwargs):
  2244. return sqrt(arg**2)/arg*(S.Pi/2 - acsc(sqrt(1 + arg**2)))
  2245. class acot(InverseTrigonometricFunction):
  2246. r"""
  2247. The inverse cotangent function.
  2248. Returns the arc cotangent of x (measured in radians).
  2249. Explanation
  2250. ===========
  2251. ``acot(x)`` will evaluate automatically in the cases
  2252. $x \in \{\infty, -\infty, \tilde{\infty}, 0, 1, -1\}$
  2253. and for some instances when the result is a rational multiple of $\pi$
  2254. (see the eval class method).
  2255. A purely imaginary argument will lead to an ``acoth`` expression.
  2256. ``acot(x)`` has a branch cut along $(-i, i)$, hence it is discontinuous
  2257. at 0. Its range for real $x$ is $(-\frac{\pi}{2}, \frac{\pi}{2}]$.
  2258. Examples
  2259. ========
  2260. >>> from sympy import acot, sqrt
  2261. >>> acot(0)
  2262. pi/2
  2263. >>> acot(1)
  2264. pi/4
  2265. >>> acot(sqrt(3) - 2)
  2266. -5*pi/12
  2267. See Also
  2268. ========
  2269. sin, csc, cos, sec, tan, cot
  2270. asin, acsc, acos, asec, atan, atan2
  2271. References
  2272. ==========
  2273. .. [1] http://dlmf.nist.gov/4.23
  2274. .. [2] http://functions.wolfram.com/ElementaryFunctions/ArcCot
  2275. """
  2276. _singularities = (S.ImaginaryUnit, -S.ImaginaryUnit)
  2277. def fdiff(self, argindex=1):
  2278. if argindex == 1:
  2279. return -1/(1 + self.args[0]**2)
  2280. else:
  2281. raise ArgumentIndexError(self, argindex)
  2282. def _eval_is_rational(self):
  2283. s = self.func(*self.args)
  2284. if s.func == self.func:
  2285. if s.args[0].is_rational:
  2286. return False
  2287. else:
  2288. return s.is_rational
  2289. def _eval_is_positive(self):
  2290. return self.args[0].is_nonnegative
  2291. def _eval_is_negative(self):
  2292. return self.args[0].is_negative
  2293. def _eval_is_extended_real(self):
  2294. return self.args[0].is_extended_real
  2295. @classmethod
  2296. def eval(cls, arg):
  2297. if arg.is_Number:
  2298. if arg is S.NaN:
  2299. return S.NaN
  2300. elif arg is S.Infinity:
  2301. return S.Zero
  2302. elif arg is S.NegativeInfinity:
  2303. return S.Zero
  2304. elif arg.is_zero:
  2305. return S.Pi/ 2
  2306. elif arg is S.One:
  2307. return S.Pi/4
  2308. elif arg is S.NegativeOne:
  2309. return -S.Pi/4
  2310. if arg is S.ComplexInfinity:
  2311. return S.Zero
  2312. if arg.could_extract_minus_sign():
  2313. return -cls(-arg)
  2314. if arg.is_number:
  2315. atan_table = cls._atan_table()
  2316. if arg in atan_table:
  2317. ang = pi/2 - atan_table[arg]
  2318. if ang > pi/2: # restrict to (-pi/2,pi/2]
  2319. ang -= pi
  2320. return ang
  2321. i_coeff = arg.as_coefficient(S.ImaginaryUnit)
  2322. if i_coeff is not None:
  2323. return -S.ImaginaryUnit*acoth(i_coeff)
  2324. if arg.is_zero:
  2325. return S.Pi*S.Half
  2326. if isinstance(arg, cot):
  2327. ang = arg.args[0]
  2328. if ang.is_comparable:
  2329. ang %= pi # restrict to [0,pi)
  2330. if ang > pi/2: # restrict to (-pi/2,pi/2]
  2331. ang -= pi;
  2332. return ang
  2333. if isinstance(arg, tan): # atan(x) + acot(x) = pi/2
  2334. ang = arg.args[0]
  2335. if ang.is_comparable:
  2336. ang = pi/2 - atan(arg)
  2337. if ang > pi/2: # restrict to (-pi/2,pi/2]
  2338. ang -= pi
  2339. return ang
  2340. @staticmethod
  2341. @cacheit
  2342. def taylor_term(n, x, *previous_terms):
  2343. if n == 0:
  2344. return S.Pi/2 # FIX THIS
  2345. elif n < 0 or n % 2 == 0:
  2346. return S.Zero
  2347. else:
  2348. x = sympify(x)
  2349. return S.NegativeOne**((n + 1)//2)*x**n/n
  2350. def _eval_as_leading_term(self, x, logx=None, cdir=0):
  2351. from sympy.functions.elementary.complexes import (im, re)
  2352. arg = self.args[0]
  2353. x0 = arg.subs(x, 0).cancel()
  2354. if x0 is S.ComplexInfinity:
  2355. return (1/arg).as_leading_term(x)
  2356. if cdir != 0:
  2357. cdir = arg.dir(x, cdir)
  2358. if x0.is_zero:
  2359. if re(cdir) < 0:
  2360. return self.func(x0) - S.Pi
  2361. return self.func(x0)
  2362. if re(cdir) > 0 and re(x0).is_zero and im(x0) > S.Zero and im(x0) < S.One:
  2363. return self.func(x0) + S.Pi
  2364. if re(cdir) < 0 and re(x0).is_zero and im(x0) < S.Zero and im(x0) > S.NegativeOne:
  2365. return self.func(x0) - S.Pi
  2366. return self.func(x0)
  2367. def _eval_nseries(self, x, n, logx, cdir=0): # acot
  2368. from sympy.functions.elementary.complexes import (im, re)
  2369. arg0 = self.args[0].subs(x, 0)
  2370. res = Function._eval_nseries(self, x, n=n, logx=logx)
  2371. if arg0 is S.ComplexInfinity:
  2372. return res
  2373. if cdir != 0:
  2374. cdir = self.args[0].dir(x, cdir)
  2375. if arg0.is_zero:
  2376. if re(cdir) < 0:
  2377. return res - S.Pi
  2378. return res
  2379. if re(cdir) > 0 and re(arg0).is_zero and im(arg0) > S.Zero and im(arg0) < S.One:
  2380. return res + S.Pi
  2381. if re(cdir) < 0 and re(arg0).is_zero and im(arg0) < S.Zero and im(arg0) > S.NegativeOne:
  2382. return res - S.Pi
  2383. return res
  2384. def _eval_aseries(self, n, args0, x, logx):
  2385. if args0[0] is S.Infinity:
  2386. return (S.Pi/2 - acot(1/self.args[0]))._eval_nseries(x, n, logx)
  2387. elif args0[0] is S.NegativeInfinity:
  2388. return (S.Pi*Rational(3, 2) - acot(1/self.args[0]))._eval_nseries(x, n, logx)
  2389. else:
  2390. return super(atan, self)._eval_aseries(n, args0, x, logx)
  2391. def _eval_rewrite_as_log(self, x, **kwargs):
  2392. return S.ImaginaryUnit/2*(log(1 - S.ImaginaryUnit/x)
  2393. - log(1 + S.ImaginaryUnit/x))
  2394. def inverse(self, argindex=1):
  2395. """
  2396. Returns the inverse of this function.
  2397. """
  2398. return cot
  2399. def _eval_rewrite_as_asin(self, arg, **kwargs):
  2400. return (arg*sqrt(1/arg**2)*
  2401. (S.Pi/2 - asin(sqrt(-arg**2)/sqrt(-arg**2 - 1))))
  2402. def _eval_rewrite_as_acos(self, arg, **kwargs):
  2403. return arg*sqrt(1/arg**2)*acos(sqrt(-arg**2)/sqrt(-arg**2 - 1))
  2404. def _eval_rewrite_as_atan(self, arg, **kwargs):
  2405. return atan(1/arg)
  2406. def _eval_rewrite_as_asec(self, arg, **kwargs):
  2407. return arg*sqrt(1/arg**2)*asec(sqrt((1 + arg**2)/arg**2))
  2408. def _eval_rewrite_as_acsc(self, arg, **kwargs):
  2409. return arg*sqrt(1/arg**2)*(S.Pi/2 - acsc(sqrt((1 + arg**2)/arg**2)))
  2410. class asec(InverseTrigonometricFunction):
  2411. r"""
  2412. The inverse secant function.
  2413. Returns the arc secant of x (measured in radians).
  2414. Explanation
  2415. ===========
  2416. ``asec(x)`` will evaluate automatically in the cases
  2417. $x \in \{\infty, -\infty, 0, 1, -1\}$ and for some instances when the
  2418. result is a rational multiple of $\pi$ (see the eval class method).
  2419. ``asec(x)`` has branch cut in the interval $[-1, 1]$. For complex arguments,
  2420. it can be defined [4]_ as
  2421. .. math::
  2422. \operatorname{sec^{-1}}(z) = -i\frac{\log\left(\sqrt{1 - z^2} + 1\right)}{z}
  2423. At ``x = 0``, for positive branch cut, the limit evaluates to ``zoo``. For
  2424. negative branch cut, the limit
  2425. .. math::
  2426. \lim_{z \to 0}-i\frac{\log\left(-\sqrt{1 - z^2} + 1\right)}{z}
  2427. simplifies to :math:`-i\log\left(z/2 + O\left(z^3\right)\right)` which
  2428. ultimately evaluates to ``zoo``.
  2429. As ``acos(x) = asec(1/x)``, a similar argument can be given for
  2430. ``acos(x)``.
  2431. Examples
  2432. ========
  2433. >>> from sympy import asec, oo
  2434. >>> asec(1)
  2435. 0
  2436. >>> asec(-1)
  2437. pi
  2438. >>> asec(0)
  2439. zoo
  2440. >>> asec(-oo)
  2441. pi/2
  2442. See Also
  2443. ========
  2444. sin, csc, cos, sec, tan, cot
  2445. asin, acsc, acos, atan, acot, atan2
  2446. References
  2447. ==========
  2448. .. [1] https://en.wikipedia.org/wiki/Inverse_trigonometric_functions
  2449. .. [2] http://dlmf.nist.gov/4.23
  2450. .. [3] http://functions.wolfram.com/ElementaryFunctions/ArcSec
  2451. .. [4] http://reference.wolfram.com/language/ref/ArcSec.html
  2452. """
  2453. @classmethod
  2454. def eval(cls, arg):
  2455. if arg.is_zero:
  2456. return S.ComplexInfinity
  2457. if arg.is_Number:
  2458. if arg is S.NaN:
  2459. return S.NaN
  2460. elif arg is S.One:
  2461. return S.Zero
  2462. elif arg is S.NegativeOne:
  2463. return S.Pi
  2464. if arg in [S.Infinity, S.NegativeInfinity, S.ComplexInfinity]:
  2465. return S.Pi/2
  2466. if arg.is_number:
  2467. acsc_table = cls._acsc_table()
  2468. if arg in acsc_table:
  2469. return pi/2 - acsc_table[arg]
  2470. elif -arg in acsc_table:
  2471. return pi/2 + acsc_table[-arg]
  2472. if isinstance(arg, sec):
  2473. ang = arg.args[0]
  2474. if ang.is_comparable:
  2475. ang %= 2*pi # restrict to [0,2*pi)
  2476. if ang > pi: # restrict to [0,pi]
  2477. ang = 2*pi - ang
  2478. return ang
  2479. if isinstance(arg, csc): # asec(x) + acsc(x) = pi/2
  2480. ang = arg.args[0]
  2481. if ang.is_comparable:
  2482. return pi/2 - acsc(arg)
  2483. def fdiff(self, argindex=1):
  2484. if argindex == 1:
  2485. return 1/(self.args[0]**2*sqrt(1 - 1/self.args[0]**2))
  2486. else:
  2487. raise ArgumentIndexError(self, argindex)
  2488. def inverse(self, argindex=1):
  2489. """
  2490. Returns the inverse of this function.
  2491. """
  2492. return sec
  2493. def _eval_as_leading_term(self, x, logx=None, cdir=0):
  2494. from sympy.functions.elementary.complexes import im
  2495. arg = self.args[0]
  2496. x0 = arg.subs(x, 0).cancel()
  2497. if x0 == 1:
  2498. return sqrt(2)*sqrt((arg - S.One).as_leading_term(x))
  2499. if x0.is_zero:
  2500. return S.ImaginaryUnit*log(arg.as_leading_term(x))
  2501. if cdir != 0:
  2502. cdir = arg.dir(x, cdir)
  2503. if im(cdir) < 0 and x0.is_real and x0 > S.Zero and x0 < S.One:
  2504. return -self.func(x0)
  2505. elif im(cdir) > 0 and x0.is_real and x0 < S.Zero and x0 > S.NegativeOne:
  2506. return 2*S.Pi - self.func(x0)
  2507. return self.func(x0)
  2508. def _eval_nseries(self, x, n, logx, cdir=0): # asec
  2509. from sympy.functions.elementary.complexes import im
  2510. from sympy.series.order import O
  2511. arg0 = self.args[0].subs(x, 0)
  2512. if arg0 is S.One:
  2513. t = Dummy('t', positive=True)
  2514. ser = asec(S.One + t**2).rewrite(log).nseries(t, 0, 2*n)
  2515. arg1 = S.NegativeOne + self.args[0]
  2516. f = arg1.as_leading_term(x)
  2517. g = (arg1 - f)/ f
  2518. res1 = sqrt(S.One + g)._eval_nseries(x, n=n, logx=logx)
  2519. res = (res1.removeO()*sqrt(f)).expand()
  2520. return ser.removeO().subs(t, res).expand().powsimp() + O(x**n, x)
  2521. if arg0 is S.NegativeOne:
  2522. t = Dummy('t', positive=True)
  2523. ser = asec(S.NegativeOne - t**2).rewrite(log).nseries(t, 0, 2*n)
  2524. arg1 = S.NegativeOne - self.args[0]
  2525. f = arg1.as_leading_term(x)
  2526. g = (arg1 - f)/ f
  2527. res1 = sqrt(S.One + g)._eval_nseries(x, n=n, logx=logx)
  2528. res = (res1.removeO()*sqrt(f)).expand()
  2529. return ser.removeO().subs(t, res).expand().powsimp() + O(x**n, x)
  2530. res = Function._eval_nseries(self, x, n=n, logx=logx)
  2531. if arg0 is S.ComplexInfinity:
  2532. return res
  2533. if cdir != 0:
  2534. cdir = self.args[0].dir(x, cdir)
  2535. if im(cdir) < 0 and arg0.is_real and arg0 > S.Zero and arg0 < S.One:
  2536. return -res
  2537. elif im(cdir) > 0 and arg0.is_real and arg0 < S.Zero and arg0 > S.NegativeOne:
  2538. return 2*S.Pi - res
  2539. return res
  2540. def _eval_is_extended_real(self):
  2541. x = self.args[0]
  2542. if x.is_extended_real is False:
  2543. return False
  2544. return fuzzy_or(((x - 1).is_nonnegative, (-x - 1).is_nonnegative))
  2545. def _eval_rewrite_as_log(self, arg, **kwargs):
  2546. return S.Pi/2 + S.ImaginaryUnit*log(S.ImaginaryUnit/arg + sqrt(1 - 1/arg**2))
  2547. def _eval_rewrite_as_asin(self, arg, **kwargs):
  2548. return S.Pi/2 - asin(1/arg)
  2549. def _eval_rewrite_as_acos(self, arg, **kwargs):
  2550. return acos(1/arg)
  2551. def _eval_rewrite_as_atan(self, arg, **kwargs):
  2552. return sqrt(arg**2)/arg*(-S.Pi/2 + 2*atan(arg + sqrt(arg**2 - 1)))
  2553. def _eval_rewrite_as_acot(self, arg, **kwargs):
  2554. return sqrt(arg**2)/arg*(-S.Pi/2 + 2*acot(arg - sqrt(arg**2 - 1)))
  2555. def _eval_rewrite_as_acsc(self, arg, **kwargs):
  2556. return S.Pi/2 - acsc(arg)
  2557. class acsc(InverseTrigonometricFunction):
  2558. r"""
  2559. The inverse cosecant function.
  2560. Returns the arc cosecant of x (measured in radians).
  2561. Explanation
  2562. ===========
  2563. ``acsc(x)`` will evaluate automatically in the cases
  2564. $x \in \{\infty, -\infty, 0, 1, -1\}$` and for some instances when the
  2565. result is a rational multiple of $\pi$ (see the ``eval`` class method).
  2566. Examples
  2567. ========
  2568. >>> from sympy import acsc, oo
  2569. >>> acsc(1)
  2570. pi/2
  2571. >>> acsc(-1)
  2572. -pi/2
  2573. >>> acsc(oo)
  2574. 0
  2575. >>> acsc(-oo) == acsc(oo)
  2576. True
  2577. >>> acsc(0)
  2578. zoo
  2579. See Also
  2580. ========
  2581. sin, csc, cos, sec, tan, cot
  2582. asin, acos, asec, atan, acot, atan2
  2583. References
  2584. ==========
  2585. .. [1] https://en.wikipedia.org/wiki/Inverse_trigonometric_functions
  2586. .. [2] http://dlmf.nist.gov/4.23
  2587. .. [3] http://functions.wolfram.com/ElementaryFunctions/ArcCsc
  2588. """
  2589. @classmethod
  2590. def eval(cls, arg):
  2591. if arg.is_zero:
  2592. return S.ComplexInfinity
  2593. if arg.is_Number:
  2594. if arg is S.NaN:
  2595. return S.NaN
  2596. elif arg is S.One:
  2597. return S.Pi/2
  2598. elif arg is S.NegativeOne:
  2599. return -S.Pi/2
  2600. if arg in [S.Infinity, S.NegativeInfinity, S.ComplexInfinity]:
  2601. return S.Zero
  2602. if arg.could_extract_minus_sign():
  2603. return -cls(-arg)
  2604. if arg.is_number:
  2605. acsc_table = cls._acsc_table()
  2606. if arg in acsc_table:
  2607. return acsc_table[arg]
  2608. if isinstance(arg, csc):
  2609. ang = arg.args[0]
  2610. if ang.is_comparable:
  2611. ang %= 2*pi # restrict to [0,2*pi)
  2612. if ang > pi: # restrict to (-pi,pi]
  2613. ang = pi - ang
  2614. # restrict to [-pi/2,pi/2]
  2615. if ang > pi/2:
  2616. ang = pi - ang
  2617. if ang < -pi/2:
  2618. ang = -pi - ang
  2619. return ang
  2620. if isinstance(arg, sec): # asec(x) + acsc(x) = pi/2
  2621. ang = arg.args[0]
  2622. if ang.is_comparable:
  2623. return pi/2 - asec(arg)
  2624. def fdiff(self, argindex=1):
  2625. if argindex == 1:
  2626. return -1/(self.args[0]**2*sqrt(1 - 1/self.args[0]**2))
  2627. else:
  2628. raise ArgumentIndexError(self, argindex)
  2629. def inverse(self, argindex=1):
  2630. """
  2631. Returns the inverse of this function.
  2632. """
  2633. return csc
  2634. def _eval_as_leading_term(self, x, logx=None, cdir=0):
  2635. from sympy.functions.elementary.complexes import im
  2636. arg = self.args[0]
  2637. x0 = arg.subs(x, 0).cancel()
  2638. if x0.is_zero:
  2639. return S.ImaginaryUnit*log(arg.as_leading_term(x))
  2640. if x0 is S.ComplexInfinity:
  2641. return arg.as_leading_term(x)
  2642. if cdir != 0:
  2643. cdir = arg.dir(x, cdir)
  2644. if im(cdir) < 0 and x0.is_real and x0 > S.Zero and x0 < S.One:
  2645. return S.Pi - self.func(x0)
  2646. elif im(cdir) > 0 and x0.is_real and x0 < S.Zero and x0 > S.NegativeOne:
  2647. return -S.Pi - self.func(x0)
  2648. return self.func(x0)
  2649. def _eval_nseries(self, x, n, logx, cdir=0): # acsc
  2650. from sympy.functions.elementary.complexes import im
  2651. from sympy.series.order import O
  2652. arg0 = self.args[0].subs(x, 0)
  2653. if arg0 is S.One:
  2654. t = Dummy('t', positive=True)
  2655. ser = acsc(S.One + t**2).rewrite(log).nseries(t, 0, 2*n)
  2656. arg1 = S.NegativeOne + self.args[0]
  2657. f = arg1.as_leading_term(x)
  2658. g = (arg1 - f)/ f
  2659. res1 = sqrt(S.One + g)._eval_nseries(x, n=n, logx=logx)
  2660. res = (res1.removeO()*sqrt(f)).expand()
  2661. return ser.removeO().subs(t, res).expand().powsimp() + O(x**n, x)
  2662. if arg0 is S.NegativeOne:
  2663. t = Dummy('t', positive=True)
  2664. ser = acsc(S.NegativeOne - t**2).rewrite(log).nseries(t, 0, 2*n)
  2665. arg1 = S.NegativeOne - self.args[0]
  2666. f = arg1.as_leading_term(x)
  2667. g = (arg1 - f)/ f
  2668. res1 = sqrt(S.One + g)._eval_nseries(x, n=n, logx=logx)
  2669. res = (res1.removeO()*sqrt(f)).expand()
  2670. return ser.removeO().subs(t, res).expand().powsimp() + O(x**n, x)
  2671. res = Function._eval_nseries(self, x, n=n, logx=logx)
  2672. if arg0 is S.ComplexInfinity:
  2673. return res
  2674. if cdir != 0:
  2675. cdir = self.args[0].dir(x, cdir)
  2676. if im(cdir) < 0 and arg0.is_real and arg0 > S.Zero and arg0 < S.One:
  2677. return S.Pi - res
  2678. elif im(cdir) > 0 and arg0.is_real and arg0 < S.Zero and arg0 > S.NegativeOne:
  2679. return -S.Pi - res
  2680. return res
  2681. def _eval_rewrite_as_log(self, arg, **kwargs):
  2682. return -S.ImaginaryUnit*log(S.ImaginaryUnit/arg + sqrt(1 - 1/arg**2))
  2683. def _eval_rewrite_as_asin(self, arg, **kwargs):
  2684. return asin(1/arg)
  2685. def _eval_rewrite_as_acos(self, arg, **kwargs):
  2686. return S.Pi/2 - acos(1/arg)
  2687. def _eval_rewrite_as_atan(self, arg, **kwargs):
  2688. return sqrt(arg**2)/arg*(S.Pi/2 - atan(sqrt(arg**2 - 1)))
  2689. def _eval_rewrite_as_acot(self, arg, **kwargs):
  2690. return sqrt(arg**2)/arg*(S.Pi/2 - acot(1/sqrt(arg**2 - 1)))
  2691. def _eval_rewrite_as_asec(self, arg, **kwargs):
  2692. return S.Pi/2 - asec(arg)
  2693. class atan2(InverseTrigonometricFunction):
  2694. r"""
  2695. The function ``atan2(y, x)`` computes `\operatorname{atan}(y/x)` taking
  2696. two arguments `y` and `x`. Signs of both `y` and `x` are considered to
  2697. determine the appropriate quadrant of `\operatorname{atan}(y/x)`.
  2698. The range is `(-\pi, \pi]`. The complete definition reads as follows:
  2699. .. math::
  2700. \operatorname{atan2}(y, x) =
  2701. \begin{cases}
  2702. \arctan\left(\frac y x\right) & \qquad x > 0 \\
  2703. \arctan\left(\frac y x\right) + \pi& \qquad y \ge 0, x < 0 \\
  2704. \arctan\left(\frac y x\right) - \pi& \qquad y < 0, x < 0 \\
  2705. +\frac{\pi}{2} & \qquad y > 0, x = 0 \\
  2706. -\frac{\pi}{2} & \qquad y < 0, x = 0 \\
  2707. \text{undefined} & \qquad y = 0, x = 0
  2708. \end{cases}
  2709. Attention: Note the role reversal of both arguments. The `y`-coordinate
  2710. is the first argument and the `x`-coordinate the second.
  2711. If either `x` or `y` is complex:
  2712. .. math::
  2713. \operatorname{atan2}(y, x) =
  2714. -i\log\left(\frac{x + iy}{\sqrt{x^2 + y^2}}\right)
  2715. Examples
  2716. ========
  2717. Going counter-clock wise around the origin we find the
  2718. following angles:
  2719. >>> from sympy import atan2
  2720. >>> atan2(0, 1)
  2721. 0
  2722. >>> atan2(1, 1)
  2723. pi/4
  2724. >>> atan2(1, 0)
  2725. pi/2
  2726. >>> atan2(1, -1)
  2727. 3*pi/4
  2728. >>> atan2(0, -1)
  2729. pi
  2730. >>> atan2(-1, -1)
  2731. -3*pi/4
  2732. >>> atan2(-1, 0)
  2733. -pi/2
  2734. >>> atan2(-1, 1)
  2735. -pi/4
  2736. which are all correct. Compare this to the results of the ordinary
  2737. `\operatorname{atan}` function for the point `(x, y) = (-1, 1)`
  2738. >>> from sympy import atan, S
  2739. >>> atan(S(1)/-1)
  2740. -pi/4
  2741. >>> atan2(1, -1)
  2742. 3*pi/4
  2743. where only the `\operatorname{atan2}` function reurns what we expect.
  2744. We can differentiate the function with respect to both arguments:
  2745. >>> from sympy import diff
  2746. >>> from sympy.abc import x, y
  2747. >>> diff(atan2(y, x), x)
  2748. -y/(x**2 + y**2)
  2749. >>> diff(atan2(y, x), y)
  2750. x/(x**2 + y**2)
  2751. We can express the `\operatorname{atan2}` function in terms of
  2752. complex logarithms:
  2753. >>> from sympy import log
  2754. >>> atan2(y, x).rewrite(log)
  2755. -I*log((x + I*y)/sqrt(x**2 + y**2))
  2756. and in terms of `\operatorname(atan)`:
  2757. >>> from sympy import atan
  2758. >>> atan2(y, x).rewrite(atan)
  2759. Piecewise((2*atan(y/(x + sqrt(x**2 + y**2))), Ne(y, 0)), (pi, re(x) < 0), (0, Ne(x, 0)), (nan, True))
  2760. but note that this form is undefined on the negative real axis.
  2761. See Also
  2762. ========
  2763. sin, csc, cos, sec, tan, cot
  2764. asin, acsc, acos, asec, atan, acot
  2765. References
  2766. ==========
  2767. .. [1] https://en.wikipedia.org/wiki/Inverse_trigonometric_functions
  2768. .. [2] https://en.wikipedia.org/wiki/Atan2
  2769. .. [3] http://functions.wolfram.com/ElementaryFunctions/ArcTan2
  2770. """
  2771. @classmethod
  2772. def eval(cls, y, x):
  2773. from sympy.functions.elementary.complexes import (im, re)
  2774. from sympy.functions.special.delta_functions import Heaviside
  2775. if x is S.NegativeInfinity:
  2776. if y.is_zero:
  2777. # Special case y = 0 because we define Heaviside(0) = 1/2
  2778. return S.Pi
  2779. return 2*S.Pi*(Heaviside(re(y))) - S.Pi
  2780. elif x is S.Infinity:
  2781. return S.Zero
  2782. elif x.is_imaginary and y.is_imaginary and x.is_number and y.is_number:
  2783. x = im(x)
  2784. y = im(y)
  2785. if x.is_extended_real and y.is_extended_real:
  2786. if x.is_positive:
  2787. return atan(y/x)
  2788. elif x.is_negative:
  2789. if y.is_negative:
  2790. return atan(y/x) - S.Pi
  2791. elif y.is_nonnegative:
  2792. return atan(y/x) + S.Pi
  2793. elif x.is_zero:
  2794. if y.is_positive:
  2795. return S.Pi/2
  2796. elif y.is_negative:
  2797. return -S.Pi/2
  2798. elif y.is_zero:
  2799. return S.NaN
  2800. if y.is_zero:
  2801. if x.is_extended_nonzero:
  2802. return S.Pi*(S.One - Heaviside(x))
  2803. if x.is_number:
  2804. return Piecewise((S.Pi, re(x) < 0),
  2805. (0, Ne(x, 0)),
  2806. (S.NaN, True))
  2807. if x.is_number and y.is_number:
  2808. return -S.ImaginaryUnit*log(
  2809. (x + S.ImaginaryUnit*y)/sqrt(x**2 + y**2))
  2810. def _eval_rewrite_as_log(self, y, x, **kwargs):
  2811. return -S.ImaginaryUnit*log((x + S.ImaginaryUnit*y)/sqrt(x**2 + y**2))
  2812. def _eval_rewrite_as_atan(self, y, x, **kwargs):
  2813. from sympy.functions.elementary.complexes import re
  2814. return Piecewise((2*atan(y/(x + sqrt(x**2 + y**2))), Ne(y, 0)),
  2815. (pi, re(x) < 0),
  2816. (0, Ne(x, 0)),
  2817. (S.NaN, True))
  2818. def _eval_rewrite_as_arg(self, y, x, **kwargs):
  2819. from sympy.functions.elementary.complexes import arg
  2820. if x.is_extended_real and y.is_extended_real:
  2821. return arg(x + y*S.ImaginaryUnit)
  2822. n = x + S.ImaginaryUnit*y
  2823. d = x**2 + y**2
  2824. return arg(n/sqrt(d)) - S.ImaginaryUnit*log(abs(n)/sqrt(abs(d)))
  2825. def _eval_is_extended_real(self):
  2826. return self.args[0].is_extended_real and self.args[1].is_extended_real
  2827. def _eval_conjugate(self):
  2828. return self.func(self.args[0].conjugate(), self.args[1].conjugate())
  2829. def fdiff(self, argindex):
  2830. y, x = self.args
  2831. if argindex == 1:
  2832. # Diff wrt y
  2833. return x/(x**2 + y**2)
  2834. elif argindex == 2:
  2835. # Diff wrt x
  2836. return -y/(x**2 + y**2)
  2837. else:
  2838. raise ArgumentIndexError(self, argindex)
  2839. def _eval_evalf(self, prec):
  2840. y, x = self.args
  2841. if x.is_extended_real and y.is_extended_real:
  2842. return super()._eval_evalf(prec)