Beispiel #1
0
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)
Beispiel #2
0
    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
Beispiel #3
0
    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
Beispiel #4
0
    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