Ondrej Certik wrote: > On Tue, Dec 30, 2008 at 12:04 PM, Alan Bromborsky <abro...@verizon.net> wrote: > >> Ondrej Certik wrote: >> >>> On Tue, Dec 30, 2008 at 10:59 AM, Alan Bromborsky <abro...@verizon.net> >>> wrote: >>> >>> >>>> Ondrej Certik wrote: >>>> >>>> >>>>> On Tue, Dec 30, 2008 at 10:15 AM, Alan Bromborsky <abro...@verizon.net> >>>>> wrote: >>>>> >>>>> >>>>> >>>>>> I have gotten the latest sympy distribution with git, have commited my >>>>>> changes to galgebra. Now how do I send the revised distribution back to >>>>>> you? >>>>>> >>>>>> >>>>>> >>>>> $ git ci -a >>>>> $ git format-patch -1 >>>>> >>>>> and send the generated patch. More info at: >>>>> >>>>> http://docs.sympy.org/sympy-patches-tutorial.html#id7 >>>>> >>>>> Ondrej >>>>> >>>>> >>>>> >>>>> >>>> Patch is attached. >>>> >>>> >>> Thanks! When I test it, I get: >>> >>> $ bin/test sympy/galgebra/ >>> ============================= test process starts >>> ============================== >>> executable: /usr/bin/python (2.5.2-final-0) >>> >>> sympy/galgebra/tests/test_GA.py[?] Failed to import >>> [FAIL] >>> >>> ________________________________________________________________________________ >>> ___________ /home/ondra/repos/sympy/sympy/galgebra/tests/test_GA.py >>> ____________ >>> File "/home/ondra/repos/sympy/sympy/galgebra/tests/test_GA.py", line >>> 12, in <module> >>> from sympy.galgebra.GAsympy import set_main, MV, make_symbols, >>> types, ZERO, ONE, HALF >>> File "/home/ondra/repos/sympy/sympy/galgebra/GAsympy.py", line 25, in >>> <module> >>> import sympy.galgebra.latex_ex >>> ImportError: No module named latex_ex >>> >>> ============ tests finished: 0 passed, 1 exceptions in 0.20 seconds >>> ============ >>> DO *NOT* COMMIT! >>> >>> >>> Do you think you could please fix that? I guess just removing that >>> import would work. >>> >>> Ondrej >>> >>> >>> >> When I run test I get - >> >> bro...@ga:~/SYMPY-git/sympy$ bin/test sympy/galgebra/ >> ============================= test process starts >> ============================== >> executable: /usr/bin/python (2.5.2-final-0) >> >> sympy/galgebra/tests/test_GA.py[6] >> ...... [OK] >> >> =================== tests finished: 6 passed in 1.32 seconds >> =================== >> bro...@ga:~/SYMPY-git/sympy$ >> >> Note that when I updated I deleted latex_out.py and replaced it with >> latex_ex.py. Does this information need to be put in some configuration >> file or is it all automatic now. I remember that that when I first >> submitted >> GAsympy.py and latex_out.py the file names had to be added to some >> python setup file? >> > > Yes, you need to do: > > $ git add sympy/galgebra/latex_ex.py > > Then the file will get added when you do "git ci" or "git ci -a". > > Ondrej > > > > > Trying again. Note that when I try 'git ci -a' I get //
bro...@ga:~/SYMPY-git/sympy$ git ci -a git: 'ci' is not a git-command. See 'git --help'. I used git-citool --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "sympy" group. To post to this group, send email to sympy@googlegroups.com To unsubscribe from this group, send email to sympy+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sympy?hl=en -~----------~----~----~----~------~----~------~--~---
>From d36263ef90e5a12a9cce483f8f2bba4c0c5dc36f Mon Sep 17 00:00:00 2001 From: Alan Bromborsky <bro...@ga.(none)> Date: Tue, 30 Dec 2008 15:13:42 -0500 Subject: [PATCH] Added latex_ex.py to repository list --- sympy/galgebra/latex_ex.py | 1102 ++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 1102 insertions(+), 0 deletions(-) create mode 100644 sympy/galgebra/latex_ex.py diff --git a/sympy/galgebra/latex_ex.py b/sympy/galgebra/latex_ex.py new file mode 100644 index 0000000..d443e0e --- /dev/null +++ b/sympy/galgebra/latex_ex.py @@ -0,0 +1,1102 @@ +#latex_ex.py + +import sys,os,types,StringIO + +from sympy.core import S, C, Basic, Symbol +from sympy.printing.printer import Printer +from sympy.simplify import fraction +import re as regrep +import sympy.galgebra.GAsympy +import numpy + +def debug(tstr): + return + +def len_cmp(str1,str2): + return(len(str2)-len(str1)) + +def process_equals(xstr): + eq1 = xstr.find('=') + eq2 = xstr.rfind('=') + if eq1 == eq2: + return(xstr) + xstr = xstr[:eq1]+xstr[eq2:] + return(xstr) + +class LaTeXPrinter(Printer): + """ + A printer class which converts an expression into its LaTeX equivalent. This + class extends the LatexPrinter class currently in sympy in the following ways: + + 1. Variable and function names can now encode multiple greek symbols, + number, greek, and roman super and sub scipts and accents plus bold + math in an alphanumeric ascii string consisting of [A-Za-z0-9_] + symbols + 1 - Accents and bold math are implemented in reverse notation. For + example if you wished the LaTeX output to be '\bm{\hat{\sigma}}' + you would give the variable the name sigmahatbm. + 2 - Subscripts are denoted by a single underscore and superscripts + by a double underscore so that A_{\rho\beta}^{25} would be + input as A_rhobeta__25. + 2. Some standard function names have been improved such as asin is now + denoted by Sin^{-1} and log by ln. + 3. Several LaTeX formats for multivectors are available: + 1 - Print multivector on one line + 2 - Print each grade of multivector on one line + 3 - Print each base of multivector on one line + 4. A LaTeX output for numpy arrays containing sympy expressions is + implemented for upto a three dimensional array. + 5. LaTeX formatting for raw LaTeX, eqnarray, and array is available + in simple output strings. + 1 - The delimeter for rew LaTeX imput is '%'. The raw input starts + on the line where '%' is first encountered and continues untill + the next line where '%' is encountered. It does not matter where + '%' is in the line. + 2 - The delimeter for eqnarray input is '@'. The rules are the same + as for raw input except that '=' in the first line is replaced + be '&=&' and '\begin{eqnarray*}' is added before the first line + and '\end{eqnarray*}' to after the last line in the group of + lines. + 3 - The delimeter for array input is '#'. The rules are the same + as for raw input except that '\begin{equation*}' is added before + the first line and '\end{equation*}' to after the last line in + the group of lines. + 6. Additonal formats for partial derivatives: + 0 - Same as sympy latex module + 1 - Use subscript notation with partial symbol to indicate which + variable the differentiation is with respect to. Symbol is of + form \partial_{differentiation variable} + + """ + + #printmethod ='_latex_ex_' + sym_fmt = 0 + fct_fmt = 0 + pdiff_fmt = 0 + mv_fmt = 0 + str_fmt = 1 + LaTeX_flg = False + + mode = ('_','^') + + fmt_dict = {'sym':0,'fct':0,'pdiff':0,'mv':0,'str':1} + + fct_dict = {'sin':'sin','cos':'cos','tan':'tan','cot':'cot',\ + 'asin':'Sin^{-1}','acos':'Cos^{-1}',\ + 'atan':'Tan^{-1}','acot':'Cot^{-1}',\ + 'sinh':'sinh','cosh':'cosh','tanh':'tanh','coth':'coth',\ + 'asinh':'Sinh^{-1}','acosh':'Cosh^{-1}', + 'atanh':'Tanh^{-1}','acoth':'Coth^{-1}',\ + 'sqrt':'sqrt','exp':'exp','log':'ln'} + + fct_dict_keys = fct_dict.keys() + + greek_keys = sorted(('alpha','beta','gamma','delta','varepsilon','epsilon','zeta',\ + 'vartheta','theta','iota','kappa','lambda','mu','nu','xi',\ + 'varpi','pi','rho','varrho','varsigma','sigma','tau','upsilon',\ + 'varphi','phi','chi','psi','omega','Gamma','Delta','Theta',\ + 'Lambda','Xi','Pi','Sigma','Upsilon','Phi','Psi','Omega','partial',\ + 'nabla','eta'),len_cmp) + + accent_keys = sorted(('hat','check','dot','breve','acute','ddot','grave','tilde',\ + 'mathring','bar','vec','bm','prm','abs'),len_cmp) + + greek_cnt = 0 + greek_dict = {} + accent_cnt = 0 + accent_dict = {} + + preamble = '\\documentclass[10pt,letter,fleqn]{report}\n'+\ + '\\pagestyle{empty}\n'+\ + '\\usepackage[latin1]{inputenc}\n'+\ + '\\usepackage[dvips,landscape,top=1cm,nohead,nofoot]{geometry}\n'+\ + '\\usepackage{amsmath}\n'+\ + '\\usepackage{bm}\n'+\ + '\\usepackage{amsfonts}\n'+\ + '\\usepackage{amssymb}\n'+\ + '\\setlength{\\parindent}{0pt}\n'+\ + '\\newcommand{\\bfrac}[2]{\\displaystyle\\frac{#1}{#2}}\n'+\ + '\\newcommand{\\lp}{\\left (}\n'+\ + '\\newcommand{\\rp}{\\right )}\n'+\ + '\\newcommand{\\half}{\\frac{1}{2}}\n'+\ + '\\newcommand{\\llt}{\\left <}\n'+\ + '\\newcommand{\\rgt}{\\right >}\n'+\ + '\\newcommand{\\abs}[1]{\\left |{#1}\\right | }\n'+\ + '\\newcommand{\\pdiff}[2]{\\bfrac{\\partial {#1}}{\\partial {#2}}}\n'+\ + '\\newcommand{\\lbrc}{\\left \\{}\n'+\ + '\\newcommand{\\rbrc}{\\right \\}}\n'+\ + '\\newcommand{\\W}{\\wedge}\n'+\ + "\\newcommand{\\prm}[1]{{#1}'}\n"+\ + '\\newcommand{\\ddt}[1]{\\bfrac{d{#1}}{dt}}\n'+\ + '\\newcommand{\\R}{\\dagger}\n'+\ + '\\begin{document}\n' + postscript = '\\end{document}\n' + + @staticmethod + def latex_bases(): + """ + Generate LaTeX strings for multivector bases + """ + if type(sympy.galgebra.GAsympy.MV.basislabel_lst) == types.IntType: + sys.stderr.write('MV.setup() must be executed before LaTeXPrinter.format()!\n') + sys.exit(1) + LaTeXPrinter.latexbasis_lst = [['']] + for grades in sympy.galgebra.GAsympy.MV.basislabel_lst[1:]: + grades_lst = [] + for grade in grades: + grade_lst = [] + for base in grade: + latex_base = LaTeXPrinter.extended_symbol(base) + grade_lst.append(latex_base) + grades_lst.append(grade_lst) + LaTeXPrinter.latexbasis_lst.append(grades_lst) + return + + @staticmethod + def build_base(igrade,iblade,bld_flg): + if igrade == 0: + return('') + base_lst = LaTeXPrinter.latexbasis_lst[igrade][iblade] + if len(base_lst) == 1: + return(base_lst[0]) + base_str = '' + for base in base_lst[:-1]: + if bld_flg: + base_str += base+'\\W ' + else: + base_str += base + base_str += base_lst[-1] + return(base_str) + + @staticmethod + def format(sym=0,fct=0,pdiff=0,mv=0): + LaTeXPrinter.LaTeX_flg = True + LaTeXPrinter.fmt_dict['sym'] = sym + LaTeXPrinter.fmt_dict['fct'] = fct + LaTeXPrinter.fmt_dict['pdiff'] = pdiff + LaTeXPrinter.fmt_dict['mv'] = mv + LaTeXPrinter.fmt_dict['str'] = 1 + if sympy.galgebra.GAsympy.MV.is_setup: + LaTeXPrinter.latex_bases() + LaTeXPrinter.redirect() + return + + @staticmethod + def str_basic(in_str): + if not LaTeXPrinter.LaTeX_flg: + return(str(in_str)) + Basic.__str__ = LaTeXPrinter.Basic__str__ + out_str = str(in_str) + Basic.__str__ = LaTeX + return(out_str) + + @staticmethod + def redirect(): + LaTeXPrinter.Basic__str__ = Basic.__str__ + LaTeXPrinter.MV__str__ = sympy.galgebra.GAsympy.MV.__str__ + LaTeXPrinter.stdout = sys.stdout + sys.stdout = StringIO.StringIO() + Basic.__str__ = LaTeX + sympy.galgebra.GAsympy.MV.__str__ = LaTeX + return + + @staticmethod + def restore(): + LaTeXPrinter_stdout = sys.stdout + LaTeXPrinter_Basic__str__ = Basic.__str__ + LaTeXPrinter_MV__str__ = sympy.galgebra.GAsympy.MV.__str__ + + sys.stdout = LaTeXPrinter.stdout + Basic.__str__ = LaTeXPrinter.Basic__str__ + sympy.galgebra.GAsympy.MV.__str__ = LaTeXPrinter.MV__str__ + + LaTeXPrinter.stdout = LaTeXPrinter_stdout + LaTeXPrinter.Basic__str__ = LaTeXPrinter_Basic__str__ + LaTeXPrinter.MV__str__ = LaTeXPrinter_MV__str__ + return + + @staticmethod + def format_str(fmt='0 0 0 0'): + fmt_lst = fmt.split() + if '=' not in fmt: + LaTeXPrinter.fmt_dict['sym'] = int(fmt_lst[0]) + LaTeXPrinter.fmt_dict['fct'] = int(fmt_lst[1]) + LaTeXPrinter.fmt_dict['pdiff'] = int(fmt_lst[2]) + LaTeXPrinter.fmt_dict['mv'] = int(fmt_lst[3]) + else: + for fmt in fmt_lst: + x = fmt.split('=') + LaTeXPrinter.fmt_dict[x[0]] = int(x[1]) + + if LaTeXPrinter.LaTeX_flg == False: + if sympy.galgebra.GAsympy.MV.is_setup: + LaTeXPrinter.latex_bases() + LaTeXPrinter.redirect() + LaTeXPrinter.LaTeX_flg = True + return + + @staticmethod + def append_body(xstr): + if LaTeXPrinter.body_flg: + LaTeXPrinter.body += xstr + return('') + else: + return(xstr[:-1]) + + @staticmethod + def tokenize_greek(name_str): + for sym in LaTeXPrinter.greek_keys: + isym = name_str.find(sym) + if isym > -1: + keystr = '@'+str(LaTeXPrinter.greek_cnt) + LaTeXPrinter.greek_cnt += 1 + LaTeXPrinter.greek_dict[keystr] = sym + name_str = name_str.replace(sym,keystr) + return(name_str) + + @staticmethod + def tokenize_accents(name_str): + for sym in LaTeXPrinter.accent_keys: + if name_str.find(sym) > -1: + keystr = '#'+str(LaTeXPrinter.accent_cnt)+'#' + LaTeXPrinter.accent_cnt += 1 + LaTeXPrinter.accent_dict[keystr] = '\\'+sym + name_str = name_str.replace(sym,keystr) + return(name_str) + + @staticmethod + def replace_greek_tokens(name_str): + if name_str.find('@') == -1: + return(name_str) + for token in LaTeXPrinter.greek_dict.keys(): + name_str = name_str.replace(token,'{\\'+LaTeXPrinter.greek_dict[token]+'}') + LaTeXPrinter.greek_cnt = 0 + LaTeXPrinter.greek_dict = {} + return(name_str) + + @staticmethod + def replace_accent_tokens(name_str): + tmp_lst = name_str.split('#') + name_str = tmp_lst[0] + if len(tmp_lst) == 1: + return(name_str) + for x in tmp_lst[1:]: + if x != '': + name_str = '{}'+LaTeXPrinter.accent_dict['#'+x+'#']+'{'+name_str+'}' + LaTeXPrinter.accent_cnt = 0 + LaTeXPrinter.accent_dict = {} + return(name_str) + + @staticmethod + def extended_symbol(name_str): + name_str = LaTeXPrinter.tokenize_greek(name_str) + tmp_lst = name_str.split('_') + subsup_str = '' + sym_str = tmp_lst[0] + sym_str = LaTeXPrinter.tokenize_accents(sym_str) + sym_str = LaTeXPrinter.replace_accent_tokens(sym_str) + if len(tmp_lst) > 1: + imode = 0 + for x in tmp_lst[1:]: + if x == '': + imode = (imode+1)%2 + else: + subsup_str += LaTeXPrinter.mode[imode]+'{'+x+'}' + #subsup_str += LaTeXPrinter.mode[imode]+x+' ' + imode = (imode+1)%2 + name_str = sym_str+subsup_str + name_str = LaTeXPrinter.replace_greek_tokens(name_str) + return(name_str) + + def coefficient(self,coef,first_flg): + if isinstance(coef, C.AssocOp) and isinstance(-coef, C.AssocOp): + coef_str = r"\lp %s\rp " % self._print(coef) + else: + coef_str = self._print(coef) + if first_flg: + first_flg = False + if coef_str[0] == '+': + coef_str = coef_str[1:] + else: + if coef_str[0] != '-': + if coef_str[0] != '+': + coef_str = '+'+coef_str + if coef_str in ('1','+1','-1'): + if coef_str == '1': + coef_str = '' + else: + coef_str = coef_str[0] + return(coef_str,first_flg) + + def __init__(self,inline=True): + Printer.__init__(self) + self._inline = inline + + def doprint(self, expr): + tex = Printer.doprint(self, expr) + xstr = '' + + if self._inline: + if LaTeXPrinter.fmt_dict['fct'] == 1: + xstr = r"%s" % tex + else: + xstr = r"$%s$" % tex + else: + xstr = r"\begin{equation*}%s\end{equation*}" % tex + return(xstr) + + def _needs_brackets(self, expr): + return not ((expr.is_Integer and expr.is_nonnegative) or expr.is_Atom) + + def _do_exponent(self, expr, exp): + if exp is not None: + return r"\left(%s\right)^{%s}" % (expr, exp) + else: + return expr + + def _print_Add(self, expr): + tex = str(self._print(expr.args[0])) + + for term in expr.args[1:]: + coeff = term.as_coeff_terms()[0] + + if coeff.is_negative: + tex += r" %s" % self._print(term) + else: + tex += r" + %s" % self._print(term) + + return tex + + def _print_Mul(self, expr): + coeff, terms = expr.as_coeff_terms() + + if not coeff.is_negative: + tex = "" + else: + coeff = -coeff + tex = "- " + + numer, denom = fraction(C.Mul(*terms)) + + def convert(terms): + product = [] + + if not terms.is_Mul: + return str(self._print(terms)) + else: + for term in terms.args: + pretty = self._print(term) + + if term.is_Add: + product.append(r"\left(%s\right)" % pretty) + else: + product.append(str(pretty)) + + return r" ".join(product) + + if denom is S.One: + if coeff is not S.One: + tex += str(self._print(coeff)) + " " + + if numer.is_Add: + tex += r"\left(%s\right)" % convert(numer) + else: + tex += r"%s" % convert(numer) + else: + if numer is S.One: + if coeff.is_Integer: + numer *= coeff.p + elif coeff.is_Rational: + if coeff.p != 1: + numer *= coeff.p + + denom *= coeff.q + elif coeff is not S.One: + tex += str(self._print(coeff)) + " " + else: + if coeff.is_Rational and coeff.p == 1: + denom *= coeff.q + elif coeff is not S.One: + tex += str(self._print(coeff)) + " " + + tex += r"\frac{%s}{%s}" % \ + (convert(numer), convert(denom)) + + return tex + + def _print_Pow(self, expr): + if expr.exp.is_Rational and expr.exp.q == 2: + base, exp = self._print(expr.base), abs(expr.exp.p) + + if exp == 1: + tex = r"\sqrt{%s}" % base + else: + tex = r"\sqrt[%s]{%s}" % (exp, base) + + if expr.exp.is_negative: + return r"\frac{1}{%s}" % tex + else: + return tex + else: + if expr.base.is_Function: + return self._print(expr.base, self._print(expr.exp)) + else: + if expr.exp == S.NegativeOne: + #solves issue 1030 + #As Mul always simplify 1/x to x**-1 + #The objective is achieved with this hack + #first we get the latex for -1 * expr, + #which is a Mul expression + tex = self._print(S.NegativeOne * expr).strip() + #the result comes with a minus and a space, so we remove + if tex[:1] == "-": + return tex[1:].strip() + if self._needs_brackets(expr.base): + tex = r"\left(%s\right)^{%s}" + else: + tex = r"{%s}^{%s}" + + return tex % (self._print(expr.base), + self._print(expr.exp)) + + def _print_Derivative(self, expr): + dim = len(expr.symbols) + + if dim == 1: + if LaTeXPrinter.fmt_dict['pdiff'] == 1: + tex = r'\partial_{%s}' % self._print(expr.symbols[0]) + else: + tex = r"\frac{\partial}{\partial %s}" % self._print(expr.symbols[0]) + else: + multiplicity, i, tex = [], 1, "" + current = expr.symbols[0] + for symbol in expr.symbols[1:]: + if symbol == current: + i = i + 1 + else: + multiplicity.append((current, i)) + current, i = symbol, 1 + else: + multiplicity.append((current, i)) + + if LaTeXPrinter.fmt_dict['pdiff'] == 1: + for x, i in multiplicity: + if i == 1: + tex += r"\partial_{%s}" % self._print(x) + else: + tex += r"\partial^{%s}_{%s}" % (i, self._print(x)) + else: + for x, i in multiplicity: + if i == 1: + tex += r"\partial %s" % self._print(x) + else: + tex += r"\partial^{%s} %s" % (i, self._print(x)) + + tex = r"\frac{\partial^{%s}}{%s} " % (dim, tex) + + if isinstance(expr.expr, C.AssocOp): + return r"%s\left(%s\right)" % (tex, self._print(expr.expr)) + else: + return r"%s %s" % (tex, self._print(expr.expr)) + + def _print_Integral(self, expr): + tex, symbols = "", [] + + for symbol, limits in reversed(expr.limits): + tex += r"\int" + + if limits is not None: + if not self._inline: + tex += r"\limits" + + tex += "_{%s}^{%s}" % (self._print(limits[0]), + self._print(limits[1])) + + symbols.insert(0, "d%s" % self._print(symbol)) + + return r"%s %s\,%s" % (tex, + str(self._print(expr.function)), " ".join(symbols)) + + def _print_Limit(self, expr): + tex = r"\lim_{%s \to %s}" % (self._print(expr.var), + self._print(expr.varlim)) + + if isinstance(expr.expr, C.AssocOp): + return r"%s\left(%s\right)" % (tex, self._print(expr.expr)) + else: + return r"%s %s" % (tex, self._print(expr.expr)) + + def _print_Function(self, expr, exp=None): + func = expr.func.__name__ + + if hasattr(self, '_print_' + func): + return getattr(self, '_print_' + func)(expr, exp) + else: + args = [ str(self._print(arg)) for arg in expr.args ] + + if LaTeXPrinter.fmt_dict['fct'] == 1: + if func in LaTeXPrinter.fct_dict_keys: + if exp is not None: + name = r"\operatorname{%s}^{%s}" % (LaTeXPrinter.fct_dict[func], exp) + else: + name = r"\operatorname{%s}" % LaTeXPrinter.fct_dict[func] + name += r"\left(%s\right)" % ",".join(args) + return name + else: + func = self.print_Symbol_name(func) + if exp is not None: + name = r"{%s}^{%s}" % (func, exp) + else: + name = r"{%s}" % func + return name + else: + if exp is not None: + name = r"\operatorname{%s}^{%s}" % (func, exp) + else: + name = r"\operatorname{%s}" % func + return name + r"\left(%s\right)" % ",".join(args) + + def _print_floor(self, expr, exp=None): + tex = r"\lfloor{%s}\rfloor" % self._print(expr.args[0]) + + if exp is not None: + return r"%s^{%s}" % (tex, exp) + else: + return tex + + def _print_ceiling(self, expr, exp=None): + tex = r"\lceil{%s}\rceil" % self._print(expr.args[0]) + + if exp is not None: + return r"%s^{%s}" % (tex, exp) + else: + return tex + + def _print_abs(self, expr, exp=None): + tex = r"\lvert{%s}\rvert" % self._print(expr.args[0]) + + if exp is not None: + return r"%s^{%s}" % (tex, exp) + else: + return tex + + def _print_re(self, expr, exp=None): + if self._needs_brackets(expr.args[0]): + tex = r"\Re\left(%s\right)" % self._print(expr.args[0]) + else: + tex = r"\Re{%s}" % self._print(expr.args[0]) + + return self._do_exponent(tex, exp) + + def _print_im(self, expr, exp=None): + if self._needs_brackets(expr.args[0]): + tex = r"\Im\left(%s\right)" % self._print(expr.args[0]) + else: + tex = r"\Im{%s}" % self._print(expr.args[0]) + + return self._do_exponent(tex, exp) + + def _print_conjugate(self, expr, exp=None): + tex = r"\overline{%s}" % self._print(expr.args[0]) + + if exp is not None: + return r"%s^{%s}" % (tex, exp) + else: + return tex + + def _print_exp(self, expr, exp=None): + tex = r"{e}^{%s}" % self._print(expr.args[0]) + return self._do_exponent(tex, exp) + + def _print_gamma(self, expr, exp=None): + tex = r"\left(%s\right)" % self._print(expr.args[0]) + + if exp is not None: + return r"\operatorname{\Gamma}^{%s}%s" % (exp, tex) + else: + return r"\operatorname{\Gamma}%s" % tex + + def _print_Factorial(self, expr, exp=None): + x = expr.args[0] + if self._needs_brackets(x): + tex = r"\left(%s\right)!" % self._print(x) + else: + tex = self._print(x) + "!" + + if exp is not None: + return r"%s^{%s}" % (tex, exp) + else: + return tex + + def _print_Binomial(self, expr, exp=None): + tex = r"{{%s}\choose{%s}}" % (self._print(expr[0]), + self._print(expr[1])) + + if exp is not None: + return r"%s^{%s}" % (tex, exp) + else: + return tex + + def _print_RisingFactorial(self, expr, exp=None): + tex = r"{\left(%s\right)}^{\left(%s\right)}" % \ + (self._print(expr[0]), self._print(expr[1])) + + return self._do_exponent(tex, exp) + + def _print_FallingFactorial(self, expr, exp=None): + tex = r"{\left(%s\right)}_{\left(%s\right)}" % \ + (self._print(expr[0]), self._print(expr[1])) + + return self._do_exponent(tex, exp) + + def _print_Rational(self, expr): + if expr.q != 1: + sign = "" + p = expr.p + if expr.p < 0: + sign = "- " + p = -p + return r"%s\frac{%d}{%d}" % (sign, p, expr.q) + else: + return self._print(expr.p) + + def _print_Infinity(self, expr): + return r"\infty" + + def _print_NegativeInfinity(self, expr): + return r"-\infty" + + def _print_ComplexInfinity(self, expr): + return r"\tilde{\infty}" + + def _print_ImaginaryUnit(self, expr): + return r"\mathbf{\imath}" + + def _print_NaN(self, expr): + return r"\bot" + + def _print_Pi(self, expr): + return r"\pi" + + def _print_Exp1(self, expr): + return r"e" + + def _print_EulerGamma(self, expr): + return r"\gamma" + + def _print_Order(self, expr): + return r"\operatorname{\mathcal{O}}\left(%s\right)" % \ + self._print(expr.args[0]) + + @staticmethod + def print_Symbol_name(name_str): + if len(name_str) == 1: + return (name_str) + if LaTeXPrinter.fmt_dict['sym'] == 1: + return LaTeXPrinter.extended_symbol(name_str) + else: + return(name_str) + """ + #convert trailing digits to subscript + m = regrep.match('(^[a-zA-Z]+)([0-9]+)$',name_str) + if m is not None: + name, sub=m.groups() + tex=self._print_Symbol(Symbol(name)) + tex="%s_{%s}" %(tex, sub) + return tex + + # insert braces to expresions containing '_' or '^' + m = regrep.match('(^[a-zA-Z0-9]+)([_\^]{1})([a-zA-Z0-9]+)$',name_str) + if m is not None: + name, sep, rest=m.groups() + tex=self._print_Symbol(Symbol(name)) + tex="%s%s{%s}" %(tex, sep, rest) + return tex + + greek = set([ 'alpha', 'beta', 'gamma', 'delta', 'epsilon', 'zeta', + 'eta', 'theta', 'iota', 'kappa', 'lambda', 'mu', 'nu', + 'xi', 'omicron', 'pi', 'rho', 'sigma', 'tau', 'upsilon', + 'phi', 'chi', 'psi', 'omega' ]) + + other = set( ['aleph', 'beth', 'daleth', 'gimel', 'ell', 'eth', + 'hbar', 'hslash', 'mho' ]) + + if name_str.lower() in greek: + return "\\" + name_str + elif name_str in other: + return "\\" + name_str + else: + return name_str + """ + + def _print_Symbol(self, expr): + return LaTeXPrinter.print_Symbol_name(expr.name) + + def _print_str(self,expr): + if LaTeXPrinter.fmt_dict['str'] > 0: + expr = expr.replace('^','{\\wedge}') + expr = expr.replace('|','{\\cdot}') + expr = expr.replace('__','^') + return(expr) + + def _print_ndarray(self,expr): + shape = numpy.shape(expr) + ndim = len(shape) + expr_str = '' + + if ndim == 1: + expr_str += '#\\left [ \\begin{array}{'+shape[0]*'c'+'} \n' + for col in expr: + expr_str += self._print(col)+' & ' + expr_str = expr_str[:-2]+'\n\\end{array}\\right ]#\n' + return(expr_str) + + if ndim == 2: + expr_str += '#\\left [ \\begin{array}{'+shape[1]*'c'+'} \n' + for row in expr[:-1]: + for xij in row[:-1]: + expr_str += self._print(xij) + ' & ' + expr_str += self._print(row[-1]) + ' \\\\ \n' + for xij in expr[-1][:-1]: + expr_str += self._print(xij) + ' & ' + expr_str += self._print(expr[-1][-1]) + '\n \\end{array} \\right ] #\n' + return(expr_str) + + if ndim == 3: + expr_str = '#\\left \\{ \\begin{array}{'+shape[0]*'c'+'} \n' + for x in expr[:-1]: + xstr = self._print(x).replace('#','') + expr_str += xstr + ' , & ' + xstr = self._print(expr[-1]).replace('#','') + expr_str += xstr+'\n\\end{array} \\right \\}#\n' + return(expr_str) + + def _print_MV(self,expr): + igrade = 0 + MV_str = '' + line_lst = [] + first_flg = True + for grade in expr.mv: + if type(grade) != types.IntType: + if type(grade) != types.IntType: + ibase = 0 + for base in grade: + if base != 0: + tmp = Symbol('XYZW') + base_str = str(base*tmp) + if base_str[0] != '-': + base_str = '+'+base_str + base_str = base_str.replace('- ','-') + if base_str[1:5] == 'XYZW': + base_str = base_str.replace('XYZW','') + else: + base_str = base_str.replace('XYZW','1') + MV_str += base_str+\ + LaTeXPrinter.build_base(igrade,ibase,expr.bladeflg) + if LaTeXPrinter.fmt_dict['mv'] == 3: + line_lst.append(MV_str) + MV_str = '' + ibase += 1 + if LaTeXPrinter.fmt_dict['mv'] == 2: + if MV_str != '': + line_lst.append(MV_str) + MV_str = '' + igrade += 1 + n_lines = len(line_lst) + if MV_str == '': + if n_lines > 0 and line_lst[0][0] == '+': + line_lst[0] = line_lst[0][1:] + else: + if MV_str[0] == '+': + MV_str = MV_str[1:] + if n_lines == 1: + MV_str = line_lst[0] + n_lines = 0 + if LaTeXPrinter.fmt_dict['mv'] >= 2: + MV_str = '@'+line_lst[0]+' \\\\ \n' + for line in line_lst[1:-1]: + MV_str += '& '+line+' \\\\ \n' + MV_str += '& '+line_lst[-1]+'@\n' + if MV_str == '': + MV_str = '0' + if expr.name != '': + MV_str = LaTeXPrinter.extended_symbol(expr.name)+' = '+MV_str + return(MV_str) + + def _print_Relational(self, expr): + charmap = { + "==" : "=", + "<" : "<", + "<=" : r"\leq", + "!=" : r"\neq", + } + + return "%s %s %s" % (self._print(expr.lhs), + charmap[expr.rel_op], self._print(expr.rhs)) + + def _print_Matrix(self, expr): + lines = [] + + for line in range(expr.lines): # horrible, should be 'rows' + lines.append(" & ".join([ self._print(i) for i in expr[line,:] ])) + + if self._inline: + tex = r"\left(\begin{smallmatrix}%s\end{smallmatrix}\right)" + else: + tex = r"\begin{pmatrix}%s\end{pmatrix}" + + return tex % r"\\".join(lines) + + def _print_tuple(self, expr): + return r"\begin{pmatrix}%s\end{pmatrix}" % \ + r", & ".join([ self._print(i) for i in expr ]) + + def _print_list(self, expr): + return r"\begin{bmatrix}%s\end{bmatrix}" % \ + r", & ".join([ self._print(i) for i in expr ]) + + def _print_dict(self, expr): + items = [] + + keys = expr.keys() + keys.sort(Basic.compare_pretty) + for key in keys: + val = expr[key] + items.append("%s : %s" % (self._print(key), self._print(val))) + + return r"\begin{Bmatrix}%s\end{Bmatrix}" % r", & ".join(items) + + def _print_DiracDelta(self, expr): + if len(expr.args) == 1 or expr.args[1] == 0: + tex = r"\delta\left(%s\right)" % self._print(expr.args[0]) + else: + tex = r"\delta^{\left( %s \right)}\left( %s \right)" % (\ + self._print(expr.args[1]), self._print(expr.args[0])) + return tex + +def LaTeX(expr, inline=True): + """ + Convert the given expression to LaTeX representation. + + You can specify how the generated code will be delimited. + If the 'inline' keyword is set then inline LaTeX $ $ will + be used. Otherwise the resulting code will be enclosed in + 'equation*' environment (remember to import 'amsmath'). + + >>> from sympy import * + >>> from sympy.abc import * + + >>> latex((2*tau)**Rational(7,2)) + '$8 \\sqrt{2} \\sqrt[7]{\\tau}$' + + >>> latex((2*mu)**Rational(7,2), inline=False) + '\\begin{equation*}8 \\sqrt{2} \\sqrt[7]{\\mu}\\end{equation*}' + + Besides all Basic based expressions, you can recursively + convert Pyhon containers (lists, tuples and dicts) and + also SymPy matrices: + + >>> latex([2/x, y]) + '$\\begin{bmatrix}\\frac{2}{x}, & y\\end{bmatrix}$' + + The extended latex printer will also append the output to a + string (LaTeXPrinter.body) that will be processed by xdvi() + for immediate display one xdvi() is called. + """ + + xstr = LaTeXPrinter(inline).doprint(expr) + #xstr = LaTeXPrinter.append_body(xstr+'\n') + return (xstr) + +def print_LaTeX(expr): + """Prints LaTeX representation of the given expression.""" + print LaTeX(expr) + +def Format(fmt='1 1 1 1'): + LaTeXPrinter.format_str(fmt) + return + +def xdvi(filename='tmplatex.tex',debug=False): + """ + Post processes LaTeX output (see comments below), adds preamble and + postscript, generates tex file, inputs file to latex, displays resulting + dvi file with xdvi. + """ + if not LaTeXPrinter.LaTeX_flg: + return + body = sys.stdout.getvalue() + LaTeXPrinter.restore() + + body_lst = body.split('\n') + body = '' + array_flg = False + eqnarray_flg = False + raw_flg = False + nline = len(body_lst) + iline = 0 + i = iter(body_lst) + line = i.next() + while True: + if '$' in line: #Inline math expression(s) + line += '\\newline \n' + body += line + try: + line = i.next() + except StopIteration: + break + + elif '%' in line: #Raw LaTeX input + """ + If % in line assume line is beginning of raw LaTeX input and stop + post processing + """ + line = line.replace('%','') + raw_flg = True + while raw_flg: + if '%' in line: + """ + If % in line assume line is end of LaTeX input and begin + post processing + """ + raw_flg = False + line = line.replace('%','')+'\n' + else: + line += '\n' + line = process_equals(line) + body += line + try: + line = i.next() + except StopIteration: + break + + elif '#' in line: #Array input + """ + If # in line assume line is beginning of array input and contains + \begin{array} statement + """ + line = line.replace('#','') + array_flg = True + line = '\\begin{equation*}\n'+line + while array_flg: + if '#' in line: + """ + If # in line assume line is end of array input and contains + \end{array} statment + """ + array_flg = False + line = line.replace('#','') + line += '\\end{equation*}\n' + else: + line += '\n' + line = process_equals(line) + body += line + try: + line = i.next() + except StopIteration: + break + + elif '@' in line: #Align input + """ + If @ in line assume line is beginning of align input + """ + line = line.replace('@','') + line = line.replace('=','& = ') + eqnarray_flg = True + line = '\\begin{align*}\n'+line + line = process_equals(line) + body += line + try: + line = i.next() + except StopIteration: + break + while eqnarray_flg: + if '@' in line: + """ + If @ in line assume line is end of align input + """ + eqnarray_flg = False + line = line.replace('@','') + line += '\\end{align*}\n' + else: + line+'\n' + line = process_equals(line) + body += line + try: + line = i.next() + except StopIteration: + break + + else: + if '=' in line: #Single line equation + line = '\\begin{equation*}\n'+line+'\n\\end{equation*}\n' + else: #Text with no math expression(s) + line += '\\newline \n' + line = process_equals(line) + body += line + try: + line = i.next() + except StopIteration: + break + body = LaTeXPrinter.preamble+body+LaTeXPrinter.postscript + latex_file = open(filename,'w') + latex_file.write(body) + latex_file.close() + if debug: #Display latex excution output for debugging purposes + os.system('latex '+filename[:-4]) + else: #Works for Linux don't know about Windows + os.system('latex '+filename[:-4]+' > /dev/null') + os.system('xdvi '+filename[:-4]+' &') + LaTeXPrinter.LaTeX_flg = False + return + +def MV_format(mv_fmt): + """ + 0 or 1 - Print multivector on one line + 2 - Print each multivector grade on one line + 3 - Print each multivector base on one line + """ + LaTeXPrinter.fmt_dict['mv'] = mv_fmt + return + +def fct_format(fct_fmt): + """ + 0 - Default sympy latex format + 1 - Do not print arguments of arbitrary functions. + Use symbol font for arbitrary functions. + Use enhanced symbol nameing for arbitrary functions. + Use new names for standard functions (acos -> Cos^{-1}) + """ + LaTeXPrinter.fct = fct_fmt + return + +def pdiff_format(pdiff_fmt): + """ + 0 - Use default sympy partial derivative format + 1 - Contracted derivative format (no fraction symbols) + """ + LaTeXPrinter.fmt_dict['pdiff'] = pdiff_fmt + return + +def sym_format(sym_fmt): + """ + 0 - Use default sympy format + 1 - Ues extended symbol format including multiple greek letters in + basic symbol (symbol precceeding sub and superscripts)and in + sub and superscripts of basic symbol and accents in basic symbol + """ + LaTeXPrinter.fmt_dict['sym'] = sym_fmt + return + +def str_format(str_fmt): + """ + 0 - Use default sympy format + 1 - Ues extended symbol format including multiple greek letters in + basic symbol (symbol precceeding sub and superscripts)and in + sub and superscripts of basic symbol and accents in basic symbol + """ + LaTeXPrinter.fmt_dict['str'] = str_fmt + return + +def ext_str(xstr): + return(LaTeXPrinter.extended_symbol(xstr)) + -- 1.5.6.3