Example #1
0
    def apply(self, f, x, x0, evaluation, options):
        "FindRoot[f_, {x_, x0_}, OptionsPattern[]]"
        # First, determine x0 and x
        x0 = apply_N(x0, evaluation)
        if not isinstance(x0, Number):
            evaluation.message("FindRoot", "snum", x0)
            return
        x_name = x.get_name()
        if not x_name:
            evaluation.message("FindRoot", "sym", x, 2)
            return

        # Now, get the explicit form of f, depending of x
        # keeping x without evaluation (Like inside a "Block[{x},f])
        f = dynamic_scoping(lambda ev: f.evaluate(ev), {x_name: None},
                            evaluation)
        # If after evaluation, we get an "Equal" expression,
        # convert it in a function by substracting both
        # members. Again, ensure the scope in the evaluation
        if f.get_head_name() == "System`Equal":
            f = Expression("Plus", f.leaves[0],
                           Expression("Times", Integer(-1), f.leaves[1]))
            f = dynamic_scoping(lambda ev: f.evaluate(ev), {x_name: None},
                                evaluation)

        # Determine the method
        method = options["System`Method"]
        if isinstance(method, Symbol):
            method = method.get_name().split("`")[-1]
        if method == "Automatic":
            method = "Newton"
        elif not isinstance(method, String):
            method = None
            evaluation.message("FindRoot", "bdmthd", method,
                               [String(m) for m in self.methods.keys()])
            return
        else:
            method = method.value

        # Determine the "jacobian"
        if method in ("Newton", ) and options["System`Jacobian"].sameQ(
                Symbol("Automatic")):

            def diff(evaluation):
                return Expression("D", f, x).evaluate(evaluation)

            d = dynamic_scoping(diff, {x_name: None}, evaluation)
            options["System`Jacobian"] = d

        method = self.methods.get(method, None)
        if method is None:
            evaluation.message("FindRoot", "bdmthd", method,
                               [String(m) for m in self.methods.keys()])
            return

        x0, success = method(f, x0, x, options, evaluation)
        if not success:
            return
        return Expression(SymbolList, Expression(SymbolRule, x, x0))
Example #2
0
    def apply_iter(self, expr, i, imin, imax, di, evaluation):
        '%(name)s[expr_, {i_Symbol, imin_, imax_, di_}]'

        index = imin.evaluate(evaluation).get_real_value()
        imax = imax.evaluate(evaluation).get_real_value()
        di = di.evaluate(evaluation).get_real_value()
        if index is None or imax is None or di is None:
            if self.throw_iterb:
                evaluation.message(self.get_name(), 'iterb')
            return
        result = []
        while index <= imax:
            evaluation.check_stopped()
            try:
                item = dynamic_scoping(expr.evaluate,
                                       {i.name: Number.from_mp(index)},
                                       evaluation)
                result.append(item)
            except ContinueInterrupt:
                if self.allow_loopcontrol:
                    pass
                else:
                    raise
            except BreakInterrupt:
                if self.allow_loopcontrol:
                    break
                else:
                    raise
            index = add(index, di)
        return self.get_result(result)
Example #3
0
 def apply_iter(self, expr, i, imin, imax, di, evaluation):
     '%(name)s[expr_, {i_Symbol, imin_, imax_, di_}]'
     
     index = imin.evaluate(evaluation).get_real_value()
     imax = imax.evaluate(evaluation).get_real_value()
     di = di.evaluate(evaluation).get_real_value()
     if index is None or imax is None or di is None:
         if self.throw_iterb:
             evaluation.message(self.get_name(), 'iterb')
         return
     result = []
     while index <= imax:
         evaluation.check_stopped()
         try:
             item = dynamic_scoping(expr.evaluate, {i.name: Number.from_mp(index)}, evaluation)
             result.append(item)
         except ContinueInterrupt:
             if self.allow_loopcontrol:
                 pass
             else:
                 raise
         except BreakInterrupt:
             if self.allow_loopcontrol:
                 break
             else:
                 raise
         index = add(index, di)
     return self.get_result(result)
Example #4
0
    def apply(self, f, x, x0, evaluation):
        "FindRoot[f_, {x_, x0_}]"

        x0 = Expression(SymbolN, x0).evaluate(evaluation)
        if not isinstance(x0, Number):
            evaluation.message("FindRoot", "snum", x0)
            return
        x_name = x.get_name()
        if not x_name:
            evaluation.message("FindRoot", "sym", x, 2)
            return
        count = 0

        def diff(evaluation):
            return Expression("D", f, x).evaluate(evaluation)

        d = dynamic_scoping(diff, {x_name: None}, evaluation)

        def sub(evaluation):
            d_value = d.evaluate(evaluation)
            if d_value == Integer(0):
                return None
            return Expression(
                "Times", f, Expression("Power", d_value, Integer(-1))
            ).evaluate(evaluation)

        while count < 100:
            minus = dynamic_scoping(sub, {x_name: x0}, evaluation)
            if minus is None:
                evaluation.message("FindRoot", "dsing", x, x0)
                return
            x1 = Expression(
                "Plus", x0, Expression("Times", Integer(-1), minus)
            ).evaluate(evaluation)
            if not isinstance(x1, Number):
                evaluation.message("FindRoot", "nnum", x, x0)
                return
            if x1 == x0:
                break
            x0 = Expression(SymbolN, x1).evaluate(
                evaluation
            )  # N required due to bug in sympy arithmetic
            count += 1
        else:
            evaluation.message("FindRoot", "maxiter")

        return Expression(SymbolList, Expression(SymbolRule, x, x0))
Example #5
0
 def eval_f(x_value, y_value):
     value = stored.get((x_value, y_value), False)
     if value == False:
         value = dynamic_scoping(f.evaluate, {x: Real(x_value), y: Real(y_value)}, evaluation)
         value = chop(value).get_real_value()
         value = float(value)
         stored[(x_value, y_value)] = value
     return value
Example #6
0
    def apply(self, f, x, x0, evaluation):
        'FindRoot[f_, {x_, x0_}]'

        x0 = Expression('N', x0).evaluate(evaluation)
        if not isinstance(x0, Number):
            evaluation.message('FindRoot', 'snum', x0)
            return
        x_name = x.get_name()
        if not x_name:
            evaluation.message('FindRoot', 'sym', x, 2)
            return
        count = 0

        def diff(evaluation):
            return Expression('D', f, x).evaluate(evaluation)

        d = dynamic_scoping(diff, {x_name: None}, evaluation)

        def sub(evaluation):
            d_value = d.evaluate(evaluation)
            if d_value == Integer(0):
                return None
            return Expression('Times', f,
                              Expression('Power', d_value,
                                         Integer(-1))).evaluate(evaluation)

        while count < 100:
            minus = dynamic_scoping(sub, {x_name: x0}, evaluation)
            if minus is None:
                evaluation.message('FindRoot', 'dsing', x, x0)
                return
            x1 = Expression('Plus', x0, Expression('Times', Integer(-1),
                                                   minus)).evaluate(evaluation)
            if not isinstance(x1, Number):
                evaluation.message('FindRoot', 'nnum', x, x0)
                return
            if x1 == x0:
                break
            x0 = Expression('N', x1).evaluate(
                evaluation)  # N required due to bug in sympy arithmetic
            count += 1
        else:
            evaluation.message('FindRoot', 'maxiter')

        return Expression('List', Expression('Rule', x, x0))
Example #7
0
    def apply(self, f, x, x0, evaluation):
        'FindRoot[f_, {x_, x0_}]'

        x0 = Expression('N', x0).evaluate(evaluation)
        if not isinstance(x0, Number):
            evaluation.message('FindRoot', 'snum', x0)
            return
        x_name = x.get_name()
        if not x_name:
            evaluation.message('FindRoot', 'sym', x, 2)
            return
        count = 0

        def diff(evaluation):
            return Expression('D', f, x).evaluate(evaluation)

        d = dynamic_scoping(diff, {x_name: None}, evaluation)

        def sub(evaluation):
            d_value = d.evaluate(evaluation)
            if d_value == Integer(0):
                return None
            return Expression('Times', f, Expression(
                'Power', d_value, Integer(-1))).evaluate(evaluation)

        while count < 100:
            minus = dynamic_scoping(sub, {x_name: x0}, evaluation)
            if minus is None:
                evaluation.message('FindRoot', 'dsing', x, x0)
                return
            x1 = Expression('Plus', x0, Expression(
                'Times', Integer(-1), minus)).evaluate(evaluation)
            if not isinstance(x1, Number):
                evaluation.message('FindRoot', 'nnum', x, x0)
                return
            if x1 == x0:
                break
            x0 = Expression('N', x1).evaluate(
                evaluation)       # N required due to bug in sympy arithmetic
            count += 1
        else:
            evaluation.message('FindRoot', 'maxiter')

        return Expression('List', Expression('Rule', x, x0))
Example #8
0
 def eval_f(x_value, y_value):
     value = stored.get((x_value, y_value), False)
     if value == False:
         value = dynamic_scoping(f.evaluate, {
             x: Real(x_value),
             y: Real(y_value)
         }, evaluation)
         value = chop(value).get_real_value()
         value = float(value)
         stored[(x_value, y_value)] = value
     return value
Example #9
0
    def apply(self, f, x, x0, evaluation):
        "FindRoot[f_, {x_, x0_}]"

        x0 = Expression("N", x0).evaluate(evaluation)
        if not isinstance(x0, Number):
            evaluation.message("FindRoot", "snum", x0)
            return
        x_name = x.get_name()
        if not x_name:
            evaluation.message("FindRoot", "sym", x, 2)
            return
        count = 0

        def diff(evaluation):
            return Expression("D", f, x).evaluate(evaluation)

        d = dynamic_scoping(diff, {x_name: None}, evaluation)

        def sub(evaluation):
            d_value = d.evaluate(evaluation)
            if d_value == Integer(0):
                return None
            return Expression("Times", f, Expression("Power", d_value, Integer(-1))).evaluate(evaluation)

        while count < 100:
            minus = dynamic_scoping(sub, {x_name: x0}, evaluation)
            if minus is None:
                evaluation.message("FindRoot", "dsing", x_name, x0)
                return
            x1 = Expression("Plus", x0, Expression("Times", Integer(-1), minus)).evaluate(evaluation)
            if not isinstance(x1, Number):
                evaluation.message("FindRoot", "nnum", x_name, x0)
                return
            if x1 == x0:
                break
            x0 = Expression("N", x1).evaluate(evaluation)  # N required due to bug in sympy arithmetic
            count += 1
        else:
            evaluation.message("FindRoot", "maxiter")

        return Expression("List", Expression("Rule", x, x0))
Example #10
0
 def apply_assuming(self, assumptions, expr, evaluation):
     "Assuming[assumptions_, expr_]"
     assumptions = assumptions.evaluate(evaluation)
     if assumptions.is_true():
         cond = []
     elif assumptions.is_symbol() or not assumptions.has_form("List", None):
         cond = [assumptions]
     else:
         cond = assumptions._leaves
     cond = tuple(cond) + get_assumptions_list(evaluation)
     list_cond = Expression("List", *cond)
     # TODO: reduce the list of predicates
     return dynamic_scoping(lambda ev: expr.evaluate(ev),
                            {"System`$Assumptions": list_cond}, evaluation)
Example #11
0
    def apply_iter(self, expr, i, imin, imax, di, evaluation):
        '%(name)s[expr_, {i_Symbol, imin_, imax_, di_}]'

        if isinstance(self, SympyFunction) and di.get_int_value() == 1:
            whole_expr = Expression(self.get_name(), expr,
                                    Expression('List', i, imin, imax))
            sympy_expr = whole_expr.to_sympy()

            # apply Together to produce results similar to Mathematica
            result = sympy.together(sympy_expr)
            result = from_sympy(result)
            result = cancel(result)

            if not result.same(whole_expr):
                return result

        index = imin.evaluate(evaluation)
        imax = imax.evaluate(evaluation)
        di = di.evaluate(evaluation)

        result = []
        while True:
            cont = Expression('LessEqual', index, imax).evaluate(evaluation)
            if cont == Symbol('False'):
                break
            if cont != Symbol('True'):
                if self.throw_iterb:
                    evaluation.message(self.get_name(), 'iterb')
                return

            evaluation.check_stopped()
            try:
                item = dynamic_scoping(expr.evaluate, {i.name: index},
                                       evaluation)
                result.append(item)
            except ContinueInterrupt:
                if self.allow_loopcontrol:
                    pass
                else:
                    raise
            except BreakInterrupt:
                if self.allow_loopcontrol:
                    break
                else:
                    raise
            index = Expression('Plus', index, di).evaluate(evaluation)
        return self.get_result(result)
Example #12
0
def quiet_evaluate(expr, vars, evaluation, expect_list=False):
    """ Evaluates expr with given dynamic scoping values
    without producing arithmetic error messages. """
    expr = Expression('N', expr)
    quiet_expr = Expression('Quiet', expr, Expression(
        'List', Expression('MessageName', Symbol('Power'), String('infy'))))
    value = dynamic_scoping(quiet_expr.evaluate, vars, evaluation)
    if expect_list:
        if value.has_form('List', None):
            value = [chop(item).get_real_value() for item in value.leaves]
            if any(item is None for item in value):
                return None
            return value
        else:
            return None
    else:
        return chop(value).get_real_value()
Example #13
0
    def apply_iter(self, expr, i, imin, imax, di, evaluation):
        '%(name)s[expr_, {i_Symbol, imin_, imax_, di_}]'

        if di.get_int_value() == 1 and isinstance(self, SympyFunction):
            whole_expr = Expression(self.get_name(), expr,
                                    Expression('List', i, imin, imax))
            sympy_expr = whole_expr.to_sympy()

            # apply Together to produce results similar to Mathematica
            result = sympy.together(sympy_expr)
            result = from_sympy(result)
            result = cancel(result)

            if not result.same(whole_expr):
                return result

        index = imin.evaluate(evaluation).get_real_value()
        imax = imax.evaluate(evaluation).get_real_value()
        di = di.evaluate(evaluation).get_real_value()

        if index is None or imax is None or di is None:
            if self.throw_iterb:
                evaluation.message(self.get_name(), 'iterb')
            return

        result = []
        while index <= imax:
            evaluation.check_stopped()
            try:
                item = dynamic_scoping(expr.evaluate,
                                       {i.name: Number.from_mp(index)},
                                       evaluation)
                result.append(item)
            except ContinueInterrupt:
                if self.allow_loopcontrol:
                    pass
                else:
                    raise
            except BreakInterrupt:
                if self.allow_loopcontrol:
                    break
                else:
                    raise
            index = index + di
        return self.get_result(result)
Example #14
0
    def apply_iter(self, expr, i, imin, imax, di, evaluation):
        '%(name)s[expr_, {i_Symbol, imin_, imax_, di_}]'
        
        if isinstance(self, SympyFunction) and di.get_int_value() == 1:
            whole_expr = Expression(self.get_name(), expr, Expression('List', i, imin, imax))
            sympy_expr = whole_expr.to_sympy()
            
            # apply Together to produce results similar to Mathematica
            result = sympy.together(sympy_expr)
            result = from_sympy(result)
            result = cancel(result)
            
            if not result.same(whole_expr):
                return result
        
        index = imin.evaluate(evaluation)
        imax = imax.evaluate(evaluation)
        di = di.evaluate(evaluation)

        result = []
        while True:
            cont = Expression('LessEqual', index, imax).evaluate(evaluation)
            if cont == Symbol('False'):
                break
            if cont != Symbol('True'):
                if self.throw_iterb:
                    evaluation.message(self.get_name(), 'iterb')
                return

            evaluation.check_stopped()
            try:
                item = dynamic_scoping(expr.evaluate, {i.name: index}, evaluation)
                result.append(item)
            except ContinueInterrupt:
                if self.allow_loopcontrol:
                    pass
                else:
                    raise
            except BreakInterrupt:
                if self.allow_loopcontrol:
                    break
                else:
                    raise
            index = Expression('Plus', index, di).evaluate(evaluation)
        return self.get_result(result)
Example #15
0
 def apply_iter(self, expr, i, imin, imax, di, evaluation):
     '%(name)s[expr_, {i_Symbol, imin_, imax_, di_}]'
     
     if di.get_int_value() == 1 and isinstance(self, SageFunction):
         whole_expr = Expression(self.get_name(), expr, Expression('List', i, imin, imax))
         sympy_expr = whole_expr.to_sympy()
         
         # apply Together to produce results similar to Mathematica
         result = sympy.together(sympy_expr)
         result = from_sympy(result)
         result = cancel(result)
         
         if not result.same(whole_expr):
             return result
     
     index = imin.evaluate(evaluation).get_real_value()
     imax = imax.evaluate(evaluation).get_real_value()
     di = di.evaluate(evaluation).get_real_value()
     
     if index is None or imax is None or di is None:
         if self.throw_iterb:
             evaluation.message(self.get_name(), 'iterb')
         return
     
     result = []
     while index <= imax:
         evaluation.check_stopped()
         try:
             item = dynamic_scoping(expr.evaluate, {i.name: Number.from_mp(index)}, evaluation)
             result.append(item)
         except ContinueInterrupt:
             if self.allow_loopcontrol:
                 pass
             else:
                 raise
         except BreakInterrupt:
             if self.allow_loopcontrol:
                 break
             else:
                 raise
         index = add(index, di)
     return self.get_result(result)
Example #16
0
 def apply_list(self, expr, i, items, evaluation):
     '%(name)s[expr_, {i_Symbol, {items___}}]'
     
     items = items.evaluate(evaluation).get_sequence()
     result = []
     for item in items:
         evaluation.check_stopped()
         try:
             item = dynamic_scoping(expr.evaluate, {i.name: item}, evaluation)
             result.append(item)
         except ContinueInterrupt:
             if self.allow_loopcontrol:
                 pass
             else:
                 raise
         except BreakInterrupt:
             if self.allow_loopcontrol:
                 break
             else:
                 raise
     return self.get_result(result)
Example #17
0
def find_root_newton(f, x0, x, opts, evaluation) -> (Number, bool):
    df = opts["System`Jacobian"]
    maxit = opts["System`MaxIterations"]
    x_name = x.get_name()
    if maxit.sameQ(Symbol("Automatic")):
        maxit = 100
    else:
        maxit = maxit.evaluate(evaluation).get_int_value()

    def sub(evaluation):
        d_value = df.evaluate(evaluation)
        if d_value == Integer(0):
            return None
        return Expression(
            "Times", f, Expression("Power", d_value, Integer(-1))
        ).evaluate(evaluation)

    count = 0
    while count < maxit:
        minus = dynamic_scoping(sub, {x_name: x0}, evaluation)
        if minus is None:
            evaluation.message("FindRoot", "dsing", x, x0)
            return x0, False
        x1 = Expression("Plus", x0, Expression("Times", Integer(-1), minus)).evaluate(
            evaluation
        )
        if not isinstance(x1, Number):
            evaluation.message("FindRoot", "nnum", x, x0)
            return x0, False
        # TODO: use Precision goal...
        if x1 == x0:
            break
        x0 = Expression(SymbolN, x1).evaluate(
            evaluation
        )  # N required due to bug in sympy arithmetic
        count += 1
    else:
        evaluation.message("FindRoot", "maxiter")
    return x0, True
Example #18
0
    def apply_list(self, expr, i, items, evaluation):
        '%(name)s[expr_, {i_Symbol, {items___}}]'

        items = items.evaluate(evaluation).get_sequence()
        result = []
        for item in items:
            evaluation.check_stopped()
            try:
                item = dynamic_scoping(expr.evaluate, {i.name: item},
                                       evaluation)
                result.append(item)
            except ContinueInterrupt:
                if self.allow_loopcontrol:
                    pass
                else:
                    raise
            except BreakInterrupt:
                if self.allow_loopcontrol:
                    break
                else:
                    raise
        return self.get_result(result)
Example #19
0
 def eval_f(f, x_value):
     value = dynamic_scoping(f.evaluate, {x: x_value}, evaluation)
     value = chop(value).get_real_value()
     return value
Example #20
0
def find_root_secant(f, x0, x, opts, evaluation) -> (Number, bool):
    region = opts.get("$$Region", None)
    if not type(region) is list:
        if x0.is_zero:
            region = (Real(-1), Real(1))
        else:
            xmax = 2 * x0.to_python()
            xmin = -2 * x0.to_python()
            if xmin > xmax:
                region = (Real(xmax), Real(xmin))
            else:
                region = (Real(xmin), Real(xmax))

    maxit = opts["System`MaxIterations"]
    x_name = x.get_name()
    if maxit.sameQ(Symbol("Automatic")):
        maxit = 100
    else:
        maxit = maxit.evaluate(evaluation).get_int_value()

    x0 = from_python(region[0])
    x1 = from_python(region[1])
    f0 = dynamic_scoping(lambda ev: f.evaluate(evaluation), {x_name: x0},
                         evaluation)
    f1 = dynamic_scoping(lambda ev: f.evaluate(evaluation), {x_name: x1},
                         evaluation)
    if not isinstance(f0, Number):
        return x0, False
    if not isinstance(f1, Number):
        return x0, False
    f0 = f0.to_python(n_evaluation=True)
    f1 = f1.to_python(n_evaluation=True)
    count = 0
    while count < maxit:
        if f0 == f1:
            x1 = Expression(
                "Plus",
                x0,
                Expression(
                    "Times",
                    Real(0.75),
                    Expression("Plus", x1, Expression("Times", Integer(-1),
                                                      x0)),
                ),
            )
            x1 = x1.evaluate(evaluation)
            f1 = dynamic_scoping(lambda ev: f.evaluate(evaluation),
                                 {x_name: x1}, evaluation)
            if not isinstance(f1, Number):
                return x0, False
            f1 = f1.to_python(n_evaluation=True)
            continue

        inv_deltaf = from_python(1.0 / (f1 - f0))
        num = Expression(
            "Plus",
            Expression("Times", x0, f1),
            Expression("Times", x1, f0, Integer(-1)),
        )
        x2 = Expression("Times", num, inv_deltaf)
        x2 = x2.evaluate(evaluation)
        f2 = dynamic_scoping(lambda ev: f.evaluate(evaluation), {x_name: x2},
                             evaluation)
        if not isinstance(f2, Number):
            return x0, False
        f2 = f2.to_python(n_evaluation=True)
        f1, f0 = f2, f1
        x1, x0 = x2, x1
        if x1 == x0 or abs(f2) == 0:
            break
        count = count + 1
    else:
        evaluation.message("FindRoot", "maxiter")
        return x0, False
    return x0, True
Example #21
0
 def eval_f(f, x_value):
     value = dynamic_scoping(f.evaluate, {x: x_value}, evaluation)
     value = chop(value).get_real_value()
     return value