trigonometric.py 111 KB

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