Skip to content

Commit 6f7f836

Browse files
authored
Merge pull request #1000 from weakit/minmax
Symbolic comparisions.
2 parents 9bc2c8f + 3479ad6 commit 6f7f836

File tree

2 files changed

+41
-32
lines changed

2 files changed

+41
-32
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,5 @@ mathics/web/media/pdf/
5353
mathics/web/media/doc/classes.pdf
5454
mathics/web/media/doc/classes.png
5555
tmp
56+
57+
.idea/

mathics/builtin/comparison.py

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22
# -*- coding: utf-8 -*-
33

44

5-
import sympy
65
import itertools
76

8-
from mathics.builtin.base import Builtin, BinaryOperator, Test, SympyFunction
9-
from mathics.core.expression import (Expression, Number, Integer, Rational,
10-
Real, Symbol, String)
11-
from mathics.core.numbers import get_type, dps
7+
import sympy
8+
9+
from mathics.builtin.base import BinaryOperator, Builtin, SympyFunction
10+
from mathics.core.expression import (Complex, Expression, Integer, Number,
11+
Real, String, Symbol)
12+
from mathics.core.numbers import dps
1213

1314

1415
class SameQ(BinaryOperator):
@@ -88,6 +89,7 @@ class TrueQ(Builtin):
8889
'TrueQ[expr_]': 'If[expr, True, False, False]',
8990
}
9091

92+
9193
class BooleanQ(Builtin):
9294
"""
9395
<dl>
@@ -313,36 +315,37 @@ def apply(self, items, evaluation):
313315

314316

315317
def do_cmp(x1, x2):
316-
inf1 = inf2 = real1 = real2 = None
317-
if isinstance(x1, (Real, Integer, Rational)):
318-
real1 = x1.to_sympy()
319-
if isinstance(x2, (Real, Integer, Rational)):
320-
real2 = x2.to_sympy()
321-
if x1.has_form('DirectedInfinity', 1):
322-
inf1 = x1.leaves[0].get_int_value()
323-
if x2.has_form('DirectedInfinity', 1):
324-
inf2 = x2.leaves[0].get_int_value()
325-
326-
if real1 is not None and real2 is not None:
318+
319+
# don't attempt to compare complex numbers
320+
for x in (x1, x2):
321+
# TODO: Send message General::nord
322+
if isinstance(x, Complex) or (
323+
x.has_form("DirectedInfinity", 1) and isinstance(x.leaves[0], Complex)
324+
):
325+
return None
326+
327+
s1 = x1.to_sympy()
328+
s2 = x2.to_sympy()
329+
330+
# use internal comparisons only for Reals
331+
# and use sympy for everything else
332+
if s1.is_Float and s2.is_Float:
327333
if x1 == x2:
328334
return 0
329-
elif x1 < x2:
335+
if x1 < x2:
330336
return -1
331-
else:
332-
return 1
333-
elif inf1 is not None and inf2 is not None:
334-
if inf1 == inf2:
337+
return 1
338+
339+
# we don't want to compare anything that
340+
# cannot be represented as a numeric value
341+
if s1.is_number and s2.is_number:
342+
if s1 == s2:
335343
return 0
336-
elif inf1 < inf2:
344+
if s1 < s2:
337345
return -1
338-
else:
339-
return 1
340-
elif inf1 is not None and real2 is not None:
341-
return inf1
342-
elif real1 is not None and inf2 is not None:
343-
return -inf2
344-
else:
345-
return None
346+
return 1
347+
348+
return None
346349

347350

348351
class SympyComparison(SympyFunction):
@@ -732,9 +735,11 @@ class Max(_MinMax):
732735
<dd>returns the expression with the greatest value among the $e_i$.
733736
</dl>
734737
735-
Maximum of a series of numbers:
738+
Maximum of a series of values:
736739
>> Max[4, -8, 1]
737740
= 4
741+
>> Max[E - Pi, Pi, E + Pi, 2 E]
742+
= E + Pi
738743
739744
'Max' flattens lists in its arguments:
740745
>> Max[{1,2},3,{-3,3.5,-Infinity},{{1/2}}]
@@ -764,9 +769,11 @@ class Min(_MinMax):
764769
<dd>returns the expression with the lowest value among the $e_i$.
765770
</dl>
766771
767-
Minimum of a series of numbers:
772+
Minimum of a series of values:
768773
>> Min[4, -8, 1]
769774
= -8
775+
>> Min[E - Pi, Pi, E + Pi, 2 E]
776+
= E - Pi
770777
771778
'Min' flattens lists in its arguments:
772779
>> Min[{1,2},3,{-3,3.5,-Infinity},{{1/2}}]

0 commit comments

Comments
 (0)