Ejemplo n.º 1
0
Archivo: rules.py Proyecto: 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
Ejemplo n.º 2
0
Archivo: rules.py Proyecto: bzhan/holpy
    def eval(self, e):
        """
        Parameters:
        e: Expr, the integral on which to perform substitution.

        Returns:
        The new integral e', and stores in self.f the parameter used to
        specify the substitution.

        """
        if isinstance(e, str):
            e = parser.parse_expr(e)


        var_name = parser.parse_expr(self.var_name)
        var_subst = self.var_subst
        dfx = expr.deriv(e.var, var_subst)
        body = holpy_style(sympy_style(e.body/dfx))
        body_subst = body.replace_trig(var_subst, var_name)
        if body_subst == body:
            body_subst = body.replace_trig(var_subst, var_name)
        lower = var_subst.subst(e.var, e.lower).normalize()
        upper = var_subst.subst(e.var, e.upper).normalize()
        if parser.parse_expr(e.var) not in body_subst.findVar():
            # Substitution is able to clear all x in original integrand
            # print('Substitution: case 1')
            self.f = body_subst
            if sympy_style(lower) <= sympy_style(upper):
                return Integral(self.var_name, lower, upper, body_subst).normalize()
            else:
                return Integral(self.var_name, upper, lower, Op("-", body_subst)).normalize()
        else:
            # Substitution is unable to clear x, need to solve for x
            # print('Substitution: case 2')
            gu = solvers.solve(expr.sympy_style(var_subst - var_name), expr.sympy_style(e.var))
            if gu == []:  # sympy can't solve the equation
                return e
            gu = gu[-1] if isinstance(gu, list) else gu
            gu = expr.holpy_style(gu)
            c = e.body.replace_trig(parser.parse_expr(e.var), gu)
            new_problem_body = (e.body.replace_trig(parser.parse_expr(e.var), gu)*expr.deriv(str(var_name), gu))
            lower = holpy_style(sympy_style(var_subst).subs(sympy_style(e.var), sympy_style(e.lower)))
            upper = holpy_style(sympy_style(var_subst).subs(sympy_style(e.var), sympy_style(e.upper)))
            self.f = new_problem_body
            if sympy_style(lower) < sympy_style(upper):
                return Integral(self.var_name, lower, upper, new_problem_body).normalize()
            else:
                return Integral(self.var_name, upper, lower, Op("-", new_problem_body)).normalize()
Ejemplo n.º 3
0
Archivo: rules.py Proyecto: bzhan/holpy
    def eval(self, e):
        if isinstance(e, str):
            e = parser.parse_expr(e)

        if e.ty != expr.INTEGRAL:
            return e
        e.body = e.body.normalize()
        du = expr.deriv(e.var, self.u)
        dv = expr.deriv(e.var, self.v)
        udv = (self.u * dv).normalize()
        if udv == e.body:
            return expr.EvalAt(e.var, e.lower, e.upper, (self.u * self.v).normalize()) - \
                   expr.Integral(e.var, e.lower, e.upper, (self.v * du).normalize())
        else:
            print("%s != %s" % (str(udv), str(e.body)))
            raise NotImplementedError("%s != %s" % (str(udv), str(e.body)))
Ejemplo n.º 4
0
Archivo: rules.py Proyecto: bzhan/holpy
    def eval(self, e):
        if isinstance(e, str):
            e = parser.parse_expr(e)

        if e.ty == expr.DERIV:
            return expr.deriv(e.var, e.body)
        else:
            return e
Ejemplo n.º 5
0
Archivo: rules.py Proyecto: bzhan/holpy
    def eval(self, e):
        if isinstance(e, str):
            e = parser.parse_expr(e)

        subst_deriv = expr.deriv(self.var_name, self.var_subst) #dx = d(x(u)) = x'(u) *du
        new_e_body = e.body.replace_trig(expr.holpy_style(str(e.var)), self.var_subst) #replace all x with x(u)
        new_e_body = expr.Op("*", new_e_body, subst_deriv) # g(x) = g(x(u)) * x'(u)
        lower = solvers.solve(expr.sympy_style(self.var_subst - e.lower))[0]
        upper = solvers.solve(expr.sympy_style(self.var_subst - e.upper))[0]
        return expr.Integral(self.var_name, expr.holpy_style(lower), expr.holpy_style(upper), new_e_body)
Ejemplo n.º 6
0
    def testDeriv(self):
        test_data = [
            ("1", "0"),
            ("x", "1"),
            ("2 * x", "2"),
            ("x ^ 2", "2 * x"),
            ("x * y", "y"),
            ("1 / x", "-1 / x ^ 2"),
            ("3 * x + 1", "3"),
            ("x + pi / 3", "1"),
            ("2 * x + pi / 3", "2"),
            ("sin(x)", "cos(x)"),
            ("sin(x^2)", "2 * x * cos(x ^ 2)"),
            ("cos(x)", "-sin(x)"),
            ("log(x)", "x ^ -1"),
            ("x * log(x)", "1 + log(x)"),
            ("exp(x)", "exp(x)"),
            ("exp(x^2)", "2 * x * exp(x ^ 2)"),
        ]

        for s, s2 in test_data:
            s = parse_expr(s)
            self.assertEqual(str(expr.deriv("x", s)), s2)