latex.py 115 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222
  1. """
  2. A Printer which converts an expression into its LaTeX equivalent.
  3. """
  4. from typing import Any, Dict as tDict
  5. import itertools
  6. from sympy.core import Add, Float, Mod, Mul, Number, S, Symbol
  7. from sympy.core.alphabets import greeks
  8. from sympy.core.containers import Tuple
  9. from sympy.core.function import AppliedUndef, Derivative
  10. from sympy.core.operations import AssocOp
  11. from sympy.core.power import Pow
  12. from sympy.core.sorting import default_sort_key
  13. from sympy.core.sympify import SympifyError
  14. from sympy.logic.boolalg import true
  15. # sympy.printing imports
  16. from sympy.printing.precedence import precedence_traditional
  17. from sympy.printing.printer import Printer, print_function
  18. from sympy.printing.conventions import split_super_sub, requires_partial
  19. from sympy.printing.precedence import precedence, PRECEDENCE
  20. from mpmath.libmp.libmpf import prec_to_dps, to_str as mlib_to_str
  21. from sympy.utilities.iterables import has_variety
  22. import re
  23. # Hand-picked functions which can be used directly in both LaTeX and MathJax
  24. # Complete list at
  25. # https://docs.mathjax.org/en/latest/tex.html#supported-latex-commands
  26. # This variable only contains those functions which SymPy uses.
  27. accepted_latex_functions = ['arcsin', 'arccos', 'arctan', 'sin', 'cos', 'tan',
  28. 'sinh', 'cosh', 'tanh', 'sqrt', 'ln', 'log', 'sec',
  29. 'csc', 'cot', 'coth', 're', 'im', 'frac', 'root',
  30. 'arg',
  31. ]
  32. tex_greek_dictionary = {
  33. 'Alpha': 'A',
  34. 'Beta': 'B',
  35. 'Gamma': r'\Gamma',
  36. 'Delta': r'\Delta',
  37. 'Epsilon': 'E',
  38. 'Zeta': 'Z',
  39. 'Eta': 'H',
  40. 'Theta': r'\Theta',
  41. 'Iota': 'I',
  42. 'Kappa': 'K',
  43. 'Lambda': r'\Lambda',
  44. 'Mu': 'M',
  45. 'Nu': 'N',
  46. 'Xi': r'\Xi',
  47. 'omicron': 'o',
  48. 'Omicron': 'O',
  49. 'Pi': r'\Pi',
  50. 'Rho': 'P',
  51. 'Sigma': r'\Sigma',
  52. 'Tau': 'T',
  53. 'Upsilon': r'\Upsilon',
  54. 'Phi': r'\Phi',
  55. 'Chi': 'X',
  56. 'Psi': r'\Psi',
  57. 'Omega': r'\Omega',
  58. 'lamda': r'\lambda',
  59. 'Lamda': r'\Lambda',
  60. 'khi': r'\chi',
  61. 'Khi': r'X',
  62. 'varepsilon': r'\varepsilon',
  63. 'varkappa': r'\varkappa',
  64. 'varphi': r'\varphi',
  65. 'varpi': r'\varpi',
  66. 'varrho': r'\varrho',
  67. 'varsigma': r'\varsigma',
  68. 'vartheta': r'\vartheta',
  69. }
  70. other_symbols = {'aleph', 'beth', 'daleth', 'gimel', 'ell', 'eth', 'hbar',
  71. 'hslash', 'mho', 'wp'}
  72. # Variable name modifiers
  73. modifier_dict = {
  74. # Accents
  75. 'mathring': lambda s: r'\mathring{'+s+r'}',
  76. 'ddddot': lambda s: r'\ddddot{'+s+r'}',
  77. 'dddot': lambda s: r'\dddot{'+s+r'}',
  78. 'ddot': lambda s: r'\ddot{'+s+r'}',
  79. 'dot': lambda s: r'\dot{'+s+r'}',
  80. 'check': lambda s: r'\check{'+s+r'}',
  81. 'breve': lambda s: r'\breve{'+s+r'}',
  82. 'acute': lambda s: r'\acute{'+s+r'}',
  83. 'grave': lambda s: r'\grave{'+s+r'}',
  84. 'tilde': lambda s: r'\tilde{'+s+r'}',
  85. 'hat': lambda s: r'\hat{'+s+r'}',
  86. 'bar': lambda s: r'\bar{'+s+r'}',
  87. 'vec': lambda s: r'\vec{'+s+r'}',
  88. 'prime': lambda s: "{"+s+"}'",
  89. 'prm': lambda s: "{"+s+"}'",
  90. # Faces
  91. 'bold': lambda s: r'\boldsymbol{'+s+r'}',
  92. 'bm': lambda s: r'\boldsymbol{'+s+r'}',
  93. 'cal': lambda s: r'\mathcal{'+s+r'}',
  94. 'scr': lambda s: r'\mathscr{'+s+r'}',
  95. 'frak': lambda s: r'\mathfrak{'+s+r'}',
  96. # Brackets
  97. 'norm': lambda s: r'\left\|{'+s+r'}\right\|',
  98. 'avg': lambda s: r'\left\langle{'+s+r'}\right\rangle',
  99. 'abs': lambda s: r'\left|{'+s+r'}\right|',
  100. 'mag': lambda s: r'\left|{'+s+r'}\right|',
  101. }
  102. greek_letters_set = frozenset(greeks)
  103. _between_two_numbers_p = (
  104. re.compile(r'[0-9][} ]*$'), # search
  105. re.compile(r'[0-9]'), # match
  106. )
  107. def latex_escape(s):
  108. """
  109. Escape a string such that latex interprets it as plaintext.
  110. We cannot use verbatim easily with mathjax, so escaping is easier.
  111. Rules from https://tex.stackexchange.com/a/34586/41112.
  112. """
  113. s = s.replace('\\', r'\textbackslash')
  114. for c in '&%$#_{}':
  115. s = s.replace(c, '\\' + c)
  116. s = s.replace('~', r'\textasciitilde')
  117. s = s.replace('^', r'\textasciicircum')
  118. return s
  119. class LatexPrinter(Printer):
  120. printmethod = "_latex"
  121. _default_settings = {
  122. "full_prec": False,
  123. "fold_frac_powers": False,
  124. "fold_func_brackets": False,
  125. "fold_short_frac": None,
  126. "inv_trig_style": "abbreviated",
  127. "itex": False,
  128. "ln_notation": False,
  129. "long_frac_ratio": None,
  130. "mat_delim": "[",
  131. "mat_str": None,
  132. "mode": "plain",
  133. "mul_symbol": None,
  134. "order": None,
  135. "symbol_names": {},
  136. "root_notation": True,
  137. "mat_symbol_style": "plain",
  138. "imaginary_unit": "i",
  139. "gothic_re_im": False,
  140. "decimal_separator": "period",
  141. "perm_cyclic": True,
  142. "parenthesize_super": True,
  143. "min": None,
  144. "max": None,
  145. } # type: tDict[str, Any]
  146. def __init__(self, settings=None):
  147. Printer.__init__(self, settings)
  148. if 'mode' in self._settings:
  149. valid_modes = ['inline', 'plain', 'equation',
  150. 'equation*']
  151. if self._settings['mode'] not in valid_modes:
  152. raise ValueError("'mode' must be one of 'inline', 'plain', "
  153. "'equation' or 'equation*'")
  154. if self._settings['fold_short_frac'] is None and \
  155. self._settings['mode'] == 'inline':
  156. self._settings['fold_short_frac'] = True
  157. mul_symbol_table = {
  158. None: r" ",
  159. "ldot": r" \,.\, ",
  160. "dot": r" \cdot ",
  161. "times": r" \times "
  162. }
  163. try:
  164. self._settings['mul_symbol_latex'] = \
  165. mul_symbol_table[self._settings['mul_symbol']]
  166. except KeyError:
  167. self._settings['mul_symbol_latex'] = \
  168. self._settings['mul_symbol']
  169. try:
  170. self._settings['mul_symbol_latex_numbers'] = \
  171. mul_symbol_table[self._settings['mul_symbol'] or 'dot']
  172. except KeyError:
  173. if (self._settings['mul_symbol'].strip() in
  174. ['', ' ', '\\', '\\,', '\\:', '\\;', '\\quad']):
  175. self._settings['mul_symbol_latex_numbers'] = \
  176. mul_symbol_table['dot']
  177. else:
  178. self._settings['mul_symbol_latex_numbers'] = \
  179. self._settings['mul_symbol']
  180. self._delim_dict = {'(': ')', '[': ']'}
  181. imaginary_unit_table = {
  182. None: r"i",
  183. "i": r"i",
  184. "ri": r"\mathrm{i}",
  185. "ti": r"\text{i}",
  186. "j": r"j",
  187. "rj": r"\mathrm{j}",
  188. "tj": r"\text{j}",
  189. }
  190. try:
  191. self._settings['imaginary_unit_latex'] = \
  192. imaginary_unit_table[self._settings['imaginary_unit']]
  193. except KeyError:
  194. self._settings['imaginary_unit_latex'] = \
  195. self._settings['imaginary_unit']
  196. def _add_parens(self, s):
  197. return r"\left({}\right)".format(s)
  198. # TODO: merge this with the above, which requires a lot of test changes
  199. def _add_parens_lspace(self, s):
  200. return r"\left( {}\right)".format(s)
  201. def parenthesize(self, item, level, is_neg=False, strict=False):
  202. prec_val = precedence_traditional(item)
  203. if is_neg and strict:
  204. return self._add_parens(self._print(item))
  205. if (prec_val < level) or ((not strict) and prec_val <= level):
  206. return self._add_parens(self._print(item))
  207. else:
  208. return self._print(item)
  209. def parenthesize_super(self, s):
  210. """
  211. Protect superscripts in s
  212. If the parenthesize_super option is set, protect with parentheses, else
  213. wrap in braces.
  214. """
  215. if "^" in s:
  216. if self._settings['parenthesize_super']:
  217. return self._add_parens(s)
  218. else:
  219. return "{{{}}}".format(s)
  220. return s
  221. def doprint(self, expr):
  222. tex = Printer.doprint(self, expr)
  223. if self._settings['mode'] == 'plain':
  224. return tex
  225. elif self._settings['mode'] == 'inline':
  226. return r"$%s$" % tex
  227. elif self._settings['itex']:
  228. return r"$$%s$$" % tex
  229. else:
  230. env_str = self._settings['mode']
  231. return r"\begin{%s}%s\end{%s}" % (env_str, tex, env_str)
  232. def _needs_brackets(self, expr):
  233. """
  234. Returns True if the expression needs to be wrapped in brackets when
  235. printed, False otherwise. For example: a + b => True; a => False;
  236. 10 => False; -10 => True.
  237. """
  238. return not ((expr.is_Integer and expr.is_nonnegative)
  239. or (expr.is_Atom and (expr is not S.NegativeOne
  240. and expr.is_Rational is False)))
  241. def _needs_function_brackets(self, expr):
  242. """
  243. Returns True if the expression needs to be wrapped in brackets when
  244. passed as an argument to a function, False otherwise. This is a more
  245. liberal version of _needs_brackets, in that many expressions which need
  246. to be wrapped in brackets when added/subtracted/raised to a power do
  247. not need them when passed to a function. Such an example is a*b.
  248. """
  249. if not self._needs_brackets(expr):
  250. return False
  251. else:
  252. # Muls of the form a*b*c... can be folded
  253. if expr.is_Mul and not self._mul_is_clean(expr):
  254. return True
  255. # Pows which don't need brackets can be folded
  256. elif expr.is_Pow and not self._pow_is_clean(expr):
  257. return True
  258. # Add and Function always need brackets
  259. elif expr.is_Add or expr.is_Function:
  260. return True
  261. else:
  262. return False
  263. def _needs_mul_brackets(self, expr, first=False, last=False):
  264. """
  265. Returns True if the expression needs to be wrapped in brackets when
  266. printed as part of a Mul, False otherwise. This is True for Add,
  267. but also for some container objects that would not need brackets
  268. when appearing last in a Mul, e.g. an Integral. ``last=True``
  269. specifies that this expr is the last to appear in a Mul.
  270. ``first=True`` specifies that this expr is the first to appear in
  271. a Mul.
  272. """
  273. from sympy.concrete.products import Product
  274. from sympy.concrete.summations import Sum
  275. from sympy.integrals.integrals import Integral
  276. if expr.is_Mul:
  277. if not first and expr.could_extract_minus_sign():
  278. return True
  279. elif precedence_traditional(expr) < PRECEDENCE["Mul"]:
  280. return True
  281. elif expr.is_Relational:
  282. return True
  283. if expr.is_Piecewise:
  284. return True
  285. if any(expr.has(x) for x in (Mod,)):
  286. return True
  287. if (not last and
  288. any(expr.has(x) for x in (Integral, Product, Sum))):
  289. return True
  290. return False
  291. def _needs_add_brackets(self, expr):
  292. """
  293. Returns True if the expression needs to be wrapped in brackets when
  294. printed as part of an Add, False otherwise. This is False for most
  295. things.
  296. """
  297. if expr.is_Relational:
  298. return True
  299. if any(expr.has(x) for x in (Mod,)):
  300. return True
  301. if expr.is_Add:
  302. return True
  303. return False
  304. def _mul_is_clean(self, expr):
  305. for arg in expr.args:
  306. if arg.is_Function:
  307. return False
  308. return True
  309. def _pow_is_clean(self, expr):
  310. return not self._needs_brackets(expr.base)
  311. def _do_exponent(self, expr, exp):
  312. if exp is not None:
  313. return r"\left(%s\right)^{%s}" % (expr, exp)
  314. else:
  315. return expr
  316. def _print_Basic(self, expr):
  317. name = self._deal_with_super_sub(expr.__class__.__name__)
  318. if expr.args:
  319. ls = [self._print(o) for o in expr.args]
  320. s = r"\operatorname{{{}}}\left({}\right)"
  321. return s.format(name, ", ".join(ls))
  322. else:
  323. return r"\text{{{}}}".format(name)
  324. def _print_bool(self, e):
  325. return r"\text{%s}" % e
  326. _print_BooleanTrue = _print_bool
  327. _print_BooleanFalse = _print_bool
  328. def _print_NoneType(self, e):
  329. return r"\text{%s}" % e
  330. def _print_Add(self, expr, order=None):
  331. terms = self._as_ordered_terms(expr, order=order)
  332. tex = ""
  333. for i, term in enumerate(terms):
  334. if i == 0:
  335. pass
  336. elif term.could_extract_minus_sign():
  337. tex += " - "
  338. term = -term
  339. else:
  340. tex += " + "
  341. term_tex = self._print(term)
  342. if self._needs_add_brackets(term):
  343. term_tex = r"\left(%s\right)" % term_tex
  344. tex += term_tex
  345. return tex
  346. def _print_Cycle(self, expr):
  347. from sympy.combinatorics.permutations import Permutation
  348. if expr.size == 0:
  349. return r"\left( \right)"
  350. expr = Permutation(expr)
  351. expr_perm = expr.cyclic_form
  352. siz = expr.size
  353. if expr.array_form[-1] == siz - 1:
  354. expr_perm = expr_perm + [[siz - 1]]
  355. term_tex = ''
  356. for i in expr_perm:
  357. term_tex += str(i).replace(',', r"\;")
  358. term_tex = term_tex.replace('[', r"\left( ")
  359. term_tex = term_tex.replace(']', r"\right)")
  360. return term_tex
  361. def _print_Permutation(self, expr):
  362. from sympy.combinatorics.permutations import Permutation
  363. from sympy.utilities.exceptions import sympy_deprecation_warning
  364. perm_cyclic = Permutation.print_cyclic
  365. if perm_cyclic is not None:
  366. sympy_deprecation_warning(
  367. f"""
  368. Setting Permutation.print_cyclic is deprecated. Instead use
  369. init_printing(perm_cyclic={perm_cyclic}).
  370. """,
  371. deprecated_since_version="1.6",
  372. active_deprecations_target="deprecated-permutation-print_cyclic",
  373. stacklevel=8,
  374. )
  375. else:
  376. perm_cyclic = self._settings.get("perm_cyclic", True)
  377. if perm_cyclic:
  378. return self._print_Cycle(expr)
  379. if expr.size == 0:
  380. return r"\left( \right)"
  381. lower = [self._print(arg) for arg in expr.array_form]
  382. upper = [self._print(arg) for arg in range(len(lower))]
  383. row1 = " & ".join(upper)
  384. row2 = " & ".join(lower)
  385. mat = r" \\ ".join((row1, row2))
  386. return r"\begin{pmatrix} %s \end{pmatrix}" % mat
  387. def _print_AppliedPermutation(self, expr):
  388. perm, var = expr.args
  389. return r"\sigma_{%s}(%s)" % (self._print(perm), self._print(var))
  390. def _print_Float(self, expr):
  391. # Based off of that in StrPrinter
  392. dps = prec_to_dps(expr._prec)
  393. strip = False if self._settings['full_prec'] else True
  394. low = self._settings["min"] if "min" in self._settings else None
  395. high = self._settings["max"] if "max" in self._settings else None
  396. str_real = mlib_to_str(expr._mpf_, dps, strip_zeros=strip, min_fixed=low, max_fixed=high)
  397. # Must always have a mul symbol (as 2.5 10^{20} just looks odd)
  398. # thus we use the number separator
  399. separator = self._settings['mul_symbol_latex_numbers']
  400. if 'e' in str_real:
  401. (mant, exp) = str_real.split('e')
  402. if exp[0] == '+':
  403. exp = exp[1:]
  404. if self._settings['decimal_separator'] == 'comma':
  405. mant = mant.replace('.','{,}')
  406. return r"%s%s10^{%s}" % (mant, separator, exp)
  407. elif str_real == "+inf":
  408. return r"\infty"
  409. elif str_real == "-inf":
  410. return r"- \infty"
  411. else:
  412. if self._settings['decimal_separator'] == 'comma':
  413. str_real = str_real.replace('.','{,}')
  414. return str_real
  415. def _print_Cross(self, expr):
  416. vec1 = expr._expr1
  417. vec2 = expr._expr2
  418. return r"%s \times %s" % (self.parenthesize(vec1, PRECEDENCE['Mul']),
  419. self.parenthesize(vec2, PRECEDENCE['Mul']))
  420. def _print_Curl(self, expr):
  421. vec = expr._expr
  422. return r"\nabla\times %s" % self.parenthesize(vec, PRECEDENCE['Mul'])
  423. def _print_Divergence(self, expr):
  424. vec = expr._expr
  425. return r"\nabla\cdot %s" % self.parenthesize(vec, PRECEDENCE['Mul'])
  426. def _print_Dot(self, expr):
  427. vec1 = expr._expr1
  428. vec2 = expr._expr2
  429. return r"%s \cdot %s" % (self.parenthesize(vec1, PRECEDENCE['Mul']),
  430. self.parenthesize(vec2, PRECEDENCE['Mul']))
  431. def _print_Gradient(self, expr):
  432. func = expr._expr
  433. return r"\nabla %s" % self.parenthesize(func, PRECEDENCE['Mul'])
  434. def _print_Laplacian(self, expr):
  435. func = expr._expr
  436. return r"\triangle %s" % self.parenthesize(func, PRECEDENCE['Mul'])
  437. def _print_Mul(self, expr):
  438. from sympy.physics.units import Quantity
  439. from sympy.simplify import fraction
  440. separator = self._settings['mul_symbol_latex']
  441. numbersep = self._settings['mul_symbol_latex_numbers']
  442. def convert(expr):
  443. if not expr.is_Mul:
  444. return str(self._print(expr))
  445. else:
  446. if self.order not in ('old', 'none'):
  447. args = expr.as_ordered_factors()
  448. else:
  449. args = list(expr.args)
  450. # If quantities are present append them at the back
  451. args = sorted(args, key=lambda x: isinstance(x, Quantity) or
  452. (isinstance(x, Pow) and
  453. isinstance(x.base, Quantity)))
  454. return convert_args(args)
  455. def convert_args(args):
  456. _tex = last_term_tex = ""
  457. for i, term in enumerate(args):
  458. term_tex = self._print(term)
  459. if self._needs_mul_brackets(term, first=(i == 0),
  460. last=(i == len(args) - 1)):
  461. term_tex = r"\left(%s\right)" % term_tex
  462. if _between_two_numbers_p[0].search(last_term_tex) and \
  463. _between_two_numbers_p[1].match(str(term)):
  464. # between two numbers
  465. _tex += numbersep
  466. elif _tex:
  467. _tex += separator
  468. _tex += term_tex
  469. last_term_tex = term_tex
  470. return _tex
  471. # Check for unevaluated Mul. In this case we need to make sure the
  472. # identities are visible, multiple Rational factors are not combined
  473. # etc so we display in a straight-forward form that fully preserves all
  474. # args and their order.
  475. # XXX: _print_Pow calls this routine with instances of Pow...
  476. if isinstance(expr, Mul):
  477. args = expr.args
  478. if args[0] is S.One or any(isinstance(arg, Number) for arg in args[1:]):
  479. return convert_args(args)
  480. include_parens = False
  481. if expr.could_extract_minus_sign():
  482. expr = -expr
  483. tex = "- "
  484. if expr.is_Add:
  485. tex += "("
  486. include_parens = True
  487. else:
  488. tex = ""
  489. numer, denom = fraction(expr, exact=True)
  490. if denom is S.One and Pow(1, -1, evaluate=False) not in expr.args:
  491. # use the original expression here, since fraction() may have
  492. # altered it when producing numer and denom
  493. tex += convert(expr)
  494. else:
  495. snumer = convert(numer)
  496. sdenom = convert(denom)
  497. ldenom = len(sdenom.split())
  498. ratio = self._settings['long_frac_ratio']
  499. if self._settings['fold_short_frac'] and ldenom <= 2 and \
  500. "^" not in sdenom:
  501. # handle short fractions
  502. if self._needs_mul_brackets(numer, last=False):
  503. tex += r"\left(%s\right) / %s" % (snumer, sdenom)
  504. else:
  505. tex += r"%s / %s" % (snumer, sdenom)
  506. elif ratio is not None and \
  507. len(snumer.split()) > ratio*ldenom:
  508. # handle long fractions
  509. if self._needs_mul_brackets(numer, last=True):
  510. tex += r"\frac{1}{%s}%s\left(%s\right)" \
  511. % (sdenom, separator, snumer)
  512. elif numer.is_Mul:
  513. # split a long numerator
  514. a = S.One
  515. b = S.One
  516. for x in numer.args:
  517. if self._needs_mul_brackets(x, last=False) or \
  518. len(convert(a*x).split()) > ratio*ldenom or \
  519. (b.is_commutative is x.is_commutative is False):
  520. b *= x
  521. else:
  522. a *= x
  523. if self._needs_mul_brackets(b, last=True):
  524. tex += r"\frac{%s}{%s}%s\left(%s\right)" \
  525. % (convert(a), sdenom, separator, convert(b))
  526. else:
  527. tex += r"\frac{%s}{%s}%s%s" \
  528. % (convert(a), sdenom, separator, convert(b))
  529. else:
  530. tex += r"\frac{1}{%s}%s%s" % (sdenom, separator, snumer)
  531. else:
  532. tex += r"\frac{%s}{%s}" % (snumer, sdenom)
  533. if include_parens:
  534. tex += ")"
  535. return tex
  536. def _print_AlgebraicNumber(self, expr):
  537. if expr.is_aliased:
  538. return self._print(expr.as_poly().as_expr())
  539. else:
  540. return self._print(expr.as_expr())
  541. def _print_Pow(self, expr):
  542. # Treat x**Rational(1,n) as special case
  543. if expr.exp.is_Rational and abs(expr.exp.p) == 1 and expr.exp.q != 1 \
  544. and self._settings['root_notation']:
  545. base = self._print(expr.base)
  546. expq = expr.exp.q
  547. if expq == 2:
  548. tex = r"\sqrt{%s}" % base
  549. elif self._settings['itex']:
  550. tex = r"\root{%d}{%s}" % (expq, base)
  551. else:
  552. tex = r"\sqrt[%d]{%s}" % (expq, base)
  553. if expr.exp.is_negative:
  554. return r"\frac{1}{%s}" % tex
  555. else:
  556. return tex
  557. elif self._settings['fold_frac_powers'] \
  558. and expr.exp.is_Rational \
  559. and expr.exp.q != 1:
  560. base = self.parenthesize(expr.base, PRECEDENCE['Pow'])
  561. p, q = expr.exp.p, expr.exp.q
  562. # issue #12886: add parentheses for superscripts raised to powers
  563. if expr.base.is_Symbol:
  564. base = self.parenthesize_super(base)
  565. if expr.base.is_Function:
  566. return self._print(expr.base, exp="%s/%s" % (p, q))
  567. return r"%s^{%s/%s}" % (base, p, q)
  568. elif expr.exp.is_Rational and expr.exp.is_negative and \
  569. expr.base.is_commutative:
  570. # special case for 1^(-x), issue 9216
  571. if expr.base == 1:
  572. return r"%s^{%s}" % (expr.base, expr.exp)
  573. # special case for (1/x)^(-y) and (-1/-x)^(-y), issue 20252
  574. if expr.base.is_Rational and \
  575. expr.base.p*expr.base.q == abs(expr.base.q):
  576. if expr.exp == -1:
  577. return r"\frac{1}{\frac{%s}{%s}}" % (expr.base.p, expr.base.q)
  578. else:
  579. return r"\frac{1}{(\frac{%s}{%s})^{%s}}" % (expr.base.p, expr.base.q, abs(expr.exp))
  580. # things like 1/x
  581. return self._print_Mul(expr)
  582. else:
  583. if expr.base.is_Function:
  584. return self._print(expr.base, exp=self._print(expr.exp))
  585. else:
  586. tex = r"%s^{%s}"
  587. return self._helper_print_standard_power(expr, tex)
  588. def _helper_print_standard_power(self, expr, template):
  589. exp = self._print(expr.exp)
  590. # issue #12886: add parentheses around superscripts raised
  591. # to powers
  592. base = self.parenthesize(expr.base, PRECEDENCE['Pow'])
  593. if expr.base.is_Symbol:
  594. base = self.parenthesize_super(base)
  595. elif (isinstance(expr.base, Derivative)
  596. and base.startswith(r'\left(')
  597. and re.match(r'\\left\(\\d?d?dot', base)
  598. and base.endswith(r'\right)')):
  599. # don't use parentheses around dotted derivative
  600. base = base[6: -7] # remove outermost added parens
  601. return template % (base, exp)
  602. def _print_UnevaluatedExpr(self, expr):
  603. return self._print(expr.args[0])
  604. def _print_Sum(self, expr):
  605. if len(expr.limits) == 1:
  606. tex = r"\sum_{%s=%s}^{%s} " % \
  607. tuple([self._print(i) for i in expr.limits[0]])
  608. else:
  609. def _format_ineq(l):
  610. return r"%s \leq %s \leq %s" % \
  611. tuple([self._print(s) for s in (l[1], l[0], l[2])])
  612. tex = r"\sum_{\substack{%s}} " % \
  613. str.join('\\\\', [_format_ineq(l) for l in expr.limits])
  614. if isinstance(expr.function, Add):
  615. tex += r"\left(%s\right)" % self._print(expr.function)
  616. else:
  617. tex += self._print(expr.function)
  618. return tex
  619. def _print_Product(self, expr):
  620. if len(expr.limits) == 1:
  621. tex = r"\prod_{%s=%s}^{%s} " % \
  622. tuple([self._print(i) for i in expr.limits[0]])
  623. else:
  624. def _format_ineq(l):
  625. return r"%s \leq %s \leq %s" % \
  626. tuple([self._print(s) for s in (l[1], l[0], l[2])])
  627. tex = r"\prod_{\substack{%s}} " % \
  628. str.join('\\\\', [_format_ineq(l) for l in expr.limits])
  629. if isinstance(expr.function, Add):
  630. tex += r"\left(%s\right)" % self._print(expr.function)
  631. else:
  632. tex += self._print(expr.function)
  633. return tex
  634. def _print_BasisDependent(self, expr):
  635. from sympy.vector import Vector
  636. o1 = []
  637. if expr == expr.zero:
  638. return expr.zero._latex_form
  639. if isinstance(expr, Vector):
  640. items = expr.separate().items()
  641. else:
  642. items = [(0, expr)]
  643. for system, vect in items:
  644. inneritems = list(vect.components.items())
  645. inneritems.sort(key=lambda x: x[0].__str__())
  646. for k, v in inneritems:
  647. if v == 1:
  648. o1.append(' + ' + k._latex_form)
  649. elif v == -1:
  650. o1.append(' - ' + k._latex_form)
  651. else:
  652. arg_str = '(' + self._print(v) + ')'
  653. o1.append(' + ' + arg_str + k._latex_form)
  654. outstr = (''.join(o1))
  655. if outstr[1] != '-':
  656. outstr = outstr[3:]
  657. else:
  658. outstr = outstr[1:]
  659. return outstr
  660. def _print_Indexed(self, expr):
  661. tex_base = self._print(expr.base)
  662. tex = '{'+tex_base+'}'+'_{%s}' % ','.join(
  663. map(self._print, expr.indices))
  664. return tex
  665. def _print_IndexedBase(self, expr):
  666. return self._print(expr.label)
  667. def _print_Idx(self, expr):
  668. label = self._print(expr.label)
  669. if expr.upper is not None:
  670. upper = self._print(expr.upper)
  671. if expr.lower is not None:
  672. lower = self._print(expr.lower)
  673. else:
  674. lower = self._print(S.Zero)
  675. interval = '{lower}\\mathrel{{..}}\\nobreak{upper}'.format(
  676. lower = lower, upper = upper)
  677. return '{{{label}}}_{{{interval}}}'.format(
  678. label = label, interval = interval)
  679. #if no bounds are defined this just prints the label
  680. return label
  681. def _print_Derivative(self, expr):
  682. if requires_partial(expr.expr):
  683. diff_symbol = r'\partial'
  684. else:
  685. diff_symbol = r'd'
  686. tex = ""
  687. dim = 0
  688. for x, num in reversed(expr.variable_count):
  689. dim += num
  690. if num == 1:
  691. tex += r"%s %s" % (diff_symbol, self._print(x))
  692. else:
  693. tex += r"%s %s^{%s}" % (diff_symbol,
  694. self.parenthesize_super(self._print(x)),
  695. self._print(num))
  696. if dim == 1:
  697. tex = r"\frac{%s}{%s}" % (diff_symbol, tex)
  698. else:
  699. tex = r"\frac{%s^{%s}}{%s}" % (diff_symbol, self._print(dim), tex)
  700. if any(i.could_extract_minus_sign() for i in expr.args):
  701. return r"%s %s" % (tex, self.parenthesize(expr.expr,
  702. PRECEDENCE["Mul"],
  703. is_neg=True,
  704. strict=True))
  705. return r"%s %s" % (tex, self.parenthesize(expr.expr,
  706. PRECEDENCE["Mul"],
  707. is_neg=False,
  708. strict=True))
  709. def _print_Subs(self, subs):
  710. expr, old, new = subs.args
  711. latex_expr = self._print(expr)
  712. latex_old = (self._print(e) for e in old)
  713. latex_new = (self._print(e) for e in new)
  714. latex_subs = r'\\ '.join(
  715. e[0] + '=' + e[1] for e in zip(latex_old, latex_new))
  716. return r'\left. %s \right|_{\substack{ %s }}' % (latex_expr,
  717. latex_subs)
  718. def _print_Integral(self, expr):
  719. tex, symbols = "", []
  720. # Only up to \iiiint exists
  721. if len(expr.limits) <= 4 and all(len(lim) == 1 for lim in expr.limits):
  722. # Use len(expr.limits)-1 so that syntax highlighters don't think
  723. # \" is an escaped quote
  724. tex = r"\i" + "i"*(len(expr.limits) - 1) + "nt"
  725. symbols = [r"\, d%s" % self._print(symbol[0])
  726. for symbol in expr.limits]
  727. else:
  728. for lim in reversed(expr.limits):
  729. symbol = lim[0]
  730. tex += r"\int"
  731. if len(lim) > 1:
  732. if self._settings['mode'] != 'inline' \
  733. and not self._settings['itex']:
  734. tex += r"\limits"
  735. if len(lim) == 3:
  736. tex += "_{%s}^{%s}" % (self._print(lim[1]),
  737. self._print(lim[2]))
  738. if len(lim) == 2:
  739. tex += "^{%s}" % (self._print(lim[1]))
  740. symbols.insert(0, r"\, d%s" % self._print(symbol))
  741. return r"%s %s%s" % (tex, self.parenthesize(expr.function,
  742. PRECEDENCE["Mul"],
  743. is_neg=any(i.could_extract_minus_sign() for i in expr.args),
  744. strict=True),
  745. "".join(symbols))
  746. def _print_Limit(self, expr):
  747. e, z, z0, dir = expr.args
  748. tex = r"\lim_{%s \to " % self._print(z)
  749. if str(dir) == '+-' or z0 in (S.Infinity, S.NegativeInfinity):
  750. tex += r"%s}" % self._print(z0)
  751. else:
  752. tex += r"%s^%s}" % (self._print(z0), self._print(dir))
  753. if isinstance(e, AssocOp):
  754. return r"%s\left(%s\right)" % (tex, self._print(e))
  755. else:
  756. return r"%s %s" % (tex, self._print(e))
  757. def _hprint_Function(self, func):
  758. r'''
  759. Logic to decide how to render a function to latex
  760. - if it is a recognized latex name, use the appropriate latex command
  761. - if it is a single letter, just use that letter
  762. - if it is a longer name, then put \operatorname{} around it and be
  763. mindful of undercores in the name
  764. '''
  765. func = self._deal_with_super_sub(func)
  766. if func in accepted_latex_functions:
  767. name = r"\%s" % func
  768. elif len(func) == 1 or func.startswith('\\'):
  769. name = func
  770. else:
  771. name = r"\operatorname{%s}" % func
  772. return name
  773. def _print_Function(self, expr, exp=None):
  774. r'''
  775. Render functions to LaTeX, handling functions that LaTeX knows about
  776. e.g., sin, cos, ... by using the proper LaTeX command (\sin, \cos, ...).
  777. For single-letter function names, render them as regular LaTeX math
  778. symbols. For multi-letter function names that LaTeX does not know
  779. about, (e.g., Li, sech) use \operatorname{} so that the function name
  780. is rendered in Roman font and LaTeX handles spacing properly.
  781. expr is the expression involving the function
  782. exp is an exponent
  783. '''
  784. func = expr.func.__name__
  785. if hasattr(self, '_print_' + func) and \
  786. not isinstance(expr, AppliedUndef):
  787. return getattr(self, '_print_' + func)(expr, exp)
  788. else:
  789. args = [str(self._print(arg)) for arg in expr.args]
  790. # How inverse trig functions should be displayed, formats are:
  791. # abbreviated: asin, full: arcsin, power: sin^-1
  792. inv_trig_style = self._settings['inv_trig_style']
  793. # If we are dealing with a power-style inverse trig function
  794. inv_trig_power_case = False
  795. # If it is applicable to fold the argument brackets
  796. can_fold_brackets = self._settings['fold_func_brackets'] and \
  797. len(args) == 1 and \
  798. not self._needs_function_brackets(expr.args[0])
  799. inv_trig_table = [
  800. "asin", "acos", "atan",
  801. "acsc", "asec", "acot",
  802. "asinh", "acosh", "atanh",
  803. "acsch", "asech", "acoth",
  804. ]
  805. # If the function is an inverse trig function, handle the style
  806. if func in inv_trig_table:
  807. if inv_trig_style == "abbreviated":
  808. pass
  809. elif inv_trig_style == "full":
  810. func = ("ar" if func[-1] == "h" else "arc") + func[1:]
  811. elif inv_trig_style == "power":
  812. func = func[1:]
  813. inv_trig_power_case = True
  814. # Can never fold brackets if we're raised to a power
  815. if exp is not None:
  816. can_fold_brackets = False
  817. if inv_trig_power_case:
  818. if func in accepted_latex_functions:
  819. name = r"\%s^{-1}" % func
  820. else:
  821. name = r"\operatorname{%s}^{-1}" % func
  822. elif exp is not None:
  823. func_tex = self._hprint_Function(func)
  824. func_tex = self.parenthesize_super(func_tex)
  825. name = r'%s^{%s}' % (func_tex, exp)
  826. else:
  827. name = self._hprint_Function(func)
  828. if can_fold_brackets:
  829. if func in accepted_latex_functions:
  830. # Wrap argument safely to avoid parse-time conflicts
  831. # with the function name itself
  832. name += r" {%s}"
  833. else:
  834. name += r"%s"
  835. else:
  836. name += r"{\left(%s \right)}"
  837. if inv_trig_power_case and exp is not None:
  838. name += r"^{%s}" % exp
  839. return name % ",".join(args)
  840. def _print_UndefinedFunction(self, expr):
  841. return self._hprint_Function(str(expr))
  842. def _print_ElementwiseApplyFunction(self, expr):
  843. return r"{%s}_{\circ}\left({%s}\right)" % (
  844. self._print(expr.function),
  845. self._print(expr.expr),
  846. )
  847. @property
  848. def _special_function_classes(self):
  849. from sympy.functions.special.tensor_functions import KroneckerDelta
  850. from sympy.functions.special.gamma_functions import gamma, lowergamma
  851. from sympy.functions.special.beta_functions import beta
  852. from sympy.functions.special.delta_functions import DiracDelta
  853. from sympy.functions.special.error_functions import Chi
  854. return {KroneckerDelta: r'\delta',
  855. gamma: r'\Gamma',
  856. lowergamma: r'\gamma',
  857. beta: r'\operatorname{B}',
  858. DiracDelta: r'\delta',
  859. Chi: r'\operatorname{Chi}'}
  860. def _print_FunctionClass(self, expr):
  861. for cls in self._special_function_classes:
  862. if issubclass(expr, cls) and expr.__name__ == cls.__name__:
  863. return self._special_function_classes[cls]
  864. return self._hprint_Function(str(expr))
  865. def _print_Lambda(self, expr):
  866. symbols, expr = expr.args
  867. if len(symbols) == 1:
  868. symbols = self._print(symbols[0])
  869. else:
  870. symbols = self._print(tuple(symbols))
  871. tex = r"\left( %s \mapsto %s \right)" % (symbols, self._print(expr))
  872. return tex
  873. def _print_IdentityFunction(self, expr):
  874. return r"\left( x \mapsto x \right)"
  875. def _hprint_variadic_function(self, expr, exp=None):
  876. args = sorted(expr.args, key=default_sort_key)
  877. texargs = [r"%s" % self._print(symbol) for symbol in args]
  878. tex = r"\%s\left(%s\right)" % (str(expr.func).lower(),
  879. ", ".join(texargs))
  880. if exp is not None:
  881. return r"%s^{%s}" % (tex, exp)
  882. else:
  883. return tex
  884. _print_Min = _print_Max = _hprint_variadic_function
  885. def _print_floor(self, expr, exp=None):
  886. tex = r"\left\lfloor{%s}\right\rfloor" % self._print(expr.args[0])
  887. if exp is not None:
  888. return r"%s^{%s}" % (tex, exp)
  889. else:
  890. return tex
  891. def _print_ceiling(self, expr, exp=None):
  892. tex = r"\left\lceil{%s}\right\rceil" % self._print(expr.args[0])
  893. if exp is not None:
  894. return r"%s^{%s}" % (tex, exp)
  895. else:
  896. return tex
  897. def _print_log(self, expr, exp=None):
  898. if not self._settings["ln_notation"]:
  899. tex = r"\log{\left(%s \right)}" % self._print(expr.args[0])
  900. else:
  901. tex = r"\ln{\left(%s \right)}" % self._print(expr.args[0])
  902. if exp is not None:
  903. return r"%s^{%s}" % (tex, exp)
  904. else:
  905. return tex
  906. def _print_Abs(self, expr, exp=None):
  907. tex = r"\left|{%s}\right|" % self._print(expr.args[0])
  908. if exp is not None:
  909. return r"%s^{%s}" % (tex, exp)
  910. else:
  911. return tex
  912. _print_Determinant = _print_Abs
  913. def _print_re(self, expr, exp=None):
  914. if self._settings['gothic_re_im']:
  915. tex = r"\Re{%s}" % self.parenthesize(expr.args[0], PRECEDENCE['Atom'])
  916. else:
  917. tex = r"\operatorname{{re}}{{{}}}".format(self.parenthesize(expr.args[0], PRECEDENCE['Atom']))
  918. return self._do_exponent(tex, exp)
  919. def _print_im(self, expr, exp=None):
  920. if self._settings['gothic_re_im']:
  921. tex = r"\Im{%s}" % self.parenthesize(expr.args[0], PRECEDENCE['Atom'])
  922. else:
  923. tex = r"\operatorname{{im}}{{{}}}".format(self.parenthesize(expr.args[0], PRECEDENCE['Atom']))
  924. return self._do_exponent(tex, exp)
  925. def _print_Not(self, e):
  926. from sympy.logic.boolalg import (Equivalent, Implies)
  927. if isinstance(e.args[0], Equivalent):
  928. return self._print_Equivalent(e.args[0], r"\not\Leftrightarrow")
  929. if isinstance(e.args[0], Implies):
  930. return self._print_Implies(e.args[0], r"\not\Rightarrow")
  931. if (e.args[0].is_Boolean):
  932. return r"\neg \left(%s\right)" % self._print(e.args[0])
  933. else:
  934. return r"\neg %s" % self._print(e.args[0])
  935. def _print_LogOp(self, args, char):
  936. arg = args[0]
  937. if arg.is_Boolean and not arg.is_Not:
  938. tex = r"\left(%s\right)" % self._print(arg)
  939. else:
  940. tex = r"%s" % self._print(arg)
  941. for arg in args[1:]:
  942. if arg.is_Boolean and not arg.is_Not:
  943. tex += r" %s \left(%s\right)" % (char, self._print(arg))
  944. else:
  945. tex += r" %s %s" % (char, self._print(arg))
  946. return tex
  947. def _print_And(self, e):
  948. args = sorted(e.args, key=default_sort_key)
  949. return self._print_LogOp(args, r"\wedge")
  950. def _print_Or(self, e):
  951. args = sorted(e.args, key=default_sort_key)
  952. return self._print_LogOp(args, r"\vee")
  953. def _print_Xor(self, e):
  954. args = sorted(e.args, key=default_sort_key)
  955. return self._print_LogOp(args, r"\veebar")
  956. def _print_Implies(self, e, altchar=None):
  957. return self._print_LogOp(e.args, altchar or r"\Rightarrow")
  958. def _print_Equivalent(self, e, altchar=None):
  959. args = sorted(e.args, key=default_sort_key)
  960. return self._print_LogOp(args, altchar or r"\Leftrightarrow")
  961. def _print_conjugate(self, expr, exp=None):
  962. tex = r"\overline{%s}" % self._print(expr.args[0])
  963. if exp is not None:
  964. return r"%s^{%s}" % (tex, exp)
  965. else:
  966. return tex
  967. def _print_polar_lift(self, expr, exp=None):
  968. func = r"\operatorname{polar\_lift}"
  969. arg = r"{\left(%s \right)}" % self._print(expr.args[0])
  970. if exp is not None:
  971. return r"%s^{%s}%s" % (func, exp, arg)
  972. else:
  973. return r"%s%s" % (func, arg)
  974. def _print_ExpBase(self, expr, exp=None):
  975. # TODO should exp_polar be printed differently?
  976. # what about exp_polar(0), exp_polar(1)?
  977. tex = r"e^{%s}" % self._print(expr.args[0])
  978. return self._do_exponent(tex, exp)
  979. def _print_Exp1(self, expr, exp=None):
  980. return "e"
  981. def _print_elliptic_k(self, expr, exp=None):
  982. tex = r"\left(%s\right)" % self._print(expr.args[0])
  983. if exp is not None:
  984. return r"K^{%s}%s" % (exp, tex)
  985. else:
  986. return r"K%s" % tex
  987. def _print_elliptic_f(self, expr, exp=None):
  988. tex = r"\left(%s\middle| %s\right)" % \
  989. (self._print(expr.args[0]), self._print(expr.args[1]))
  990. if exp is not None:
  991. return r"F^{%s}%s" % (exp, tex)
  992. else:
  993. return r"F%s" % tex
  994. def _print_elliptic_e(self, expr, exp=None):
  995. if len(expr.args) == 2:
  996. tex = r"\left(%s\middle| %s\right)" % \
  997. (self._print(expr.args[0]), self._print(expr.args[1]))
  998. else:
  999. tex = r"\left(%s\right)" % self._print(expr.args[0])
  1000. if exp is not None:
  1001. return r"E^{%s}%s" % (exp, tex)
  1002. else:
  1003. return r"E%s" % tex
  1004. def _print_elliptic_pi(self, expr, exp=None):
  1005. if len(expr.args) == 3:
  1006. tex = r"\left(%s; %s\middle| %s\right)" % \
  1007. (self._print(expr.args[0]), self._print(expr.args[1]),
  1008. self._print(expr.args[2]))
  1009. else:
  1010. tex = r"\left(%s\middle| %s\right)" % \
  1011. (self._print(expr.args[0]), self._print(expr.args[1]))
  1012. if exp is not None:
  1013. return r"\Pi^{%s}%s" % (exp, tex)
  1014. else:
  1015. return r"\Pi%s" % tex
  1016. def _print_beta(self, expr, exp=None):
  1017. tex = r"\left(%s, %s\right)" % (self._print(expr.args[0]),
  1018. self._print(expr.args[1]))
  1019. if exp is not None:
  1020. return r"\operatorname{B}^{%s}%s" % (exp, tex)
  1021. else:
  1022. return r"\operatorname{B}%s" % tex
  1023. def _print_betainc(self, expr, exp=None, operator='B'):
  1024. largs = [self._print(arg) for arg in expr.args]
  1025. tex = r"\left(%s, %s\right)" % (largs[0], largs[1])
  1026. if exp is not None:
  1027. return r"\operatorname{%s}_{(%s, %s)}^{%s}%s" % (operator, largs[2], largs[3], exp, tex)
  1028. else:
  1029. return r"\operatorname{%s}_{(%s, %s)}%s" % (operator, largs[2], largs[3], tex)
  1030. def _print_betainc_regularized(self, expr, exp=None):
  1031. return self._print_betainc(expr, exp, operator='I')
  1032. def _print_uppergamma(self, expr, exp=None):
  1033. tex = r"\left(%s, %s\right)" % (self._print(expr.args[0]),
  1034. self._print(expr.args[1]))
  1035. if exp is not None:
  1036. return r"\Gamma^{%s}%s" % (exp, tex)
  1037. else:
  1038. return r"\Gamma%s" % tex
  1039. def _print_lowergamma(self, expr, exp=None):
  1040. tex = r"\left(%s, %s\right)" % (self._print(expr.args[0]),
  1041. self._print(expr.args[1]))
  1042. if exp is not None:
  1043. return r"\gamma^{%s}%s" % (exp, tex)
  1044. else:
  1045. return r"\gamma%s" % tex
  1046. def _hprint_one_arg_func(self, expr, exp=None):
  1047. tex = r"\left(%s\right)" % self._print(expr.args[0])
  1048. if exp is not None:
  1049. return r"%s^{%s}%s" % (self._print(expr.func), exp, tex)
  1050. else:
  1051. return r"%s%s" % (self._print(expr.func), tex)
  1052. _print_gamma = _hprint_one_arg_func
  1053. def _print_Chi(self, expr, exp=None):
  1054. tex = r"\left(%s\right)" % self._print(expr.args[0])
  1055. if exp is not None:
  1056. return r"\operatorname{Chi}^{%s}%s" % (exp, tex)
  1057. else:
  1058. return r"\operatorname{Chi}%s" % tex
  1059. def _print_expint(self, expr, exp=None):
  1060. tex = r"\left(%s\right)" % self._print(expr.args[1])
  1061. nu = self._print(expr.args[0])
  1062. if exp is not None:
  1063. return r"\operatorname{E}_{%s}^{%s}%s" % (nu, exp, tex)
  1064. else:
  1065. return r"\operatorname{E}_{%s}%s" % (nu, tex)
  1066. def _print_fresnels(self, expr, exp=None):
  1067. tex = r"\left(%s\right)" % self._print(expr.args[0])
  1068. if exp is not None:
  1069. return r"S^{%s}%s" % (exp, tex)
  1070. else:
  1071. return r"S%s" % tex
  1072. def _print_fresnelc(self, expr, exp=None):
  1073. tex = r"\left(%s\right)" % self._print(expr.args[0])
  1074. if exp is not None:
  1075. return r"C^{%s}%s" % (exp, tex)
  1076. else:
  1077. return r"C%s" % tex
  1078. def _print_subfactorial(self, expr, exp=None):
  1079. tex = r"!%s" % self.parenthesize(expr.args[0], PRECEDENCE["Func"])
  1080. if exp is not None:
  1081. return r"\left(%s\right)^{%s}" % (tex, exp)
  1082. else:
  1083. return tex
  1084. def _print_factorial(self, expr, exp=None):
  1085. tex = r"%s!" % self.parenthesize(expr.args[0], PRECEDENCE["Func"])
  1086. if exp is not None:
  1087. return r"%s^{%s}" % (tex, exp)
  1088. else:
  1089. return tex
  1090. def _print_factorial2(self, expr, exp=None):
  1091. tex = r"%s!!" % self.parenthesize(expr.args[0], PRECEDENCE["Func"])
  1092. if exp is not None:
  1093. return r"%s^{%s}" % (tex, exp)
  1094. else:
  1095. return tex
  1096. def _print_binomial(self, expr, exp=None):
  1097. tex = r"{\binom{%s}{%s}}" % (self._print(expr.args[0]),
  1098. self._print(expr.args[1]))
  1099. if exp is not None:
  1100. return r"%s^{%s}" % (tex, exp)
  1101. else:
  1102. return tex
  1103. def _print_RisingFactorial(self, expr, exp=None):
  1104. n, k = expr.args
  1105. base = r"%s" % self.parenthesize(n, PRECEDENCE['Func'])
  1106. tex = r"{%s}^{\left(%s\right)}" % (base, self._print(k))
  1107. return self._do_exponent(tex, exp)
  1108. def _print_FallingFactorial(self, expr, exp=None):
  1109. n, k = expr.args
  1110. sub = r"%s" % self.parenthesize(k, PRECEDENCE['Func'])
  1111. tex = r"{\left(%s\right)}_{%s}" % (self._print(n), sub)
  1112. return self._do_exponent(tex, exp)
  1113. def _hprint_BesselBase(self, expr, exp, sym):
  1114. tex = r"%s" % (sym)
  1115. need_exp = False
  1116. if exp is not None:
  1117. if tex.find('^') == -1:
  1118. tex = r"%s^{%s}" % (tex, exp)
  1119. else:
  1120. need_exp = True
  1121. tex = r"%s_{%s}\left(%s\right)" % (tex, self._print(expr.order),
  1122. self._print(expr.argument))
  1123. if need_exp:
  1124. tex = self._do_exponent(tex, exp)
  1125. return tex
  1126. def _hprint_vec(self, vec):
  1127. if not vec:
  1128. return ""
  1129. s = ""
  1130. for i in vec[:-1]:
  1131. s += "%s, " % self._print(i)
  1132. s += self._print(vec[-1])
  1133. return s
  1134. def _print_besselj(self, expr, exp=None):
  1135. return self._hprint_BesselBase(expr, exp, 'J')
  1136. def _print_besseli(self, expr, exp=None):
  1137. return self._hprint_BesselBase(expr, exp, 'I')
  1138. def _print_besselk(self, expr, exp=None):
  1139. return self._hprint_BesselBase(expr, exp, 'K')
  1140. def _print_bessely(self, expr, exp=None):
  1141. return self._hprint_BesselBase(expr, exp, 'Y')
  1142. def _print_yn(self, expr, exp=None):
  1143. return self._hprint_BesselBase(expr, exp, 'y')
  1144. def _print_jn(self, expr, exp=None):
  1145. return self._hprint_BesselBase(expr, exp, 'j')
  1146. def _print_hankel1(self, expr, exp=None):
  1147. return self._hprint_BesselBase(expr, exp, 'H^{(1)}')
  1148. def _print_hankel2(self, expr, exp=None):
  1149. return self._hprint_BesselBase(expr, exp, 'H^{(2)}')
  1150. def _print_hn1(self, expr, exp=None):
  1151. return self._hprint_BesselBase(expr, exp, 'h^{(1)}')
  1152. def _print_hn2(self, expr, exp=None):
  1153. return self._hprint_BesselBase(expr, exp, 'h^{(2)}')
  1154. def _hprint_airy(self, expr, exp=None, notation=""):
  1155. tex = r"\left(%s\right)" % self._print(expr.args[0])
  1156. if exp is not None:
  1157. return r"%s^{%s}%s" % (notation, exp, tex)
  1158. else:
  1159. return r"%s%s" % (notation, tex)
  1160. def _hprint_airy_prime(self, expr, exp=None, notation=""):
  1161. tex = r"\left(%s\right)" % self._print(expr.args[0])
  1162. if exp is not None:
  1163. return r"{%s^\prime}^{%s}%s" % (notation, exp, tex)
  1164. else:
  1165. return r"%s^\prime%s" % (notation, tex)
  1166. def _print_airyai(self, expr, exp=None):
  1167. return self._hprint_airy(expr, exp, 'Ai')
  1168. def _print_airybi(self, expr, exp=None):
  1169. return self._hprint_airy(expr, exp, 'Bi')
  1170. def _print_airyaiprime(self, expr, exp=None):
  1171. return self._hprint_airy_prime(expr, exp, 'Ai')
  1172. def _print_airybiprime(self, expr, exp=None):
  1173. return self._hprint_airy_prime(expr, exp, 'Bi')
  1174. def _print_hyper(self, expr, exp=None):
  1175. tex = r"{{}_{%s}F_{%s}\left(\begin{matrix} %s \\ %s \end{matrix}" \
  1176. r"\middle| {%s} \right)}" % \
  1177. (self._print(len(expr.ap)), self._print(len(expr.bq)),
  1178. self._hprint_vec(expr.ap), self._hprint_vec(expr.bq),
  1179. self._print(expr.argument))
  1180. if exp is not None:
  1181. tex = r"{%s}^{%s}" % (tex, exp)
  1182. return tex
  1183. def _print_meijerg(self, expr, exp=None):
  1184. tex = r"{G_{%s, %s}^{%s, %s}\left(\begin{matrix} %s & %s \\" \
  1185. r"%s & %s \end{matrix} \middle| {%s} \right)}" % \
  1186. (self._print(len(expr.ap)), self._print(len(expr.bq)),
  1187. self._print(len(expr.bm)), self._print(len(expr.an)),
  1188. self._hprint_vec(expr.an), self._hprint_vec(expr.aother),
  1189. self._hprint_vec(expr.bm), self._hprint_vec(expr.bother),
  1190. self._print(expr.argument))
  1191. if exp is not None:
  1192. tex = r"{%s}^{%s}" % (tex, exp)
  1193. return tex
  1194. def _print_dirichlet_eta(self, expr, exp=None):
  1195. tex = r"\left(%s\right)" % self._print(expr.args[0])
  1196. if exp is not None:
  1197. return r"\eta^{%s}%s" % (exp, tex)
  1198. return r"\eta%s" % tex
  1199. def _print_zeta(self, expr, exp=None):
  1200. if len(expr.args) == 2:
  1201. tex = r"\left(%s, %s\right)" % tuple(map(self._print, expr.args))
  1202. else:
  1203. tex = r"\left(%s\right)" % self._print(expr.args[0])
  1204. if exp is not None:
  1205. return r"\zeta^{%s}%s" % (exp, tex)
  1206. return r"\zeta%s" % tex
  1207. def _print_stieltjes(self, expr, exp=None):
  1208. if len(expr.args) == 2:
  1209. tex = r"_{%s}\left(%s\right)" % tuple(map(self._print, expr.args))
  1210. else:
  1211. tex = r"_{%s}" % self._print(expr.args[0])
  1212. if exp is not None:
  1213. return r"\gamma%s^{%s}" % (tex, exp)
  1214. return r"\gamma%s" % tex
  1215. def _print_lerchphi(self, expr, exp=None):
  1216. tex = r"\left(%s, %s, %s\right)" % tuple(map(self._print, expr.args))
  1217. if exp is None:
  1218. return r"\Phi%s" % tex
  1219. return r"\Phi^{%s}%s" % (exp, tex)
  1220. def _print_polylog(self, expr, exp=None):
  1221. s, z = map(self._print, expr.args)
  1222. tex = r"\left(%s\right)" % z
  1223. if exp is None:
  1224. return r"\operatorname{Li}_{%s}%s" % (s, tex)
  1225. return r"\operatorname{Li}_{%s}^{%s}%s" % (s, exp, tex)
  1226. def _print_jacobi(self, expr, exp=None):
  1227. n, a, b, x = map(self._print, expr.args)
  1228. tex = r"P_{%s}^{\left(%s,%s\right)}\left(%s\right)" % (n, a, b, x)
  1229. if exp is not None:
  1230. tex = r"\left(" + tex + r"\right)^{%s}" % (exp)
  1231. return tex
  1232. def _print_gegenbauer(self, expr, exp=None):
  1233. n, a, x = map(self._print, expr.args)
  1234. tex = r"C_{%s}^{\left(%s\right)}\left(%s\right)" % (n, a, x)
  1235. if exp is not None:
  1236. tex = r"\left(" + tex + r"\right)^{%s}" % (exp)
  1237. return tex
  1238. def _print_chebyshevt(self, expr, exp=None):
  1239. n, x = map(self._print, expr.args)
  1240. tex = r"T_{%s}\left(%s\right)" % (n, x)
  1241. if exp is not None:
  1242. tex = r"\left(" + tex + r"\right)^{%s}" % (exp)
  1243. return tex
  1244. def _print_chebyshevu(self, expr, exp=None):
  1245. n, x = map(self._print, expr.args)
  1246. tex = r"U_{%s}\left(%s\right)" % (n, x)
  1247. if exp is not None:
  1248. tex = r"\left(" + tex + r"\right)^{%s}" % (exp)
  1249. return tex
  1250. def _print_legendre(self, expr, exp=None):
  1251. n, x = map(self._print, expr.args)
  1252. tex = r"P_{%s}\left(%s\right)" % (n, x)
  1253. if exp is not None:
  1254. tex = r"\left(" + tex + r"\right)^{%s}" % (exp)
  1255. return tex
  1256. def _print_assoc_legendre(self, expr, exp=None):
  1257. n, a, x = map(self._print, expr.args)
  1258. tex = r"P_{%s}^{\left(%s\right)}\left(%s\right)" % (n, a, x)
  1259. if exp is not None:
  1260. tex = r"\left(" + tex + r"\right)^{%s}" % (exp)
  1261. return tex
  1262. def _print_hermite(self, expr, exp=None):
  1263. n, x = map(self._print, expr.args)
  1264. tex = r"H_{%s}\left(%s\right)" % (n, x)
  1265. if exp is not None:
  1266. tex = r"\left(" + tex + r"\right)^{%s}" % (exp)
  1267. return tex
  1268. def _print_laguerre(self, expr, exp=None):
  1269. n, x = map(self._print, expr.args)
  1270. tex = r"L_{%s}\left(%s\right)" % (n, x)
  1271. if exp is not None:
  1272. tex = r"\left(" + tex + r"\right)^{%s}" % (exp)
  1273. return tex
  1274. def _print_assoc_laguerre(self, expr, exp=None):
  1275. n, a, x = map(self._print, expr.args)
  1276. tex = r"L_{%s}^{\left(%s\right)}\left(%s\right)" % (n, a, x)
  1277. if exp is not None:
  1278. tex = r"\left(" + tex + r"\right)^{%s}" % (exp)
  1279. return tex
  1280. def _print_Ynm(self, expr, exp=None):
  1281. n, m, theta, phi = map(self._print, expr.args)
  1282. tex = r"Y_{%s}^{%s}\left(%s,%s\right)" % (n, m, theta, phi)
  1283. if exp is not None:
  1284. tex = r"\left(" + tex + r"\right)^{%s}" % (exp)
  1285. return tex
  1286. def _print_Znm(self, expr, exp=None):
  1287. n, m, theta, phi = map(self._print, expr.args)
  1288. tex = r"Z_{%s}^{%s}\left(%s,%s\right)" % (n, m, theta, phi)
  1289. if exp is not None:
  1290. tex = r"\left(" + tex + r"\right)^{%s}" % (exp)
  1291. return tex
  1292. def __print_mathieu_functions(self, character, args, prime=False, exp=None):
  1293. a, q, z = map(self._print, args)
  1294. sup = r"^{\prime}" if prime else ""
  1295. exp = "" if not exp else "^{%s}" % exp
  1296. return r"%s%s\left(%s, %s, %s\right)%s" % (character, sup, a, q, z, exp)
  1297. def _print_mathieuc(self, expr, exp=None):
  1298. return self.__print_mathieu_functions("C", expr.args, exp=exp)
  1299. def _print_mathieus(self, expr, exp=None):
  1300. return self.__print_mathieu_functions("S", expr.args, exp=exp)
  1301. def _print_mathieucprime(self, expr, exp=None):
  1302. return self.__print_mathieu_functions("C", expr.args, prime=True, exp=exp)
  1303. def _print_mathieusprime(self, expr, exp=None):
  1304. return self.__print_mathieu_functions("S", expr.args, prime=True, exp=exp)
  1305. def _print_Rational(self, expr):
  1306. if expr.q != 1:
  1307. sign = ""
  1308. p = expr.p
  1309. if expr.p < 0:
  1310. sign = "- "
  1311. p = -p
  1312. if self._settings['fold_short_frac']:
  1313. return r"%s%d / %d" % (sign, p, expr.q)
  1314. return r"%s\frac{%d}{%d}" % (sign, p, expr.q)
  1315. else:
  1316. return self._print(expr.p)
  1317. def _print_Order(self, expr):
  1318. s = self._print(expr.expr)
  1319. if expr.point and any(p != S.Zero for p in expr.point) or \
  1320. len(expr.variables) > 1:
  1321. s += '; '
  1322. if len(expr.variables) > 1:
  1323. s += self._print(expr.variables)
  1324. elif expr.variables:
  1325. s += self._print(expr.variables[0])
  1326. s += r'\rightarrow '
  1327. if len(expr.point) > 1:
  1328. s += self._print(expr.point)
  1329. else:
  1330. s += self._print(expr.point[0])
  1331. return r"O\left(%s\right)" % s
  1332. def _print_Symbol(self, expr, style='plain'):
  1333. if expr in self._settings['symbol_names']:
  1334. return self._settings['symbol_names'][expr]
  1335. return self._deal_with_super_sub(expr.name, style=style)
  1336. _print_RandomSymbol = _print_Symbol
  1337. def _deal_with_super_sub(self, string, style='plain'):
  1338. if '{' in string:
  1339. name, supers, subs = string, [], []
  1340. else:
  1341. name, supers, subs = split_super_sub(string)
  1342. name = translate(name)
  1343. supers = [translate(sup) for sup in supers]
  1344. subs = [translate(sub) for sub in subs]
  1345. # apply the style only to the name
  1346. if style == 'bold':
  1347. name = "\\mathbf{{{}}}".format(name)
  1348. # glue all items together:
  1349. if supers:
  1350. name += "^{%s}" % " ".join(supers)
  1351. if subs:
  1352. name += "_{%s}" % " ".join(subs)
  1353. return name
  1354. def _print_Relational(self, expr):
  1355. if self._settings['itex']:
  1356. gt = r"\gt"
  1357. lt = r"\lt"
  1358. else:
  1359. gt = ">"
  1360. lt = "<"
  1361. charmap = {
  1362. "==": "=",
  1363. ">": gt,
  1364. "<": lt,
  1365. ">=": r"\geq",
  1366. "<=": r"\leq",
  1367. "!=": r"\neq",
  1368. }
  1369. return "%s %s %s" % (self._print(expr.lhs),
  1370. charmap[expr.rel_op], self._print(expr.rhs))
  1371. def _print_Piecewise(self, expr):
  1372. ecpairs = [r"%s & \text{for}\: %s" % (self._print(e), self._print(c))
  1373. for e, c in expr.args[:-1]]
  1374. if expr.args[-1].cond == true:
  1375. ecpairs.append(r"%s & \text{otherwise}" %
  1376. self._print(expr.args[-1].expr))
  1377. else:
  1378. ecpairs.append(r"%s & \text{for}\: %s" %
  1379. (self._print(expr.args[-1].expr),
  1380. self._print(expr.args[-1].cond)))
  1381. tex = r"\begin{cases} %s \end{cases}"
  1382. return tex % r" \\".join(ecpairs)
  1383. def _print_MatrixBase(self, expr):
  1384. lines = []
  1385. for line in range(expr.rows): # horrible, should be 'rows'
  1386. lines.append(" & ".join([self._print(i) for i in expr[line, :]]))
  1387. mat_str = self._settings['mat_str']
  1388. if mat_str is None:
  1389. if self._settings['mode'] == 'inline':
  1390. mat_str = 'smallmatrix'
  1391. else:
  1392. if (expr.cols <= 10) is True:
  1393. mat_str = 'matrix'
  1394. else:
  1395. mat_str = 'array'
  1396. out_str = r'\begin{%MATSTR%}%s\end{%MATSTR%}'
  1397. out_str = out_str.replace('%MATSTR%', mat_str)
  1398. if mat_str == 'array':
  1399. out_str = out_str.replace('%s', '{' + 'c'*expr.cols + '}%s')
  1400. if self._settings['mat_delim']:
  1401. left_delim = self._settings['mat_delim']
  1402. right_delim = self._delim_dict[left_delim]
  1403. out_str = r'\left' + left_delim + out_str + \
  1404. r'\right' + right_delim
  1405. return out_str % r"\\".join(lines)
  1406. def _print_MatrixElement(self, expr):
  1407. return self.parenthesize(expr.parent, PRECEDENCE["Atom"], strict=True)\
  1408. + '_{%s, %s}' % (self._print(expr.i), self._print(expr.j))
  1409. def _print_MatrixSlice(self, expr):
  1410. def latexslice(x, dim):
  1411. x = list(x)
  1412. if x[2] == 1:
  1413. del x[2]
  1414. if x[0] == 0:
  1415. x[0] = None
  1416. if x[1] == dim:
  1417. x[1] = None
  1418. return ':'.join(self._print(xi) if xi is not None else '' for xi in x)
  1419. return (self.parenthesize(expr.parent, PRECEDENCE["Atom"], strict=True) + r'\left[' +
  1420. latexslice(expr.rowslice, expr.parent.rows) + ', ' +
  1421. latexslice(expr.colslice, expr.parent.cols) + r'\right]')
  1422. def _print_BlockMatrix(self, expr):
  1423. return self._print(expr.blocks)
  1424. def _print_Transpose(self, expr):
  1425. mat = expr.arg
  1426. from sympy.matrices import MatrixSymbol
  1427. if not isinstance(mat, MatrixSymbol) and mat.is_MatrixExpr:
  1428. return r"\left(%s\right)^{T}" % self._print(mat)
  1429. else:
  1430. s = self.parenthesize(mat, precedence_traditional(expr), True)
  1431. if '^' in s:
  1432. return r"\left(%s\right)^{T}" % s
  1433. else:
  1434. return "%s^{T}" % s
  1435. def _print_Trace(self, expr):
  1436. mat = expr.arg
  1437. return r"\operatorname{tr}\left(%s \right)" % self._print(mat)
  1438. def _print_Adjoint(self, expr):
  1439. mat = expr.arg
  1440. from sympy.matrices import MatrixSymbol
  1441. if not isinstance(mat, MatrixSymbol) and mat.is_MatrixExpr:
  1442. return r"\left(%s\right)^{\dagger}" % self._print(mat)
  1443. else:
  1444. s = self.parenthesize(mat, precedence_traditional(expr), True)
  1445. if '^' in s:
  1446. return r"\left(%s\right)^{\dagger}" % s
  1447. else:
  1448. return r"%s^{\dagger}" % s
  1449. def _print_MatMul(self, expr):
  1450. from sympy.matrices.expressions.matmul import MatMul
  1451. parens = lambda x: self.parenthesize(x, precedence_traditional(expr),
  1452. False)
  1453. args = expr.args
  1454. if isinstance(args[0], Mul):
  1455. args = args[0].as_ordered_factors() + list(args[1:])
  1456. else:
  1457. args = list(args)
  1458. if isinstance(expr, MatMul) and expr.could_extract_minus_sign():
  1459. if args[0] == -1:
  1460. args = args[1:]
  1461. else:
  1462. args[0] = -args[0]
  1463. return '- ' + ' '.join(map(parens, args))
  1464. else:
  1465. return ' '.join(map(parens, args))
  1466. def _print_Mod(self, expr, exp=None):
  1467. if exp is not None:
  1468. return r'\left(%s \bmod %s\right)^{%s}' % \
  1469. (self.parenthesize(expr.args[0], PRECEDENCE['Mul'],
  1470. strict=True),
  1471. self.parenthesize(expr.args[1], PRECEDENCE['Mul'],
  1472. strict=True),
  1473. exp)
  1474. return r'%s \bmod %s' % (self.parenthesize(expr.args[0],
  1475. PRECEDENCE['Mul'],
  1476. strict=True),
  1477. self.parenthesize(expr.args[1],
  1478. PRECEDENCE['Mul'],
  1479. strict=True))
  1480. def _print_HadamardProduct(self, expr):
  1481. args = expr.args
  1482. prec = PRECEDENCE['Pow']
  1483. parens = self.parenthesize
  1484. return r' \circ '.join(
  1485. map(lambda arg: parens(arg, prec, strict=True), args))
  1486. def _print_HadamardPower(self, expr):
  1487. if precedence_traditional(expr.exp) < PRECEDENCE["Mul"]:
  1488. template = r"%s^{\circ \left({%s}\right)}"
  1489. else:
  1490. template = r"%s^{\circ {%s}}"
  1491. return self._helper_print_standard_power(expr, template)
  1492. def _print_KroneckerProduct(self, expr):
  1493. args = expr.args
  1494. prec = PRECEDENCE['Pow']
  1495. parens = self.parenthesize
  1496. return r' \otimes '.join(
  1497. map(lambda arg: parens(arg, prec, strict=True), args))
  1498. def _print_MatPow(self, expr):
  1499. base, exp = expr.base, expr.exp
  1500. from sympy.matrices import MatrixSymbol
  1501. if not isinstance(base, MatrixSymbol):
  1502. return "\\left(%s\\right)^{%s}" % (self._print(base),
  1503. self._print(exp))
  1504. else:
  1505. base_str = self._print(base)
  1506. if '^' in base_str:
  1507. return r"\left(%s\right)^{%s}" % (base_str, self._print(exp))
  1508. else:
  1509. return "%s^{%s}" % (base_str, self._print(exp))
  1510. def _print_MatrixSymbol(self, expr):
  1511. return self._print_Symbol(expr, style=self._settings[
  1512. 'mat_symbol_style'])
  1513. def _print_ZeroMatrix(self, Z):
  1514. return "0" if self._settings[
  1515. 'mat_symbol_style'] == 'plain' else r"\mathbf{0}"
  1516. def _print_OneMatrix(self, O):
  1517. return "1" if self._settings[
  1518. 'mat_symbol_style'] == 'plain' else r"\mathbf{1}"
  1519. def _print_Identity(self, I):
  1520. return r"\mathbb{I}" if self._settings[
  1521. 'mat_symbol_style'] == 'plain' else r"\mathbf{I}"
  1522. def _print_PermutationMatrix(self, P):
  1523. perm_str = self._print(P.args[0])
  1524. return "P_{%s}" % perm_str
  1525. def _print_NDimArray(self, expr):
  1526. if expr.rank() == 0:
  1527. return self._print(expr[()])
  1528. mat_str = self._settings['mat_str']
  1529. if mat_str is None:
  1530. if self._settings['mode'] == 'inline':
  1531. mat_str = 'smallmatrix'
  1532. else:
  1533. if (expr.rank() == 0) or (expr.shape[-1] <= 10):
  1534. mat_str = 'matrix'
  1535. else:
  1536. mat_str = 'array'
  1537. block_str = r'\begin{%MATSTR%}%s\end{%MATSTR%}'
  1538. block_str = block_str.replace('%MATSTR%', mat_str)
  1539. if self._settings['mat_delim']:
  1540. left_delim = self._settings['mat_delim']
  1541. right_delim = self._delim_dict[left_delim]
  1542. block_str = r'\left' + left_delim + block_str + \
  1543. r'\right' + right_delim
  1544. if expr.rank() == 0:
  1545. return block_str % ""
  1546. level_str = [[]] + [[] for i in range(expr.rank())]
  1547. shape_ranges = [list(range(i)) for i in expr.shape]
  1548. for outer_i in itertools.product(*shape_ranges):
  1549. level_str[-1].append(self._print(expr[outer_i]))
  1550. even = True
  1551. for back_outer_i in range(expr.rank()-1, -1, -1):
  1552. if len(level_str[back_outer_i+1]) < expr.shape[back_outer_i]:
  1553. break
  1554. if even:
  1555. level_str[back_outer_i].append(
  1556. r" & ".join(level_str[back_outer_i+1]))
  1557. else:
  1558. level_str[back_outer_i].append(
  1559. block_str % (r"\\".join(level_str[back_outer_i+1])))
  1560. if len(level_str[back_outer_i+1]) == 1:
  1561. level_str[back_outer_i][-1] = r"\left[" + \
  1562. level_str[back_outer_i][-1] + r"\right]"
  1563. even = not even
  1564. level_str[back_outer_i+1] = []
  1565. out_str = level_str[0][0]
  1566. if expr.rank() % 2 == 1:
  1567. out_str = block_str % out_str
  1568. return out_str
  1569. def _printer_tensor_indices(self, name, indices, index_map={}):
  1570. out_str = self._print(name)
  1571. last_valence = None
  1572. prev_map = None
  1573. for index in indices:
  1574. new_valence = index.is_up
  1575. if ((index in index_map) or prev_map) and \
  1576. last_valence == new_valence:
  1577. out_str += ","
  1578. if last_valence != new_valence:
  1579. if last_valence is not None:
  1580. out_str += "}"
  1581. if index.is_up:
  1582. out_str += "{}^{"
  1583. else:
  1584. out_str += "{}_{"
  1585. out_str += self._print(index.args[0])
  1586. if index in index_map:
  1587. out_str += "="
  1588. out_str += self._print(index_map[index])
  1589. prev_map = True
  1590. else:
  1591. prev_map = False
  1592. last_valence = new_valence
  1593. if last_valence is not None:
  1594. out_str += "}"
  1595. return out_str
  1596. def _print_Tensor(self, expr):
  1597. name = expr.args[0].args[0]
  1598. indices = expr.get_indices()
  1599. return self._printer_tensor_indices(name, indices)
  1600. def _print_TensorElement(self, expr):
  1601. name = expr.expr.args[0].args[0]
  1602. indices = expr.expr.get_indices()
  1603. index_map = expr.index_map
  1604. return self._printer_tensor_indices(name, indices, index_map)
  1605. def _print_TensMul(self, expr):
  1606. # prints expressions like "A(a)", "3*A(a)", "(1+x)*A(a)"
  1607. sign, args = expr._get_args_for_traditional_printer()
  1608. return sign + "".join(
  1609. [self.parenthesize(arg, precedence(expr)) for arg in args]
  1610. )
  1611. def _print_TensAdd(self, expr):
  1612. a = []
  1613. args = expr.args
  1614. for x in args:
  1615. a.append(self.parenthesize(x, precedence(expr)))
  1616. a.sort()
  1617. s = ' + '.join(a)
  1618. s = s.replace('+ -', '- ')
  1619. return s
  1620. def _print_TensorIndex(self, expr):
  1621. return "{}%s{%s}" % (
  1622. "^" if expr.is_up else "_",
  1623. self._print(expr.args[0])
  1624. )
  1625. def _print_PartialDerivative(self, expr):
  1626. if len(expr.variables) == 1:
  1627. return r"\frac{\partial}{\partial {%s}}{%s}" % (
  1628. self._print(expr.variables[0]),
  1629. self.parenthesize(expr.expr, PRECEDENCE["Mul"], False)
  1630. )
  1631. else:
  1632. return r"\frac{\partial^{%s}}{%s}{%s}" % (
  1633. len(expr.variables),
  1634. " ".join([r"\partial {%s}" % self._print(i) for i in expr.variables]),
  1635. self.parenthesize(expr.expr, PRECEDENCE["Mul"], False)
  1636. )
  1637. def _print_ArraySymbol(self, expr):
  1638. return self._print(expr.name)
  1639. def _print_ArrayElement(self, expr):
  1640. return "{{%s}_{%s}}" % (
  1641. self.parenthesize(expr.name, PRECEDENCE["Func"], True),
  1642. ", ".join([f"{self._print(i)}" for i in expr.indices]))
  1643. def _print_UniversalSet(self, expr):
  1644. return r"\mathbb{U}"
  1645. def _print_frac(self, expr, exp=None):
  1646. if exp is None:
  1647. return r"\operatorname{frac}{\left(%s\right)}" % self._print(expr.args[0])
  1648. else:
  1649. return r"\operatorname{frac}{\left(%s\right)}^{%s}" % (
  1650. self._print(expr.args[0]), exp)
  1651. def _print_tuple(self, expr):
  1652. if self._settings['decimal_separator'] == 'comma':
  1653. sep = ";"
  1654. elif self._settings['decimal_separator'] == 'period':
  1655. sep = ","
  1656. else:
  1657. raise ValueError('Unknown Decimal Separator')
  1658. if len(expr) == 1:
  1659. # 1-tuple needs a trailing separator
  1660. return self._add_parens_lspace(self._print(expr[0]) + sep)
  1661. else:
  1662. return self._add_parens_lspace(
  1663. (sep + r" \ ").join([self._print(i) for i in expr]))
  1664. def _print_TensorProduct(self, expr):
  1665. elements = [self._print(a) for a in expr.args]
  1666. return r' \otimes '.join(elements)
  1667. def _print_WedgeProduct(self, expr):
  1668. elements = [self._print(a) for a in expr.args]
  1669. return r' \wedge '.join(elements)
  1670. def _print_Tuple(self, expr):
  1671. return self._print_tuple(expr)
  1672. def _print_list(self, expr):
  1673. if self._settings['decimal_separator'] == 'comma':
  1674. return r"\left[ %s\right]" % \
  1675. r"; \ ".join([self._print(i) for i in expr])
  1676. elif self._settings['decimal_separator'] == 'period':
  1677. return r"\left[ %s\right]" % \
  1678. r", \ ".join([self._print(i) for i in expr])
  1679. else:
  1680. raise ValueError('Unknown Decimal Separator')
  1681. def _print_dict(self, d):
  1682. keys = sorted(d.keys(), key=default_sort_key)
  1683. items = []
  1684. for key in keys:
  1685. val = d[key]
  1686. items.append("%s : %s" % (self._print(key), self._print(val)))
  1687. return r"\left\{ %s\right\}" % r", \ ".join(items)
  1688. def _print_Dict(self, expr):
  1689. return self._print_dict(expr)
  1690. def _print_DiracDelta(self, expr, exp=None):
  1691. if len(expr.args) == 1 or expr.args[1] == 0:
  1692. tex = r"\delta\left(%s\right)" % self._print(expr.args[0])
  1693. else:
  1694. tex = r"\delta^{\left( %s \right)}\left( %s \right)" % (
  1695. self._print(expr.args[1]), self._print(expr.args[0]))
  1696. if exp:
  1697. tex = r"\left(%s\right)^{%s}" % (tex, exp)
  1698. return tex
  1699. def _print_SingularityFunction(self, expr, exp=None):
  1700. shift = self._print(expr.args[0] - expr.args[1])
  1701. power = self._print(expr.args[2])
  1702. tex = r"{\left\langle %s \right\rangle}^{%s}" % (shift, power)
  1703. if exp is not None:
  1704. tex = r"{\left({\langle %s \rangle}^{%s}\right)}^{%s}" % (shift, power, exp)
  1705. return tex
  1706. def _print_Heaviside(self, expr, exp=None):
  1707. pargs = ', '.join(self._print(arg) for arg in expr.pargs)
  1708. tex = r"\theta\left(%s\right)" % pargs
  1709. if exp:
  1710. tex = r"\left(%s\right)^{%s}" % (tex, exp)
  1711. return tex
  1712. def _print_KroneckerDelta(self, expr, exp=None):
  1713. i = self._print(expr.args[0])
  1714. j = self._print(expr.args[1])
  1715. if expr.args[0].is_Atom and expr.args[1].is_Atom:
  1716. tex = r'\delta_{%s %s}' % (i, j)
  1717. else:
  1718. tex = r'\delta_{%s, %s}' % (i, j)
  1719. if exp is not None:
  1720. tex = r'\left(%s\right)^{%s}' % (tex, exp)
  1721. return tex
  1722. def _print_LeviCivita(self, expr, exp=None):
  1723. indices = map(self._print, expr.args)
  1724. if all(x.is_Atom for x in expr.args):
  1725. tex = r'\varepsilon_{%s}' % " ".join(indices)
  1726. else:
  1727. tex = r'\varepsilon_{%s}' % ", ".join(indices)
  1728. if exp:
  1729. tex = r'\left(%s\right)^{%s}' % (tex, exp)
  1730. return tex
  1731. def _print_RandomDomain(self, d):
  1732. if hasattr(d, 'as_boolean'):
  1733. return '\\text{Domain: }' + self._print(d.as_boolean())
  1734. elif hasattr(d, 'set'):
  1735. return ('\\text{Domain: }' + self._print(d.symbols) + ' \\in ' +
  1736. self._print(d.set))
  1737. elif hasattr(d, 'symbols'):
  1738. return '\\text{Domain on }' + self._print(d.symbols)
  1739. else:
  1740. return self._print(None)
  1741. def _print_FiniteSet(self, s):
  1742. items = sorted(s.args, key=default_sort_key)
  1743. return self._print_set(items)
  1744. def _print_set(self, s):
  1745. items = sorted(s, key=default_sort_key)
  1746. if self._settings['decimal_separator'] == 'comma':
  1747. items = "; ".join(map(self._print, items))
  1748. elif self._settings['decimal_separator'] == 'period':
  1749. items = ", ".join(map(self._print, items))
  1750. else:
  1751. raise ValueError('Unknown Decimal Separator')
  1752. return r"\left\{%s\right\}" % items
  1753. _print_frozenset = _print_set
  1754. def _print_Range(self, s):
  1755. def _print_symbolic_range():
  1756. # Symbolic Range that cannot be resolved
  1757. if s.args[0] == 0:
  1758. if s.args[2] == 1:
  1759. cont = self._print(s.args[1])
  1760. else:
  1761. cont = ", ".join(self._print(arg) for arg in s.args)
  1762. else:
  1763. if s.args[2] == 1:
  1764. cont = ", ".join(self._print(arg) for arg in s.args[:2])
  1765. else:
  1766. cont = ", ".join(self._print(arg) for arg in s.args)
  1767. return(f"\\text{{Range}}\\left({cont}\\right)")
  1768. dots = object()
  1769. if s.start.is_infinite and s.stop.is_infinite:
  1770. if s.step.is_positive:
  1771. printset = dots, -1, 0, 1, dots
  1772. else:
  1773. printset = dots, 1, 0, -1, dots
  1774. elif s.start.is_infinite:
  1775. printset = dots, s[-1] - s.step, s[-1]
  1776. elif s.stop.is_infinite:
  1777. it = iter(s)
  1778. printset = next(it), next(it), dots
  1779. elif s.is_empty is not None:
  1780. if (s.size < 4) == True:
  1781. printset = tuple(s)
  1782. elif s.is_iterable:
  1783. it = iter(s)
  1784. printset = next(it), next(it), dots, s[-1]
  1785. else:
  1786. return _print_symbolic_range()
  1787. else:
  1788. return _print_symbolic_range()
  1789. return (r"\left\{" +
  1790. r", ".join(self._print(el) if el is not dots else r'\ldots' for el in printset) +
  1791. r"\right\}")
  1792. def __print_number_polynomial(self, expr, letter, exp=None):
  1793. if len(expr.args) == 2:
  1794. if exp is not None:
  1795. return r"%s_{%s}^{%s}\left(%s\right)" % (letter,
  1796. self._print(expr.args[0]), exp,
  1797. self._print(expr.args[1]))
  1798. return r"%s_{%s}\left(%s\right)" % (letter,
  1799. self._print(expr.args[0]), self._print(expr.args[1]))
  1800. tex = r"%s_{%s}" % (letter, self._print(expr.args[0]))
  1801. if exp is not None:
  1802. tex = r"%s^{%s}" % (tex, exp)
  1803. return tex
  1804. def _print_bernoulli(self, expr, exp=None):
  1805. return self.__print_number_polynomial(expr, "B", exp)
  1806. def _print_bell(self, expr, exp=None):
  1807. if len(expr.args) == 3:
  1808. tex1 = r"B_{%s, %s}" % (self._print(expr.args[0]),
  1809. self._print(expr.args[1]))
  1810. tex2 = r"\left(%s\right)" % r", ".join(self._print(el) for
  1811. el in expr.args[2])
  1812. if exp is not None:
  1813. tex = r"%s^{%s}%s" % (tex1, exp, tex2)
  1814. else:
  1815. tex = tex1 + tex2
  1816. return tex
  1817. return self.__print_number_polynomial(expr, "B", exp)
  1818. def _print_fibonacci(self, expr, exp=None):
  1819. return self.__print_number_polynomial(expr, "F", exp)
  1820. def _print_lucas(self, expr, exp=None):
  1821. tex = r"L_{%s}" % self._print(expr.args[0])
  1822. if exp is not None:
  1823. tex = r"%s^{%s}" % (tex, exp)
  1824. return tex
  1825. def _print_tribonacci(self, expr, exp=None):
  1826. return self.__print_number_polynomial(expr, "T", exp)
  1827. def _print_SeqFormula(self, s):
  1828. dots = object()
  1829. if len(s.start.free_symbols) > 0 or len(s.stop.free_symbols) > 0:
  1830. return r"\left\{%s\right\}_{%s=%s}^{%s}" % (
  1831. self._print(s.formula),
  1832. self._print(s.variables[0]),
  1833. self._print(s.start),
  1834. self._print(s.stop)
  1835. )
  1836. if s.start is S.NegativeInfinity:
  1837. stop = s.stop
  1838. printset = (dots, s.coeff(stop - 3), s.coeff(stop - 2),
  1839. s.coeff(stop - 1), s.coeff(stop))
  1840. elif s.stop is S.Infinity or s.length > 4:
  1841. printset = s[:4]
  1842. printset.append(dots)
  1843. else:
  1844. printset = tuple(s)
  1845. return (r"\left[" +
  1846. r", ".join(self._print(el) if el is not dots else r'\ldots' for el in printset) +
  1847. r"\right]")
  1848. _print_SeqPer = _print_SeqFormula
  1849. _print_SeqAdd = _print_SeqFormula
  1850. _print_SeqMul = _print_SeqFormula
  1851. def _print_Interval(self, i):
  1852. if i.start == i.end:
  1853. return r"\left\{%s\right\}" % self._print(i.start)
  1854. else:
  1855. if i.left_open:
  1856. left = '('
  1857. else:
  1858. left = '['
  1859. if i.right_open:
  1860. right = ')'
  1861. else:
  1862. right = ']'
  1863. return r"\left%s%s, %s\right%s" % \
  1864. (left, self._print(i.start), self._print(i.end), right)
  1865. def _print_AccumulationBounds(self, i):
  1866. return r"\left\langle %s, %s\right\rangle" % \
  1867. (self._print(i.min), self._print(i.max))
  1868. def _print_Union(self, u):
  1869. prec = precedence_traditional(u)
  1870. args_str = [self.parenthesize(i, prec) for i in u.args]
  1871. return r" \cup ".join(args_str)
  1872. def _print_Complement(self, u):
  1873. prec = precedence_traditional(u)
  1874. args_str = [self.parenthesize(i, prec) for i in u.args]
  1875. return r" \setminus ".join(args_str)
  1876. def _print_Intersection(self, u):
  1877. prec = precedence_traditional(u)
  1878. args_str = [self.parenthesize(i, prec) for i in u.args]
  1879. return r" \cap ".join(args_str)
  1880. def _print_SymmetricDifference(self, u):
  1881. prec = precedence_traditional(u)
  1882. args_str = [self.parenthesize(i, prec) for i in u.args]
  1883. return r" \triangle ".join(args_str)
  1884. def _print_ProductSet(self, p):
  1885. prec = precedence_traditional(p)
  1886. if len(p.sets) >= 1 and not has_variety(p.sets):
  1887. return self.parenthesize(p.sets[0], prec) + "^{%d}" % len(p.sets)
  1888. return r" \times ".join(
  1889. self.parenthesize(set, prec) for set in p.sets)
  1890. def _print_EmptySet(self, e):
  1891. return r"\emptyset"
  1892. def _print_Naturals(self, n):
  1893. return r"\mathbb{N}"
  1894. def _print_Naturals0(self, n):
  1895. return r"\mathbb{N}_0"
  1896. def _print_Integers(self, i):
  1897. return r"\mathbb{Z}"
  1898. def _print_Rationals(self, i):
  1899. return r"\mathbb{Q}"
  1900. def _print_Reals(self, i):
  1901. return r"\mathbb{R}"
  1902. def _print_Complexes(self, i):
  1903. return r"\mathbb{C}"
  1904. def _print_ImageSet(self, s):
  1905. expr = s.lamda.expr
  1906. sig = s.lamda.signature
  1907. xys = ((self._print(x), self._print(y)) for x, y in zip(sig, s.base_sets))
  1908. xinys = r", ".join(r"%s \in %s" % xy for xy in xys)
  1909. return r"\left\{%s\; \middle|\; %s\right\}" % (self._print(expr), xinys)
  1910. def _print_ConditionSet(self, s):
  1911. vars_print = ', '.join([self._print(var) for var in Tuple(s.sym)])
  1912. if s.base_set is S.UniversalSet:
  1913. return r"\left\{%s\; \middle|\; %s \right\}" % \
  1914. (vars_print, self._print(s.condition))
  1915. return r"\left\{%s\; \middle|\; %s \in %s \wedge %s \right\}" % (
  1916. vars_print,
  1917. vars_print,
  1918. self._print(s.base_set),
  1919. self._print(s.condition))
  1920. def _print_PowerSet(self, expr):
  1921. arg_print = self._print(expr.args[0])
  1922. return r"\mathcal{{P}}\left({}\right)".format(arg_print)
  1923. def _print_ComplexRegion(self, s):
  1924. vars_print = ', '.join([self._print(var) for var in s.variables])
  1925. return r"\left\{%s\; \middle|\; %s \in %s \right\}" % (
  1926. self._print(s.expr),
  1927. vars_print,
  1928. self._print(s.sets))
  1929. def _print_Contains(self, e):
  1930. return r"%s \in %s" % tuple(self._print(a) for a in e.args)
  1931. def _print_FourierSeries(self, s):
  1932. if s.an.formula is S.Zero and s.bn.formula is S.Zero:
  1933. return self._print(s.a0)
  1934. return self._print_Add(s.truncate()) + r' + \ldots'
  1935. def _print_FormalPowerSeries(self, s):
  1936. return self._print_Add(s.infinite)
  1937. def _print_FiniteField(self, expr):
  1938. return r"\mathbb{F}_{%s}" % expr.mod
  1939. def _print_IntegerRing(self, expr):
  1940. return r"\mathbb{Z}"
  1941. def _print_RationalField(self, expr):
  1942. return r"\mathbb{Q}"
  1943. def _print_RealField(self, expr):
  1944. return r"\mathbb{R}"
  1945. def _print_ComplexField(self, expr):
  1946. return r"\mathbb{C}"
  1947. def _print_PolynomialRing(self, expr):
  1948. domain = self._print(expr.domain)
  1949. symbols = ", ".join(map(self._print, expr.symbols))
  1950. return r"%s\left[%s\right]" % (domain, symbols)
  1951. def _print_FractionField(self, expr):
  1952. domain = self._print(expr.domain)
  1953. symbols = ", ".join(map(self._print, expr.symbols))
  1954. return r"%s\left(%s\right)" % (domain, symbols)
  1955. def _print_PolynomialRingBase(self, expr):
  1956. domain = self._print(expr.domain)
  1957. symbols = ", ".join(map(self._print, expr.symbols))
  1958. inv = ""
  1959. if not expr.is_Poly:
  1960. inv = r"S_<^{-1}"
  1961. return r"%s%s\left[%s\right]" % (inv, domain, symbols)
  1962. def _print_Poly(self, poly):
  1963. cls = poly.__class__.__name__
  1964. terms = []
  1965. for monom, coeff in poly.terms():
  1966. s_monom = ''
  1967. for i, exp in enumerate(monom):
  1968. if exp > 0:
  1969. if exp == 1:
  1970. s_monom += self._print(poly.gens[i])
  1971. else:
  1972. s_monom += self._print(pow(poly.gens[i], exp))
  1973. if coeff.is_Add:
  1974. if s_monom:
  1975. s_coeff = r"\left(%s\right)" % self._print(coeff)
  1976. else:
  1977. s_coeff = self._print(coeff)
  1978. else:
  1979. if s_monom:
  1980. if coeff is S.One:
  1981. terms.extend(['+', s_monom])
  1982. continue
  1983. if coeff is S.NegativeOne:
  1984. terms.extend(['-', s_monom])
  1985. continue
  1986. s_coeff = self._print(coeff)
  1987. if not s_monom:
  1988. s_term = s_coeff
  1989. else:
  1990. s_term = s_coeff + " " + s_monom
  1991. if s_term.startswith('-'):
  1992. terms.extend(['-', s_term[1:]])
  1993. else:
  1994. terms.extend(['+', s_term])
  1995. if terms[0] in ('-', '+'):
  1996. modifier = terms.pop(0)
  1997. if modifier == '-':
  1998. terms[0] = '-' + terms[0]
  1999. expr = ' '.join(terms)
  2000. gens = list(map(self._print, poly.gens))
  2001. domain = "domain=%s" % self._print(poly.get_domain())
  2002. args = ", ".join([expr] + gens + [domain])
  2003. if cls in accepted_latex_functions:
  2004. tex = r"\%s {\left(%s \right)}" % (cls, args)
  2005. else:
  2006. tex = r"\operatorname{%s}{\left( %s \right)}" % (cls, args)
  2007. return tex
  2008. def _print_ComplexRootOf(self, root):
  2009. cls = root.__class__.__name__
  2010. if cls == "ComplexRootOf":
  2011. cls = "CRootOf"
  2012. expr = self._print(root.expr)
  2013. index = root.index
  2014. if cls in accepted_latex_functions:
  2015. return r"\%s {\left(%s, %d\right)}" % (cls, expr, index)
  2016. else:
  2017. return r"\operatorname{%s} {\left(%s, %d\right)}" % (cls, expr,
  2018. index)
  2019. def _print_RootSum(self, expr):
  2020. cls = expr.__class__.__name__
  2021. args = [self._print(expr.expr)]
  2022. if expr.fun is not S.IdentityFunction:
  2023. args.append(self._print(expr.fun))
  2024. if cls in accepted_latex_functions:
  2025. return r"\%s {\left(%s\right)}" % (cls, ", ".join(args))
  2026. else:
  2027. return r"\operatorname{%s} {\left(%s\right)}" % (cls,
  2028. ", ".join(args))
  2029. def _print_OrdinalOmega(self, expr):
  2030. return r"\omega"
  2031. def _print_OmegaPower(self, expr):
  2032. exp, mul = expr.args
  2033. if mul != 1:
  2034. if exp != 1:
  2035. return r"{} \omega^{{{}}}".format(mul, exp)
  2036. else:
  2037. return r"{} \omega".format(mul)
  2038. else:
  2039. if exp != 1:
  2040. return r"\omega^{{{}}}".format(exp)
  2041. else:
  2042. return r"\omega"
  2043. def _print_Ordinal(self, expr):
  2044. return " + ".join([self._print(arg) for arg in expr.args])
  2045. def _print_PolyElement(self, poly):
  2046. mul_symbol = self._settings['mul_symbol_latex']
  2047. return poly.str(self, PRECEDENCE, "{%s}^{%d}", mul_symbol)
  2048. def _print_FracElement(self, frac):
  2049. if frac.denom == 1:
  2050. return self._print(frac.numer)
  2051. else:
  2052. numer = self._print(frac.numer)
  2053. denom = self._print(frac.denom)
  2054. return r"\frac{%s}{%s}" % (numer, denom)
  2055. def _print_euler(self, expr, exp=None):
  2056. m, x = (expr.args[0], None) if len(expr.args) == 1 else expr.args
  2057. tex = r"E_{%s}" % self._print(m)
  2058. if exp is not None:
  2059. tex = r"%s^{%s}" % (tex, exp)
  2060. if x is not None:
  2061. tex = r"%s\left(%s\right)" % (tex, self._print(x))
  2062. return tex
  2063. def _print_catalan(self, expr, exp=None):
  2064. tex = r"C_{%s}" % self._print(expr.args[0])
  2065. if exp is not None:
  2066. tex = r"%s^{%s}" % (tex, exp)
  2067. return tex
  2068. def _print_UnifiedTransform(self, expr, s, inverse=False):
  2069. return r"\mathcal{{{}}}{}_{{{}}}\left[{}\right]\left({}\right)".format(s, '^{-1}' if inverse else '', self._print(expr.args[1]), self._print(expr.args[0]), self._print(expr.args[2]))
  2070. def _print_MellinTransform(self, expr):
  2071. return self._print_UnifiedTransform(expr, 'M')
  2072. def _print_InverseMellinTransform(self, expr):
  2073. return self._print_UnifiedTransform(expr, 'M', True)
  2074. def _print_LaplaceTransform(self, expr):
  2075. return self._print_UnifiedTransform(expr, 'L')
  2076. def _print_InverseLaplaceTransform(self, expr):
  2077. return self._print_UnifiedTransform(expr, 'L', True)
  2078. def _print_FourierTransform(self, expr):
  2079. return self._print_UnifiedTransform(expr, 'F')
  2080. def _print_InverseFourierTransform(self, expr):
  2081. return self._print_UnifiedTransform(expr, 'F', True)
  2082. def _print_SineTransform(self, expr):
  2083. return self._print_UnifiedTransform(expr, 'SIN')
  2084. def _print_InverseSineTransform(self, expr):
  2085. return self._print_UnifiedTransform(expr, 'SIN', True)
  2086. def _print_CosineTransform(self, expr):
  2087. return self._print_UnifiedTransform(expr, 'COS')
  2088. def _print_InverseCosineTransform(self, expr):
  2089. return self._print_UnifiedTransform(expr, 'COS', True)
  2090. def _print_DMP(self, p):
  2091. try:
  2092. if p.ring is not None:
  2093. # TODO incorporate order
  2094. return self._print(p.ring.to_sympy(p))
  2095. except SympifyError:
  2096. pass
  2097. return self._print(repr(p))
  2098. def _print_DMF(self, p):
  2099. return self._print_DMP(p)
  2100. def _print_Object(self, object):
  2101. return self._print(Symbol(object.name))
  2102. def _print_LambertW(self, expr, exp=None):
  2103. arg0 = self._print(expr.args[0])
  2104. exp = r"^{%s}" % (exp,) if exp is not None else ""
  2105. if len(expr.args) == 1:
  2106. result = r"W%s\left(%s\right)" % (exp, arg0)
  2107. else:
  2108. arg1 = self._print(expr.args[1])
  2109. result = "W{0}_{{{1}}}\\left({2}\\right)".format(exp, arg1, arg0)
  2110. return result
  2111. def _print_Expectation(self, expr):
  2112. return r"\operatorname{{E}}\left[{}\right]".format(self._print(expr.args[0]))
  2113. def _print_Variance(self, expr):
  2114. return r"\operatorname{{Var}}\left({}\right)".format(self._print(expr.args[0]))
  2115. def _print_Covariance(self, expr):
  2116. return r"\operatorname{{Cov}}\left({}\right)".format(", ".join(self._print(arg) for arg in expr.args))
  2117. def _print_Probability(self, expr):
  2118. return r"\operatorname{{P}}\left({}\right)".format(self._print(expr.args[0]))
  2119. def _print_Morphism(self, morphism):
  2120. domain = self._print(morphism.domain)
  2121. codomain = self._print(morphism.codomain)
  2122. return "%s\\rightarrow %s" % (domain, codomain)
  2123. def _print_TransferFunction(self, expr):
  2124. num, den = self._print(expr.num), self._print(expr.den)
  2125. return r"\frac{%s}{%s}" % (num, den)
  2126. def _print_Series(self, expr):
  2127. args = list(expr.args)
  2128. parens = lambda x: self.parenthesize(x, precedence_traditional(expr),
  2129. False)
  2130. return ' '.join(map(parens, args))
  2131. def _print_MIMOSeries(self, expr):
  2132. from sympy.physics.control.lti import MIMOParallel
  2133. args = list(expr.args)[::-1]
  2134. parens = lambda x: self.parenthesize(x, precedence_traditional(expr),
  2135. False) if isinstance(x, MIMOParallel) else self._print(x)
  2136. return r"\cdot".join(map(parens, args))
  2137. def _print_Parallel(self, expr):
  2138. return ' + '.join(map(self._print, expr.args))
  2139. def _print_MIMOParallel(self, expr):
  2140. return ' + '.join(map(self._print, expr.args))
  2141. def _print_Feedback(self, expr):
  2142. from sympy.physics.control import TransferFunction, Series
  2143. num, tf = expr.sys1, TransferFunction(1, 1, expr.var)
  2144. num_arg_list = list(num.args) if isinstance(num, Series) else [num]
  2145. den_arg_list = list(expr.sys2.args) if \
  2146. isinstance(expr.sys2, Series) else [expr.sys2]
  2147. den_term_1 = tf
  2148. if isinstance(num, Series) and isinstance(expr.sys2, Series):
  2149. den_term_2 = Series(*num_arg_list, *den_arg_list)
  2150. elif isinstance(num, Series) and isinstance(expr.sys2, TransferFunction):
  2151. if expr.sys2 == tf:
  2152. den_term_2 = Series(*num_arg_list)
  2153. else:
  2154. den_term_2 = tf, Series(*num_arg_list, expr.sys2)
  2155. elif isinstance(num, TransferFunction) and isinstance(expr.sys2, Series):
  2156. if num == tf:
  2157. den_term_2 = Series(*den_arg_list)
  2158. else:
  2159. den_term_2 = Series(num, *den_arg_list)
  2160. else:
  2161. if num == tf:
  2162. den_term_2 = Series(*den_arg_list)
  2163. elif expr.sys2 == tf:
  2164. den_term_2 = Series(*num_arg_list)
  2165. else:
  2166. den_term_2 = Series(*num_arg_list, *den_arg_list)
  2167. numer = self._print(num)
  2168. denom_1 = self._print(den_term_1)
  2169. denom_2 = self._print(den_term_2)
  2170. _sign = "+" if expr.sign == -1 else "-"
  2171. return r"\frac{%s}{%s %s %s}" % (numer, denom_1, _sign, denom_2)
  2172. def _print_MIMOFeedback(self, expr):
  2173. from sympy.physics.control import MIMOSeries
  2174. inv_mat = self._print(MIMOSeries(expr.sys2, expr.sys1))
  2175. sys1 = self._print(expr.sys1)
  2176. _sign = "+" if expr.sign == -1 else "-"
  2177. return r"\left(I_{\tau} %s %s\right)^{-1} \cdot %s" % (_sign, inv_mat, sys1)
  2178. def _print_TransferFunctionMatrix(self, expr):
  2179. mat = self._print(expr._expr_mat)
  2180. return r"%s_\tau" % mat
  2181. def _print_DFT(self, expr):
  2182. return r"\text{{{}}}_{{{}}}".format(expr.__class__.__name__, expr.n)
  2183. _print_IDFT = _print_DFT
  2184. def _print_NamedMorphism(self, morphism):
  2185. pretty_name = self._print(Symbol(morphism.name))
  2186. pretty_morphism = self._print_Morphism(morphism)
  2187. return "%s:%s" % (pretty_name, pretty_morphism)
  2188. def _print_IdentityMorphism(self, morphism):
  2189. from sympy.categories import NamedMorphism
  2190. return self._print_NamedMorphism(NamedMorphism(
  2191. morphism.domain, morphism.codomain, "id"))
  2192. def _print_CompositeMorphism(self, morphism):
  2193. # All components of the morphism have names and it is thus
  2194. # possible to build the name of the composite.
  2195. component_names_list = [self._print(Symbol(component.name)) for
  2196. component in morphism.components]
  2197. component_names_list.reverse()
  2198. component_names = "\\circ ".join(component_names_list) + ":"
  2199. pretty_morphism = self._print_Morphism(morphism)
  2200. return component_names + pretty_morphism
  2201. def _print_Category(self, morphism):
  2202. return r"\mathbf{{{}}}".format(self._print(Symbol(morphism.name)))
  2203. def _print_Diagram(self, diagram):
  2204. if not diagram.premises:
  2205. # This is an empty diagram.
  2206. return self._print(S.EmptySet)
  2207. latex_result = self._print(diagram.premises)
  2208. if diagram.conclusions:
  2209. latex_result += "\\Longrightarrow %s" % \
  2210. self._print(diagram.conclusions)
  2211. return latex_result
  2212. def _print_DiagramGrid(self, grid):
  2213. latex_result = "\\begin{array}{%s}\n" % ("c" * grid.width)
  2214. for i in range(grid.height):
  2215. for j in range(grid.width):
  2216. if grid[i, j]:
  2217. latex_result += latex(grid[i, j])
  2218. latex_result += " "
  2219. if j != grid.width - 1:
  2220. latex_result += "& "
  2221. if i != grid.height - 1:
  2222. latex_result += "\\\\"
  2223. latex_result += "\n"
  2224. latex_result += "\\end{array}\n"
  2225. return latex_result
  2226. def _print_FreeModule(self, M):
  2227. return '{{{}}}^{{{}}}'.format(self._print(M.ring), self._print(M.rank))
  2228. def _print_FreeModuleElement(self, m):
  2229. # Print as row vector for convenience, for now.
  2230. return r"\left[ {} \right]".format(",".join(
  2231. '{' + self._print(x) + '}' for x in m))
  2232. def _print_SubModule(self, m):
  2233. return r"\left\langle {} \right\rangle".format(",".join(
  2234. '{' + self._print(x) + '}' for x in m.gens))
  2235. def _print_ModuleImplementedIdeal(self, m):
  2236. return r"\left\langle {} \right\rangle".format(",".join(
  2237. '{' + self._print(x) + '}' for [x] in m._module.gens))
  2238. def _print_Quaternion(self, expr):
  2239. # TODO: This expression is potentially confusing,
  2240. # shall we print it as `Quaternion( ... )`?
  2241. s = [self.parenthesize(i, PRECEDENCE["Mul"], strict=True)
  2242. for i in expr.args]
  2243. a = [s[0]] + [i+" "+j for i, j in zip(s[1:], "ijk")]
  2244. return " + ".join(a)
  2245. def _print_QuotientRing(self, R):
  2246. # TODO nicer fractions for few generators...
  2247. return r"\frac{{{}}}{{{}}}".format(self._print(R.ring),
  2248. self._print(R.base_ideal))
  2249. def _print_QuotientRingElement(self, x):
  2250. return r"{{{}}} + {{{}}}".format(self._print(x.data),
  2251. self._print(x.ring.base_ideal))
  2252. def _print_QuotientModuleElement(self, m):
  2253. return r"{{{}}} + {{{}}}".format(self._print(m.data),
  2254. self._print(m.module.killed_module))
  2255. def _print_QuotientModule(self, M):
  2256. # TODO nicer fractions for few generators...
  2257. return r"\frac{{{}}}{{{}}}".format(self._print(M.base),
  2258. self._print(M.killed_module))
  2259. def _print_MatrixHomomorphism(self, h):
  2260. return r"{{{}}} : {{{}}} \to {{{}}}".format(self._print(h._sympy_matrix()),
  2261. self._print(h.domain), self._print(h.codomain))
  2262. def _print_Manifold(self, manifold):
  2263. string = manifold.name.name
  2264. if '{' in string:
  2265. name, supers, subs = string, [], []
  2266. else:
  2267. name, supers, subs = split_super_sub(string)
  2268. name = translate(name)
  2269. supers = [translate(sup) for sup in supers]
  2270. subs = [translate(sub) for sub in subs]
  2271. name = r'\text{%s}' % name
  2272. if supers:
  2273. name += "^{%s}" % " ".join(supers)
  2274. if subs:
  2275. name += "_{%s}" % " ".join(subs)
  2276. return name
  2277. def _print_Patch(self, patch):
  2278. return r'\text{%s}_{%s}' % (self._print(patch.name), self._print(patch.manifold))
  2279. def _print_CoordSystem(self, coordsys):
  2280. return r'\text{%s}^{\text{%s}}_{%s}' % (
  2281. self._print(coordsys.name), self._print(coordsys.patch.name), self._print(coordsys.manifold)
  2282. )
  2283. def _print_CovarDerivativeOp(self, cvd):
  2284. return r'\mathbb{\nabla}_{%s}' % self._print(cvd._wrt)
  2285. def _print_BaseScalarField(self, field):
  2286. string = field._coord_sys.symbols[field._index].name
  2287. return r'\mathbf{{{}}}'.format(self._print(Symbol(string)))
  2288. def _print_BaseVectorField(self, field):
  2289. string = field._coord_sys.symbols[field._index].name
  2290. return r'\partial_{{{}}}'.format(self._print(Symbol(string)))
  2291. def _print_Differential(self, diff):
  2292. field = diff._form_field
  2293. if hasattr(field, '_coord_sys'):
  2294. string = field._coord_sys.symbols[field._index].name
  2295. return r'\operatorname{{d}}{}'.format(self._print(Symbol(string)))
  2296. else:
  2297. string = self._print(field)
  2298. return r'\operatorname{{d}}\left({}\right)'.format(string)
  2299. def _print_Tr(self, p):
  2300. # TODO: Handle indices
  2301. contents = self._print(p.args[0])
  2302. return r'\operatorname{{tr}}\left({}\right)'.format(contents)
  2303. def _print_totient(self, expr, exp=None):
  2304. if exp is not None:
  2305. return r'\left(\phi\left(%s\right)\right)^{%s}' % \
  2306. (self._print(expr.args[0]), exp)
  2307. return r'\phi\left(%s\right)' % self._print(expr.args[0])
  2308. def _print_reduced_totient(self, expr, exp=None):
  2309. if exp is not None:
  2310. return r'\left(\lambda\left(%s\right)\right)^{%s}' % \
  2311. (self._print(expr.args[0]), exp)
  2312. return r'\lambda\left(%s\right)' % self._print(expr.args[0])
  2313. def _print_divisor_sigma(self, expr, exp=None):
  2314. if len(expr.args) == 2:
  2315. tex = r"_%s\left(%s\right)" % tuple(map(self._print,
  2316. (expr.args[1], expr.args[0])))
  2317. else:
  2318. tex = r"\left(%s\right)" % self._print(expr.args[0])
  2319. if exp is not None:
  2320. return r"\sigma^{%s}%s" % (exp, tex)
  2321. return r"\sigma%s" % tex
  2322. def _print_udivisor_sigma(self, expr, exp=None):
  2323. if len(expr.args) == 2:
  2324. tex = r"_%s\left(%s\right)" % tuple(map(self._print,
  2325. (expr.args[1], expr.args[0])))
  2326. else:
  2327. tex = r"\left(%s\right)" % self._print(expr.args[0])
  2328. if exp is not None:
  2329. return r"\sigma^*^{%s}%s" % (exp, tex)
  2330. return r"\sigma^*%s" % tex
  2331. def _print_primenu(self, expr, exp=None):
  2332. if exp is not None:
  2333. return r'\left(\nu\left(%s\right)\right)^{%s}' % \
  2334. (self._print(expr.args[0]), exp)
  2335. return r'\nu\left(%s\right)' % self._print(expr.args[0])
  2336. def _print_primeomega(self, expr, exp=None):
  2337. if exp is not None:
  2338. return r'\left(\Omega\left(%s\right)\right)^{%s}' % \
  2339. (self._print(expr.args[0]), exp)
  2340. return r'\Omega\left(%s\right)' % self._print(expr.args[0])
  2341. def _print_Str(self, s):
  2342. return str(s.name)
  2343. def _print_float(self, expr):
  2344. return self._print(Float(expr))
  2345. def _print_int(self, expr):
  2346. return str(expr)
  2347. def _print_mpz(self, expr):
  2348. return str(expr)
  2349. def _print_mpq(self, expr):
  2350. return str(expr)
  2351. def _print_Predicate(self, expr):
  2352. return r"\operatorname{{Q}}_{{\text{{{}}}}}".format(latex_escape(str(expr.name)))
  2353. def _print_AppliedPredicate(self, expr):
  2354. pred = expr.function
  2355. args = expr.arguments
  2356. pred_latex = self._print(pred)
  2357. args_latex = ', '.join([self._print(a) for a in args])
  2358. return '%s(%s)' % (pred_latex, args_latex)
  2359. def emptyPrinter(self, expr):
  2360. # default to just printing as monospace, like would normally be shown
  2361. s = super().emptyPrinter(expr)
  2362. return r"\mathtt{\text{%s}}" % latex_escape(s)
  2363. def translate(s):
  2364. r'''
  2365. Check for a modifier ending the string. If present, convert the
  2366. modifier to latex and translate the rest recursively.
  2367. Given a description of a Greek letter or other special character,
  2368. return the appropriate latex.
  2369. Let everything else pass as given.
  2370. >>> from sympy.printing.latex import translate
  2371. >>> translate('alphahatdotprime')
  2372. "{\\dot{\\hat{\\alpha}}}'"
  2373. '''
  2374. # Process the rest
  2375. tex = tex_greek_dictionary.get(s)
  2376. if tex:
  2377. return tex
  2378. elif s.lower() in greek_letters_set:
  2379. return "\\" + s.lower()
  2380. elif s in other_symbols:
  2381. return "\\" + s
  2382. else:
  2383. # Process modifiers, if any, and recurse
  2384. for key in sorted(modifier_dict.keys(), key=len, reverse=True):
  2385. if s.lower().endswith(key) and len(s) > len(key):
  2386. return modifier_dict[key](translate(s[:-len(key)]))
  2387. return s
  2388. @print_function(LatexPrinter)
  2389. def latex(expr, **settings):
  2390. r"""Convert the given expression to LaTeX string representation.
  2391. Parameters
  2392. ==========
  2393. full_prec: boolean, optional
  2394. If set to True, a floating point number is printed with full precision.
  2395. fold_frac_powers : boolean, optional
  2396. Emit ``^{p/q}`` instead of ``^{\frac{p}{q}}`` for fractional powers.
  2397. fold_func_brackets : boolean, optional
  2398. Fold function brackets where applicable.
  2399. fold_short_frac : boolean, optional
  2400. Emit ``p / q`` instead of ``\frac{p}{q}`` when the denominator is
  2401. simple enough (at most two terms and no powers). The default value is
  2402. ``True`` for inline mode, ``False`` otherwise.
  2403. inv_trig_style : string, optional
  2404. How inverse trig functions should be displayed. Can be one of
  2405. ``abbreviated``, ``full``, or ``power``. Defaults to ``abbreviated``.
  2406. itex : boolean, optional
  2407. Specifies if itex-specific syntax is used, including emitting
  2408. ``$$...$$``.
  2409. ln_notation : boolean, optional
  2410. If set to ``True``, ``\ln`` is used instead of default ``\log``.
  2411. long_frac_ratio : float or None, optional
  2412. The allowed ratio of the width of the numerator to the width of the
  2413. denominator before the printer breaks off long fractions. If ``None``
  2414. (the default value), long fractions are not broken up.
  2415. mat_delim : string, optional
  2416. The delimiter to wrap around matrices. Can be one of ``[``, ``(``, or
  2417. the empty string. Defaults to ``[``.
  2418. mat_str : string, optional
  2419. Which matrix environment string to emit. ``smallmatrix``, ``matrix``,
  2420. ``array``, etc. Defaults to ``smallmatrix`` for inline mode, ``matrix``
  2421. for matrices of no more than 10 columns, and ``array`` otherwise.
  2422. mode: string, optional
  2423. Specifies how the generated code will be delimited. ``mode`` can be one
  2424. of ``plain``, ``inline``, ``equation`` or ``equation*``. If ``mode``
  2425. is set to ``plain``, then the resulting code will not be delimited at
  2426. all (this is the default). If ``mode`` is set to ``inline`` then inline
  2427. LaTeX ``$...$`` will be used. If ``mode`` is set to ``equation`` or
  2428. ``equation*``, the resulting code will be enclosed in the ``equation``
  2429. or ``equation*`` environment (remember to import ``amsmath`` for
  2430. ``equation*``), unless the ``itex`` option is set. In the latter case,
  2431. the ``$$...$$`` syntax is used.
  2432. mul_symbol : string or None, optional
  2433. The symbol to use for multiplication. Can be one of ``None``, ``ldot``,
  2434. ``dot``, or ``times``.
  2435. order: string, optional
  2436. Any of the supported monomial orderings (currently ``lex``, ``grlex``,
  2437. or ``grevlex``), ``old``, and ``none``. This parameter does nothing for
  2438. Mul objects. Setting order to ``old`` uses the compatibility ordering
  2439. for Add defined in Printer. For very large expressions, set the
  2440. ``order`` keyword to ``none`` if speed is a concern.
  2441. symbol_names : dictionary of strings mapped to symbols, optional
  2442. Dictionary of symbols and the custom strings they should be emitted as.
  2443. root_notation : boolean, optional
  2444. If set to ``False``, exponents of the form 1/n are printed in fractonal
  2445. form. Default is ``True``, to print exponent in root form.
  2446. mat_symbol_style : string, optional
  2447. Can be either ``plain`` (default) or ``bold``. If set to ``bold``,
  2448. a MatrixSymbol A will be printed as ``\mathbf{A}``, otherwise as ``A``.
  2449. imaginary_unit : string, optional
  2450. String to use for the imaginary unit. Defined options are "i" (default)
  2451. and "j". Adding "r" or "t" in front gives ``\mathrm`` or ``\text``, so
  2452. "ri" leads to ``\mathrm{i}`` which gives `\mathrm{i}`.
  2453. gothic_re_im : boolean, optional
  2454. If set to ``True``, `\Re` and `\Im` is used for ``re`` and ``im``, respectively.
  2455. The default is ``False`` leading to `\operatorname{re}` and `\operatorname{im}`.
  2456. decimal_separator : string, optional
  2457. Specifies what separator to use to separate the whole and fractional parts of a
  2458. floating point number as in `2.5` for the default, ``period`` or `2{,}5`
  2459. when ``comma`` is specified. Lists, sets, and tuple are printed with semicolon
  2460. separating the elements when ``comma`` is chosen. For example, [1; 2; 3] when
  2461. ``comma`` is chosen and [1,2,3] for when ``period`` is chosen.
  2462. parenthesize_super : boolean, optional
  2463. If set to ``False``, superscripted expressions will not be parenthesized when
  2464. powered. Default is ``True``, which parenthesizes the expression when powered.
  2465. min: Integer or None, optional
  2466. Sets the lower bound for the exponent to print floating point numbers in
  2467. fixed-point format.
  2468. max: Integer or None, optional
  2469. Sets the upper bound for the exponent to print floating point numbers in
  2470. fixed-point format.
  2471. Notes
  2472. =====
  2473. Not using a print statement for printing, results in double backslashes for
  2474. latex commands since that's the way Python escapes backslashes in strings.
  2475. >>> from sympy import latex, Rational
  2476. >>> from sympy.abc import tau
  2477. >>> latex((2*tau)**Rational(7,2))
  2478. '8 \\sqrt{2} \\tau^{\\frac{7}{2}}'
  2479. >>> print(latex((2*tau)**Rational(7,2)))
  2480. 8 \sqrt{2} \tau^{\frac{7}{2}}
  2481. Examples
  2482. ========
  2483. >>> from sympy import latex, pi, sin, asin, Integral, Matrix, Rational, log
  2484. >>> from sympy.abc import x, y, mu, r, tau
  2485. Basic usage:
  2486. >>> print(latex((2*tau)**Rational(7,2)))
  2487. 8 \sqrt{2} \tau^{\frac{7}{2}}
  2488. ``mode`` and ``itex`` options:
  2489. >>> print(latex((2*mu)**Rational(7,2), mode='plain'))
  2490. 8 \sqrt{2} \mu^{\frac{7}{2}}
  2491. >>> print(latex((2*tau)**Rational(7,2), mode='inline'))
  2492. $8 \sqrt{2} \tau^{7 / 2}$
  2493. >>> print(latex((2*mu)**Rational(7,2), mode='equation*'))
  2494. \begin{equation*}8 \sqrt{2} \mu^{\frac{7}{2}}\end{equation*}
  2495. >>> print(latex((2*mu)**Rational(7,2), mode='equation'))
  2496. \begin{equation}8 \sqrt{2} \mu^{\frac{7}{2}}\end{equation}
  2497. >>> print(latex((2*mu)**Rational(7,2), mode='equation', itex=True))
  2498. $$8 \sqrt{2} \mu^{\frac{7}{2}}$$
  2499. >>> print(latex((2*mu)**Rational(7,2), mode='plain'))
  2500. 8 \sqrt{2} \mu^{\frac{7}{2}}
  2501. >>> print(latex((2*tau)**Rational(7,2), mode='inline'))
  2502. $8 \sqrt{2} \tau^{7 / 2}$
  2503. >>> print(latex((2*mu)**Rational(7,2), mode='equation*'))
  2504. \begin{equation*}8 \sqrt{2} \mu^{\frac{7}{2}}\end{equation*}
  2505. >>> print(latex((2*mu)**Rational(7,2), mode='equation'))
  2506. \begin{equation}8 \sqrt{2} \mu^{\frac{7}{2}}\end{equation}
  2507. >>> print(latex((2*mu)**Rational(7,2), mode='equation', itex=True))
  2508. $$8 \sqrt{2} \mu^{\frac{7}{2}}$$
  2509. Fraction options:
  2510. >>> print(latex((2*tau)**Rational(7,2), fold_frac_powers=True))
  2511. 8 \sqrt{2} \tau^{7/2}
  2512. >>> print(latex((2*tau)**sin(Rational(7,2))))
  2513. \left(2 \tau\right)^{\sin{\left(\frac{7}{2} \right)}}
  2514. >>> print(latex((2*tau)**sin(Rational(7,2)), fold_func_brackets=True))
  2515. \left(2 \tau\right)^{\sin {\frac{7}{2}}}
  2516. >>> print(latex(3*x**2/y))
  2517. \frac{3 x^{2}}{y}
  2518. >>> print(latex(3*x**2/y, fold_short_frac=True))
  2519. 3 x^{2} / y
  2520. >>> print(latex(Integral(r, r)/2/pi, long_frac_ratio=2))
  2521. \frac{\int r\, dr}{2 \pi}
  2522. >>> print(latex(Integral(r, r)/2/pi, long_frac_ratio=0))
  2523. \frac{1}{2 \pi} \int r\, dr
  2524. Multiplication options:
  2525. >>> print(latex((2*tau)**sin(Rational(7,2)), mul_symbol="times"))
  2526. \left(2 \times \tau\right)^{\sin{\left(\frac{7}{2} \right)}}
  2527. Trig options:
  2528. >>> print(latex(asin(Rational(7,2))))
  2529. \operatorname{asin}{\left(\frac{7}{2} \right)}
  2530. >>> print(latex(asin(Rational(7,2)), inv_trig_style="full"))
  2531. \arcsin{\left(\frac{7}{2} \right)}
  2532. >>> print(latex(asin(Rational(7,2)), inv_trig_style="power"))
  2533. \sin^{-1}{\left(\frac{7}{2} \right)}
  2534. Matrix options:
  2535. >>> print(latex(Matrix(2, 1, [x, y])))
  2536. \left[\begin{matrix}x\\y\end{matrix}\right]
  2537. >>> print(latex(Matrix(2, 1, [x, y]), mat_str = "array"))
  2538. \left[\begin{array}{c}x\\y\end{array}\right]
  2539. >>> print(latex(Matrix(2, 1, [x, y]), mat_delim="("))
  2540. \left(\begin{matrix}x\\y\end{matrix}\right)
  2541. Custom printing of symbols:
  2542. >>> print(latex(x**2, symbol_names={x: 'x_i'}))
  2543. x_i^{2}
  2544. Logarithms:
  2545. >>> print(latex(log(10)))
  2546. \log{\left(10 \right)}
  2547. >>> print(latex(log(10), ln_notation=True))
  2548. \ln{\left(10 \right)}
  2549. ``latex()`` also supports the builtin container types :class:`list`,
  2550. :class:`tuple`, and :class:`dict`:
  2551. >>> print(latex([2/x, y], mode='inline'))
  2552. $\left[ 2 / x, \ y\right]$
  2553. Unsupported types are rendered as monospaced plaintext:
  2554. >>> print(latex(int))
  2555. \mathtt{\text{<class 'int'>}}
  2556. >>> print(latex("plain % text"))
  2557. \mathtt{\text{plain \% text}}
  2558. See :ref:`printer_method_example` for an example of how to override
  2559. this behavior for your own types by implementing ``_latex``.
  2560. .. versionchanged:: 1.7.0
  2561. Unsupported types no longer have their ``str`` representation treated as valid latex.
  2562. """
  2563. return LatexPrinter(settings).doprint(expr)
  2564. def print_latex(expr, **settings):
  2565. """Prints LaTeX representation of the given expression. Takes the same
  2566. settings as ``latex()``."""
  2567. print(latex(expr, **settings))
  2568. def multiline_latex(lhs, rhs, terms_per_line=1, environment="align*", use_dots=False, **settings):
  2569. r"""
  2570. This function generates a LaTeX equation with a multiline right-hand side
  2571. in an ``align*``, ``eqnarray`` or ``IEEEeqnarray`` environment.
  2572. Parameters
  2573. ==========
  2574. lhs : Expr
  2575. Left-hand side of equation
  2576. rhs : Expr
  2577. Right-hand side of equation
  2578. terms_per_line : integer, optional
  2579. Number of terms per line to print. Default is 1.
  2580. environment : "string", optional
  2581. Which LaTeX wnvironment to use for the output. Options are "align*"
  2582. (default), "eqnarray", and "IEEEeqnarray".
  2583. use_dots : boolean, optional
  2584. If ``True``, ``\\dots`` is added to the end of each line. Default is ``False``.
  2585. Examples
  2586. ========
  2587. >>> from sympy import multiline_latex, symbols, sin, cos, exp, log, I
  2588. >>> x, y, alpha = symbols('x y alpha')
  2589. >>> expr = sin(alpha*y) + exp(I*alpha) - cos(log(y))
  2590. >>> print(multiline_latex(x, expr))
  2591. \begin{align*}
  2592. x = & e^{i \alpha} \\
  2593. & + \sin{\left(\alpha y \right)} \\
  2594. & - \cos{\left(\log{\left(y \right)} \right)}
  2595. \end{align*}
  2596. Using at most two terms per line:
  2597. >>> print(multiline_latex(x, expr, 2))
  2598. \begin{align*}
  2599. x = & e^{i \alpha} + \sin{\left(\alpha y \right)} \\
  2600. & - \cos{\left(\log{\left(y \right)} \right)}
  2601. \end{align*}
  2602. Using ``eqnarray`` and dots:
  2603. >>> print(multiline_latex(x, expr, terms_per_line=2, environment="eqnarray", use_dots=True))
  2604. \begin{eqnarray}
  2605. x & = & e^{i \alpha} + \sin{\left(\alpha y \right)} \dots\nonumber\\
  2606. & & - \cos{\left(\log{\left(y \right)} \right)}
  2607. \end{eqnarray}
  2608. Using ``IEEEeqnarray``:
  2609. >>> print(multiline_latex(x, expr, environment="IEEEeqnarray"))
  2610. \begin{IEEEeqnarray}{rCl}
  2611. x & = & e^{i \alpha} \nonumber\\
  2612. & & + \sin{\left(\alpha y \right)} \nonumber\\
  2613. & & - \cos{\left(\log{\left(y \right)} \right)}
  2614. \end{IEEEeqnarray}
  2615. Notes
  2616. =====
  2617. All optional parameters from ``latex`` can also be used.
  2618. """
  2619. # Based on code from https://github.com/sympy/sympy/issues/3001
  2620. l = LatexPrinter(**settings)
  2621. if environment == "eqnarray":
  2622. result = r'\begin{eqnarray}' + '\n'
  2623. first_term = '& = &'
  2624. nonumber = r'\nonumber'
  2625. end_term = '\n\\end{eqnarray}'
  2626. doubleet = True
  2627. elif environment == "IEEEeqnarray":
  2628. result = r'\begin{IEEEeqnarray}{rCl}' + '\n'
  2629. first_term = '& = &'
  2630. nonumber = r'\nonumber'
  2631. end_term = '\n\\end{IEEEeqnarray}'
  2632. doubleet = True
  2633. elif environment == "align*":
  2634. result = r'\begin{align*}' + '\n'
  2635. first_term = '= &'
  2636. nonumber = ''
  2637. end_term = '\n\\end{align*}'
  2638. doubleet = False
  2639. else:
  2640. raise ValueError("Unknown environment: {}".format(environment))
  2641. dots = ''
  2642. if use_dots:
  2643. dots=r'\dots'
  2644. terms = rhs.as_ordered_terms()
  2645. n_terms = len(terms)
  2646. term_count = 1
  2647. for i in range(n_terms):
  2648. term = terms[i]
  2649. term_start = ''
  2650. term_end = ''
  2651. sign = '+'
  2652. if term_count > terms_per_line:
  2653. if doubleet:
  2654. term_start = '& & '
  2655. else:
  2656. term_start = '& '
  2657. term_count = 1
  2658. if term_count == terms_per_line:
  2659. # End of line
  2660. if i < n_terms-1:
  2661. # There are terms remaining
  2662. term_end = dots + nonumber + r'\\' + '\n'
  2663. else:
  2664. term_end = ''
  2665. if term.as_ordered_factors()[0] == -1:
  2666. term = -1*term
  2667. sign = r'-'
  2668. if i == 0: # beginning
  2669. if sign == '+':
  2670. sign = ''
  2671. result += r'{:s} {:s}{:s} {:s} {:s}'.format(l.doprint(lhs),
  2672. first_term, sign, l.doprint(term), term_end)
  2673. else:
  2674. result += r'{:s}{:s} {:s} {:s}'.format(term_start, sign,
  2675. l.doprint(term), term_end)
  2676. term_count += 1
  2677. result += end_term
  2678. return result