示例#1
0
文件: rules.py 项目: bzhan/holpy
    def eval(self, e):
        if isinstance(e, str):
            e = parser.parse_expr(e)

        if e.ty != expr.INTEGRAL:
            return e

        rec = Linearity().eval

        if e.body.is_plus():
            return rec(expr.Integral(e.var, e.lower, e.upper, e.body.args[0])) + \
                   rec(expr.Integral(e.var, e.lower, e.upper, e.body.args[1]))
        elif e.body.is_uminus():
            return -rec(expr.Integral(e.var, e.lower, e.upper, e.body.args[0]))
        elif e.body.is_minus():
            return rec(expr.Integral(e.var, e.lower, e.upper, e.body.args[0])) - \
                   rec(expr.Integral(e.var, e.lower, e.upper, e.body.args[1]))
        elif e.body.is_times():
            factors = decompose_expr_factor(e.body)
            if factors[0].is_constant():
                return factors[0] * rec(expr.Integral(e.var, e.lower, e.upper, 
                            functools.reduce(lambda x, y: x * y, factors[2:], factors[1])))
            else:
                return e
        elif e.body.is_constant() and e.body != Const(1):
            return e.body * expr.Integral(e.var, e.lower, e.upper, Const(1))
        else:
            return e
示例#2
0
文件: rules.py 项目: bzhan/holpy
    def eval(self, e):
        """Eliminate the lhs's integral in rhs by solving equation."""
        if isinstance(e, str):
            e = parser.parse_expr(e)
        norm_e = e.normalize()
        rhs_var = None
        def get_coeff(t):
            nonlocal rhs_var
            if t.ty == INTEGRAL:
                if t == self.lhs:
                    rhs_var = t.var
                    return 1
                else:
                    return 0
            elif t.is_plus():
                return get_coeff(t.args[0]) + get_coeff(t.args[1])
            elif t.is_minus():
                return get_coeff(t.args[0]) - get_coeff(t.args[1])
            elif t.is_uminus():
                return -get_coeff(t.args[0])
            elif t.is_times() and t.args[0].ty == CONST:
                return t.args[0].val * get_coeff(t.args[1])
            else:
                return 0

        coeff = get_coeff(norm_e)
        if coeff == 0:
            return e
        new_rhs = (norm_e + (Const(-coeff)*self.lhs.alpha_convert(rhs_var))).normalize()
        self.coeff = (-Const(coeff)).normalize()
        return (new_rhs/(Const(1-coeff))).normalize()
示例#3
0
    def testPriority(self):
        x = parse_expr("x")
        test_data = [
            (Const(1) + (x ^ Const(2)), "1 + x^2"),
        ]

        for s, s2 in test_data:
            self.assertEqual(s, parse_expr(s2))
示例#4
0
 def testParseTerm3(self):
     test_data = [
         ("$sin(x)^2$*sin(x)", Op("*", Op("^",Fun("sin",Var("x")),Const(2)), Fun("sin",Var("x")))),
         ("x + $x + y$", Op("+", Var("x"), Op("+", Var("x"), Var("y")))),
     ]
     
     for s, e in test_data:
         self.assertEqual(parse_expr(s), e)
         self.assertTrue(Op("^",Fun("sin",Var("x")),Const(2)) in trig_identity)
示例#5
0
    def testParseTerm2(self):
        test_data = [
            ("-x", -Var("x")),
            ("-2", Const(-2)),
            ("1/2", Const(Fraction(1) / 2)),
            ("-1/2", Const(Fraction(-1) / 2)),
            ("0.5", Const(Decimal("0.5"))),
            ("pi", Fun("pi")),
            ("-x^2", Op("-", Op("^", Var("x"), Const(2))))
        ]

        for s, e, in test_data:
            self.assertEqual(parse_expr(s), e)
示例#6
0
文件: rules.py 项目: bzhan/holpy
    def eval(self, e):
        if e.ty != LIMIT:
            return e

        bd = e.body
        subst_poly = bd.replace_trig(Var(e.var), e.lim).to_poly()
        if subst_poly.T != poly.UNKNOWN:
            return e
        inf_part, zero_part, const_part = [], [], []

        bd_poly = bd.to_poly()
        if len(bd_poly) != 1:
            raise NotImplementedError
        m = bd_poly[0]
        factors = m.factors
        for i, j in factors:
            mono = poly.Polynomial([poly.Monomial(1, ((i, j),))])
            norm_m = expr.from_poly(mono)
            subst_m = norm_m.replace_trig(Var(e.var), e.lim).to_poly()
            if subst_m.T == poly.ZERO:
                zero_part.append((Const(1) / norm_m).normalize())
            elif subst_m.T in (poly.POS_INF, poly.NEG_INF):
                inf_part.append(norm_m)
            elif subst_m.T == poly.NON_ZERO:
                const_part.append(norm_m)
            else:
                raise NotImplementedError(str(mono))

        assert inf_part and zero_part
        inf_expr = functools.reduce(operator.mul, inf_part[1:], inf_part[0])
        zero_expr = functools.reduce(operator.mul, zero_part[1:], zero_part[0])

        nm_trace = [inf_expr]
        denom_trace = [zero_expr]
        while True:
            nm, denom = nm_trace[-1], denom_trace[-1]
            nm_deriv, denom_deriv = expr.deriv(e.var, nm), expr.deriv(e.var, denom)
            nm_subst, denom_subst = nm_deriv.replace_trig(Var(e.var), e.lim), denom_deriv.replace_trig(Var(e.var), e.lim)
            nm_poly, denom_poly = nm_subst.to_poly(), denom_subst.to_poly()
            if nm_poly.T in (poly.POS_INF, poly.NEG_INF) and denom_poly.T in (poly.POS_INF, poly.NEG_INF):
                continue
            elif nm_poly.T in (poly.ZERO, poly.NON_ZERO) and denom_poly.T in (poly.POS_INF, poly.NEG_INF):
                return Const(0)
            elif nm_poly.T in (poly.POS_INF, poly.NEG_INF) and denom_poly.T in (poly.ZERO, poly.NON_ZERO):
                return expr.from_poly(nm_poly)
            elif nm_poly.T == poly.NON_ZERO and denom_poly.T == poly.NON_ZERO:
                return (nm_subst / denom_subst).normalize()
            else:
                raise NotImplementedError
示例#7
0
 def testSubstitution(self):
     e = parse_expr("INT x:[0,1]. (3 * x + 1) ^ (-2)")
     e = rules.Substitution1("u", parse_expr("3 * x + 1")).eval(e)
     e = rules.Linearity().eval(e)
     e = rules.OnSubterm(rules.CommonIntegral()).eval(e)
     e = rules.Simplify().eval(e)
     self.assertEqual(e, Const(Fraction("1/4")))
示例#8
0
文件: poly_test.py 项目: bzhan/holpy
    def testConstantMonomial(self):
        test_data = [
            (1, [], "1"),
            (1, [(2, "1/2")], "2^(1/2)"),
            (1, [(2, "3/2")], "2 * 2^(1/2)"),
            (1, [(2, "-1/2")], "1/2 * 2^(1/2)"),
            (1, [(6, "1/2")], "2^(1/2) * 3^(1/2)"),
            (1, [(pi, "1/2")], "pi^(1/2)"),
            (1, [(E, "1/2")], "e^(1/2)"),
            (1, [(9, "1/2")], "3"),
            (1, [(2, 2)], "4"),
            (1, [(8, "1/2"), (6, "1/2"), (9, "1/3")], "12 * 3^(1/6)"),
            (1, [(expr.sin(Const(1)), 2)], "sin(1)^2"),
            (1, [(expr.sin(Const(1)) + expr.sin(Const(2)), 2)],
             "(sin(1) + sin(2))^2"),
        ]

        for coeff, factors, res in test_data:
            factors = [(n, Fraction(e)) for n, e in factors]
            mono = ConstantMonomial(coeff, factors)
            self.assertEqual(str(mono), res)
示例#9
0
文件: rules.py 项目: bzhan/holpy
    def eval(self, e, a=Const(0)):
        if isinstance(e, str):
            e = parser.parse_expr(e)

        def gen_lim_expr(var, lim, lower, upper):
            return expr.Limit(new_var, lim, expr.Integral(e.var, lower, upper, e.body))
        
        if e.ty != expr.INTEGRAL:
            return e
        upper, lower = e.upper, e.lower
        if upper != expr.inf and lower != expr.neg_inf:
            return e
        
        new_var = "s" if e.var == "t" else "t"
        if upper == expr.inf and lower != expr.neg_inf:
            return gen_lim_expr(new_var, expr.inf, lower, Var(new_var))
        elif upper != expr.inf and lower == expr.neg_inf:
            return gen_lim_expr(new_var, expr.neg_inf, Var(new_var), upper)
        elif upper == expr.inf and lower == expr.neg_inf:
            assert a is not None, "No split point provided"
            return gen_lim_expr(new_var, expr.neg_inf, Var(new_var), a) + \
                gen_lim_expr(new_var, expr.inf, a, Var(new_var))
        else:
            raise NotImplementedError
示例#10
0
    def testCompareExpr(self):
        x, y, z = Var("x"), Var("y"), Var("z")
        test_data = [
            (x, y),
            (x, Const(3)),
            (Const(3), Const(4)),
            (Const(4), x * y),
            (x * y, x + y),
            (x * y, x * z),
            (x * y, z * y),
            (sin(x), x * y),
            (x * y, sin(sin(x))),
            (sin(x), Deriv("x", x)),
            (Deriv("x", x), Integral("x", Const(1), Const(2), x)),
        ]

        for s, t in test_data:
            self.assertTrue(s <= t)
            self.assertTrue(s < t)
            self.assertFalse(t <= s)
            self.assertFalse(t < s)
示例#11
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
示例#12
0
文件: rules.py 项目: bzhan/holpy
    def eval(self, e):
        if isinstance(e, str):
            e = parser.parse_expr(e)
        if e.ty != expr.INTEGRAL:
            return e

        if e.body.is_constant() and e.body != Const(1):
            return EvalAt(e.var, e.lower, e.upper, e.body * Var(e.var))

        x = Var(e.var)
        c = Symbol('c', [CONST])
        rules = [
            (Const(1), None, Var(e.var)),
            (c, None, c * Var(e.var)),
            (x, None, (x ^ 2) / 2),
            (x ^ c, lambda m: m[c].val != -1, lambda m: (x ^ Const(m[c].val + 1)) / (Const(m[c].val + 1))),
            (Const(1) / x ^ c, lambda m: m[c].val != 1, (-c) / (x ^ (c + 1))),
            (expr.sqrt(x), None, Fraction(2,3) * (x ^ Fraction(3,2))),
            (sin(x), None, -cos(x)),
            (cos(x), None, sin(x)),
            (expr.exp(x), None, expr.exp(x)),
            (Const(1) / x, None, expr.log(expr.Fun('abs', x))),
            (x ^ Const(-1), None, expr.log(expr.Fun('abs', x))),
            ((1 + (x ^ Const(2))) ^ Const(-1), None, expr.arctan(x)),
            (expr.sec(x) ^ Const(2), None, expr.tan(x)),
            (expr.csc(x) ^ Const(2), None, -expr.cot(x)),
        ]

        for pat, cond, pat_res in rules:
            mapping = expr.match(e.body, pat)
            if mapping is not None and (cond is None or cond(mapping)):
                if isinstance(pat_res, expr.Expr):
                    integral = pat_res.inst_pat(mapping)
                else:
                    integral = pat_res(mapping)
                return EvalAt(e.var, e.lower, e.upper, integral)

        return e
示例#13
0
    def testMatching(self):
        a = Symbol('a', [CONST])
        b = Symbol('b', [CONST])
        x = Symbol('x', [VAR])
        y = Symbol('y', [VAR, OP, FUN])

        test_data = [
            ('x - 1', x - a, {x: Var('x'), a: Const(1)}),
            ('x - 2', x - Const(2), {x: Var('x')}),
            ('x + 3', x - b, None),
            ('x', x + a, None),
            ('3*x', a * x, {a: Const(3), x: Var('x')}),
            ('3 * x + 5', a * x + b, {a: Const(3), x: Var('x'), b: Const(5)}),
            ('2 * x + 3', a * x + a, None),
            ('x ^ 2', x ^ Const(2), {x: Var('x')}),
            ('x ^ 3 - 2', x ^ Const(3), None),
            ('1 - x ^ 2', a - (x ^ Const(2)), {a: Const(1), x: Var('x')}),
            ('cos(x) ^ 2', cos(x) ^ Const(2), {x: Var('x')}),
            ('(1 - x ^ 2) ^ (1/2)', (Const(1) - (x ^ Const(2)))^(Const(Fraction(1/2))), {x: Var('x')}),
            ('(1 - x ^ 3) ^ (1/2)', (Const(1) - (x ^ Const(2)))^(Const(Fraction(1/2))), None),
            ('(1 - 2 * sin(x) ^ 2) ^ (1/2)', (b - a * (sin(x) ^ Const(2)))^Const(Fraction(1/2)), {b: Const(1), a: Const(2), x: Var('x')}),
            ('sin(x) ^ 2 + cos(y)^2', (sin(x)^Const(2))+(cos(x)^Const(2)), None),
            ('sin(2*x+1)^2 + cos(2*x+1) ^ 2', (sin(y)^Const(2))+(cos(y)^Const(2)), {y: Op("+",Op("*",Const(2),Var('x')),Const(1))}),
            ('2*pi', a * pi, {a: Const(2)}),
        ]

        for r1, r2, r3 in test_data:
            self.assertEqual(match(parse_expr(r1), r2), r3)
示例#14
0
    def testPrintExpr(self):
        x, y, z = Var("x"), Var("y"), Var("z")
        test_data = [
            (x, "x"),
            (Const(1), "1"),
            (Const(Decimal("1.1")), "11/10"),
            (Const((-1)), "-1"),
            (x + y, "x + y"),
            (x - y, "x - y"),
            (-x, "-x"),
            (x * y, "x * y"),
            (x / y, "x / y"),
            (x ^ y, "x ^ y"),
            ((x + y) * z, "(x + y) * z"),
            (x + (y * z), "x + y * z"),
            (x * y + z, "x * y + z"),
            (x * (y + z), "x * (y + z)"),
            (x + y + z, "x + y + z"),
            (x + (y + z), "x + (y + z)"),
            (x * (y ^ Const(2)), "x * y ^ 2"),
            ((x * y) ^ Const(2), "(x * y) ^ 2"),
            (-(x + y), "-(x + y)"),
            (x ^ Const(Fraction("1/2")), "x ^ (1/2)"),
            (-x + y, "-x + y"),
            (x - (x - y), "x - (x - y)"),
            (x - (x + y), "x - (x + y)"),
            (x / (x / y), "x / (x / y)"),
            (x / (x * y), "x / (x * y)"), 
            (sin(x), "sin(x)"),
            (cos(x), "cos(x)"),
            (log(x), "log(x)"),
            (exp(x), "exp(x)"),
            (-x * exp(x), "-x * exp(x)"),
            (-(x * exp(x)), "-(x * exp(x))"),
            (sin(x ^ Const(2)), "sin(x ^ 2)"),
            (sin(x) * cos(x), "sin(x) * cos(x)"),
            (Deriv("x", Const(3) * x), "D x. 3 * x"),
            (Integral("x", Const(1), Const(2), Const(3) * x), "INT x:[1,2]. 3 * x"),
            (Deriv("x", Const(3) * x) * x, "(D x. 3 * x) * x"),
            (Integral("x", Const(1), Const(2), Const(3) * x) * x, "(INT x:[1,2]. 3 * x) * x"),
            (EvalAt("x", Const(1), Const(2), Const(3) * x), "[3 * x]_x=1,2"),
            (EvalAt("x", Const(1), Const(2), Const(3) * x) * x, "([3 * x]_x=1,2) * x"),
        ]

        for e, s in test_data:
            self.assertEqual(str(e), s)
示例#15
0
 def testIntegral1(self):
     e = parse_expr("INT x:[2,3]. 2 * x + x ^ 2")
     e = rules.Linearity().eval(e)
     e = rules.OnSubterm(rules.CommonIntegral()).eval(e)
     e = rules.Simplify().eval(e)
     self.assertEqual(e, Const(Fraction(34, 3)))