def _print_Add(self, expr): args = list(expr.args) # Now we need to sort the factors in Add, which are in "rest". Any # ordering is fine, but some ordering looks better and some looks bad. # This particular solution is slow, but it ensures a sane ordering. It # can of course be improved: args.sort(Basic._compare_pretty) PREC = precedence(expr) l = [] for term in args: t = self._print(term) if t.startswith('-'): sign = "-" t = t[1:] else: sign = "+" if precedence(term) < PREC: l.extend([sign, "(%s)"%t]) else: l.extend([sign, t]) sign = l.pop(0) if sign=='+': sign = "" return sign + ' '.join(l)
def test_Number(): assert precedence(Integer(0)) == PRECEDENCE["Atom"] assert precedence(Integer(1)) == PRECEDENCE["Atom"] assert precedence(Integer(-1)) == PRECEDENCE["Add"] assert precedence(Integer(10)) == PRECEDENCE["Atom"] assert precedence(Rational(5, 2)) == PRECEDENCE["Mul"] assert precedence(Rational(-5, 2)) == PRECEDENCE["Add"] assert precedence(Float(5)) == PRECEDENCE["Atom"] assert precedence(Float(-5)) == PRECEDENCE["Add"] assert precedence(oo) == PRECEDENCE["Atom"] assert precedence(-oo) == PRECEDENCE["Add"]
def _print_Relational(self, expr): charmap = {"==": "Eq", "!=": "Ne", ":=": "Assignment"} if expr.rel_op in charmap: return "%s(%s, %s)" % (charmap[expr.rel_op], expr.lhs, expr.rhs) return "%s %s %s" % ( self.parenthesize(expr.lhs, precedence(expr)), self._relationals.get(expr.rel_op) or expr.rel_op, self.parenthesize(expr.rhs, precedence(expr)), )
def parenthesize(self, item, level): printed = self._print(item) if precedence(item) <= level: return "(%s)" % printed else: return printed
def _print_Pow(self, expr, rational=False): PREC = precedence(expr) #if expr.base is RootOfUnity: # return 'Exp['+str(2*expr.base.n)+ 'I Pi /'+ str(expr.base.n) + ']' if expr.exp is S.Half and not rational: return "sqrt(%s)" % self._print(expr.base) if expr.is_commutative: if -expr.exp is S.Half and not rational: # Note: Don't test "expr.exp == -S.Half" here, because that will # match -0.5, which we don't want. return "1/sqrt(%s)" % self._print(expr.base) if expr.exp is -S.One: # Similarly to the S.Half case, don't test with "==" here. return '1/%s' % self.parenthesize(expr.base, PREC) e = self.parenthesize(expr.exp, PREC) if self.printmethod == '_sympyrepr' and expr.exp.is_Rational and expr.exp.q != 1: # the parenthesized exp should be '(Rational(a, b))' so strip parens, # but just check to be sure. if e.startswith('(Rational'): return '%s^%s' % (self.parenthesize(expr.base, PREC), e[1:-1]) return '%s^%s' % (self.parenthesize(expr.base, PREC), e)
def _print_Pow(self, expr, rational=False): # WARNING: Code mostly copied from sympy source code! from sympy.core import S from sympy.printing.precedence import precedence PREC = precedence(expr) if expr.exp is S.Half and not rational: return "sqrt(%s)" % self._print(expr.base) if expr.is_commutative: if -expr.exp is S.Half and not rational: # Note: Don't test "expr.exp == -S.Half" here, because that will # match -0.5, which we don't want. return "1/sqrt(%s)" % self._print(expr.base) if expr.exp is -S.One: # Similarly to the S.Half case, don't test with "==" here. return '1/%s' % self.parenthesize(expr.base, PREC) e = self.parenthesize(expr.exp, PREC) if self.printmethod == '_sympyrepr' and expr.exp.is_Rational and expr.exp.q != 1: # the parenthesized exp should be '(Rational(a, b))' so strip parens, # but just check to be sure. if e.startswith('(Rational'): e = e[1:-1] # Changes below this line! if e == "2": return '{0}*{0}'.format(self.parenthesize(expr.base, PREC)) elif e == "3": return '{0}*{0}*{0}'.format(self.parenthesize(expr.base, PREC)) else: return 'pow(%s,%s)' % (self.parenthesize(expr.base, PREC), e)
def _print_Pow(self, expr): PREC = precedence(expr) if expr.exp is S.NegativeOne: return '1/%s'%(self.parenthesize(expr.base, PREC)) else: return '%s**%s'%(self.parenthesize(expr.base, PREC), self.parenthesize(expr.exp, PREC))
def _print_Pow(self, expr): if expr.exp == 2: PREC = precedence(expr) s = str(self.parenthesize(expr.base, PREC)) return '%s*%s' % (s,s) else: return super(CCodePrinter,self)._print_Pow(expr)
def _print_Pow(self, expr): prec = precedence(expr) if expr.exp == -1: return '1/%s' % (self.parenthesize(expr.base, prec)) else: return '%s^%s' % (self.parenthesize(expr.base, prec), self.parenthesize(expr.exp, prec))
def _print_Mul(self, expr): PREC = precedence(expr) c, nc = expr.args_cnc() res = super(MCodePrinter, self)._print_Mul(expr.func(*c)) if nc: res += '*' res += '**'.join(self.parenthesize(a, PREC) for a in nc) return res
def _print_Mul(self, expr): coeff, terms = expr.as_coeff_mul() if coeff.is_negative: coeff = -coeff if coeff is not S.One: terms = (coeff,) + terms sign = "-" else: terms = (coeff,) + terms sign = "" a = [] # items in the numerator b = [] # items that are in the denominator (if any) if self.order != 'old': args = expr._new_rawargs(*terms).as_ordered_factors() else: args = terms # Gather args for numerator/denominator for item in args: if item.is_Pow and item.exp.is_Rational and item.exp.is_negative: 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) if len(a)==0: a = [S.One] a_str = map(lambda x:self.parenthesize(x, precedence(expr)), a) b_str = map(lambda x:self.parenthesize(x, precedence(expr)), b) if len(b)==0: return sign + '*'.join(a_str) elif len(b)==1: if len(a)==1 and not (a[0].is_Atom or a[0].is_Add): return sign + "%s/"%a_str[0] + '*'.join(b_str) else: return sign + '*'.join(a_str) + "/%s"%b_str[0] else: return sign + '*'.join(a_str) + "/(%s)"%'*'.join(b_str)
def _print_Pow(self, expr): PREC = precedence(expr) if expr.exp == -1: return "1.0/%s" % (self.parenthesize(expr.base, PREC)) elif expr.exp == 0.5: return "sqrt(%s)" % self._print(expr.base) else: return "pow(%s, %s)" % (self._print(expr.base), self._print(expr.exp))
def _print_Pow(self, expr): PREC = precedence(expr) if expr.exp is S.NegativeOne: return '1.0/%s'%(self.parenthesize(expr.base, PREC)) elif expr.exp == 0.5: return 'sqrt(%s)' % self._print(expr.base) else: return StrPrinter._print_Pow(self, expr)
def _print_Pow(self, expr): PREC = precedence(expr) if expr.exp.is_Rational and expr.exp.p == 1 and expr.exp.q == 2: return 'sqrt(%s)' % self._print(expr.base) if expr.exp.is_Rational and expr.exp.is_negative: return '1/%s'%self._print(expr.base**abs(expr.exp)) else: return '%s^%s'%(self.parenthesize(expr.base, PREC), self.parenthesize(expr.exp, PREC))
def _print_Pow(self, expr): PREC = precedence(expr) if expr.exp == -1: return '1/%s' % (self.parenthesize(expr.base, PREC)) elif expr.exp == 0.5: return 'Math.sqrt(%s)' % self._print(expr.base) else: return 'Math.pow(%s, %s)' % (self._print(expr.base), self._print(expr.exp))
def _print_Pow(self, expr): PREC = precedence(expr) if expr.exp is S.NegativeOne: return '1.0/%s'%(self.parenthesize(expr.base, PREC)) elif isinstance(expr.base, Symbol) and expr.exp == 2: tmp = self.parenthesize(expr.base, PREC) return tmp+"*"+tmp else: return 'pow(%s,%s)'%(self.parenthesize(expr.base, PREC), self.parenthesize(expr.exp, PREC))
def _print_MatMul(self, expr): c, m = expr.as_coeff_mmul() if c.is_number and c < 0: expr = _keep_coeff(-c, m) sign = "-" else: sign = "" return sign + '*'.join([self.parenthesize(arg, precedence(expr)) for arg in expr.args])
def _print_Pow(self, expr): PREC = precedence(expr) if expr.exp is NegativeOne: return "(1.0/%s)" % (self.parenthesize(expr.base, PREC)) # For the kernel code, it's better to calculate the power # here explicitly by multiplication. elif expr.exp == 2: return "(%s*%s)" % (self.parenthesize(expr.base, PREC), self.parenthesize(expr.base, PREC)) else: return int2float("powf(%s,%s)" % (self.parenthesize(expr.base, PREC), self.parenthesize(expr.exp, PREC)))
def _print_Relational(self, expr): charmap = { "==": "Eq", "!=": "Ne", ":=": "Assignment", '+=': "AddAugmentedAssignment", "-=": "SubAugmentedAssignment", "*=": "MulAugmentedAssignment", "/=": "DivAugmentedAssignment", "%=": "ModAugmentedAssignment", } if expr.rel_op in charmap: return '%s(%s, %s)' % (charmap[expr.rel_op], expr.lhs, expr.rhs) return '%s %s %s' % (self.parenthesize(expr.lhs, precedence(expr)), self._relationals.get(expr.rel_op) or expr.rel_op, self.parenthesize(expr.rhs, precedence(expr)))
def _print_Mul(self, expr): prec = precedence(expr) c, e = expr.as_coeff_Mul() if c < 0: expr = _keep_coeff(-c, e) sign = "-" else: sign = "" a = [] # items in the numerator b = [] # items that are in the denominator (if any) pow_paren = [] # Will collect all pow with more than one base element and exp = -1 if self.order not in ('old', 'none'): args = expr.as_ordered_factors() else: # use make_args in case expr was something like -x -> x args = Mul.make_args(expr) # Gather args for numerator/denominator 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: if len(item.args[0].args) != 1 and isinstance(item.base, Mul): # To avoid situations like #14160 pow_paren.append(item) 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 = a or [S.One] a_str = [self.parenthesize(x, prec, strict=False) for x in a] b_str = [self.parenthesize(x, prec, strict=False) for x in b] # To parenthesize Pow with exp = -1 and having more than one Symbol for item in pow_paren: if item.base in b: b_str[b.index(item.base)] = "(%s)" % b_str[b.index(item.base)] if len(b) == 0: return sign + '*'.join(a_str) elif len(b) == 1: return sign + '*'.join(a_str) + "/" + b_str[0] else: return sign + '*'.join(a_str) + "/(%s)" % '*'.join(b_str)
def _print_Pow(self, expr): if "Pow" in self.known_functions: return self._print_Function(expr) PREC = precedence(expr) if expr.exp == -1: return '1.0/%s' % (self.parenthesize(expr.base, PREC)) elif expr.exp == 0.5: return 'sqrt(%s)' % self._print(expr.base) else: return 'pow(%s, %s)' % (self._print(expr.base), self._print(expr.exp))
def _print_Pow(self, expr, rational=False): "Copied from sympy StrPrinter to remove TC-incompatible Pow simplifications." PREC = precedence(expr) e = self.parenthesize(expr.exp, PREC) if self.printmethod == '_sympyrepr' and expr.exp.is_Rational and expr.exp.q != 1: # the parenthesized exp should be '(Rational(a, b))' so strip parens, # but just check to be sure. if e.startswith('(Rational'): return '%s**%s' % (self.parenthesize(expr.base, PREC), e[1:-1]) return '%s**%s' % (self.parenthesize(expr.base, PREC), e)
def _print_Add(self, expr, order=None): terms = self._as_ordered_terms(expr, order=order) PREC = precedence(expr) l = [] for term in terms: t = self._print(term) if t.startswith('-'): sign = "-" t = t[1:] else: sign = "+" if precedence(term) < PREC: l.extend([sign, "(%s)"%t]) else: l.extend([sign, t]) sign = l.pop(0) if sign=='+': sign = "" return sign + ' '.join(l)
def _print_Pow(self, expr): PREC = precedence(expr) if expr.exp == -1: return '1/%s' % (self.parenthesize(expr.base, PREC)) elif expr.exp == 0.5: return 'sqrt(%s)' % self._print(expr.base) elif expr.base == 2: return 'exp2(%s)' % self._print(expr.exp) else: return '%s^%s' % (self.parenthesize(expr.base, PREC), self.parenthesize(expr.exp, PREC))
def _print_Pow(self, expr): PREC = precedence(expr) if expr.exp == -1: return '1.0/%s' % (self.parenthesize(expr.base, PREC)) elif expr.exp == 0.5: return 'sqrt(%s)' % self._print(expr.base) else: try: e = self._print(float(expr.exp)) except TypeError: e = self._print(expr.exp) # return self.known_functions['pow']+'(%s, %s)' % (self._print(expr.base),e) return self._print_Function_with_args('pow',self._print(expr.base),e)
def _print_Pow(self, expr): if "Pow" in self.known_functions: return self._print_Function(expr) PREC = precedence(expr) if expr.exp == -1: return '1.0/%s' % (self.parenthesize(expr.base, PREC)) elif expr.exp == 0.5: return '%ssqrt(%s)' % (self._ns, self._print(expr.base)) elif expr.exp == S.One/3 and self.standard != 'C89': return '%scbrt(%s)' % (self._ns, self._print(expr.base)) else: return '%spow(%s, %s)' % (self._ns, self._print(expr.base), self._print(expr.exp))
def _print_Add(self, expr): # purpose: print complex numbers nicely in Fortran. # collect the purely real and purely imaginary parts: pure_real = [] pure_imaginary = [] mixed = [] for arg in expr.args: if arg.is_real and arg.is_number: pure_real.append(arg) elif arg.is_imaginary and arg.is_number: pure_imaginary.append(arg) else: mixed.append(arg) if len(pure_imaginary) > 0: if len(mixed) > 0: PREC = precedence(expr) term = Add(*mixed) t = self._print(term) if t.startswith('-'): sign = "-" t = t[1:] else: sign = "+" if precedence(term) < PREC: t = "(%s)" % t return "cmplx(%s,%s) %s %s" % ( self._print(Add(*pure_real)), self._print(-I*Add(*pure_imaginary)), sign, t, ) else: return "cmplx(%s,%s)" % ( self._print(Add(*pure_real)), self._print(-I*Add(*pure_imaginary)), ) else: return StrPrinter._print_Add(self, expr)
def _print_Pow(self, expr): if "Pow" in self.known_functions: return self._print_Function(expr) PREC = precedence(expr) suffix = self._get_func_suffix(real) if expr.exp == -1: return '1.0%s/%s' % (suffix.upper(), self.parenthesize(expr.base, PREC)) elif expr.exp == 0.5: return '%ssqrt%s(%s)' % (self._ns, suffix, self._print(expr.base)) elif expr.exp == S.One/3 and self.standard != 'C89': return '%scbrt%s(%s)' % (self._ns, suffix, self._print(expr.base)) else: return '%spow%s(%s, %s)' % (self._ns, suffix, self._print(expr.base), self._print(expr.exp))
def _print_Add(self, expr, order=None): if self.order == "none": terms = list(expr.args) else: terms = self._as_ordered_terms(expr, order=order) PREC = precedence(expr) l = [] for term in terms: t = self._print(term) if t.startswith("-"): sign = "-" t = t[1:] else: sign = "+" if precedence(term) < PREC: l.extend([sign, "(%s)" % t]) else: l.extend([sign, t]) sign = l.pop(0) if sign == "+": sign = "" return sign + " ".join(l)
def _print_Mul(self, expr): "Copied from sympy StrPrinter and modified to remove division." prec = precedence(expr) c, e = expr.as_coeff_Mul() if c < 0: expr = _keep_coeff(-c, e) sign = "-" else: sign = "" a = [] # items in the numerator b = [] # items that are in the denominator (if any) if self.order not in ('old', 'none'): args = expr.as_ordered_factors() else: # use make_args in case expr was something like -x -> x args = Mul.make_args(expr) # Gather args for numerator/denominator 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 = a or [S.One] a_str = [self.parenthesize(x, prec) for x in a] b_str = [self.parenthesize(x, prec) for x in b] if len(b) == 0: return sign + '*'.join(a_str) elif len(b) == 1: # Thermo-Calc's parser can't handle division operators return sign + '*'.join(a_str) + "*%s" % self.parenthesize(b[0]**(-1), prec) else: # TODO: Make this Thermo-Calc compatible by removing division operation return sign + '*'.join(a_str) + "/(%s)" % '*'.join(b_str)
def _print_Mul(self, expr): # print complex numbers nicely in Octave if (expr.is_number and expr.is_imaginary and expr.as_coeff_Mul()[0].is_integer): return "%si" % self._print(-S.ImaginaryUnit*expr) # cribbed from str.py prec = precedence(expr) c, e = expr.as_coeff_Mul() if c < 0: expr = _keep_coeff(-c, e) sign = "-" else: sign = "" a = [] # items in the numerator b = [] # items that are in the denominator (if any) if self.order not in ('old', 'none'): args = expr.as_ordered_factors() else: # use make_args in case expr was something like -x -> x args = Mul.make_args(expr) # Gather args for numerator/denominator 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 = a or [S.One] a_str = list(map(lambda x: self.parenthesize(x, prec), a)) b_str = list(map(lambda x: self.parenthesize(x, prec), b)) # from here it differs from str.py to deal with "*" and ".*" def multjoin(a, a_str): # here we probably are assuming the constants will come first r = a_str[0] for i in range(1, len(a)): mulsym = '*' if a[i-1].is_number else '.*' r = r + mulsym + a_str[i] return r if len(b) == 0: return sign + multjoin(a, a_str) elif len(b) == 1: divsym = '/' if b[0].is_number else './' return sign + multjoin(a, a_str) + divsym + b_str[0] else: divsym = '/' if all([bi.is_number for bi in b]) else './' return (sign + multjoin(a, a_str) + divsym + "(%s)" % multjoin(b, b_str))
def _print_Not(self, expr): PREC = precedence(expr) return '!' + self.parenthesize(expr.args[0], PREC)
def _print_Mul(self, expr): prec = precedence(expr) c, e = expr.as_coeff_Mul() if c == 1.0: expr = e sign = "" elif e == 1.0: expr = c sign = "" elif c < 0: if c == -1.0: expr = e sign = "-" elif e == -1.0: expr = c sign = "-" else: expr = _keep_coeff(-c, e) sign = "-" else: sign = "" a = [] # items in the numerator b = [] # items that are in the denominator (if any) pow_paren = [ ] # Will collect all pow with more than one base element and exp = -1 if self.order not in ('old', 'none'): args = expr.as_ordered_factors() else: # use make_args in case expr was something like -x -> x args = Mul.make_args(expr) # Gather args for numerator/denominator 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: if len(item.args[0].args) != 1 and isinstance( item.base, Mul): # To avoid situations like #14160 pow_paren.append(item) b.append(Pow(item.base, -item.exp)) else: a.append(item) a = a or [S.One] a_str = [self.parenthesize(x, prec) for x in a] b_str = [self.parenthesize(x, prec) for x in b] # To parenthesize Pow with exp = -1 and having more than one Symbol for item in pow_paren: if item.base in b: b_str[b.index(item.base)] = "(%s)" % b_str[b.index(item.base)] if not b: return sign + '*'.join(a_str) elif len(b) == 1: return sign + '*'.join(a_str) + "/" + b_str[0] else: return sign + '*'.join(a_str) + "/(%s)" % '*'.join(b_str)
def test_Function(): assert precedence(sin(x)) == PRECEDENCE["Func"]
def test_Integral(): assert precedence(Integral(x, y)) == PRECEDENCE["Atom"]
def test_Order(): assert precedence(Order(x)) == PRECEDENCE["Atom"]
def _print_Or(self, expr): PREC = precedence(expr) return (" %s " % self._operators['or']).join( self.parenthesize(a, PREC) for a in sorted(expr.args, key=default_sort_key))
def _print_Equivalent(self, expr): if self._operators.get('equivalent') is None: return self._print_not_supported(expr) PREC = precedence(expr) return (" %s " % self._operators['equivalent']).join( self.parenthesize(a, PREC) for a in expr.args)
def _print_Pow(self, expr): PREC = precedence(expr) return '%s^%s' % (self.parenthesize( expr.base, PREC), self.parenthesize(expr.exp, PREC))
def _print_MatPow(self, expr): PREC = precedence(expr) return '%s**%s' % (self.parenthesize(expr.base, PREC, strict=False), self.parenthesize(expr.exp, PREC, strict=False))
def _print_MatAdd(self, expr): return ' + '.join([self.parenthesize(arg, precedence(expr)) for arg in expr.args])
def _print_HadamardProduct(self, expr): return '.*'.join([self.parenthesize(arg, precedence(expr)) for arg in expr.args])
def _print_Not(self, expr): PREC = precedence(expr) return self._operators['not'] + self.parenthesize(expr.args[0], PREC)
def _print_Mul(self, expr): # print complex numbers nicely in Octave if (expr.is_number and expr.is_imaginary and (S.ImaginaryUnit * expr).is_Integer): return "%si" % self._print(-S.ImaginaryUnit * expr) # cribbed from str.py prec = precedence(expr) c, e = expr.as_coeff_Mul() if c < 0: expr = _keep_coeff(-c, e) sign = "-" else: sign = "" a = [] # items in the numerator b = [] # items that are in the denominator (if any) pow_paren = [ ] # Will collect all pow with more than one base element and exp = -1 if self.order not in ('old', 'none'): args = expr.as_ordered_factors() else: # use make_args in case expr was something like -x -> x args = Mul.make_args(expr) # Gather args for numerator/denominator 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: if len(item.args[0].args) != 1 and isinstance( item.base, Mul): # To avoid situations like #14160 pow_paren.append(item) 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 = a or [S.One] a_str = [self.parenthesize(x, prec) for x in a] b_str = [self.parenthesize(x, prec) for x in b] # To parenthesize Pow with exp = -1 and having more than one Symbol for item in pow_paren: if item.base in b: b_str[b.index(item.base)] = "(%s)" % b_str[b.index(item.base)] # from here it differs from str.py to deal with "*" and ".*" def multjoin(a, a_str): # here we probably are assuming the constants will come first r = a_str[0] for i in range(1, len(a)): mulsym = '*' if a[i - 1].is_number else '.*' r = r + mulsym + a_str[i] return r if not b: return sign + multjoin(a, a_str) elif len(b) == 1: divsym = '/' if b[0].is_number else './' return sign + multjoin(a, a_str) + divsym + b_str[0] else: divsym = '/' if all([bi.is_number for bi in b]) else './' return (sign + multjoin(a, a_str) + divsym + "(%s)" % multjoin(b, b_str))
def _print_HadamardPower(self, expr): PREC = precedence(expr) return '.**'.join([ self.parenthesize(expr.base, PREC), self.parenthesize(expr.exp, PREC) ])
def _print_MatrixSolve(self, expr): PREC = precedence(expr) return "%s \\ %s" % (self.parenthesize(expr.matrix, PREC), self.parenthesize(expr.vector, PREC))
def test_Mul(): assert precedence(x * y) == PRECEDENCE["Mul"] assert precedence(-x * y) == PRECEDENCE["Add"]
def test_And_Or(): # precedence relations between logical operators, ... assert precedence(x & y) > precedence(x | y) assert precedence(~y) > precedence(x & y) # ... and with other operators (cfr. other programming languages) assert precedence(x + y) > precedence(x | y) assert precedence(x + y) > precedence(x & y) assert precedence(x * y) > precedence(x | y) assert precedence(x * y) > precedence(x & y) assert precedence(~y) > precedence(x * y) assert precedence(~y) > precedence(x - y) # double checks assert precedence(x & y) == PRECEDENCE["And"] assert precedence(x | y) == PRECEDENCE["Or"] assert precedence(~y) == PRECEDENCE["Not"]
def test_Derivative(): assert precedence(Derivative(x, y)) == PRECEDENCE["Atom"]
def test_Symbol(): assert precedence(x) == PRECEDENCE["Atom"]
def test_Add(): assert precedence(x + y) == PRECEDENCE["Add"] assert precedence(x * y + 1) == PRECEDENCE["Add"]
def test_Sum(): assert precedence(Sum(x, (x, y, y + 1))) == PRECEDENCE["Atom"]
def _print_Mul(self, expr): """ Handles multiplication & division, with n terms. Division is specified as a power: ``x / y --> x * y**-1``. Subtraction is specified as ``x - y --> x + (-1 * y)``. """ # This method is mostly copied from sympy.printing.Str # Check overall sign of multiplication sign = '' c, e = expr.as_coeff_Mul() if c < 0: expr = _keep_coeff(-c, e) sign = '-' # Collect all pows with more than one base element and exp = -1 pow_brackets = [] # Gather terms for numerator and denominator a, b = [], [] for item in Mul.make_args(expr): if item != 1.0: # In multiplications remove 1.0 * ... # Check if this is a negative power and it's not in a lookup table, so we can write it as a division if (item.is_commutative and item.is_Pow and item.exp.is_Rational and item.exp.is_negative and not self.lookup_table_function(item)): if item.exp != -1: # E.g. x * y**(-2 / 3) --> x / y**(2 / 3) # Add as power b.append(Pow(item.base, -item.exp, evaluate=False)) else: # Add without power b.append(Pow(item.base, -item.exp)) # Check if it's a negative power that needs brackets # Sympy issue #14160 if (len(item.args[0].args) != 1 and isinstance(item.base, Mul)): pow_brackets.append(item) # Split Rationals over a and b, ignoring any 1s elif item.is_Rational: if item.p != 1: a.append(Rational(item.p)) if item.q != 1: b.append(Rational(item.q)) else: a.append(item) # Replace empty numerator with one a = a or [S.One] # Convert terms to code my_prec = precedence(expr) a_str = [self._bracket(x, my_prec) for x in a] b_str = [self._bracket(x, my_prec) for x in b] # Fix brackets for Pow with exp -1 with more than one Symbol for item in pow_brackets: assert item.base in b, "item.base should be kept in b for powers" b_str[b.index(item.base)] = '(' + b_str[b.index(item.base)] + ')' # Combine numerator and denomenator and return a_str = sign + ' * '.join(a_str) if len(b) == 0: return a_str b_str = ' * '.join(b_str) return a_str + ' / ' + (b_str if len(b) == 1 else '(' + b_str + ')')
def test_Relational(): assert precedence(Rel(x + y, y, "<")) == PRECEDENCE["Relational"]
def _print_Or(self, expr): """ Handles logical Or. """ my_prec = precedence(expr) return ' || '.join( ['(' + self._bracket(x, my_prec) + ')' for x in expr.args])
def test_Product(): assert precedence(Product(x, (x, y, y + 1))) == PRECEDENCE["Atom"]
def _print_Or(self, expr): PREC = precedence(expr) return ' || '.join( self.parenthesize(a, PREC) for a in sorted(expr.args, key=default_sort_key))
def test_Pow(): assert precedence(x**y) == PRECEDENCE["Pow"] assert precedence(-x**y) == PRECEDENCE["Add"] assert precedence(x**-y) == PRECEDENCE["Pow"]
def parenthesize(self, item, level, strict=False): if (precedence(item) < level) or ((not strict) and precedence(item) <= level): return "(%s)" % self._print(item) else: return self._print(item)
def _print_TribonacciConstant(self, expr): expanded = expr.expand(func=True) PREC = precedence(expr) return self.parenthesize(expanded, PREC)