/

# Source code for sympy.galgebra.latex_ex

#latex_ex.py

from __future__ import with_statement

import sys
#if sys.version.find('Stackless') >= 0:
#    sys.path.append('/usr/lib/python2.5/site-packages')

import types
import StringIO

from sympy.core import S, C, Basic, Symbol
from sympy.core.function import _coeff_isneg
from sympy.printing.printer import Printer
from sympy.simplify import fraction
import re as regrep

import sympy.galgebra.GA
#import sympy.galgebra.OGA
import numpy

from sympy.core.compatibility import cmp_to_key
from sympy.utilities import default_sort_key

from sympy.printing.latex import accepted_latex_functions
from sympy.printing.preview import preview

def debug(txt):
sys.stderr.write(txt + '\n')
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)

[docs]class LatexPrinter(Printer):
r"""
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 subscripts and accents plus bold
math in an alphanumeric ASCII string consisting of [A-Za-z0-9_]
symbols

a)  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.

b)  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:

a)  Print multivector on one line

b)  Print each grade of multivector on one line

c)  Print each base of multivector on one line

4.  A LaTeX output for numpy arrays containing sympy expressions is
implemented for up to a three dimensional array.

5.  LaTeX formatting for raw LaTeX, eqnarray, and array is available
in simple output strings.

a)  The delimiter for raw LaTeX input is '%'.  The raw input starts
on the line where '%' is first encountered and continues until
the next line where '%' is encountered. It does not matter where
'%' is in the line.

b)  The delimiter 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.

c)  The delimiter 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.  Additional formats for partial derivatives:

a)  Same as sympy latex module

b)  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'), key=cmp_to_key(len_cmp))

accent_keys = sorted(
('hat', 'check', 'dot', 'breve', 'acute', 'ddot', 'grave', 'tilde',
'mathring', 'bar', 'vec', 'bm', 'prm', 'abs'), key=cmp_to_key(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{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'

@staticmethod
[docs]    def latex_bases():
"""
Generate LaTeX strings for multivector bases
"""
if isinstance(sympy.galgebra.GA.MV.basislabel_lst, types.IntType):
sys.stderr.write(
'MV.setup() must be executed before LatexPrinter.format()!\n')
sys.exit(1)
LatexPrinter.latexbasis_lst = [['']]
latex_base = LatexPrinter.extended_symbol(base)
return

@staticmethod
return('')
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.GA.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.GA.MV.__str__
LatexPrinter.stdout = sys.stdout
sys.stdout = StringIO.StringIO()
Basic.__str__ = LaTeX
sympy.galgebra.GA.MV.__str__ = LaTeX
return

@staticmethod
def restore():
LatexPrinter_stdout = sys.stdout
LatexPrinter_Basic__str__ = Basic.__str__
LatexPrinter_MV__str__ = sympy.galgebra.GA.MV.__str__

sys.stdout = LatexPrinter.stdout
Basic.__str__ = LatexPrinter.Basic__str__
sympy.galgebra.GA.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 is False:
if sympy.galgebra.GA.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

tex = str(self._print(expr.args[0]))

for term in expr.args[1:]:
if _coeff_isneg(term):
tex += r" %s" % self._print(term)
else:
tex += r" + %s" % self._print(term)

return tex

def _print_Mul(self, expr):
coeff, tail = expr.as_coeff_Mul()

if coeff.is_negative:
coeff = -coeff
tex = "- "
else:
tex = ""

numer, denom = fraction(tail)

def convert(terms):
product = []

if not terms.is_Mul:
return str(self._print(terms))
else:
for term in terms.args:
pretty = self._print(term)

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)) + " "

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.variables)

if dim == 1:
if LatexPrinter.fmt_dict['pdiff'] == 1:
tex = r'\partial_{%s}' % self._print(expr.variables[0])
else:
tex = r"\frac{\partial}{\partial %s}" % self._print(
expr.variables[0])
else:
multiplicity, i, tex = [], 1, ""
current = expr.variables[0]
for symbol in expr.variables[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:
if func in accepted_latex_functions:
name = r"\%s^{%s}" % (
LatexPrinter.fct_dict[func], exp)
else:
name = r"\operatorname{%s}^{%s}" % (
LatexPrinter.fct_dict[func], exp)
else:
if LatexPrinter.fct_dict[func] in accepted_latex_functions:
name = r"\%s" % LatexPrinter.fct_dict[func]
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:
if func in accepted_latex_functions:
name = r"\%s^{%s}" % (func, exp)
else:
name = r"\operatorname{%s}^{%s}" % (func, exp)
else:
if func in accepted_latex_functions:
name = r"\%s" % func
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"\Gamma^{%s}%s" % (exp, tex)
else:
return r"\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_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"\\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):
MV_str = ''
line_lst = []
ibase = 0
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(
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 = ''
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_OMV(self, expr):
MV_str = ''
line_lst = []
ibase = 0
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(
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 = ''
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(key=default_sort_key)
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

[docs]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 Rational
>>> from sympy.abc import tau, mu, x, y
>>> from sympy.galgebra.latex_ex import LaTeX

>>> 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 Python 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)
return (xstr)

[docs]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

[docs]def xdvi(filename='tmplatex.tex', debug=False):
"""
postscript, generates tex file, inputs file to latex, displays resulting
dvi file with xdvi or yap.
"""
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
i = iter(body_lst)
line = i.next()

while True:
if '\$' in line:  # Inline math expression(s)
if len(line) > 0:
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} statement
"""
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*}'
else:  # Text with no math expression(s)unless \ or _ in line
if '\\' in line or '_' in line or '^' in line:
line = '\\begin{equation*}\n' + line + '\n\\end{equation*}'
else:
if len(line) > 0:
line += '\\newline \n'
line = process_equals(line)
body += line
try:
line = i.next()
except StopIteration:
break
preview(body, output='dvi', outputTexFile=filename,
preamble=LatexPrinter.preamble)
LatexPrinter.LaTeX_flg = False
return

[docs]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
"""
if LatexPrinter.LaTeX_flg:
LatexPrinter.fmt_dict['mv'] = mv_fmt
return

[docs]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 naming for arbitrary functions.
Use new names for standard functions (acos -> Cos^{-1})

"""
if LatexPrinter.LaTeX_flg:
LatexPrinter.fct = fct_fmt
return

[docs]def pdiff_format(pdiff_fmt):
"""
0 - Use default sympy partial derivative format

1 - Contracted derivative format (no fraction symbols)
"""
if LatexPrinter.LaTeX_flg:
LatexPrinter.fmt_dict['pdiff'] = pdiff_fmt
return

[docs]def sym_format(sym_fmt):
"""
0 - Use default sympy format

1 - Use extended symbol format including multiple Greek letters in
basic symbol (symbol preceding sub and superscripts)and in
sub and superscripts of basic symbol and accents in basic symbol

"""
if LatexPrinter.LaTeX_flg:
LatexPrinter.fmt_dict['sym'] = sym_fmt
return

[docs]def str_format(str_fmt):
"""
0 - Use default sympy format

1 - Use extended symbol format including multiple Greek letters in
basic symbol (symbol preceding sub and superscripts)and in
sub and superscripts of basic symbol and accents in basic symbol

"""
if LatexPrinter.LaTeX_flg:
LatexPrinter.fmt_dict['str'] = str_fmt
return

def ext_str(xstr):
return(LatexPrinter.extended_symbol(xstr))