| import itertools |
|
|
| from sympy.core import S |
| from sympy.core.add import Add |
| from sympy.core.containers import Tuple |
| from sympy.core.function import Function |
| from sympy.core.mul import Mul |
| from sympy.core.numbers import Number, Rational |
| from sympy.core.power import Pow |
| from sympy.core.sorting import default_sort_key |
| from sympy.core.symbol import Symbol |
| from sympy.core.sympify import SympifyError |
| from sympy.printing.conventions import requires_partial |
| from sympy.printing.precedence import PRECEDENCE, precedence, precedence_traditional |
| from sympy.printing.printer import Printer, print_function |
| from sympy.printing.str import sstr |
| from sympy.utilities.iterables import has_variety |
| from sympy.utilities.exceptions import sympy_deprecation_warning |
|
|
| from sympy.printing.pretty.stringpict import prettyForm, stringPict |
| from sympy.printing.pretty.pretty_symbology import hobj, vobj, xobj, \ |
| xsym, pretty_symbol, pretty_atom, pretty_use_unicode, greek_unicode, U, \ |
| pretty_try_use_unicode, annotated, is_subscriptable_in_unicode, center_pad, root as nth_root |
|
|
| |
| pprint_use_unicode = pretty_use_unicode |
| pprint_try_use_unicode = pretty_try_use_unicode |
|
|
|
|
| class PrettyPrinter(Printer): |
| """Printer, which converts an expression into 2D ASCII-art figure.""" |
| printmethod = "_pretty" |
|
|
| _default_settings = { |
| "order": None, |
| "full_prec": "auto", |
| "use_unicode": None, |
| "wrap_line": True, |
| "num_columns": None, |
| "use_unicode_sqrt_char": True, |
| "root_notation": True, |
| "mat_symbol_style": "plain", |
| "imaginary_unit": "i", |
| "perm_cyclic": True |
| } |
|
|
| def __init__(self, settings=None): |
| Printer.__init__(self, settings) |
|
|
| if not isinstance(self._settings['imaginary_unit'], str): |
| raise TypeError("'imaginary_unit' must a string, not {}".format(self._settings['imaginary_unit'])) |
| elif self._settings['imaginary_unit'] not in ("i", "j"): |
| raise ValueError("'imaginary_unit' must be either 'i' or 'j', not '{}'".format(self._settings['imaginary_unit'])) |
|
|
| def emptyPrinter(self, expr): |
| return prettyForm(str(expr)) |
|
|
| @property |
| def _use_unicode(self): |
| if self._settings['use_unicode']: |
| return True |
| else: |
| return pretty_use_unicode() |
|
|
| def doprint(self, expr): |
| return self._print(expr).render(**self._settings) |
|
|
| |
| def _print_stringPict(self, e): |
| return e |
|
|
| def _print_basestring(self, e): |
| return prettyForm(e) |
|
|
| def _print_atan2(self, e): |
| pform = prettyForm(*self._print_seq(e.args).parens()) |
| pform = prettyForm(*pform.left('atan2')) |
| return pform |
|
|
| def _print_Symbol(self, e, bold_name=False): |
| symb = pretty_symbol(e.name, bold_name) |
| return prettyForm(symb) |
| _print_RandomSymbol = _print_Symbol |
| def _print_MatrixSymbol(self, e): |
| return self._print_Symbol(e, self._settings['mat_symbol_style'] == "bold") |
|
|
| def _print_Float(self, e): |
| |
| |
| full_prec = self._settings["full_prec"] |
| if full_prec == "auto": |
| full_prec = self._print_level == 1 |
| return prettyForm(sstr(e, full_prec=full_prec)) |
|
|
| def _print_Cross(self, e): |
| vec1 = e._expr1 |
| vec2 = e._expr2 |
| pform = self._print(vec2) |
| pform = prettyForm(*pform.left('(')) |
| pform = prettyForm(*pform.right(')')) |
| pform = prettyForm(*pform.left(self._print(U('MULTIPLICATION SIGN')))) |
| pform = prettyForm(*pform.left(')')) |
| pform = prettyForm(*pform.left(self._print(vec1))) |
| pform = prettyForm(*pform.left('(')) |
| return pform |
|
|
| def _print_Curl(self, e): |
| vec = e._expr |
| pform = self._print(vec) |
| pform = prettyForm(*pform.left('(')) |
| pform = prettyForm(*pform.right(')')) |
| pform = prettyForm(*pform.left(self._print(U('MULTIPLICATION SIGN')))) |
| pform = prettyForm(*pform.left(self._print(U('NABLA')))) |
| return pform |
|
|
| def _print_Divergence(self, e): |
| vec = e._expr |
| pform = self._print(vec) |
| pform = prettyForm(*pform.left('(')) |
| pform = prettyForm(*pform.right(')')) |
| pform = prettyForm(*pform.left(self._print(U('DOT OPERATOR')))) |
| pform = prettyForm(*pform.left(self._print(U('NABLA')))) |
| return pform |
|
|
| def _print_Dot(self, e): |
| vec1 = e._expr1 |
| vec2 = e._expr2 |
| pform = self._print(vec2) |
| pform = prettyForm(*pform.left('(')) |
| pform = prettyForm(*pform.right(')')) |
| pform = prettyForm(*pform.left(self._print(U('DOT OPERATOR')))) |
| pform = prettyForm(*pform.left(')')) |
| pform = prettyForm(*pform.left(self._print(vec1))) |
| pform = prettyForm(*pform.left('(')) |
| return pform |
|
|
| def _print_Gradient(self, e): |
| func = e._expr |
| pform = self._print(func) |
| pform = prettyForm(*pform.left('(')) |
| pform = prettyForm(*pform.right(')')) |
| pform = prettyForm(*pform.left(self._print(U('NABLA')))) |
| return pform |
|
|
| def _print_Laplacian(self, e): |
| func = e._expr |
| pform = self._print(func) |
| pform = prettyForm(*pform.left('(')) |
| pform = prettyForm(*pform.right(')')) |
| pform = prettyForm(*pform.left(self._print(U('INCREMENT')))) |
| return pform |
|
|
| def _print_Atom(self, e): |
| try: |
| |
| return prettyForm(pretty_atom(e.__class__.__name__, printer=self)) |
| except KeyError: |
| return self.emptyPrinter(e) |
|
|
| |
| _print_Infinity = _print_Atom |
| _print_NegativeInfinity = _print_Atom |
| _print_EmptySet = _print_Atom |
| _print_Naturals = _print_Atom |
| _print_Naturals0 = _print_Atom |
| _print_Integers = _print_Atom |
| _print_Rationals = _print_Atom |
| _print_Complexes = _print_Atom |
|
|
| _print_EmptySequence = _print_Atom |
|
|
| def _print_Reals(self, e): |
| if self._use_unicode: |
| return self._print_Atom(e) |
| else: |
| inf_list = ['-oo', 'oo'] |
| return self._print_seq(inf_list, '(', ')') |
|
|
| def _print_subfactorial(self, e): |
| x = e.args[0] |
| pform = self._print(x) |
| |
| if not ((x.is_Integer and x.is_nonnegative) or x.is_Symbol): |
| pform = prettyForm(*pform.parens()) |
| pform = prettyForm(*pform.left('!')) |
| return pform |
|
|
| def _print_factorial(self, e): |
| x = e.args[0] |
| pform = self._print(x) |
| |
| if not ((x.is_Integer and x.is_nonnegative) or x.is_Symbol): |
| pform = prettyForm(*pform.parens()) |
| pform = prettyForm(*pform.right('!')) |
| return pform |
|
|
| def _print_factorial2(self, e): |
| x = e.args[0] |
| pform = self._print(x) |
| |
| if not ((x.is_Integer and x.is_nonnegative) or x.is_Symbol): |
| pform = prettyForm(*pform.parens()) |
| pform = prettyForm(*pform.right('!!')) |
| return pform |
|
|
| def _print_binomial(self, e): |
| n, k = e.args |
|
|
| n_pform = self._print(n) |
| k_pform = self._print(k) |
|
|
| bar = ' '*max(n_pform.width(), k_pform.width()) |
|
|
| pform = prettyForm(*k_pform.above(bar)) |
| pform = prettyForm(*pform.above(n_pform)) |
| pform = prettyForm(*pform.parens('(', ')')) |
|
|
| pform.baseline = (pform.baseline + 1)//2 |
|
|
| return pform |
|
|
| def _print_Relational(self, e): |
| op = prettyForm(' ' + xsym(e.rel_op) + ' ') |
|
|
| l = self._print(e.lhs) |
| r = self._print(e.rhs) |
| pform = prettyForm(*stringPict.next(l, op, r), binding=prettyForm.OPEN) |
| return pform |
|
|
| def _print_Not(self, e): |
| from sympy.logic.boolalg import (Equivalent, Implies) |
| if self._use_unicode: |
| arg = e.args[0] |
| pform = self._print(arg) |
| if isinstance(arg, Equivalent): |
| return self._print_Equivalent(arg, altchar=pretty_atom('NotEquiv')) |
| if isinstance(arg, Implies): |
| return self._print_Implies(arg, altchar=pretty_atom('NotArrow')) |
|
|
| if arg.is_Boolean and not arg.is_Not: |
| pform = prettyForm(*pform.parens()) |
|
|
| return prettyForm(*pform.left(pretty_atom('Not'))) |
| else: |
| return self._print_Function(e) |
|
|
| def __print_Boolean(self, e, char, sort=True): |
| args = e.args |
| if sort: |
| args = sorted(e.args, key=default_sort_key) |
| arg = args[0] |
| pform = self._print(arg) |
|
|
| if arg.is_Boolean and not arg.is_Not: |
| pform = prettyForm(*pform.parens()) |
|
|
| for arg in args[1:]: |
| pform_arg = self._print(arg) |
|
|
| if arg.is_Boolean and not arg.is_Not: |
| pform_arg = prettyForm(*pform_arg.parens()) |
|
|
| pform = prettyForm(*pform.right(' %s ' % char)) |
| pform = prettyForm(*pform.right(pform_arg)) |
|
|
| return pform |
|
|
| def _print_And(self, e): |
| if self._use_unicode: |
| return self.__print_Boolean(e, pretty_atom('And')) |
| else: |
| return self._print_Function(e, sort=True) |
|
|
| def _print_Or(self, e): |
| if self._use_unicode: |
| return self.__print_Boolean(e, pretty_atom('Or')) |
| else: |
| return self._print_Function(e, sort=True) |
|
|
| def _print_Xor(self, e): |
| if self._use_unicode: |
| return self.__print_Boolean(e, pretty_atom("Xor")) |
| else: |
| return self._print_Function(e, sort=True) |
|
|
| def _print_Nand(self, e): |
| if self._use_unicode: |
| return self.__print_Boolean(e, pretty_atom('Nand')) |
| else: |
| return self._print_Function(e, sort=True) |
|
|
| def _print_Nor(self, e): |
| if self._use_unicode: |
| return self.__print_Boolean(e, pretty_atom('Nor')) |
| else: |
| return self._print_Function(e, sort=True) |
|
|
| def _print_Implies(self, e, altchar=None): |
| if self._use_unicode: |
| return self.__print_Boolean(e, altchar or pretty_atom('Arrow'), sort=False) |
| else: |
| return self._print_Function(e) |
|
|
| def _print_Equivalent(self, e, altchar=None): |
| if self._use_unicode: |
| return self.__print_Boolean(e, altchar or pretty_atom('Equiv')) |
| else: |
| return self._print_Function(e, sort=True) |
|
|
| def _print_conjugate(self, e): |
| pform = self._print(e.args[0]) |
| return prettyForm( *pform.above( hobj('_', pform.width())) ) |
|
|
| def _print_Abs(self, e): |
| pform = self._print(e.args[0]) |
| pform = prettyForm(*pform.parens('|', '|')) |
| return pform |
|
|
| def _print_floor(self, e): |
| if self._use_unicode: |
| pform = self._print(e.args[0]) |
| pform = prettyForm(*pform.parens('lfloor', 'rfloor')) |
| return pform |
| else: |
| return self._print_Function(e) |
|
|
| def _print_ceiling(self, e): |
| if self._use_unicode: |
| pform = self._print(e.args[0]) |
| pform = prettyForm(*pform.parens('lceil', 'rceil')) |
| return pform |
| else: |
| return self._print_Function(e) |
|
|
| def _print_Derivative(self, deriv): |
| if requires_partial(deriv.expr) and self._use_unicode: |
| deriv_symbol = U('PARTIAL DIFFERENTIAL') |
| else: |
| deriv_symbol = r'd' |
| x = None |
| count_total_deriv = 0 |
|
|
| for sym, num in reversed(deriv.variable_count): |
| s = self._print(sym) |
| ds = prettyForm(*s.left(deriv_symbol)) |
| count_total_deriv += num |
|
|
| if (not num.is_Integer) or (num > 1): |
| ds = ds**prettyForm(str(num)) |
|
|
| if x is None: |
| x = ds |
| else: |
| x = prettyForm(*x.right(' ')) |
| x = prettyForm(*x.right(ds)) |
|
|
| f = prettyForm( |
| binding=prettyForm.FUNC, *self._print(deriv.expr).parens()) |
|
|
| pform = prettyForm(deriv_symbol) |
|
|
| if (count_total_deriv > 1) != False: |
| pform = pform**prettyForm(str(count_total_deriv)) |
|
|
| pform = prettyForm(*pform.below(stringPict.LINE, x)) |
| pform.baseline = pform.baseline + 1 |
| pform = prettyForm(*stringPict.next(pform, f)) |
| pform.binding = prettyForm.MUL |
|
|
| return pform |
|
|
| def _print_Cycle(self, dc): |
| from sympy.combinatorics.permutations import Permutation, Cycle |
| |
| if dc == Cycle(): |
| cyc = stringPict('') |
| return prettyForm(*cyc.parens()) |
|
|
| dc_list = Permutation(dc.list()).cyclic_form |
| |
| if dc_list == []: |
| cyc = self._print(dc.size - 1) |
| return prettyForm(*cyc.parens()) |
|
|
| cyc = stringPict('') |
| for i in dc_list: |
| l = self._print(str(tuple(i)).replace(',', '')) |
| cyc = prettyForm(*cyc.right(l)) |
| return cyc |
|
|
| def _print_Permutation(self, expr): |
| from sympy.combinatorics.permutations import Permutation, Cycle |
|
|
| perm_cyclic = Permutation.print_cyclic |
| if perm_cyclic is not None: |
| sympy_deprecation_warning( |
| f""" |
| Setting Permutation.print_cyclic is deprecated. Instead use |
| init_printing(perm_cyclic={perm_cyclic}). |
| """, |
| deprecated_since_version="1.6", |
| active_deprecations_target="deprecated-permutation-print_cyclic", |
| stacklevel=7, |
| ) |
| else: |
| perm_cyclic = self._settings.get("perm_cyclic", True) |
|
|
| if perm_cyclic: |
| return self._print_Cycle(Cycle(expr)) |
|
|
| lower = expr.array_form |
| upper = list(range(len(lower))) |
|
|
| result = stringPict('') |
| first = True |
| for u, l in zip(upper, lower): |
| s1 = self._print(u) |
| s2 = self._print(l) |
| col = prettyForm(*s1.below(s2)) |
| if first: |
| first = False |
| else: |
| col = prettyForm(*col.left(" ")) |
| result = prettyForm(*result.right(col)) |
| return prettyForm(*result.parens()) |
|
|
|
|
| def _print_Integral(self, integral): |
| f = integral.function |
|
|
| |
| |
| prettyF = self._print(f) |
| |
| if f.is_Add: |
| prettyF = prettyForm(*prettyF.parens()) |
|
|
| |
| arg = prettyF |
| for x in integral.limits: |
| prettyArg = self._print(x[0]) |
| |
| if prettyArg.width() > 1: |
| prettyArg = prettyForm(*prettyArg.parens()) |
|
|
| arg = prettyForm(*arg.right(' d', prettyArg)) |
|
|
| |
| firstterm = True |
| s = None |
| for lim in integral.limits: |
| |
| h = arg.height() |
| H = h + 2 |
|
|
| |
| ascii_mode = not self._use_unicode |
| if ascii_mode: |
| H += 2 |
|
|
| vint = vobj('int', H) |
|
|
| |
| pform = prettyForm(vint) |
| pform.baseline = arg.baseline + ( |
| H - h)//2 |
|
|
| if len(lim) > 1: |
| |
| |
| if len(lim) == 2: |
| prettyA = prettyForm("") |
| prettyB = self._print(lim[1]) |
| if len(lim) == 3: |
| prettyA = self._print(lim[1]) |
| prettyB = self._print(lim[2]) |
|
|
| if ascii_mode: |
| |
| |
| spc = max(1, 3 - prettyB.width()) |
| prettyB = prettyForm(*prettyB.left(' ' * spc)) |
|
|
| spc = max(1, 4 - prettyA.width()) |
| prettyA = prettyForm(*prettyA.right(' ' * spc)) |
|
|
| pform = prettyForm(*pform.above(prettyB)) |
| pform = prettyForm(*pform.below(prettyA)) |
|
|
| if not ascii_mode: |
| pform = prettyForm(*pform.right(' ')) |
|
|
| if firstterm: |
| s = pform |
| firstterm = False |
| else: |
| s = prettyForm(*s.left(pform)) |
|
|
| pform = prettyForm(*arg.left(s)) |
| pform.binding = prettyForm.MUL |
| return pform |
|
|
| def _print_Product(self, expr): |
| func = expr.term |
| pretty_func = self._print(func) |
|
|
| horizontal_chr = xobj('_', 1) |
| corner_chr = xobj('_', 1) |
| vertical_chr = xobj('|', 1) |
|
|
| if self._use_unicode: |
| |
| horizontal_chr = xobj('-', 1) |
| corner_chr = xobj('UpTack', 1) |
|
|
| func_height = pretty_func.height() |
|
|
| first = True |
| max_upper = 0 |
| sign_height = 0 |
|
|
| for lim in expr.limits: |
| pretty_lower, pretty_upper = self.__print_SumProduct_Limits(lim) |
|
|
| width = (func_height + 2) * 5 // 3 - 2 |
| sign_lines = [horizontal_chr + corner_chr + (horizontal_chr * (width-2)) + corner_chr + horizontal_chr] |
| for _ in range(func_height + 1): |
| sign_lines.append(' ' + vertical_chr + (' ' * (width-2)) + vertical_chr + ' ') |
|
|
| pretty_sign = stringPict('') |
| pretty_sign = prettyForm(*pretty_sign.stack(*sign_lines)) |
|
|
|
|
| max_upper = max(max_upper, pretty_upper.height()) |
|
|
| if first: |
| sign_height = pretty_sign.height() |
|
|
| pretty_sign = prettyForm(*pretty_sign.above(pretty_upper)) |
| pretty_sign = prettyForm(*pretty_sign.below(pretty_lower)) |
|
|
| if first: |
| pretty_func.baseline = 0 |
| first = False |
|
|
| height = pretty_sign.height() |
| padding = stringPict('') |
| padding = prettyForm(*padding.stack(*[' ']*(height - 1))) |
| pretty_sign = prettyForm(*pretty_sign.right(padding)) |
|
|
| pretty_func = prettyForm(*pretty_sign.right(pretty_func)) |
|
|
| pretty_func.baseline = max_upper + sign_height//2 |
| pretty_func.binding = prettyForm.MUL |
| return pretty_func |
|
|
| def __print_SumProduct_Limits(self, lim): |
| def print_start(lhs, rhs): |
| op = prettyForm(' ' + xsym("==") + ' ') |
| l = self._print(lhs) |
| r = self._print(rhs) |
| pform = prettyForm(*stringPict.next(l, op, r)) |
| return pform |
|
|
| prettyUpper = self._print(lim[2]) |
| prettyLower = print_start(lim[0], lim[1]) |
| return prettyLower, prettyUpper |
|
|
| def _print_Sum(self, expr): |
| ascii_mode = not self._use_unicode |
|
|
| def asum(hrequired, lower, upper, use_ascii): |
| def adjust(s, wid=None, how='<^>'): |
| if not wid or len(s) > wid: |
| return s |
| need = wid - len(s) |
| if how in ('<^>', "<") or how not in list('<^>'): |
| return s + ' '*need |
| half = need//2 |
| lead = ' '*half |
| if how == ">": |
| return " "*need + s |
| return lead + s + ' '*(need - len(lead)) |
|
|
| h = max(hrequired, 2) |
| d = h//2 |
| w = d + 1 |
| more = hrequired % 2 |
|
|
| lines = [] |
| if use_ascii: |
| lines.append("_"*(w) + ' ') |
| lines.append(r"\%s`" % (' '*(w - 1))) |
| for i in range(1, d): |
| lines.append('%s\\%s' % (' '*i, ' '*(w - i))) |
| if more: |
| lines.append('%s)%s' % (' '*(d), ' '*(w - d))) |
| for i in reversed(range(1, d)): |
| lines.append('%s/%s' % (' '*i, ' '*(w - i))) |
| lines.append("/" + "_"*(w - 1) + ',') |
| return d, h + more, lines, more |
| else: |
| w = w + more |
| d = d + more |
| vsum = vobj('sum', 4) |
| lines.append("_"*(w)) |
| for i in range(0, d): |
| lines.append('%s%s%s' % (' '*i, vsum[2], ' '*(w - i - 1))) |
| for i in reversed(range(0, d)): |
| lines.append('%s%s%s' % (' '*i, vsum[4], ' '*(w - i - 1))) |
| lines.append(vsum[8]*(w)) |
| return d, h + 2*more, lines, more |
|
|
| f = expr.function |
|
|
| prettyF = self._print(f) |
|
|
| if f.is_Add: |
| prettyF = prettyForm(*prettyF.parens()) |
|
|
| H = prettyF.height() + 2 |
|
|
| |
| first = True |
| max_upper = 0 |
| sign_height = 0 |
|
|
| for lim in expr.limits: |
| prettyLower, prettyUpper = self.__print_SumProduct_Limits(lim) |
|
|
| max_upper = max(max_upper, prettyUpper.height()) |
|
|
| |
| d, h, slines, adjustment = asum( |
| H, prettyLower.width(), prettyUpper.width(), ascii_mode) |
| prettySign = stringPict('') |
| prettySign = prettyForm(*prettySign.stack(*slines)) |
|
|
| if first: |
| sign_height = prettySign.height() |
|
|
| prettySign = prettyForm(*prettySign.above(prettyUpper)) |
| prettySign = prettyForm(*prettySign.below(prettyLower)) |
|
|
| if first: |
| |
| prettyF.baseline -= d - (prettyF.height()//2 - |
| prettyF.baseline) |
| first = False |
|
|
| |
| pad = stringPict('') |
| pad = prettyForm(*pad.stack(*[' ']*h)) |
| prettySign = prettyForm(*prettySign.right(pad)) |
| |
| prettyF = prettyForm(*prettySign.right(prettyF)) |
|
|
| |
| |
| ascii_adjustment = ascii_mode if not adjustment else 0 |
| prettyF.baseline = max_upper + sign_height//2 + ascii_adjustment |
|
|
| prettyF.binding = prettyForm.MUL |
| return prettyF |
|
|
| def _print_Limit(self, l): |
| e, z, z0, dir = l.args |
|
|
| E = self._print(e) |
| if precedence(e) <= PRECEDENCE["Mul"]: |
| E = prettyForm(*E.parens('(', ')')) |
| Lim = prettyForm('lim') |
|
|
| LimArg = self._print(z) |
| if self._use_unicode: |
| LimArg = prettyForm(*LimArg.right(f"{xobj('-', 1)}{pretty_atom('Arrow')}")) |
| else: |
| LimArg = prettyForm(*LimArg.right('->')) |
| LimArg = prettyForm(*LimArg.right(self._print(z0))) |
|
|
| if str(dir) == '+-' or z0 in (S.Infinity, S.NegativeInfinity): |
| dir = "" |
| else: |
| if self._use_unicode: |
| dir = pretty_atom('SuperscriptPlus') if str(dir) == "+" else pretty_atom('SuperscriptMinus') |
|
|
| LimArg = prettyForm(*LimArg.right(self._print(dir))) |
|
|
| Lim = prettyForm(*Lim.below(LimArg)) |
| Lim = prettyForm(*Lim.right(E), binding=prettyForm.MUL) |
|
|
| return Lim |
|
|
| def _print_matrix_contents(self, e): |
| """ |
| This method factors out what is essentially grid printing. |
| """ |
| M = e |
| Ms = {} |
| for i in range(M.rows): |
| for j in range(M.cols): |
| Ms[i, j] = self._print(M[i, j]) |
|
|
| |
| hsep = 2 |
| vsep = 1 |
|
|
| |
| maxw = [-1] * M.cols |
|
|
| for j in range(M.cols): |
| maxw[j] = max([Ms[i, j].width() for i in range(M.rows)] or [0]) |
|
|
| |
| D = None |
|
|
| for i in range(M.rows): |
|
|
| D_row = None |
| for j in range(M.cols): |
| s = Ms[i, j] |
|
|
| |
| |
| assert s.width() <= maxw[j] |
|
|
| |
| |
| |
| left, right = center_pad(s.width(), maxw[j]) |
|
|
| s = prettyForm(*s.right(right)) |
| s = prettyForm(*s.left(left)) |
|
|
| |
| |
| |
|
|
| if D_row is None: |
| D_row = s |
| continue |
|
|
| D_row = prettyForm(*D_row.right(' '*hsep)) |
| D_row = prettyForm(*D_row.right(s)) |
|
|
| if D is None: |
| D = D_row |
| continue |
|
|
| |
| for _ in range(vsep): |
| D = prettyForm(*D.below(' ')) |
|
|
| D = prettyForm(*D.below(D_row)) |
|
|
| if D is None: |
| D = prettyForm('') |
|
|
| return D |
|
|
| def _print_MatrixBase(self, e, lparens='[', rparens=']'): |
| D = self._print_matrix_contents(e) |
| D.baseline = D.height()//2 |
| D = prettyForm(*D.parens(lparens, rparens)) |
| return D |
|
|
| def _print_Determinant(self, e): |
| mat = e.arg |
| if mat.is_MatrixExpr: |
| from sympy.matrices.expressions.blockmatrix import BlockMatrix |
| if isinstance(mat, BlockMatrix): |
| return self._print_MatrixBase(mat.blocks, lparens='|', rparens='|') |
| D = self._print(mat) |
| D.baseline = D.height()//2 |
| return prettyForm(*D.parens('|', '|')) |
| else: |
| return self._print_MatrixBase(mat, lparens='|', rparens='|') |
|
|
| def _print_TensorProduct(self, expr): |
| |
| if self._use_unicode: |
| circled_times = "\u2297" |
| else: |
| circled_times = ".*" |
| return self._print_seq(expr.args, None, None, circled_times, |
| parenthesize=lambda x: precedence_traditional(x) <= PRECEDENCE["Mul"]) |
|
|
| def _print_WedgeProduct(self, expr): |
| |
| if self._use_unicode: |
| wedge_symbol = "\u2227" |
| else: |
| wedge_symbol = '/\\' |
| return self._print_seq(expr.args, None, None, wedge_symbol, |
| parenthesize=lambda x: precedence_traditional(x) <= PRECEDENCE["Mul"]) |
|
|
| def _print_Trace(self, e): |
| D = self._print(e.arg) |
| D = prettyForm(*D.parens('(',')')) |
| D.baseline = D.height()//2 |
| D = prettyForm(*D.left('\n'*(0) + 'tr')) |
| return D |
|
|
|
|
| def _print_MatrixElement(self, expr): |
| from sympy.matrices import MatrixSymbol |
| if (isinstance(expr.parent, MatrixSymbol) |
| and expr.i.is_number and expr.j.is_number): |
| return self._print( |
| Symbol(expr.parent.name + '_%d%d' % (expr.i, expr.j))) |
| else: |
| prettyFunc = self._print(expr.parent) |
| prettyFunc = prettyForm(*prettyFunc.parens()) |
| prettyIndices = self._print_seq((expr.i, expr.j), delimiter=', ' |
| ).parens(left='[', right=']')[0] |
| pform = prettyForm(binding=prettyForm.FUNC, |
| *stringPict.next(prettyFunc, prettyIndices)) |
|
|
| |
| pform.prettyFunc = prettyFunc |
| pform.prettyArgs = prettyIndices |
|
|
| return pform |
|
|
|
|
| def _print_MatrixSlice(self, m): |
| |
| from sympy.matrices import MatrixSymbol |
| prettyFunc = self._print(m.parent) |
| if not isinstance(m.parent, MatrixSymbol): |
| prettyFunc = prettyForm(*prettyFunc.parens()) |
| def ppslice(x, dim): |
| x = list(x) |
| if x[2] == 1: |
| del x[2] |
| if x[0] == 0: |
| x[0] = '' |
| if x[1] == dim: |
| x[1] = '' |
| return prettyForm(*self._print_seq(x, delimiter=':')) |
| prettyArgs = self._print_seq((ppslice(m.rowslice, m.parent.rows), |
| ppslice(m.colslice, m.parent.cols)), delimiter=', ').parens(left='[', right=']')[0] |
|
|
| pform = prettyForm( |
| binding=prettyForm.FUNC, *stringPict.next(prettyFunc, prettyArgs)) |
|
|
| |
| pform.prettyFunc = prettyFunc |
| pform.prettyArgs = prettyArgs |
|
|
| return pform |
|
|
| def _print_Transpose(self, expr): |
| mat = expr.arg |
| pform = self._print(mat) |
| from sympy.matrices import MatrixSymbol, BlockMatrix |
| if (not isinstance(mat, MatrixSymbol) and |
| not isinstance(mat, BlockMatrix) and mat.is_MatrixExpr): |
| pform = prettyForm(*pform.parens()) |
| pform = pform**(prettyForm('T')) |
| return pform |
|
|
| def _print_Adjoint(self, expr): |
| mat = expr.arg |
| pform = self._print(mat) |
| if self._use_unicode: |
| dag = prettyForm(pretty_atom('Dagger')) |
| else: |
| dag = prettyForm('+') |
| from sympy.matrices import MatrixSymbol, BlockMatrix |
| if (not isinstance(mat, MatrixSymbol) and |
| not isinstance(mat, BlockMatrix) and mat.is_MatrixExpr): |
| pform = prettyForm(*pform.parens()) |
| pform = pform**dag |
| return pform |
|
|
| def _print_BlockMatrix(self, B): |
| if B.blocks.shape == (1, 1): |
| return self._print(B.blocks[0, 0]) |
| return self._print(B.blocks) |
|
|
| def _print_MatAdd(self, expr): |
| s = None |
| for item in expr.args: |
| pform = self._print(item) |
| if s is None: |
| s = pform |
| else: |
| coeff = item.as_coeff_mmul()[0] |
| if S(coeff).could_extract_minus_sign(): |
| s = prettyForm(*stringPict.next(s, ' ')) |
| pform = self._print(item) |
| else: |
| s = prettyForm(*stringPict.next(s, ' + ')) |
| s = prettyForm(*stringPict.next(s, pform)) |
|
|
| return s |
|
|
| def _print_MatMul(self, expr): |
| args = list(expr.args) |
| from sympy.matrices.expressions.hadamard import HadamardProduct |
| from sympy.matrices.expressions.kronecker import KroneckerProduct |
| from sympy.matrices.expressions.matadd import MatAdd |
| for i, a in enumerate(args): |
| if (isinstance(a, (Add, MatAdd, HadamardProduct, KroneckerProduct)) |
| and len(expr.args) > 1): |
| args[i] = prettyForm(*self._print(a).parens()) |
| else: |
| args[i] = self._print(a) |
|
|
| return prettyForm.__mul__(*args) |
|
|
| def _print_Identity(self, expr): |
| if self._use_unicode: |
| return prettyForm(pretty_atom('IdentityMatrix')) |
| else: |
| return prettyForm('I') |
|
|
| def _print_ZeroMatrix(self, expr): |
| if self._use_unicode: |
| return prettyForm(pretty_atom('ZeroMatrix')) |
| else: |
| return prettyForm('0') |
|
|
| def _print_OneMatrix(self, expr): |
| if self._use_unicode: |
| return prettyForm(pretty_atom("OneMatrix")) |
| else: |
| return prettyForm('1') |
|
|
| def _print_DotProduct(self, expr): |
| args = list(expr.args) |
|
|
| for i, a in enumerate(args): |
| args[i] = self._print(a) |
| return prettyForm.__mul__(*args) |
|
|
| def _print_MatPow(self, expr): |
| pform = self._print(expr.base) |
| from sympy.matrices import MatrixSymbol |
| if not isinstance(expr.base, MatrixSymbol) and expr.base.is_MatrixExpr: |
| pform = prettyForm(*pform.parens()) |
| pform = pform**(self._print(expr.exp)) |
| return pform |
|
|
| def _print_HadamardProduct(self, expr): |
| from sympy.matrices.expressions.hadamard import HadamardProduct |
| from sympy.matrices.expressions.matadd import MatAdd |
| from sympy.matrices.expressions.matmul import MatMul |
| if self._use_unicode: |
| delim = pretty_atom('Ring') |
| else: |
| delim = '.*' |
| return self._print_seq(expr.args, None, None, delim, |
| parenthesize=lambda x: isinstance(x, (MatAdd, MatMul, HadamardProduct))) |
|
|
| def _print_HadamardPower(self, expr): |
| |
| if self._use_unicode: |
| circ = pretty_atom('Ring') |
| else: |
| circ = self._print('.') |
| pretty_base = self._print(expr.base) |
| pretty_exp = self._print(expr.exp) |
| if precedence(expr.exp) < PRECEDENCE["Mul"]: |
| pretty_exp = prettyForm(*pretty_exp.parens()) |
| pretty_circ_exp = prettyForm( |
| binding=prettyForm.LINE, |
| *stringPict.next(circ, pretty_exp) |
| ) |
| return pretty_base**pretty_circ_exp |
|
|
| def _print_KroneckerProduct(self, expr): |
| from sympy.matrices.expressions.matadd import MatAdd |
| from sympy.matrices.expressions.matmul import MatMul |
| if self._use_unicode: |
| delim = f" {pretty_atom('TensorProduct')} " |
| else: |
| delim = ' x ' |
| return self._print_seq(expr.args, None, None, delim, |
| parenthesize=lambda x: isinstance(x, (MatAdd, MatMul))) |
|
|
| def _print_FunctionMatrix(self, X): |
| D = self._print(X.lamda.expr) |
| D = prettyForm(*D.parens('[', ']')) |
| return D |
|
|
| def _print_TransferFunction(self, expr): |
| if not expr.num == 1: |
| num, den = expr.num, expr.den |
| res = Mul(num, Pow(den, -1, evaluate=False), evaluate=False) |
| return self._print_Mul(res) |
| else: |
| return self._print(1)/self._print(expr.den) |
|
|
| def _print_Series(self, expr): |
| args = list(expr.args) |
| for i, a in enumerate(expr.args): |
| args[i] = prettyForm(*self._print(a).parens()) |
| return prettyForm.__mul__(*args) |
|
|
| def _print_MIMOSeries(self, expr): |
| from sympy.physics.control.lti import MIMOParallel |
| args = list(expr.args) |
| pretty_args = [] |
| for a in reversed(args): |
| if (isinstance(a, MIMOParallel) and len(expr.args) > 1): |
| expression = self._print(a) |
| expression.baseline = expression.height()//2 |
| pretty_args.append(prettyForm(*expression.parens())) |
| else: |
| expression = self._print(a) |
| expression.baseline = expression.height()//2 |
| pretty_args.append(expression) |
| return prettyForm.__mul__(*pretty_args) |
|
|
| def _print_Parallel(self, expr): |
| s = None |
| for item in expr.args: |
| pform = self._print(item) |
| if s is None: |
| s = pform |
| else: |
| s = prettyForm(*stringPict.next(s)) |
| s.baseline = s.height()//2 |
| s = prettyForm(*stringPict.next(s, ' + ')) |
| s = prettyForm(*stringPict.next(s, pform)) |
| return s |
|
|
| def _print_MIMOParallel(self, expr): |
| from sympy.physics.control.lti import TransferFunctionMatrix |
| s = None |
| for item in expr.args: |
| pform = self._print(item) |
| if s is None: |
| s = pform |
| else: |
| s = prettyForm(*stringPict.next(s)) |
| s.baseline = s.height()//2 |
| s = prettyForm(*stringPict.next(s, ' + ')) |
| if isinstance(item, TransferFunctionMatrix): |
| s.baseline = s.height() - 1 |
| s = prettyForm(*stringPict.next(s, pform)) |
| |
| return s |
|
|
| def _print_Feedback(self, expr): |
| from sympy.physics.control import TransferFunction, Series |
|
|
| num, tf = expr.sys1, TransferFunction(1, 1, expr.var) |
| num_arg_list = list(num.args) if isinstance(num, Series) else [num] |
| den_arg_list = list(expr.sys2.args) if \ |
| isinstance(expr.sys2, Series) else [expr.sys2] |
|
|
| if isinstance(num, Series) and isinstance(expr.sys2, Series): |
| den = Series(*num_arg_list, *den_arg_list) |
| elif isinstance(num, Series) and isinstance(expr.sys2, TransferFunction): |
| if expr.sys2 == tf: |
| den = Series(*num_arg_list) |
| else: |
| den = Series(*num_arg_list, expr.sys2) |
| elif isinstance(num, TransferFunction) and isinstance(expr.sys2, Series): |
| if num == tf: |
| den = Series(*den_arg_list) |
| else: |
| den = Series(num, *den_arg_list) |
| else: |
| if num == tf: |
| den = Series(*den_arg_list) |
| elif expr.sys2 == tf: |
| den = Series(*num_arg_list) |
| else: |
| den = Series(*num_arg_list, *den_arg_list) |
|
|
| denom = prettyForm(*stringPict.next(self._print(tf))) |
| denom.baseline = denom.height()//2 |
| denom = prettyForm(*stringPict.next(denom, ' + ')) if expr.sign == -1 \ |
| else prettyForm(*stringPict.next(denom, ' - ')) |
| denom = prettyForm(*stringPict.next(denom, self._print(den))) |
|
|
| return self._print(num)/denom |
|
|
| def _print_MIMOFeedback(self, expr): |
| from sympy.physics.control import MIMOSeries, TransferFunctionMatrix |
|
|
| inv_mat = self._print(MIMOSeries(expr.sys2, expr.sys1)) |
| plant = self._print(expr.sys1) |
| _feedback = prettyForm(*stringPict.next(inv_mat)) |
| _feedback = prettyForm(*stringPict.right("I + ", _feedback)) if expr.sign == -1 \ |
| else prettyForm(*stringPict.right("I - ", _feedback)) |
| _feedback = prettyForm(*stringPict.parens(_feedback)) |
| _feedback.baseline = 0 |
| _feedback = prettyForm(*stringPict.right(_feedback, '-1 ')) |
| _feedback.baseline = _feedback.height()//2 |
| _feedback = prettyForm.__mul__(_feedback, prettyForm(" ")) |
| if isinstance(expr.sys1, TransferFunctionMatrix): |
| _feedback.baseline = _feedback.height() - 1 |
| _feedback = prettyForm(*stringPict.next(_feedback, plant)) |
| return _feedback |
|
|
| def _print_TransferFunctionMatrix(self, expr): |
| mat = self._print(expr._expr_mat) |
| mat.baseline = mat.height() - 1 |
| subscript = greek_unicode['tau'] if self._use_unicode else r'{t}' |
| mat = prettyForm(*mat.right(subscript)) |
| return mat |
|
|
| def _print_StateSpace(self, expr): |
| from sympy.matrices.expressions.blockmatrix import BlockMatrix |
| A = expr._A |
| B = expr._B |
| C = expr._C |
| D = expr._D |
| mat = BlockMatrix([[A, B], [C, D]]) |
| return self._print(mat.blocks) |
|
|
| def _print_BasisDependent(self, expr): |
| from sympy.vector import Vector |
|
|
| if not self._use_unicode: |
| raise NotImplementedError("ASCII pretty printing of BasisDependent is not implemented") |
|
|
| if expr == expr.zero: |
| return prettyForm(expr.zero._pretty_form) |
| o1 = [] |
| vectstrs = [] |
| if isinstance(expr, Vector): |
| items = expr.separate().items() |
| else: |
| items = [(0, expr)] |
| for system, vect in items: |
| inneritems = list(vect.components.items()) |
| inneritems.sort(key = lambda x: x[0].__str__()) |
| for k, v in inneritems: |
| |
| |
| if v == 1: |
| o1.append("" + |
| k._pretty_form) |
| |
| elif v == -1: |
| o1.append("(-1) " + |
| k._pretty_form) |
| |
| else: |
| |
| |
| arg_str = self._print( |
| v).parens()[0] |
|
|
| o1.append(arg_str + ' ' + k._pretty_form) |
| vectstrs.append(k._pretty_form) |
|
|
| |
| if o1[0].startswith(" + "): |
| o1[0] = o1[0][3:] |
| elif o1[0].startswith(" "): |
| o1[0] = o1[0][1:] |
| |
| lengths = [] |
| strs = [''] |
| flag = [] |
| for i, partstr in enumerate(o1): |
| flag.append(0) |
| |
| if '\n' in partstr: |
| tempstr = partstr |
| tempstr = tempstr.replace(vectstrs[i], '') |
| if xobj(')_ext', 1) in tempstr: |
| for paren in range(len(tempstr)): |
| flag[i] = 1 |
| if tempstr[paren] == xobj(')_ext', 1) and tempstr[paren + 1] == '\n': |
| |
| |
| tempstr = tempstr[:paren] + xobj(')_ext', 1)\ |
| + ' ' + vectstrs[i] + tempstr[paren + 1:] |
| break |
| elif xobj(')_lower_hook', 1) in tempstr: |
| |
| |
| |
| index = tempstr.rfind(xobj(')_lower_hook', 1)) |
| if index != -1: |
| flag[i] = 1 |
| tempstr = tempstr[:index] + xobj(')_lower_hook', 1)\ |
| + ' ' + vectstrs[i] + tempstr[index + 1:] |
| o1[i] = tempstr |
|
|
| o1 = [x.split('\n') for x in o1] |
| n_newlines = max(len(x) for x in o1) |
|
|
| if 1 in flag: |
| for i, parts in enumerate(o1): |
| if len(parts) == 1: |
| parts.insert(0, ' ' * (len(parts[0]))) |
| flag[i] = 1 |
|
|
| for i, parts in enumerate(o1): |
| lengths.append(len(parts[flag[i]])) |
| for j in range(n_newlines): |
| if j+1 <= len(parts): |
| if j >= len(strs): |
| strs.append(' ' * (sum(lengths[:-1]) + |
| 3*(len(lengths)-1))) |
| if j == flag[i]: |
| strs[flag[i]] += parts[flag[i]] + ' + ' |
| else: |
| strs[j] += parts[j] + ' '*(lengths[-1] - |
| len(parts[j])+ |
| 3) |
| else: |
| if j >= len(strs): |
| strs.append(' ' * (sum(lengths[:-1]) + |
| 3*(len(lengths)-1))) |
| strs[j] += ' '*(lengths[-1]+3) |
|
|
| return prettyForm('\n'.join([s[:-3] for s in strs])) |
|
|
| def _print_NDimArray(self, expr): |
| from sympy.matrices.immutable import ImmutableMatrix |
|
|
| if expr.rank() == 0: |
| return self._print(expr[()]) |
|
|
| level_str = [[]] + [[] for i in range(expr.rank())] |
| shape_ranges = [list(range(i)) for i in expr.shape] |
| |
| mat = lambda x: ImmutableMatrix(x, evaluate=False) |
| for outer_i in itertools.product(*shape_ranges): |
| level_str[-1].append(expr[outer_i]) |
| even = True |
| for back_outer_i in range(expr.rank()-1, -1, -1): |
| if len(level_str[back_outer_i+1]) < expr.shape[back_outer_i]: |
| break |
| if even: |
| level_str[back_outer_i].append(level_str[back_outer_i+1]) |
| else: |
| level_str[back_outer_i].append(mat( |
| level_str[back_outer_i+1])) |
| if len(level_str[back_outer_i + 1]) == 1: |
| level_str[back_outer_i][-1] = mat( |
| [[level_str[back_outer_i][-1]]]) |
| even = not even |
| level_str[back_outer_i+1] = [] |
|
|
| out_expr = level_str[0][0] |
| if expr.rank() % 2 == 1: |
| out_expr = mat([out_expr]) |
|
|
| return self._print(out_expr) |
|
|
| def _printer_tensor_indices(self, name, indices, index_map={}): |
| center = stringPict(name) |
| top = stringPict(" "*center.width()) |
| bot = stringPict(" "*center.width()) |
|
|
| last_valence = None |
| prev_map = None |
|
|
| for index in indices: |
| indpic = self._print(index.args[0]) |
| if ((index in index_map) or prev_map) and last_valence == index.is_up: |
| if index.is_up: |
| top = prettyForm(*stringPict.next(top, ",")) |
| else: |
| bot = prettyForm(*stringPict.next(bot, ",")) |
| if index in index_map: |
| indpic = prettyForm(*stringPict.next(indpic, "=")) |
| indpic = prettyForm(*stringPict.next(indpic, self._print(index_map[index]))) |
| prev_map = True |
| else: |
| prev_map = False |
| if index.is_up: |
| top = stringPict(*top.right(indpic)) |
| center = stringPict(*center.right(" "*indpic.width())) |
| bot = stringPict(*bot.right(" "*indpic.width())) |
| else: |
| bot = stringPict(*bot.right(indpic)) |
| center = stringPict(*center.right(" "*indpic.width())) |
| top = stringPict(*top.right(" "*indpic.width())) |
| last_valence = index.is_up |
|
|
| pict = prettyForm(*center.above(top)) |
| pict = prettyForm(*pict.below(bot)) |
| return pict |
|
|
| def _print_Tensor(self, expr): |
| name = expr.args[0].name |
| indices = expr.get_indices() |
| return self._printer_tensor_indices(name, indices) |
|
|
| def _print_TensorElement(self, expr): |
| name = expr.expr.args[0].name |
| indices = expr.expr.get_indices() |
| index_map = expr.index_map |
| return self._printer_tensor_indices(name, indices, index_map) |
|
|
| def _print_TensMul(self, expr): |
| sign, args = expr._get_args_for_traditional_printer() |
| args = [ |
| prettyForm(*self._print(i).parens()) if |
| precedence_traditional(i) < PRECEDENCE["Mul"] else self._print(i) |
| for i in args |
| ] |
| pform = prettyForm.__mul__(*args) |
| if sign: |
| return prettyForm(*pform.left(sign)) |
| else: |
| return pform |
|
|
| def _print_TensAdd(self, expr): |
| args = [ |
| prettyForm(*self._print(i).parens()) if |
| precedence_traditional(i) < PRECEDENCE["Mul"] else self._print(i) |
| for i in expr.args |
| ] |
| return prettyForm.__add__(*args) |
|
|
| def _print_TensorIndex(self, expr): |
| sym = expr.args[0] |
| if not expr.is_up: |
| sym = -sym |
| return self._print(sym) |
|
|
| def _print_PartialDerivative(self, deriv): |
| if self._use_unicode: |
| deriv_symbol = U('PARTIAL DIFFERENTIAL') |
| else: |
| deriv_symbol = r'd' |
| x = None |
|
|
| for variable in reversed(deriv.variables): |
| s = self._print(variable) |
| ds = prettyForm(*s.left(deriv_symbol)) |
|
|
| if x is None: |
| x = ds |
| else: |
| x = prettyForm(*x.right(' ')) |
| x = prettyForm(*x.right(ds)) |
|
|
| f = prettyForm( |
| binding=prettyForm.FUNC, *self._print(deriv.expr).parens()) |
|
|
| pform = prettyForm(deriv_symbol) |
|
|
| if len(deriv.variables) > 1: |
| pform = pform**self._print(len(deriv.variables)) |
|
|
| pform = prettyForm(*pform.below(stringPict.LINE, x)) |
| pform.baseline = pform.baseline + 1 |
| pform = prettyForm(*stringPict.next(pform, f)) |
| pform.binding = prettyForm.MUL |
|
|
| return pform |
|
|
| def _print_Piecewise(self, pexpr): |
|
|
| P = {} |
| for n, ec in enumerate(pexpr.args): |
| P[n, 0] = self._print(ec.expr) |
| if ec.cond == True: |
| P[n, 1] = prettyForm('otherwise') |
| else: |
| P[n, 1] = prettyForm( |
| *prettyForm('for ').right(self._print(ec.cond))) |
| hsep = 2 |
| vsep = 1 |
| len_args = len(pexpr.args) |
|
|
| |
| maxw = [max(P[i, j].width() for i in range(len_args)) |
| for j in range(2)] |
|
|
| |
| |
| D = None |
|
|
| for i in range(len_args): |
| D_row = None |
| for j in range(2): |
| p = P[i, j] |
| assert p.width() <= maxw[j] |
|
|
| wdelta = maxw[j] - p.width() |
| wleft = wdelta // 2 |
| wright = wdelta - wleft |
|
|
| p = prettyForm(*p.right(' '*wright)) |
| p = prettyForm(*p.left(' '*wleft)) |
|
|
| if D_row is None: |
| D_row = p |
| continue |
|
|
| D_row = prettyForm(*D_row.right(' '*hsep)) |
| D_row = prettyForm(*D_row.right(p)) |
| if D is None: |
| D = D_row |
| continue |
|
|
| |
| for _ in range(vsep): |
| D = prettyForm(*D.below(' ')) |
|
|
| D = prettyForm(*D.below(D_row)) |
|
|
| D = prettyForm(*D.parens('{', '')) |
| D.baseline = D.height()//2 |
| D.binding = prettyForm.OPEN |
| return D |
|
|
| def _print_ITE(self, ite): |
| from sympy.functions.elementary.piecewise import Piecewise |
| return self._print(ite.rewrite(Piecewise)) |
|
|
| def _hprint_vec(self, v): |
| D = None |
|
|
| for a in v: |
| p = a |
| if D is None: |
| D = p |
| else: |
| D = prettyForm(*D.right(', ')) |
| D = prettyForm(*D.right(p)) |
| if D is None: |
| D = stringPict(' ') |
|
|
| return D |
|
|
| def _hprint_vseparator(self, p1, p2, left=None, right=None, delimiter='', ifascii_nougly=False): |
| if ifascii_nougly and not self._use_unicode: |
| return self._print_seq((p1, '|', p2), left=left, right=right, |
| delimiter=delimiter, ifascii_nougly=True) |
| tmp = self._print_seq((p1, p2,), left=left, right=right, delimiter=delimiter) |
| sep = stringPict(vobj('|', tmp.height()), baseline=tmp.baseline) |
| return self._print_seq((p1, sep, p2), left=left, right=right, |
| delimiter=delimiter) |
|
|
| def _print_hyper(self, e): |
| |
| ap = [self._print(a) for a in e.ap] |
| bq = [self._print(b) for b in e.bq] |
|
|
| P = self._print(e.argument) |
| P.baseline = P.height()//2 |
|
|
| |
| D = None |
| for v in [ap, bq]: |
| D_row = self._hprint_vec(v) |
| if D is None: |
| D = D_row |
| else: |
| D = prettyForm(*D.below(' ')) |
| D = prettyForm(*D.below(D_row)) |
|
|
| |
| D.baseline = D.height()//2 |
|
|
| |
| P = prettyForm(*P.left(' ')) |
| D = prettyForm(*D.right(' ')) |
|
|
| |
| D = self._hprint_vseparator(D, P) |
|
|
| |
| D = prettyForm(*D.parens('(', ')')) |
|
|
| |
| above = D.height()//2 - 1 |
| below = D.height() - above - 1 |
|
|
| sz, t, b, add, img = annotated('F') |
| F = prettyForm('\n' * (above - t) + img + '\n' * (below - b), |
| baseline=above + sz) |
| add = (sz + 1)//2 |
|
|
| F = prettyForm(*F.left(self._print(len(e.ap)))) |
| F = prettyForm(*F.right(self._print(len(e.bq)))) |
| F.baseline = above + add |
|
|
| D = prettyForm(*F.right(' ', D)) |
|
|
| return D |
|
|
| def _print_meijerg(self, e): |
| |
|
|
| v = {} |
| v[(0, 0)] = [self._print(a) for a in e.an] |
| v[(0, 1)] = [self._print(a) for a in e.aother] |
| v[(1, 0)] = [self._print(b) for b in e.bm] |
| v[(1, 1)] = [self._print(b) for b in e.bother] |
|
|
| P = self._print(e.argument) |
| P.baseline = P.height()//2 |
|
|
| vp = {} |
| for idx in v: |
| vp[idx] = self._hprint_vec(v[idx]) |
|
|
| for i in range(2): |
| maxw = max(vp[(0, i)].width(), vp[(1, i)].width()) |
| for j in range(2): |
| s = vp[(j, i)] |
| left = (maxw - s.width()) // 2 |
| right = maxw - left - s.width() |
| s = prettyForm(*s.left(' ' * left)) |
| s = prettyForm(*s.right(' ' * right)) |
| vp[(j, i)] = s |
|
|
| D1 = prettyForm(*vp[(0, 0)].right(' ', vp[(0, 1)])) |
| D1 = prettyForm(*D1.below(' ')) |
| D2 = prettyForm(*vp[(1, 0)].right(' ', vp[(1, 1)])) |
| D = prettyForm(*D1.below(D2)) |
|
|
| |
| D.baseline = D.height()//2 |
|
|
| |
| P = prettyForm(*P.left(' ')) |
| D = prettyForm(*D.right(' ')) |
|
|
| |
| D = self._hprint_vseparator(D, P) |
|
|
| |
| D = prettyForm(*D.parens('(', ')')) |
|
|
| |
| above = D.height()//2 - 1 |
| below = D.height() - above - 1 |
|
|
| sz, t, b, add, img = annotated('G') |
| F = prettyForm('\n' * (above - t) + img + '\n' * (below - b), |
| baseline=above + sz) |
|
|
| pp = self._print(len(e.ap)) |
| pq = self._print(len(e.bq)) |
| pm = self._print(len(e.bm)) |
| pn = self._print(len(e.an)) |
|
|
| def adjust(p1, p2): |
| diff = p1.width() - p2.width() |
| if diff == 0: |
| return p1, p2 |
| elif diff > 0: |
| return p1, prettyForm(*p2.left(' '*diff)) |
| else: |
| return prettyForm(*p1.left(' '*-diff)), p2 |
| pp, pm = adjust(pp, pm) |
| pq, pn = adjust(pq, pn) |
| pu = prettyForm(*pm.right(', ', pn)) |
| pl = prettyForm(*pp.right(', ', pq)) |
|
|
| ht = F.baseline - above - 2 |
| if ht > 0: |
| pu = prettyForm(*pu.below('\n'*ht)) |
| p = prettyForm(*pu.below(pl)) |
|
|
| F.baseline = above |
| F = prettyForm(*F.right(p)) |
|
|
| F.baseline = above + add |
|
|
| D = prettyForm(*F.right(' ', D)) |
|
|
| return D |
|
|
| def _print_ExpBase(self, e): |
| |
| |
| base = prettyForm(pretty_atom('Exp1', 'e')) |
| return base ** self._print(e.args[0]) |
|
|
| def _print_Exp1(self, e): |
| return prettyForm(pretty_atom('Exp1', 'e')) |
|
|
| def _print_Function(self, e, sort=False, func_name=None, left='(', |
| right=')'): |
| |
| |
| return self._helper_print_function(e.func, e.args, sort=sort, func_name=func_name, left=left, right=right) |
|
|
| def _print_mathieuc(self, e): |
| return self._print_Function(e, func_name='C') |
|
|
| def _print_mathieus(self, e): |
| return self._print_Function(e, func_name='S') |
|
|
| def _print_mathieucprime(self, e): |
| return self._print_Function(e, func_name="C'") |
|
|
| def _print_mathieusprime(self, e): |
| return self._print_Function(e, func_name="S'") |
|
|
| def _helper_print_function(self, func, args, sort=False, func_name=None, |
| delimiter=', ', elementwise=False, left='(', |
| right=')'): |
| if sort: |
| args = sorted(args, key=default_sort_key) |
|
|
| if not func_name and hasattr(func, "__name__"): |
| func_name = func.__name__ |
|
|
| if func_name: |
| prettyFunc = self._print(Symbol(func_name)) |
| else: |
| prettyFunc = prettyForm(*self._print(func).parens()) |
|
|
| if elementwise: |
| if self._use_unicode: |
| circ = pretty_atom('Modifier Letter Low Ring') |
| else: |
| circ = '.' |
| circ = self._print(circ) |
| prettyFunc = prettyForm( |
| binding=prettyForm.LINE, |
| *stringPict.next(prettyFunc, circ) |
| ) |
|
|
| prettyArgs = prettyForm(*self._print_seq(args, delimiter=delimiter).parens( |
| left=left, right=right)) |
|
|
| pform = prettyForm( |
| binding=prettyForm.FUNC, *stringPict.next(prettyFunc, prettyArgs)) |
|
|
| |
| pform.prettyFunc = prettyFunc |
| pform.prettyArgs = prettyArgs |
|
|
| return pform |
|
|
| def _print_ElementwiseApplyFunction(self, e): |
| func = e.function |
| arg = e.expr |
| args = [arg] |
| return self._helper_print_function(func, args, delimiter="", elementwise=True) |
|
|
| @property |
| def _special_function_classes(self): |
| from sympy.functions.special.tensor_functions import KroneckerDelta |
| from sympy.functions.special.gamma_functions import gamma, lowergamma |
| from sympy.functions.special.zeta_functions import lerchphi |
| from sympy.functions.special.beta_functions import beta |
| from sympy.functions.special.delta_functions import DiracDelta |
| from sympy.functions.special.error_functions import Chi |
| return {KroneckerDelta: [greek_unicode['delta'], 'delta'], |
| gamma: [greek_unicode['Gamma'], 'Gamma'], |
| lerchphi: [greek_unicode['Phi'], 'lerchphi'], |
| lowergamma: [greek_unicode['gamma'], 'gamma'], |
| beta: [greek_unicode['Beta'], 'B'], |
| DiracDelta: [greek_unicode['delta'], 'delta'], |
| Chi: ['Chi', 'Chi']} |
|
|
| def _print_FunctionClass(self, expr): |
| for cls in self._special_function_classes: |
| if issubclass(expr, cls) and expr.__name__ == cls.__name__: |
| if self._use_unicode: |
| return prettyForm(self._special_function_classes[cls][0]) |
| else: |
| return prettyForm(self._special_function_classes[cls][1]) |
| func_name = expr.__name__ |
| return prettyForm(pretty_symbol(func_name)) |
|
|
| def _print_GeometryEntity(self, expr): |
| |
| return self.emptyPrinter(expr) |
|
|
| def _print_polylog(self, e): |
| subscript = self._print(e.args[0]) |
| if self._use_unicode and is_subscriptable_in_unicode(subscript): |
| return self._print_Function(Function('Li_%s' % subscript)(e.args[1])) |
| return self._print_Function(e) |
|
|
| def _print_lerchphi(self, e): |
| func_name = greek_unicode['Phi'] if self._use_unicode else 'lerchphi' |
| return self._print_Function(e, func_name=func_name) |
|
|
| def _print_dirichlet_eta(self, e): |
| func_name = greek_unicode['eta'] if self._use_unicode else 'dirichlet_eta' |
| return self._print_Function(e, func_name=func_name) |
|
|
| def _print_Heaviside(self, e): |
| func_name = greek_unicode['theta'] if self._use_unicode else 'Heaviside' |
| if e.args[1] is S.Half: |
| pform = prettyForm(*self._print(e.args[0]).parens()) |
| pform = prettyForm(*pform.left(func_name)) |
| return pform |
| else: |
| return self._print_Function(e, func_name=func_name) |
|
|
| def _print_fresnels(self, e): |
| return self._print_Function(e, func_name="S") |
|
|
| def _print_fresnelc(self, e): |
| return self._print_Function(e, func_name="C") |
|
|
| def _print_airyai(self, e): |
| return self._print_Function(e, func_name="Ai") |
|
|
| def _print_airybi(self, e): |
| return self._print_Function(e, func_name="Bi") |
|
|
| def _print_airyaiprime(self, e): |
| return self._print_Function(e, func_name="Ai'") |
|
|
| def _print_airybiprime(self, e): |
| return self._print_Function(e, func_name="Bi'") |
|
|
| def _print_LambertW(self, e): |
| return self._print_Function(e, func_name="W") |
|
|
| def _print_Covariance(self, e): |
| return self._print_Function(e, func_name="Cov") |
|
|
| def _print_Variance(self, e): |
| return self._print_Function(e, func_name="Var") |
|
|
| def _print_Probability(self, e): |
| return self._print_Function(e, func_name="P") |
|
|
| def _print_Expectation(self, e): |
| return self._print_Function(e, func_name="E", left='[', right=']') |
|
|
| def _print_Lambda(self, e): |
| expr = e.expr |
| sig = e.signature |
| if self._use_unicode: |
| arrow = f" {pretty_atom('ArrowFromBar')} " |
| else: |
| arrow = " -> " |
| if len(sig) == 1 and sig[0].is_symbol: |
| sig = sig[0] |
| var_form = self._print(sig) |
|
|
| return prettyForm(*stringPict.next(var_form, arrow, self._print(expr)), binding=8) |
|
|
| def _print_Order(self, expr): |
| pform = self._print(expr.expr) |
| if (expr.point and any(p != S.Zero for p in expr.point)) or \ |
| len(expr.variables) > 1: |
| pform = prettyForm(*pform.right("; ")) |
| if len(expr.variables) > 1: |
| pform = prettyForm(*pform.right(self._print(expr.variables))) |
| elif len(expr.variables): |
| pform = prettyForm(*pform.right(self._print(expr.variables[0]))) |
| if self._use_unicode: |
| pform = prettyForm(*pform.right(f" {pretty_atom('Arrow')} ")) |
| else: |
| pform = prettyForm(*pform.right(" -> ")) |
| if len(expr.point) > 1: |
| pform = prettyForm(*pform.right(self._print(expr.point))) |
| else: |
| pform = prettyForm(*pform.right(self._print(expr.point[0]))) |
| pform = prettyForm(*pform.parens()) |
| pform = prettyForm(*pform.left("O")) |
| return pform |
|
|
| def _print_SingularityFunction(self, e): |
| if self._use_unicode: |
| shift = self._print(e.args[0]-e.args[1]) |
| n = self._print(e.args[2]) |
| base = prettyForm("<") |
| base = prettyForm(*base.right(shift)) |
| base = prettyForm(*base.right(">")) |
| pform = base**n |
| return pform |
| else: |
| n = self._print(e.args[2]) |
| shift = self._print(e.args[0]-e.args[1]) |
| base = self._print_seq(shift, "<", ">", ' ') |
| return base**n |
|
|
| def _print_beta(self, e): |
| func_name = greek_unicode['Beta'] if self._use_unicode else 'B' |
| return self._print_Function(e, func_name=func_name) |
|
|
| def _print_betainc(self, e): |
| func_name = "B'" |
| return self._print_Function(e, func_name=func_name) |
|
|
| def _print_betainc_regularized(self, e): |
| func_name = 'I' |
| return self._print_Function(e, func_name=func_name) |
|
|
| def _print_gamma(self, e): |
| func_name = greek_unicode['Gamma'] if self._use_unicode else 'Gamma' |
| return self._print_Function(e, func_name=func_name) |
|
|
| def _print_uppergamma(self, e): |
| func_name = greek_unicode['Gamma'] if self._use_unicode else 'Gamma' |
| return self._print_Function(e, func_name=func_name) |
|
|
| def _print_lowergamma(self, e): |
| func_name = greek_unicode['gamma'] if self._use_unicode else 'lowergamma' |
| return self._print_Function(e, func_name=func_name) |
|
|
| def _print_DiracDelta(self, e): |
| if self._use_unicode: |
| if len(e.args) == 2: |
| a = prettyForm(greek_unicode['delta']) |
| b = self._print(e.args[1]) |
| b = prettyForm(*b.parens()) |
| c = self._print(e.args[0]) |
| c = prettyForm(*c.parens()) |
| pform = a**b |
| pform = prettyForm(*pform.right(' ')) |
| pform = prettyForm(*pform.right(c)) |
| return pform |
| pform = self._print(e.args[0]) |
| pform = prettyForm(*pform.parens()) |
| pform = prettyForm(*pform.left(greek_unicode['delta'])) |
| return pform |
| else: |
| return self._print_Function(e) |
|
|
| def _print_expint(self, e): |
| subscript = self._print(e.args[0]) |
| if self._use_unicode and is_subscriptable_in_unicode(subscript): |
| return self._print_Function(Function('E_%s' % subscript)(e.args[1])) |
| return self._print_Function(e) |
|
|
| def _print_Chi(self, e): |
| |
| |
| prettyFunc = prettyForm("Chi") |
| prettyArgs = prettyForm(*self._print_seq(e.args).parens()) |
|
|
| pform = prettyForm( |
| binding=prettyForm.FUNC, *stringPict.next(prettyFunc, prettyArgs)) |
|
|
| |
| pform.prettyFunc = prettyFunc |
| pform.prettyArgs = prettyArgs |
|
|
| return pform |
|
|
| def _print_elliptic_e(self, e): |
| pforma0 = self._print(e.args[0]) |
| if len(e.args) == 1: |
| pform = pforma0 |
| else: |
| pforma1 = self._print(e.args[1]) |
| pform = self._hprint_vseparator(pforma0, pforma1) |
| pform = prettyForm(*pform.parens()) |
| pform = prettyForm(*pform.left('E')) |
| return pform |
|
|
| def _print_elliptic_k(self, e): |
| pform = self._print(e.args[0]) |
| pform = prettyForm(*pform.parens()) |
| pform = prettyForm(*pform.left('K')) |
| return pform |
|
|
| def _print_elliptic_f(self, e): |
| pforma0 = self._print(e.args[0]) |
| pforma1 = self._print(e.args[1]) |
| pform = self._hprint_vseparator(pforma0, pforma1) |
| pform = prettyForm(*pform.parens()) |
| pform = prettyForm(*pform.left('F')) |
| return pform |
|
|
| def _print_elliptic_pi(self, e): |
| name = greek_unicode['Pi'] if self._use_unicode else 'Pi' |
| pforma0 = self._print(e.args[0]) |
| pforma1 = self._print(e.args[1]) |
| if len(e.args) == 2: |
| pform = self._hprint_vseparator(pforma0, pforma1) |
| else: |
| pforma2 = self._print(e.args[2]) |
| pforma = self._hprint_vseparator(pforma1, pforma2, ifascii_nougly=False) |
| pforma = prettyForm(*pforma.left('; ')) |
| pform = prettyForm(*pforma.left(pforma0)) |
| pform = prettyForm(*pform.parens()) |
| pform = prettyForm(*pform.left(name)) |
| return pform |
|
|
| def _print_GoldenRatio(self, expr): |
| if self._use_unicode: |
| return prettyForm(pretty_symbol('phi')) |
| return self._print(Symbol("GoldenRatio")) |
|
|
| def _print_EulerGamma(self, expr): |
| if self._use_unicode: |
| return prettyForm(pretty_symbol('gamma')) |
| return self._print(Symbol("EulerGamma")) |
|
|
| def _print_Catalan(self, expr): |
| return self._print(Symbol("G")) |
|
|
| def _print_Mod(self, expr): |
| pform = self._print(expr.args[0]) |
| if pform.binding > prettyForm.MUL: |
| pform = prettyForm(*pform.parens()) |
| pform = prettyForm(*pform.right(' mod ')) |
| pform = prettyForm(*pform.right(self._print(expr.args[1]))) |
| pform.binding = prettyForm.OPEN |
| return pform |
|
|
| def _print_Add(self, expr, order=None): |
| terms = self._as_ordered_terms(expr, order=order) |
| pforms, indices = [], [] |
|
|
| def pretty_negative(pform, index): |
| """Prepend a minus sign to a pretty form. """ |
| |
| if index == 0: |
| if pform.height() > 1: |
| pform_neg = '- ' |
| else: |
| pform_neg = '-' |
| else: |
| pform_neg = ' - ' |
|
|
| if (pform.binding > prettyForm.NEG |
| or pform.binding == prettyForm.ADD): |
| p = stringPict(*pform.parens()) |
| else: |
| p = pform |
| p = stringPict.next(pform_neg, p) |
| |
| |
| return prettyForm(binding=prettyForm.NEG, *p) |
|
|
| for i, term in enumerate(terms): |
| if term.is_Mul and term.could_extract_minus_sign(): |
| coeff, other = term.as_coeff_mul(rational=False) |
| if coeff == -1: |
| negterm = Mul(*other, evaluate=False) |
| else: |
| negterm = Mul(-coeff, *other, evaluate=False) |
| pform = self._print(negterm) |
| pforms.append(pretty_negative(pform, i)) |
| elif term.is_Rational and term.q > 1: |
| pforms.append(None) |
| indices.append(i) |
| elif term.is_Number and term < 0: |
| pform = self._print(-term) |
| pforms.append(pretty_negative(pform, i)) |
| elif term.is_Relational: |
| pforms.append(prettyForm(*self._print(term).parens())) |
| else: |
| pforms.append(self._print(term)) |
|
|
| if indices: |
| large = True |
|
|
| for pform in pforms: |
| if pform is not None and pform.height() > 1: |
| break |
| else: |
| large = False |
|
|
| for i in indices: |
| term, negative = terms[i], False |
|
|
| if term < 0: |
| term, negative = -term, True |
|
|
| if large: |
| pform = prettyForm(str(term.p))/prettyForm(str(term.q)) |
| else: |
| pform = self._print(term) |
|
|
| if negative: |
| pform = pretty_negative(pform, i) |
|
|
| pforms[i] = pform |
|
|
| return prettyForm.__add__(*pforms) |
|
|
| def _print_Mul(self, product): |
| from sympy.physics.units import Quantity |
|
|
| |
| |
| |
| |
| args = product.args |
| if args[0] is S.One or any(isinstance(arg, Number) for arg in args[1:]): |
| strargs = list(map(self._print, args)) |
| |
| |
| |
| negone = strargs[0] == '-1' |
| if negone: |
| strargs[0] = prettyForm('1', 0, 0) |
| obj = prettyForm.__mul__(*strargs) |
| if negone: |
| obj = prettyForm('-' + obj.s, obj.baseline, obj.binding) |
| return obj |
|
|
| a = [] |
| b = [] |
|
|
| if self.order not in ('old', 'none'): |
| args = product.as_ordered_factors() |
| else: |
| args = list(product.args) |
|
|
| |
| args = sorted(args, key=lambda x: isinstance(x, Quantity) or |
| (isinstance(x, Pow) and isinstance(x.base, Quantity))) |
|
|
| |
| for item in args: |
| if item.is_commutative and item.is_Pow and item.exp.is_Rational and item.exp.is_negative: |
| if item.exp != -1: |
| b.append(Pow(item.base, -item.exp, evaluate=False)) |
| else: |
| b.append(Pow(item.base, -item.exp)) |
| elif item.is_Rational and item is not S.Infinity: |
| if item.p != 1: |
| a.append( Rational(item.p) ) |
| if item.q != 1: |
| b.append( Rational(item.q) ) |
| else: |
| a.append(item) |
|
|
| |
| a = [self._print(ai) for ai in a] |
| b = [self._print(bi) for bi in b] |
|
|
| |
| if len(b) == 0: |
| return prettyForm.__mul__(*a) |
| else: |
| if len(a) == 0: |
| a.append( self._print(S.One) ) |
| return prettyForm.__mul__(*a)/prettyForm.__mul__(*b) |
|
|
| |
| def _print_nth_root(self, base, root): |
| bpretty = self._print(base) |
|
|
| |
| if (self._settings['use_unicode_sqrt_char'] and self._use_unicode |
| and root == 2 and bpretty.height() == 1 |
| and (bpretty.width() == 1 |
| or (base.is_Integer and base.is_nonnegative))): |
| return prettyForm(*bpretty.left(nth_root[2])) |
|
|
| |
| _zZ = xobj('/', 1) |
| rootsign = xobj('\\', 1) + _zZ |
| |
| rpretty = self._print(root) |
| |
| if rpretty.height() != 1: |
| return self._print(base)**self._print(1/root) |
| |
| exp = '' if root == 2 else str(rpretty).ljust(2) |
| if len(exp) > 2: |
| rootsign = ' '*(len(exp) - 2) + rootsign |
| |
| rootsign = stringPict(exp + '\n' + rootsign) |
| rootsign.baseline = 0 |
| |
| linelength = bpretty.height() - 1 |
| diagonal = stringPict('\n'.join( |
| ' '*(linelength - i - 1) + _zZ + ' '*i |
| for i in range(linelength) |
| )) |
| |
| diagonal.baseline = linelength - 1 |
| |
| rootsign = prettyForm(*rootsign.right(diagonal)) |
| |
| |
| rootsign.baseline = max(1, bpretty.baseline) |
| |
| s = prettyForm(hobj('_', 2 + bpretty.width())) |
| s = prettyForm(*bpretty.above(s)) |
| s = prettyForm(*s.left(rootsign)) |
| return s |
|
|
| def _print_Pow(self, power): |
| from sympy.simplify.simplify import fraction |
| b, e = power.as_base_exp() |
| if power.is_commutative: |
| if e is S.NegativeOne: |
| return prettyForm("1")/self._print(b) |
| n, d = fraction(e) |
| if n is S.One and d.is_Atom and not e.is_Integer and (e.is_Rational or d.is_Symbol) \ |
| and self._settings['root_notation']: |
| return self._print_nth_root(b, d) |
| if e.is_Rational and e < 0: |
| return prettyForm("1")/self._print(Pow(b, -e, evaluate=False)) |
|
|
| if b.is_Relational: |
| return prettyForm(*self._print(b).parens()).__pow__(self._print(e)) |
|
|
| return self._print(b)**self._print(e) |
|
|
| def _print_UnevaluatedExpr(self, expr): |
| return self._print(expr.args[0]) |
|
|
| def __print_numer_denom(self, p, q): |
| if q == 1: |
| if p < 0: |
| return prettyForm(str(p), binding=prettyForm.NEG) |
| else: |
| return prettyForm(str(p)) |
| elif abs(p) >= 10 and abs(q) >= 10: |
| |
| if p < 0: |
| return prettyForm(str(p), binding=prettyForm.NEG)/prettyForm(str(q)) |
| |
| |
| |
| else: |
| return prettyForm(str(p))/prettyForm(str(q)) |
| else: |
| return None |
|
|
| def _print_Rational(self, expr): |
| result = self.__print_numer_denom(expr.p, expr.q) |
|
|
| if result is not None: |
| return result |
| else: |
| return self.emptyPrinter(expr) |
|
|
| def _print_Fraction(self, expr): |
| result = self.__print_numer_denom(expr.numerator, expr.denominator) |
|
|
| if result is not None: |
| return result |
| else: |
| return self.emptyPrinter(expr) |
|
|
| def _print_ProductSet(self, p): |
| if len(p.sets) >= 1 and not has_variety(p.sets): |
| return self._print(p.sets[0]) ** self._print(len(p.sets)) |
| else: |
| prod_char = pretty_atom('Multiplication') if self._use_unicode else 'x' |
| return self._print_seq(p.sets, None, None, ' %s ' % prod_char, |
| parenthesize=lambda set: set.is_Union or |
| set.is_Intersection or set.is_ProductSet) |
|
|
| def _print_FiniteSet(self, s): |
| items = sorted(s.args, key=default_sort_key) |
| return self._print_seq(items, '{', '}', ', ' ) |
|
|
| def _print_Range(self, s): |
|
|
| if self._use_unicode: |
| dots = pretty_atom('Dots') |
| else: |
| dots = '...' |
|
|
| if s.start.is_infinite and s.stop.is_infinite: |
| if s.step.is_positive: |
| printset = dots, -1, 0, 1, dots |
| else: |
| printset = dots, 1, 0, -1, dots |
| elif s.start.is_infinite: |
| printset = dots, s[-1] - s.step, s[-1] |
| elif s.stop.is_infinite: |
| it = iter(s) |
| printset = next(it), next(it), dots |
| elif len(s) > 4: |
| it = iter(s) |
| printset = next(it), next(it), dots, s[-1] |
| else: |
| printset = tuple(s) |
|
|
| return self._print_seq(printset, '{', '}', ', ' ) |
|
|
| def _print_Interval(self, i): |
| if i.start == i.end: |
| return self._print_seq(i.args[:1], '{', '}') |
|
|
| else: |
| if i.left_open: |
| left = '(' |
| else: |
| left = '[' |
|
|
| if i.right_open: |
| right = ')' |
| else: |
| right = ']' |
|
|
| return self._print_seq(i.args[:2], left, right) |
|
|
| def _print_AccumulationBounds(self, i): |
| left = '<' |
| right = '>' |
|
|
| return self._print_seq(i.args[:2], left, right) |
|
|
| def _print_Intersection(self, u): |
|
|
| delimiter = ' %s ' % pretty_atom('Intersection', 'n') |
|
|
| return self._print_seq(u.args, None, None, delimiter, |
| parenthesize=lambda set: set.is_ProductSet or |
| set.is_Union or set.is_Complement) |
|
|
| def _print_Union(self, u): |
|
|
| union_delimiter = ' %s ' % pretty_atom('Union', 'U') |
|
|
| return self._print_seq(u.args, None, None, union_delimiter, |
| parenthesize=lambda set: set.is_ProductSet or |
| set.is_Intersection or set.is_Complement) |
|
|
| def _print_SymmetricDifference(self, u): |
| if not self._use_unicode: |
| raise NotImplementedError("ASCII pretty printing of SymmetricDifference is not implemented") |
|
|
| sym_delimeter = ' %s ' % pretty_atom('SymmetricDifference') |
|
|
| return self._print_seq(u.args, None, None, sym_delimeter) |
|
|
| def _print_Complement(self, u): |
|
|
| delimiter = r' \ ' |
|
|
| return self._print_seq(u.args, None, None, delimiter, |
| parenthesize=lambda set: set.is_ProductSet or set.is_Intersection |
| or set.is_Union) |
|
|
| def _print_ImageSet(self, ts): |
| if self._use_unicode: |
| inn = pretty_atom("SmallElementOf") |
| else: |
| inn = 'in' |
| fun = ts.lamda |
| sets = ts.base_sets |
| signature = fun.signature |
| expr = self._print(fun.expr) |
|
|
| |
| |
| |
| |
| |
| if len(signature) == 1: |
| S = self._print_seq((signature[0], inn, sets[0]), |
| delimiter=' ') |
| return self._hprint_vseparator(expr, S, |
| left='{', right='}', |
| ifascii_nougly=True, delimiter=' ') |
| else: |
| pargs = tuple(j for var, setv in zip(signature, sets) for j in |
| (var, ' ', inn, ' ', setv, ", ")) |
| S = self._print_seq(pargs[:-1], delimiter='') |
| return self._hprint_vseparator(expr, S, |
| left='{', right='}', |
| ifascii_nougly=True, delimiter=' ') |
|
|
| def _print_ConditionSet(self, ts): |
| if self._use_unicode: |
| inn = pretty_atom('SmallElementOf') |
| |
| |
| _and = pretty_atom('And') |
| else: |
| inn = 'in' |
| _and = 'and' |
|
|
| variables = self._print_seq(Tuple(ts.sym)) |
| as_expr = getattr(ts.condition, 'as_expr', None) |
| if as_expr is not None: |
| cond = self._print(ts.condition.as_expr()) |
| else: |
| cond = self._print(ts.condition) |
| if self._use_unicode: |
| cond = self._print(cond) |
| cond = prettyForm(*cond.parens()) |
|
|
| if ts.base_set is S.UniversalSet: |
| return self._hprint_vseparator(variables, cond, left="{", |
| right="}", ifascii_nougly=True, |
| delimiter=' ') |
|
|
| base = self._print(ts.base_set) |
| C = self._print_seq((variables, inn, base, _and, cond), |
| delimiter=' ') |
| return self._hprint_vseparator(variables, C, left="{", right="}", |
| ifascii_nougly=True, delimiter=' ') |
|
|
| def _print_ComplexRegion(self, ts): |
| if self._use_unicode: |
| inn = pretty_atom('SmallElementOf') |
| else: |
| inn = 'in' |
| variables = self._print_seq(ts.variables) |
| expr = self._print(ts.expr) |
| prodsets = self._print(ts.sets) |
|
|
| C = self._print_seq((variables, inn, prodsets), |
| delimiter=' ') |
| return self._hprint_vseparator(expr, C, left="{", right="}", |
| ifascii_nougly=True, delimiter=' ') |
|
|
| def _print_Contains(self, e): |
| var, set = e.args |
| if self._use_unicode: |
| el = f" {pretty_atom('ElementOf')} " |
| return prettyForm(*stringPict.next(self._print(var), |
| el, self._print(set)), binding=8) |
| else: |
| return prettyForm(sstr(e)) |
|
|
| def _print_FourierSeries(self, s): |
| if s.an.formula is S.Zero and s.bn.formula is S.Zero: |
| return self._print(s.a0) |
| if self._use_unicode: |
| dots = pretty_atom('Dots') |
| else: |
| dots = '...' |
| return self._print_Add(s.truncate()) + self._print(dots) |
|
|
| def _print_FormalPowerSeries(self, s): |
| return self._print_Add(s.infinite) |
|
|
| def _print_SetExpr(self, se): |
| pretty_set = prettyForm(*self._print(se.set).parens()) |
| pretty_name = self._print(Symbol("SetExpr")) |
| return prettyForm(*pretty_name.right(pretty_set)) |
|
|
| def _print_SeqFormula(self, s): |
| if self._use_unicode: |
| dots = pretty_atom('Dots') |
| else: |
| dots = '...' |
|
|
| if len(s.start.free_symbols) > 0 or len(s.stop.free_symbols) > 0: |
| raise NotImplementedError("Pretty printing of sequences with symbolic bound not implemented") |
|
|
| if s.start is S.NegativeInfinity: |
| stop = s.stop |
| printset = (dots, s.coeff(stop - 3), s.coeff(stop - 2), |
| s.coeff(stop - 1), s.coeff(stop)) |
| elif s.stop is S.Infinity or s.length > 4: |
| printset = s[:4] |
| printset.append(dots) |
| printset = tuple(printset) |
| else: |
| printset = tuple(s) |
| return self._print_list(printset) |
|
|
| _print_SeqPer = _print_SeqFormula |
| _print_SeqAdd = _print_SeqFormula |
| _print_SeqMul = _print_SeqFormula |
|
|
| def _print_seq(self, seq, left=None, right=None, delimiter=', ', |
| parenthesize=lambda x: False, ifascii_nougly=True): |
|
|
| pforms = [] |
| for item in seq: |
| pform = self._print(item) |
| if parenthesize(item): |
| pform = prettyForm(*pform.parens()) |
| if pforms: |
| pforms.append(delimiter) |
| pforms.append(pform) |
|
|
| if not pforms: |
| s = stringPict('') |
| else: |
| s = prettyForm(*stringPict.next(*pforms)) |
|
|
| s = prettyForm(*s.parens(left, right, ifascii_nougly=ifascii_nougly)) |
| return s |
|
|
| def join(self, delimiter, args): |
| pform = None |
|
|
| for arg in args: |
| if pform is None: |
| pform = arg |
| else: |
| pform = prettyForm(*pform.right(delimiter)) |
| pform = prettyForm(*pform.right(arg)) |
|
|
| if pform is None: |
| return prettyForm("") |
| else: |
| return pform |
|
|
| def _print_list(self, l): |
| return self._print_seq(l, '[', ']') |
|
|
| def _print_tuple(self, t): |
| if len(t) == 1: |
| ptuple = prettyForm(*stringPict.next(self._print(t[0]), ',')) |
| return prettyForm(*ptuple.parens('(', ')', ifascii_nougly=True)) |
| else: |
| return self._print_seq(t, '(', ')') |
|
|
| def _print_Tuple(self, expr): |
| return self._print_tuple(expr) |
|
|
| def _print_dict(self, d): |
| keys = sorted(d.keys(), key=default_sort_key) |
| items = [] |
|
|
| for k in keys: |
| K = self._print(k) |
| V = self._print(d[k]) |
| s = prettyForm(*stringPict.next(K, ': ', V)) |
|
|
| items.append(s) |
|
|
| return self._print_seq(items, '{', '}') |
|
|
| def _print_Dict(self, d): |
| return self._print_dict(d) |
|
|
| def _print_set(self, s): |
| if not s: |
| return prettyForm('set()') |
| items = sorted(s, key=default_sort_key) |
| pretty = self._print_seq(items) |
| pretty = prettyForm(*pretty.parens('{', '}', ifascii_nougly=True)) |
| return pretty |
|
|
| def _print_frozenset(self, s): |
| if not s: |
| return prettyForm('frozenset()') |
| items = sorted(s, key=default_sort_key) |
| pretty = self._print_seq(items) |
| pretty = prettyForm(*pretty.parens('{', '}', ifascii_nougly=True)) |
| pretty = prettyForm(*pretty.parens('(', ')', ifascii_nougly=True)) |
| pretty = prettyForm(*stringPict.next(type(s).__name__, pretty)) |
| return pretty |
|
|
| def _print_UniversalSet(self, s): |
| if self._use_unicode: |
| return prettyForm(pretty_atom('Universe')) |
| else: |
| return prettyForm('UniversalSet') |
|
|
| def _print_PolyRing(self, ring): |
| return prettyForm(sstr(ring)) |
|
|
| def _print_FracField(self, field): |
| return prettyForm(sstr(field)) |
|
|
| def _print_FreeGroupElement(self, elm): |
| return prettyForm(str(elm)) |
|
|
| def _print_PolyElement(self, poly): |
| return prettyForm(sstr(poly)) |
|
|
| def _print_FracElement(self, frac): |
| return prettyForm(sstr(frac)) |
|
|
| def _print_AlgebraicNumber(self, expr): |
| if expr.is_aliased: |
| return self._print(expr.as_poly().as_expr()) |
| else: |
| return self._print(expr.as_expr()) |
|
|
| def _print_ComplexRootOf(self, expr): |
| args = [self._print_Add(expr.expr, order='lex'), expr.index] |
| pform = prettyForm(*self._print_seq(args).parens()) |
| pform = prettyForm(*pform.left('CRootOf')) |
| return pform |
|
|
| def _print_RootSum(self, expr): |
| args = [self._print_Add(expr.expr, order='lex')] |
|
|
| if expr.fun is not S.IdentityFunction: |
| args.append(self._print(expr.fun)) |
|
|
| pform = prettyForm(*self._print_seq(args).parens()) |
| pform = prettyForm(*pform.left('RootSum')) |
|
|
| return pform |
|
|
| def _print_FiniteField(self, expr): |
| if self._use_unicode: |
| form = f"{pretty_atom('Integers')}_%d" |
| else: |
| form = 'GF(%d)' |
|
|
| return prettyForm(pretty_symbol(form % expr.mod)) |
|
|
| def _print_IntegerRing(self, expr): |
| if self._use_unicode: |
| return prettyForm(pretty_atom('Integers')) |
| else: |
| return prettyForm('ZZ') |
|
|
| def _print_RationalField(self, expr): |
| if self._use_unicode: |
| return prettyForm(pretty_atom('Rationals')) |
| else: |
| return prettyForm('QQ') |
|
|
| def _print_RealField(self, domain): |
| if self._use_unicode: |
| prefix = pretty_atom("Reals") |
| else: |
| prefix = 'RR' |
|
|
| if domain.has_default_precision: |
| return prettyForm(prefix) |
| else: |
| return self._print(pretty_symbol(prefix + "_" + str(domain.precision))) |
|
|
| def _print_ComplexField(self, domain): |
| if self._use_unicode: |
| prefix = pretty_atom('Complexes') |
| else: |
| prefix = 'CC' |
|
|
| if domain.has_default_precision: |
| return prettyForm(prefix) |
| else: |
| return self._print(pretty_symbol(prefix + "_" + str(domain.precision))) |
|
|
| def _print_PolynomialRing(self, expr): |
| args = list(expr.symbols) |
|
|
| if not expr.order.is_default: |
| order = prettyForm(*prettyForm("order=").right(self._print(expr.order))) |
| args.append(order) |
|
|
| pform = self._print_seq(args, '[', ']') |
| pform = prettyForm(*pform.left(self._print(expr.domain))) |
|
|
| return pform |
|
|
| def _print_FractionField(self, expr): |
| args = list(expr.symbols) |
|
|
| if not expr.order.is_default: |
| order = prettyForm(*prettyForm("order=").right(self._print(expr.order))) |
| args.append(order) |
|
|
| pform = self._print_seq(args, '(', ')') |
| pform = prettyForm(*pform.left(self._print(expr.domain))) |
|
|
| return pform |
|
|
| def _print_PolynomialRingBase(self, expr): |
| g = expr.symbols |
| if str(expr.order) != str(expr.default_order): |
| g = g + ("order=" + str(expr.order),) |
| pform = self._print_seq(g, '[', ']') |
| pform = prettyForm(*pform.left(self._print(expr.domain))) |
|
|
| return pform |
|
|
| def _print_GroebnerBasis(self, basis): |
| exprs = [ self._print_Add(arg, order=basis.order) |
| for arg in basis.exprs ] |
| exprs = prettyForm(*self.join(", ", exprs).parens(left="[", right="]")) |
|
|
| gens = [ self._print(gen) for gen in basis.gens ] |
|
|
| domain = prettyForm( |
| *prettyForm("domain=").right(self._print(basis.domain))) |
| order = prettyForm( |
| *prettyForm("order=").right(self._print(basis.order))) |
|
|
| pform = self.join(", ", [exprs] + gens + [domain, order]) |
|
|
| pform = prettyForm(*pform.parens()) |
| pform = prettyForm(*pform.left(basis.__class__.__name__)) |
|
|
| return pform |
|
|
| def _print_Subs(self, e): |
| pform = self._print(e.expr) |
| pform = prettyForm(*pform.parens()) |
|
|
| h = pform.height() if pform.height() > 1 else 2 |
| rvert = stringPict(vobj('|', h), baseline=pform.baseline) |
| pform = prettyForm(*pform.right(rvert)) |
|
|
| b = pform.baseline |
| pform.baseline = pform.height() - 1 |
| pform = prettyForm(*pform.right(self._print_seq([ |
| self._print_seq((self._print(v[0]), xsym('=='), self._print(v[1])), |
| delimiter='') for v in zip(e.variables, e.point) ]))) |
|
|
| pform.baseline = b |
| return pform |
|
|
| def _print_number_function(self, e, name): |
| |
| |
| pform = prettyForm(name) |
| arg = self._print(e.args[0]) |
| pform_arg = prettyForm(" "*arg.width()) |
| pform_arg = prettyForm(*pform_arg.below(arg)) |
| pform = prettyForm(*pform.right(pform_arg)) |
| if len(e.args) == 1: |
| return pform |
| m, x = e.args |
| |
| prettyFunc = pform |
| prettyArgs = prettyForm(*self._print_seq([x]).parens()) |
| pform = prettyForm( |
| binding=prettyForm.FUNC, *stringPict.next(prettyFunc, prettyArgs)) |
| pform.prettyFunc = prettyFunc |
| pform.prettyArgs = prettyArgs |
| return pform |
|
|
| def _print_euler(self, e): |
| return self._print_number_function(e, "E") |
|
|
| def _print_catalan(self, e): |
| return self._print_number_function(e, "C") |
|
|
| def _print_bernoulli(self, e): |
| return self._print_number_function(e, "B") |
|
|
| _print_bell = _print_bernoulli |
|
|
| def _print_lucas(self, e): |
| return self._print_number_function(e, "L") |
|
|
| def _print_fibonacci(self, e): |
| return self._print_number_function(e, "F") |
|
|
| def _print_tribonacci(self, e): |
| return self._print_number_function(e, "T") |
|
|
| def _print_stieltjes(self, e): |
| if self._use_unicode: |
| return self._print_number_function(e, greek_unicode['gamma']) |
| else: |
| return self._print_number_function(e, "stieltjes") |
|
|
| def _print_KroneckerDelta(self, e): |
| pform = self._print(e.args[0]) |
| pform = prettyForm(*pform.right(prettyForm(','))) |
| pform = prettyForm(*pform.right(self._print(e.args[1]))) |
| if self._use_unicode: |
| a = stringPict(pretty_symbol('delta')) |
| else: |
| a = stringPict('d') |
| b = pform |
| top = stringPict(*b.left(' '*a.width())) |
| bot = stringPict(*a.right(' '*b.width())) |
| return prettyForm(binding=prettyForm.POW, *bot.below(top)) |
|
|
| def _print_RandomDomain(self, d): |
| if hasattr(d, 'as_boolean'): |
| pform = self._print('Domain: ') |
| pform = prettyForm(*pform.right(self._print(d.as_boolean()))) |
| return pform |
| elif hasattr(d, 'set'): |
| pform = self._print('Domain: ') |
| pform = prettyForm(*pform.right(self._print(d.symbols))) |
| pform = prettyForm(*pform.right(self._print(' in '))) |
| pform = prettyForm(*pform.right(self._print(d.set))) |
| return pform |
| elif hasattr(d, 'symbols'): |
| pform = self._print('Domain on ') |
| pform = prettyForm(*pform.right(self._print(d.symbols))) |
| return pform |
| else: |
| return self._print(None) |
|
|
| def _print_DMP(self, p): |
| try: |
| if p.ring is not None: |
| |
| return self._print(p.ring.to_sympy(p)) |
| except SympifyError: |
| pass |
| return self._print(repr(p)) |
|
|
| def _print_DMF(self, p): |
| return self._print_DMP(p) |
|
|
| def _print_Object(self, object): |
| return self._print(pretty_symbol(object.name)) |
|
|
| def _print_Morphism(self, morphism): |
| arrow = xsym("-->") |
|
|
| domain = self._print(morphism.domain) |
| codomain = self._print(morphism.codomain) |
| tail = domain.right(arrow, codomain)[0] |
|
|
| return prettyForm(tail) |
|
|
| def _print_NamedMorphism(self, morphism): |
| pretty_name = self._print(pretty_symbol(morphism.name)) |
| pretty_morphism = self._print_Morphism(morphism) |
| return prettyForm(pretty_name.right(":", pretty_morphism)[0]) |
|
|
| def _print_IdentityMorphism(self, morphism): |
| from sympy.categories import NamedMorphism |
| return self._print_NamedMorphism( |
| NamedMorphism(morphism.domain, morphism.codomain, "id")) |
|
|
| def _print_CompositeMorphism(self, morphism): |
|
|
| circle = xsym(".") |
|
|
| |
| |
| component_names_list = [pretty_symbol(component.name) for |
| component in morphism.components] |
| component_names_list.reverse() |
| component_names = circle.join(component_names_list) + ":" |
|
|
| pretty_name = self._print(component_names) |
| pretty_morphism = self._print_Morphism(morphism) |
| return prettyForm(pretty_name.right(pretty_morphism)[0]) |
|
|
| def _print_Category(self, category): |
| return self._print(pretty_symbol(category.name)) |
|
|
| def _print_Diagram(self, diagram): |
| if not diagram.premises: |
| |
| return self._print(S.EmptySet) |
|
|
| pretty_result = self._print(diagram.premises) |
| if diagram.conclusions: |
| results_arrow = " %s " % xsym("==>") |
|
|
| pretty_conclusions = self._print(diagram.conclusions)[0] |
| pretty_result = pretty_result.right( |
| results_arrow, pretty_conclusions) |
|
|
| return prettyForm(pretty_result[0]) |
|
|
| def _print_DiagramGrid(self, grid): |
| from sympy.matrices import Matrix |
| matrix = Matrix([[grid[i, j] if grid[i, j] else Symbol(" ") |
| for j in range(grid.width)] |
| for i in range(grid.height)]) |
| return self._print_matrix_contents(matrix) |
|
|
| def _print_FreeModuleElement(self, m): |
| |
| return self._print_seq(m, '[', ']') |
|
|
| def _print_SubModule(self, M): |
| gens = [[M.ring.to_sympy(g) for g in gen] for gen in M.gens] |
| return self._print_seq(gens, '<', '>') |
|
|
| def _print_FreeModule(self, M): |
| return self._print(M.ring)**self._print(M.rank) |
|
|
| def _print_ModuleImplementedIdeal(self, M): |
| sym = M.ring.to_sympy |
| return self._print_seq([sym(x) for [x] in M._module.gens], '<', '>') |
|
|
| def _print_QuotientRing(self, R): |
| return self._print(R.ring) / self._print(R.base_ideal) |
|
|
| def _print_QuotientRingElement(self, R): |
| return self._print(R.ring.to_sympy(R)) + self._print(R.ring.base_ideal) |
|
|
| def _print_QuotientModuleElement(self, m): |
| return self._print(m.data) + self._print(m.module.killed_module) |
|
|
| def _print_QuotientModule(self, M): |
| return self._print(M.base) / self._print(M.killed_module) |
|
|
| def _print_MatrixHomomorphism(self, h): |
| matrix = self._print(h._sympy_matrix()) |
| matrix.baseline = matrix.height() // 2 |
| pform = prettyForm(*matrix.right(' : ', self._print(h.domain), |
| ' %s> ' % hobj('-', 2), self._print(h.codomain))) |
| return pform |
|
|
| def _print_Manifold(self, manifold): |
| return self._print(manifold.name) |
|
|
| def _print_Patch(self, patch): |
| return self._print(patch.name) |
|
|
| def _print_CoordSystem(self, coords): |
| return self._print(coords.name) |
|
|
| def _print_BaseScalarField(self, field): |
| string = field._coord_sys.symbols[field._index].name |
| return self._print(pretty_symbol(string)) |
|
|
| def _print_BaseVectorField(self, field): |
| s = U('PARTIAL DIFFERENTIAL') + '_' + field._coord_sys.symbols[field._index].name |
| return self._print(pretty_symbol(s)) |
|
|
| def _print_Differential(self, diff): |
| if self._use_unicode: |
| d = pretty_atom('Differential') |
| else: |
| d = 'd' |
| field = diff._form_field |
| if hasattr(field, '_coord_sys'): |
| string = field._coord_sys.symbols[field._index].name |
| return self._print(d + ' ' + pretty_symbol(string)) |
| else: |
| pform = self._print(field) |
| pform = prettyForm(*pform.parens()) |
| return prettyForm(*pform.left(d)) |
|
|
| def _print_Tr(self, p): |
| |
| pform = self._print(p.args[0]) |
| pform = prettyForm(*pform.left('%s(' % (p.__class__.__name__))) |
| pform = prettyForm(*pform.right(')')) |
| return pform |
|
|
| def _print_primenu(self, e): |
| pform = self._print(e.args[0]) |
| pform = prettyForm(*pform.parens()) |
| if self._use_unicode: |
| pform = prettyForm(*pform.left(greek_unicode['nu'])) |
| else: |
| pform = prettyForm(*pform.left('nu')) |
| return pform |
|
|
| def _print_primeomega(self, e): |
| pform = self._print(e.args[0]) |
| pform = prettyForm(*pform.parens()) |
| if self._use_unicode: |
| pform = prettyForm(*pform.left(greek_unicode['Omega'])) |
| else: |
| pform = prettyForm(*pform.left('Omega')) |
| return pform |
|
|
| def _print_Quantity(self, e): |
| if e.name.name == 'degree': |
| if self._use_unicode: |
| pform = self._print(pretty_atom('Degree')) |
| else: |
| pform = self._print(chr(176)) |
| return pform |
| else: |
| return self.emptyPrinter(e) |
|
|
| def _print_AssignmentBase(self, e): |
|
|
| op = prettyForm(' ' + xsym(e.op) + ' ') |
|
|
| l = self._print(e.lhs) |
| r = self._print(e.rhs) |
| pform = prettyForm(*stringPict.next(l, op, r)) |
| return pform |
|
|
| def _print_Str(self, s): |
| return self._print(s.name) |
|
|
|
|
| @print_function(PrettyPrinter) |
| def pretty(expr, **settings): |
| """Returns a string containing the prettified form of expr. |
| |
| For information on keyword arguments see pretty_print function. |
| |
| """ |
| pp = PrettyPrinter(settings) |
|
|
| |
| use_unicode = pp._settings['use_unicode'] |
| uflag = pretty_use_unicode(use_unicode) |
|
|
| try: |
| return pp.doprint(expr) |
| finally: |
| pretty_use_unicode(uflag) |
|
|
|
|
| def pretty_print(expr, **kwargs): |
| """Prints expr in pretty form. |
| |
| pprint is just a shortcut for this function. |
| |
| Parameters |
| ========== |
| |
| expr : expression |
| The expression to print. |
| |
| wrap_line : bool, optional (default=True) |
| Line wrapping enabled/disabled. |
| |
| num_columns : int or None, optional (default=None) |
| Number of columns before line breaking (default to None which reads |
| the terminal width), useful when using SymPy without terminal. |
| |
| use_unicode : bool or None, optional (default=None) |
| Use unicode characters, such as the Greek letter pi instead of |
| the string pi. |
| |
| full_prec : bool or string, optional (default="auto") |
| Use full precision. |
| |
| order : bool or string, optional (default=None) |
| Set to 'none' for long expressions if slow; default is None. |
| |
| use_unicode_sqrt_char : bool, optional (default=True) |
| Use compact single-character square root symbol (when unambiguous). |
| |
| root_notation : bool, optional (default=True) |
| Set to 'False' for printing exponents of the form 1/n in fractional form. |
| By default exponent is printed in root form. |
| |
| mat_symbol_style : string, optional (default="plain") |
| Set to "bold" for printing MatrixSymbols using a bold mathematical symbol face. |
| By default the standard face is used. |
| |
| imaginary_unit : string, optional (default="i") |
| Letter to use for imaginary unit when use_unicode is True. |
| Can be "i" (default) or "j". |
| """ |
| print(pretty(expr, **kwargs)) |
|
|
| pprint = pretty_print |
|
|
|
|
| def pager_print(expr, **settings): |
| """Prints expr using the pager, in pretty form. |
| |
| This invokes a pager command using pydoc. Lines are not wrapped |
| automatically. This routine is meant to be used with a pager that allows |
| sideways scrolling, like ``less -S``. |
| |
| Parameters are the same as for ``pretty_print``. If you wish to wrap lines, |
| pass ``num_columns=None`` to auto-detect the width of the terminal. |
| |
| """ |
| from pydoc import pager |
| from locale import getpreferredencoding |
| if 'num_columns' not in settings: |
| settings['num_columns'] = 500000 |
| pager(pretty(expr, **settings).encode(getpreferredencoding())) |
|
|