Skip to content

Commit 8cd279e

Browse files
committed
A last improvement for complex. Moving tests to lower level
1 parent 0530fd2 commit 8cd279e

File tree

3 files changed

+158
-68
lines changed

3 files changed

+158
-68
lines changed

mathics/core/atoms.py

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -936,41 +936,14 @@ def element_order(self) -> tuple:
936936
of an expression. The tuple is ultimately compared lexicographically.
937937
"""
938938
order_real, order_imag = self.real.element_order, self.imag.element_order
939+
939940
# If the real of the imag parts are real numbers, sort according
940941
# the minimum precision.
941942
# Example:
942943
# Sort[{1+2I, 1.+2.I, 1.`4+2.`5I, 1.`2+2.`7 I}]
943944
#
944945
# = {1+2I, 1.+2.I, 1.`2+2.`7 I, 1.`4+2.`5I}
945-
946-
if len(order_real) > 4:
947-
prec = order_imag[4] if len(order_imag) > 4 else order_real[4]
948-
return (
949-
BASIC_ATOM_NUMBER_ELT_ORDER,
950-
order_real[1],
951-
0,
952-
1,
953-
prec,
954-
order_imag[1],
955-
)
956-
if len(order_imag) > 4:
957-
prec = order_imag[4]
958-
return (
959-
BASIC_ATOM_NUMBER_ELT_ORDER,
960-
order_real[1],
961-
0,
962-
1,
963-
order_imag[4],
964-
order_imag[1],
965-
)
966-
return (
967-
BASIC_ATOM_NUMBER_ELT_ORDER,
968-
order_real[1],
969-
0,
970-
1,
971-
-1,
972-
order_imag[1],
973-
)
946+
return order_real + order_imag
974947

975948
@property
976949
def pattern_precedence(self) -> tuple:

test/builtin/test_sort.py

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,44 +6,6 @@
66
from mathics.core.symbols import Symbol, SymbolPlus, SymbolTimes
77

88

9-
def test_Sorting_one():
10-
"""
11-
In WMA, canonical order for numbers with the same value in different representations:
12-
* Integer
13-
* Complex[Integer, PrecisionReal]
14-
* MachineReal
15-
* Complex[MachineReal, MachineReal]
16-
* PrecisionReal, Complex[PrecisionReal, PrecisionReal] if precision of the real parts are equal,
17-
* otherwise, sort by precision of the real part.
18-
* Rational
19-
Example: {1, 1 + 0``10.*I, 1., 1. + 0.*I, 1.`4., 1.`4. + 0``4.*I, 1.`4. + 0``3.*I, 1.`6.}
20-
and
21-
{0.2, 0.2 + 0.*I, 0.2`4., 0.2`10., 1/5}
22-
are lists in canonical order.
23-
24-
If the numbers are in different representations, numbers are sorted by their real parts,
25-
and then the imaginary part is considered:
26-
{0.2, 0.2 - 1.*I, 0.2 + 1.*I, 1/5}
27-
"""
28-
# Canonical order
29-
for expr_str in [
30-
"{1, 1., 1. + 0.*I, 1.`5. + 0.``2*I, 1.`2., 1.`49.}",
31-
"{.2, .2+0.I, .2`20+0.``20 I,.2`20,.2`21, 1/5}",
32-
]:
33-
order_equiv_forms = session.evaluate(f"OrderedFormsOfOne={expr_str}")
34-
print(order_equiv_forms)
35-
for elem, nelem in zip(order_equiv_forms[:-1], order_equiv_forms[1:]):
36-
e_order, ne_order = elem.element_order, nelem.element_order
37-
print("-------")
38-
print(type(elem), elem, e_order)
39-
print("vs", type(nelem), nelem, ne_order)
40-
assert e_order < ne_order and not (
41-
ne_order <= e_order
42-
), "wrong order or undefined."
43-
assert elem == nelem, "elements are not equal"
44-
assert nelem == elem, "elements are not equal"
45-
46-
479
def test_Expression_sameQ():
4810
"""
4911
Test Expression.SameQ

test/core/test_keycomparable.py

Lines changed: 156 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,161 @@
11
import pytest
2+
from sympy import Float
23

3-
from mathics.core.atoms import Complex, Integer0, Integer1, Real, String
4+
from mathics.core.atoms import (
5+
Complex,
6+
Integer0,
7+
Integer1,
8+
PrecisionReal,
9+
Rational,
10+
Real,
11+
String,
12+
)
13+
14+
print("creating representations")
15+
ZERO_REPRESENTATIONS = {
16+
"Integer": Integer0,
17+
"MachineReal": Real(0.0),
18+
"PrecisionReal`2": PrecisionReal(Float(0, 2)),
19+
"PrecisionReal`5": PrecisionReal(Float(0, 5)),
20+
"PrecisionReal`10": PrecisionReal(Float(0, 10)),
21+
"PrecisionReal`20": PrecisionReal(Float(0, 20)),
22+
"PrecisionReal`22": PrecisionReal(Float(0, 22)),
23+
"PrecisionReal`40": PrecisionReal(Float(0, 40)),
24+
}
25+
ZERO_REPRESENTATIONS["Complex"] = Complex(
26+
ZERO_REPRESENTATIONS["MachineReal"], ZERO_REPRESENTATIONS["MachineReal"]
27+
)
28+
ZERO_REPRESENTATIONS["Complex`20"] = Complex(
29+
ZERO_REPRESENTATIONS["PrecisionReal`20"], ZERO_REPRESENTATIONS["PrecisionReal`20"]
30+
)
31+
32+
ONE_REPRESENTATIONS = {
33+
"Integer": Integer1,
34+
"MachineReal": Real(1.0),
35+
"PrecisionReal`2": PrecisionReal(Float(1, 2)),
36+
"PrecisionReal`5": PrecisionReal(Float(1, 5)),
37+
"PrecisionReal`10": PrecisionReal(Float(1, 10)),
38+
"PrecisionReal`20": PrecisionReal(Float(1, 20)),
39+
"PrecisionReal`22": PrecisionReal(Float(1, 22)),
40+
}
41+
42+
43+
# Add some complex cases
44+
ONE_REPRESENTATIONS["Complex Integer"] = Complex(
45+
Integer1, ZERO_REPRESENTATIONS["PrecisionReal`10"]
46+
)
47+
ONE_REPRESENTATIONS["Complex"] = Complex(
48+
ONE_REPRESENTATIONS["MachineReal"], ZERO_REPRESENTATIONS["MachineReal"]
49+
)
50+
ONE_REPRESENTATIONS["Complex`5"] = Complex(
51+
ONE_REPRESENTATIONS["PrecisionReal`5"], ZERO_REPRESENTATIONS["PrecisionReal`5"]
52+
)
53+
54+
55+
ONE_FIFTH_REPRESENTATIONS = {
56+
"Rational": Rational(1, 5),
57+
"MachineReal": Real(0.2),
58+
"PrecisionReal`20": PrecisionReal(Float(".2", 20)),
59+
"PrecisionReal`22": PrecisionReal(Float(".2", 22)),
60+
}
61+
ONE_FIFTH_REPRESENTATIONS["Complex"] = Complex(
62+
ONE_FIFTH_REPRESENTATIONS["MachineReal"], ZERO_REPRESENTATIONS["MachineReal"]
63+
)
64+
ONE_FIFTH_REPRESENTATIONS["Complex`20"] = Complex(
65+
ONE_FIFTH_REPRESENTATIONS["PrecisionReal`20"],
66+
ZERO_REPRESENTATIONS["PrecisionReal`20"],
67+
)
68+
69+
70+
def test_sorting_numbers():
71+
"""
72+
In WMA, canonical order for numbers with the same value in different representations:
73+
* Integer
74+
* Complex[Integer, PrecisionReal]
75+
* MachineReal
76+
* Complex[MachineReal, MachineReal]
77+
* PrecisionReal, Complex[PrecisionReal, PrecisionReal] if precision of the real parts are equal,
78+
* otherwise, sort by precision of the real part.
79+
* Rational
80+
Example: {1, 1 + 0``10.*I, 1., 1. + 0.*I, 1.`4., 1.`4. + 0``4.*I, 1.`4. + 0``3.*I, 1.`6.}
81+
and
82+
{0.2, 0.2 + 0.*I, 0.2`4., 0.2`10., 1/5}
83+
are lists in canonical order.
84+
85+
If the numbers are in different representations, numbers are sorted by their real parts,
86+
and then the imaginary part is considered:
87+
{0.2, 0.2 - 1.*I, 0.2 + 1.*I, 1/5}
88+
"""
89+
zero_canonical_order = (
90+
"Integer",
91+
"MachineReal",
92+
"Complex",
93+
"PrecisionReal`20",
94+
"Complex`20",
95+
"PrecisionReal`22",
96+
)
97+
one_canonical_order = (
98+
"Integer",
99+
"MachineReal",
100+
"Complex",
101+
"Complex Integer",
102+
"PrecisionReal`2",
103+
"PrecisionReal`5",
104+
"Complex`5",
105+
"PrecisionReal`20",
106+
)
107+
one_fifth_canonical_order = (
108+
"MachineReal",
109+
"Complex",
110+
"PrecisionReal`20",
111+
"Complex`20",
112+
"PrecisionReal`22",
113+
"Rational",
114+
)
115+
116+
# Canonical order
117+
for order_equiv_forms in [
118+
[ZERO_REPRESENTATIONS[pos] for pos in zero_canonical_order],
119+
[ONE_REPRESENTATIONS[pos] for pos in one_canonical_order],
120+
[ONE_FIFTH_REPRESENTATIONS[pos] for pos in one_fifth_canonical_order],
121+
]:
122+
for elem, nelem in zip(order_equiv_forms[:-1], order_equiv_forms[1:]):
123+
e_order, ne_order = elem.element_order, nelem.element_order
124+
print("-------")
125+
print(type(elem), f"{elem}", e_order)
126+
print("vs", type(nelem), f"{nelem}", ne_order)
127+
assert e_order < ne_order and not (
128+
ne_order <= e_order
129+
), "wrong order or undefined."
130+
assert (
131+
elem == nelem
132+
), f"elements are not equal {elem} ({type(elem)}[{e_order}]) != {nelem}({type(nelem)}[{ne_order}])"
133+
assert (
134+
nelem == elem
135+
), f"elements are not equal {elem} ({type(elem)}[{e_order}]) != {nelem}({type(nelem)}[{ne_order}])"
136+
137+
138+
def test_sorting_complex():
139+
one_fifth_rational = ONE_FIFTH_REPRESENTATIONS["Rational"]
140+
one_fifth_mr = ONE_FIFTH_REPRESENTATIONS["MachineReal"]
141+
one_fifth_pr = ONE_FIFTH_REPRESENTATIONS["PrecisionReal`20"]
142+
one_fifth_cplx_i = Complex(one_fifth_mr, ONE_REPRESENTATIONS["MachineReal"])
143+
one_fifth_cplx_mi = Complex(one_fifth_mr, -ONE_REPRESENTATIONS["MachineReal"])
144+
canonical_sorted = [
145+
one_fifth_mr,
146+
one_fifth_cplx_mi,
147+
one_fifth_cplx_i,
148+
one_fifth_pr,
149+
one_fifth_rational,
150+
]
151+
for elem, nelem in zip(canonical_sorted[:-1], canonical_sorted[1:]):
152+
e_order, ne_order = elem.element_order, nelem.element_order
153+
print("-------")
154+
print(type(elem), f"{elem}", e_order)
155+
print("vs", type(nelem), f"{nelem}", ne_order)
156+
assert e_order < ne_order and not (
157+
ne_order <= e_order
158+
), f"{e_order}, {ne_order}"
4159

5160

6161
# Tests

0 commit comments

Comments
 (0)