Skip to content

Commit

Permalink
Merge pull request #1269 from mathics/fix1260
Browse files Browse the repository at this point in the history
fix 1260
  • Loading branch information
mmatera authored Apr 12, 2021
2 parents eb71f33 + 106df9d commit c2afe31
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 8 deletions.
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ Enhancements
* ``ToString`` accepts an optional *form* parameter.
* ``ToExpression`` handles multi-line string input
* ``FileNames`` returns a sorted list (#1250).
* ``ReplaceRepeated`` and ``FixedPoint`` now supports the ``MaxIteration`` option (#1260).
* ``FixedPoint`` now supports the ``SameTest`` option.

Bug fixes
+++++++++
Expand Down
34 changes: 28 additions & 6 deletions mathics/builtin/control.py
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ class FixedPoint(Builtin):
<dt>'FixedPoint[$f$, $expr$]'
<dd>starting with $expr$, iteratively applies $f$ until the result no longer changes.
<dt>'FixedPoint[$f$, $expr$, $n$]'
<dd>performs at most $n$ iterations.
<dd>performs at most $n$ iterations. The same that using $MaxIterations->n$
</dl>
>> FixedPoint[Cos, 1.0]
Expand All @@ -524,24 +524,46 @@ class FixedPoint(Builtin):
= 0.739085
"""

def apply(self, f, expr, n, evaluation):
"FixedPoint[f_, expr_, n_:DirectedInfinity[1]]"
options = {
"MaxIterations": "Infinity",
"SameTest": "Automatic",
}

def apply(self, f, expr, n, evaluation, options):
"FixedPoint[f_, expr_, n_:DirectedInfinity[1], OptionsPattern[FixedPoint]]"
if n == Expression("DirectedInfinity", 1):
count = None
else:
count = n.get_int_value()
if count is None or count < 0:
evaluation.message("FixedPoint", "intnn")
return

if count is None:
count = self.get_option(options, "MaxIterations", evaluation)
if count.is_numeric():
count = count.get_int_value()
else:
count = None

result = expr
index = 0
sametest = self.get_option(options, "SameTest", evaluation)
if sametest == Symbol("Automatic"):
sametest = None

while count is None or index < count:
evaluation.check_stopped()
new_result = Expression(f, result).evaluate(evaluation)
if new_result == result:
result = new_result
break
if sametest:
same = Expression(sametest, result, new_result).evaluate(evaluation)
same = same.is_true()
if same:
break
else:
if new_result == result:
result = new_result
break
result = new_result
index += 1

Expand Down
26 changes: 24 additions & 2 deletions mathics/builtin/patterns.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,11 @@ class ReplaceRepeated(BinaryOperator):
>> a+b+c //. c->d
= a + b + d
>> f = ReplaceRepeated[c->d];
>> f[a+b+c]
= a + b + d
>> Clear[f];
Simplification of logarithms:
>> logrules = {Log[x_ * y_] :> Log[x] + Log[y], Log[x_ ^ y_] :> y * Log[x]};
>> Log[a * (b * c) ^ d ^ e * f] //. logrules
Expand All @@ -324,8 +329,16 @@ class ReplaceRepeated(BinaryOperator):
"rmix": "Elements of `1` are a mixture of lists and nonlists.",
}

def apply_list(self, expr, rules, evaluation):
"ReplaceRepeated[expr_, rules_]"
options = {
"MaxIterations": "65535",
}

rules = {
"ReplaceRepeated[rules_][expr_]": "ReplaceRepeated[expr, rules]",
}

def apply_list(self, expr, rules, evaluation, options):
"ReplaceRepeated[expr_, rules_, OptionsPattern[ReplaceRepeated]]"
try:
rules, ret = create_rules(rules, expr, "ReplaceRepeated", evaluation)
except PatternError:
Expand All @@ -335,8 +348,17 @@ def apply_list(self, expr, rules, evaluation):
if ret:
return rules

maxit = self.get_option(options, "MaxIterations", evaluation)
if maxit.is_numeric():
maxit = maxit.get_int_value()
else:
maxit = -1

while True:
evaluation.check_stopped()
if maxit == 0:
break
maxit -= 1
result, applied = expr.apply_rules(rules, evaluation)
if applied:
result = result.evaluate(evaluation)
Expand Down

0 comments on commit c2afe31

Please sign in to comment.