def real_root(arg, n=None): """Return the real nth-root of arg if possible. If n is omitted then all instances of (-n)**(1/odd) will be changed to -n**(1/odd); this will only create a real root of a principle root -- the presence of other factors may cause the result to not be real. Examples ======== >>> from sympy import root, real_root, Rational >>> from sympy.abc import x, n >>> real_root(-8, 3) -2 >>> root(-8, 3) 2*(-1)**(1/3) >>> real_root(_) -2 If one creates a non-principle root and applies real_root, the result will not be real (so use with caution): >>> root(-8, 3, 2) -2*(-1)**(2/3) >>> real_root(_) -2*(-1)**(2/3) See Also ======== sympy.polys.rootoftools.RootOf sympy.core.power.integer_nthroot root, sqrt """ if n is not None: try: n = as_int(n) arg = sympify(arg) if arg.is_positive or arg.is_negative: rv = root(arg, n) else: raise ValueError except ValueError: return root(arg, n)*C.Piecewise( (S.One, ~C.Equality(C.im(arg), 0)), (C.Pow(S.NegativeOne, S.One/n)**(2*C.floor(n/2)), C.And( C.Equality(n % 2, 1), arg < 0)), (S.One, True)) else: rv = sympify(arg) n1pow = Transform(lambda x: -(-x.base)**x.exp, lambda x: x.is_Pow and x.base.is_negative and x.exp.is_Rational and x.exp.p == 1 and x.exp.q % 2) return rv.xreplace(n1pow)
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: # use unicode corners horizontal_chr = xobj('-', 1) corner_chr = u'\u252c' func_height = pretty_func.height() first = True max_upper = 0 sign_height = 0 for lim in expr.limits: width = (func_height + 2) * 5 // 3 - 2 sign_lines = [] sign_lines.append(corner_chr + (horizontal_chr * width) + corner_chr) for i in range(func_height + 1): sign_lines.append(vertical_chr + (' ' * width) + vertical_chr) pretty_sign = stringPict('') pretty_sign = prettyForm(*pretty_sign.stack(*sign_lines)) pretty_upper = self._print(lim[2]) pretty_lower = self._print(C.Equality(lim[0], lim[1])) 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 = 0 pretty_func.baseline = max_upper + sign_height // 2 return pretty_func
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: # use unicode corners horizontal_chr = xobj('-', 1) corner_chr = u'\u252c' func_height = pretty_func.height() width = (func_height + 2) * 5 // 3 - 2 sign_lines = [] sign_lines.append(corner_chr + (horizontal_chr * width) + corner_chr) for i in range(func_height + 1): sign_lines.append(vertical_chr + (' ' * width) + vertical_chr) pretty_sign = stringPict('') pretty_sign = prettyForm(*pretty_sign.stack(*sign_lines)) pretty_upper = self._print(expr.upper) pretty_lower = self._print(C.Equality(expr.index, expr.lower)) pretty_sign = prettyForm(*pretty_sign.above(pretty_upper)) pretty_sign = prettyForm(*pretty_sign.below(pretty_lower)) height = pretty_sign.height() padding = stringPict('') padding = prettyForm(*padding.stack(*[' '] * (height - 1))) pretty_sign = prettyForm(*pretty_sign.right(padding)) pretty_func.baseline = 0 pretty_func = prettyForm(*pretty_sign.right(pretty_func)) return pretty_func
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 == '<^>' or how == "<" 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 wrequired = max(lower, upper) w = d + 1 more = hrequired % 2 lines = [] if use_ascii: lines.append("_" * (w) + ' ') lines.append("\%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, 0 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: # add parens prettyF = prettyForm(*prettyF.parens()) H = prettyF.height() + 2 # \sum \sum \sum ... first = True max_upper = 0 sign_height = 0 for lim in expr.limits: if len(lim) == 3: prettyUpper = self._print(lim[2]) prettyLower = self._print(C.Equality(lim[0], lim[1])) elif len(lim) == 2: prettyUpper = self._print("") prettyLower = self._print(C.Equality(lim[0], lim[1])) elif len(lim) == 1: prettyUpper = self._print("") prettyLower = self._print(lim[0]) max_upper = max(max_upper, prettyUpper.height()) # Create sum sign based on the height of the argument 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: # change F baseline so it centers on the sign prettyF.baseline -= d - (prettyF.height() // 2 - prettyF.baseline) - adjustment first = False # put padding to the right pad = stringPict('') pad = prettyForm(*pad.stack(*[' '] * h)) prettySign = prettyForm(*prettySign.right(pad)) # put the present prettyF to the right prettyF = prettyForm(*prettySign.right(prettyF)) prettyF.baseline = max_upper + sign_height // 2 return prettyF