示例#1
0
文件: inequality.py 项目: bzhan/holpy
 def cos(self):
     """Cos function of an interval."""
     if self.contained_in(Interval(expr.Const(0), expr.pi, False, False)):
         return Interval(
             expr.Fun('cos', self.end).normalize_constant(),
             expr.Fun('cos', self.start).normalize_constant(),
             self.right_open, self.left_open)
     elif self.contained_in(
             Interval(-(expr.pi / 2), expr.pi / 2, False, False)):
         return Interval(expr.Const(0), expr.Const(1), False, False)
     else:
         raise NotImplementedError
示例#2
0
文件: poly.py 项目: bzhan/holpy
 def zero_for(v):
     if isinstance(v, expr.Expr):
         return expr.Const(0)
     elif isinstance(v, ConstantPolynomial):
         return ConstantPolynomial(tuple())
     else:
         return 0
示例#3
0
文件: poly.py 项目: bzhan/holpy
 def __pow__(self, exp):
     # Assume the power is a fraction
     if isinstance(exp, (int, Fraction)) and int(exp) == exp:
         if self.coeff in (Decimal("inf"), Decimal("-inf")):
             return ConstantMonomial(1, [(expr.Const(self.coeff), exp)] + [(n, e * exp) for n, e in self.factors])
         else:
             return ConstantMonomial(Fraction(self.coeff) ** exp, [(n, e * exp) for n, e in self.factors])
     elif isinstance(exp, Fraction):
         coeff = Fraction(self.coeff)
         num, denom = coeff.numerator, coeff.denominator
         return ConstantMonomial(1, [(num, exp), (denom, -exp)] + [(n, e * exp) for n, e in self.factors])
     else:
         raise ValueError
示例#4
0
文件: poly.py 项目: bzhan/holpy
 def __truediv__(self, other):
     inv_factors = tuple((n, -e) for n, e in other.factors)
     if other.coeff in (Decimal("inf"), Decimal("-inf")):
         inv_factors = ((expr.Const(other.coeff), -1),) + inv_factors
         return ConstantMonomial(self.coeff, self.factors + inv_factors)
     elif self.coeff in (Decimal("inf"), Decimal("-inf")):
         if other.coeff < 0:
             return ConstantMonomial(-self.coeff, self.factors + inv_factors)
         elif other.coeff > 0:
             return ConstantMonomial(self.coeff, self.factors + inv_factors)
         else:
             raise NotImplementedError
     else:
         return ConstantMonomial(self.coeff * Fraction(1,other.coeff), self.factors + inv_factors)
示例#5
0
文件: latex.py 项目: bzhan/holpy
def convert_expr(e, mode="large"):
    if e.ty == expr.VAR:
        return e.name
    elif e.ty == expr.CONST:
        if isinstance(e.val, (int, Decimal)):
            if e.val == Decimal("inf"):
                return "\\infty"
            elif e.val == Decimal("-inf"):
                return "-\\infty"
            else:
                return str(e.val)
        elif isinstance(e.val, Fraction):
            if e.val.denominator == 1:
                return "%d" % e.val.numerator
            elif mode == 'large':
                if e.val.numerator > 0:
                    return "\\frac{%d}{%d}" % (e.val.numerator,
                                               e.val.denominator)
                elif e.val.numerator < 0:
                    return "-\\frac{%d}{%d}" % (-e.val.numerator,
                                                e.val.denominator)
            else:
                return "%d/%d" % (e.val.numerator, e.val.denominator)
        else:
            raise NotImplementedError
    elif e.ty == expr.INF:
        return "\\infty"
    elif e.ty == expr.OP:
        if len(e.args) == 1:
            a, = e.args
            sa = convert_expr(a, mode)
            if a.priority() < 70:
                sa = "(%s)" % sa
            return "%s%s" % (e.op, sa)
        elif len(e.args) == 2:
            x, y = e.args
            sx = convert_expr(x, mode)
            sy = convert_expr(y, mode)
            if e.op in ("+", "-", "^"):
                if e.op == "^":
                    # Still can improve
                    if y.ty == expr.CONST and isinstance(y.val, Fraction):
                        if y.val.numerator == 1:
                            if y.val.denominator == 2:
                                return "\\sqrt{%s}" % sx
                            else:
                                return "\\sqrt[%s]{%s}" % (y.val.denominator,
                                                           sx)
                        if x.ty == OP:
                            return "(%s) ^ {%s}" % (sx, sy)
                        return "%s ^ {%s}" % (sx, sy)
                    if y.ty == expr.CONST and y.val < 0:
                        if y.val != -1:
                            new_expr = expr.Op(
                                "/", expr.Const(1),
                                expr.Op("^", x, expr.Const(-y.val)))
                        else:
                            new_expr = expr.Op("/", expr.Const(1), x)
                        return convert_expr(new_expr)
                    elif isinstance(x, expr.Fun) and len(
                            x.args) > 0 and x.func_name != "abs":
                        return "\%s^{%s}(%s)" % (x.func_name, sy,
                                                 convert_expr(x.args[0]))
                if x.priority() < expr.op_priority[e.op]:
                    sx = "(%s)" % sx
                if y.priority() < expr.op_priority[e.op]:
                    sy = "{(%s)}" % sy
                if e.op == "^" and len(sy) > 1:
                    sy = "{%s}" % sy
                if y.ty == expr.OP and y.op == e.op and y.op in ("-", "/"):
                    sy = "{(%s)}" % sy
                return "%s %s %s" % (sx, e.op, sy)
            elif e.op == "*":
                if not x.is_constant() and not y.is_constant() and not (
                        y.ty == OP and y.op == "^" and y.args[1].ty == CONST
                        and y.args[1].val < 0) or x == expr.Fun(
                            "pi") or y == expr.Fun("pi"):
                    if x.ty == expr.OP and (x.op not in (
                            "^", "*")) and not len(x.args) == 1:
                        sx = "(" + sx + ")"
                    if y.ty == expr.OP and y.op != "^":
                        sy = "(" + sy + ")"
                    return "%s %s" % (sx, sy)
                elif x.is_constant() and y.is_constant(
                ) and y.ty != CONST and not (y.ty == OP and y.op in ("+", "-")
                                             or y.ty == CONST
                                             and isinstance(y.val, Fraction)):
                    if x == Const(-1):
                        return "-%s" % sy
                    if x.ty == expr.OP and x.op != "^" and len(x.args) != 1:
                        sx = "(" + sx + ")"
                    if y.ty == expr.OP and not (
                            len(y.args) == 2 and y.op == "^" or y.args[1].ty
                            == CONST and y.args[1].val == Fraction(1 / 2)):
                        sy = "(" + sy + ")"
                    if x.ty == expr.CONST and isinstance(
                            x.val, Fraction) and mode == "short":
                        sx = "(" + sx + ")"
                    return "%s %s" % (sx, sy)
                elif x.is_constant() and y.ty == CONST and isinstance(
                        y.val, Fraction
                ) and y.val.numerator == 1 and y.val.denominator != 1:
                    return "\\frac{%s}{%s}" % (
                        sx, convert_expr(expr.Const(y.val.denominator)))
                elif y.ty == OP and y.op == "^" and y.args[
                        1].ty == CONST and y.args[1].val < 0:
                    if y.args[1].val == -1:
                        return "\\frac{%s}{%s}" % (sx, convert_expr(y.args[0]))
                    else:
                        new_denom = Op("^", y.args[0], Const(-y.args[1].val))
                        return "\\frac{%s}{%s}" % (
                            sx, convert_expr(new_denom, mode))
                elif x.ty == expr.CONST:
                    if x.val == -1:
                        if y.ty == OP:
                            return "-(%s)" % sy
                        else:
                            return "-%s" % sy
                    elif x.val == 1 and not y.ty == OP:
                        if y.ty == OP:
                            return "(%s)" % sy
                        else:
                            return "%s" % sy
                    elif isinstance(
                            x.val, Fraction
                    ) and x.val.numerator == 1 and y.ty not in (expr.INTEGRAL,
                                                                expr.OP,
                                                                expr.EVAL_AT):
                        return "\\frac{%s}{%s}" % (
                            sy, convert_expr(expr.Const(x.val.denominator)))
                    elif y.ty in (expr.VAR, expr.FUN):
                        if isinstance(x.val, Fraction):
                            return "(%s) %s" % (sx, sy)
                        else:
                            return "%s %s" % (sx, sy)
                    elif not y.is_constant():
                        if y.ty == OP and y.op != '^':
                            return "%s (%s)" % (sx, sy)
                        elif y.ty == EVAL_AT:
                            return "%s \\times (%s)" % (sx, sy)
                        return "%s %s" % (sx, sy)
                    elif y.ty != CONST and y.is_constant() and not (
                            y.ty == OP and y.op in ('+', '-')):
                        return "%s %s" % (sx, sy)
                    elif y.ty == OP and y.op == "^" and not y.args[
                            0].is_constant():
                        return "%s %s" % (sx, sy)
                    else:
                        if x.priority() < expr.op_priority[e.op]:
                            sx = "(%s)" % sx
                        if y.priority() < expr.op_priority[e.op]:
                            sy = "(%s)" % sy
                        return "%s %s %s" % (sx, e.op, sy)
                else:
                    if x.priority() < expr.op_priority[e.op]:
                        sx = "(%s)" % sx
                    if y.priority() < expr.op_priority[e.op]:
                        sy = "(%s)" % sy
                    return "%s %s %s" % (sx, e.op, sy)
            elif e.op == "/":
                if mode == 'large':
                    if sy == "1":
                        return "%s" % sx
                    elif x.ty == expr.OP:
                        if x.op == "-" and len(x.args) == 1:
                            # (-x) / y => - (x/y)
                            sxx = convert_expr(x.args[0])
                            return "-\\frac{%s}{%s}" % (sxx, sy)
                        elif y.ty == expr.CONST:
                            return "\\frac{1}{%s} \\times %s" % (sy, sx)
                        else:
                            return "\\frac{%s}{%s}" % (sx, sy)
                    else:
                        return "\\frac{%s}{%s}" % (sx, sy)
                else:
                    return "%s/%s" % (sx, sy)
            else:
                raise NotImplementedError
        else:
            raise NotImplementedError
    elif e.ty == expr.FUN:
        if len(e.args) == 0:
            return "\\%s" % e.func_name
        elif len(e.args) == 1:
            x, = e.args
            sx = convert_expr(x, mode)
            if e.func_name == "exp":
                if e.args[0] == expr.Const(1):
                    return "e"
                else:
                    return "e^{%s}" % sx
            elif e.func_name == "sqrt":
                return "\\sqrt{%s}" % sx
            elif e.func_name == "abs":
                return "\\left| %s \\right|" % sx
            elif e.func_name == "atan":
                return "\\arctan{%s}" % sx
            elif e.func_name == "asin":
                return "\\arcsin{%s}" % sx
            elif e.func_name == "acos":
                return "\\arccos{%s}" % sx
            return "\\%s{(%s)}" % (e.func_name, sx)
        else:
            raise NotImplementedError
    elif e.ty == expr.INTEGRAL:
        lower = convert_expr(e.lower, mode='short')
        upper = convert_expr(e.upper, mode='short')
        body = convert_expr(e.body, mode)
        return "\\int_{%s}^{%s} %s \\,d%s" % (lower, upper, body, e.var)
    elif e.ty == expr.EVAL_AT:
        lower = convert_expr(e.lower, mode='short')
        upper = convert_expr(e.upper, mode='short')
        body = convert_expr(e.body, mode)
        return "\\left. %s \\right\\vert_{%s=%s}^{%s}" % (body, e.var, lower,
                                                          upper)
    elif e.ty == expr.LIMIT:
        lim = convert_expr(e.lim, mode="short")
        body = convert_expr(e.body, mode)
        if e.body.ty == expr.OP and len(e.body.args) > 1:
            return "\\lim\\limits_{%s\\to %s} (\,%s\,)" % (e.var, lim, body)
        else:
            return "\\lim\\limits_{%s\\to %s} %s" % (e.var, lim, body)
    else:
        raise NotImplementedError
示例#6
0
文件: parser.py 项目: bzhan/holpy
 def uminus_expr(self, a):
     if a.ty == expr.CONST:
         return expr.Const(-a.val)
     else:
         return expr.Op("-", a)
示例#7
0
文件: parser.py 项目: bzhan/holpy
 def divides_expr(self, a, b):
     if a.ty == expr.CONST and b.ty == expr.CONST:
         return expr.Const(Fraction(a.val) / Fraction(b.val))
     else:
         return expr.Op("/", a, b)
示例#8
0
文件: parser.py 项目: bzhan/holpy
 def decimal_expr(self, n):
     return expr.Const(Decimal(n))
示例#9
0
文件: parser.py 项目: bzhan/holpy
 def neg_zero_expr(self):
     return expr.Op("-", expr.Const(0))
示例#10
0
文件: parser.py 项目: bzhan/holpy
 def int_expr(self, n):
     return expr.Const(int(n))
示例#11
0
文件: poly.py 项目: bzhan/holpy
    def T(self):
        """Determine whether self is divergent, return +oo, -oo, const or unknown (0*oo)."""
        def pair_T(i, j):
            """Determine whether i ^ j is divergent."""
            if isinstance(i, (int, Fraction)) and j not in (Decimal("inf"), Decimal("-inf")):
                return NON_ZERO
            assert isinstance(i, expr.Expr), "%s %s %s" % (self, i, type(i))
            if isinstance(i, expr.Const) and i.val == Decimal("inf"):
                if isinstance(j, (int, Fraction)):
                    if j < 0:
                        return ZERO
                    elif j > 0:
                        return POS_INF
                    else:
                        raise NotImplementedError
                else:
                    raise NotImplementedError
            elif isinstance(i, expr.Const) and i.val == Decimal("-inf"):
                if isinstance(j, (int, Fraction)):
                    if j == -1:
                        return ZERO
                    elif j == 1:
                        return NEG_INF
                    else:
                        raise NotImplementedError
                else:
                    raise NotImplementedError
            elif i.ty == expr.FUN and i.func_name == "exp":
                if i.args[0].ty == expr.CONST:
                    i_value = Decimal(i.args[0].val).exp()
                    if j == Decimal("inf"):
                        if i_value >= 0:
                            return POS_INF
                        else:
                            return ZERO
                    elif j == Decimal("-inf"):
                        if i_value >= 0:
                            return ZERO
                        else:
                            return POS_INF
                    else:
                        return NON_ZERO
                else:
                    ap = i.args[0].to_poly()
                    if ap.T == POS_INF:
                        return POS_INF
                    elif ap.T == NEG_INF:
                        return ZERO
                    elif ap.T in (ZERO, NON_ZERO):
                        return NON_ZERO
                    else:
                        raise NotImplementedError
            elif i.ty == expr.FUN and i.func_name == "pi":
                if j == Decimal("inf"):
                    return POS_INF
                elif j == Decimal("-inf"):
                    return ZERO
                else:
                    return NON_ZERO
            elif i.ty == expr.OP and i.op == "/":
                a1, a2 = i.args[0].to_const_poly(), i.args[1].to_const_poly()
                assert a1.T in (POS_INF, NEG_INF) and a2.T in (POS_INF, NEG_INF) \
                    or a1.T == ZERO and a2.T == ZERO, str(i)
                return UNKNOWN
            else:
                return NON_ZERO

        Ts = [pair_T(i, j) for i, j in ((expr.Const(self.coeff), 1), ) + self.factors]
        return determine_div(Ts)