Skip to content

Commit 31a16a0

Browse files
authored
Fix the broken Sdop.__eq__, and add the missing __ne__ operators. (#193)
`__ne__` is needed by python 2 (https://stackoverflow.com/q/4352244/102441), else it defaults to `x is not y` Also: * move some tests that ended up in the wrong place after a merge/rebase * use the helper alias methods in `Ga` to increase coverage
1 parent 09b6a73 commit 31a16a0

File tree

2 files changed

+79
-34
lines changed

2 files changed

+79
-34
lines changed

galgebra/mv.py

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1626,19 +1626,19 @@ def Add(sdop1, sdop2):
16261626
raise TypeError("Neither argument is a Dop instance")
16271627
return Sdop.Add(sdop1, sdop2)
16281628

1629-
def __eq__(self, sdop):
1630-
if isinstance(sdop, Sdop):
1631-
if self.Ga != sdop.Ga:
1632-
return False
1633-
self = Sdop.consolidate_coefs(self)
1634-
sdop = Sdop.consolidate_coefs(sdop)
1635-
if len(self.terms) != len(sdop.terms):
1636-
return False
1637-
if set(self.terms) != set(sdop.terms):
1638-
return False
1639-
return True
1629+
def __eq__(self, other):
1630+
if isinstance(other, Sdop):
1631+
if self.Ga != other.Ga:
1632+
return NotImplemented
1633+
1634+
diff = self - other
1635+
return len(diff.terms) == 0
16401636
else:
1641-
return False
1637+
return NotImplemented
1638+
1639+
if sys.version_info.major < 3:
1640+
def __ne__(self, other):
1641+
return not (self == other)
16421642

16431643
def __add__(self, sdop):
16441644
return Sdop.Add(self, sdop)
@@ -1718,6 +1718,10 @@ def __eq__(self,A):
17181718
return True
17191719
return False
17201720

1721+
if sys.version_info.major < 3:
1722+
def __ne__(self, other):
1723+
return not (self == other)
1724+
17211725
def __init__(self, __arg, **kwargs):
17221726
"""
17231727
The partial differential operator is a partial derivative with
@@ -2134,15 +2138,19 @@ def __lt__(self, dopr): # < left contraction
21342138
def __gt__(self, dopr): # > right contraction
21352139
return Dop.Mul(self, dopr, op='>')
21362140

2137-
def __eq__(self, dop):
2138-
if isinstance(dop, Dop):
2139-
if self.Ga != dop.Ga:
2140-
return False
2141+
def __eq__(self, other):
2142+
if isinstance(other, Dop):
2143+
if self.Ga != other.Ga:
2144+
return NotImplemented
21412145

2142-
diff = self - dop
2143-
return all(coef == S(0) for coef, _ in diff.terms)
2146+
diff = self - other
2147+
return len(diff.terms) == 0
21442148
else:
2145-
return False
2149+
return NotImplemented
2150+
2151+
if sys.version_info.major < 3:
2152+
def __ne__(self, other):
2153+
return not (self == other)
21462154

21472155
def __str__(self):
21482156
if printer.GaLatexPrinter.latex_flg:

test/test_differential_ops.py

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def test_empty_dop(self):
4444
ga, ex, ey, ez = Ga.build('e*x|y|z', g=[1, 1, 1], coords=coords)
4545
v = ga.mv('v', 'vector', f=True)
4646

47-
make_zero = Dop([], ga=ga)
47+
make_zero = ga.dop([])
4848
assert make_zero * v == 0
4949
assert make_zero * make_zero * v == 0
5050
assert (make_zero + make_zero) * v == 0
@@ -65,8 +65,13 @@ def test_misc(self):
6565
assert laplacian.is_scalar()
6666
assert not ga.grad.is_scalar()
6767

68+
# test comparison
6869
assert ga.grad == ga.grad
70+
assert not (ga.grad != ga.grad)
6971
assert ga.grad != laplacian
72+
assert not (ga.grad == laplacian)
73+
assert ga.grad != object()
74+
assert not (ga.grad == object())
7075

7176
# inconsistent cmpflg, not clear which side the operator goes on
7277
with pytest.raises(ValueError):
@@ -108,8 +113,7 @@ def test_shorthand(self):
108113
coords = x, y, z = symbols('x y z', real=True)
109114
ga, ex, ey, ez = Ga.build('e*x|y|z', g=[1, 1, 1], coords=coords)
110115

111-
# TODO: __eq__ is broken, remove `repr` when it is fixed
112-
assert repr(Sdop(x, ga=ga)) == repr(Sdop([(S(1), Pdop({x: 1}, ga=ga))], ga=ga))
116+
assert Sdop(x, ga=ga) == Sdop([(S(1), Pdop({x: 1}, ga=ga))], ga=ga)
113117

114118
def test_empty_sdop(self):
115119
""" Test that sdop with zero terms is equivalent to multiplying by zero """
@@ -123,18 +127,6 @@ def test_empty_sdop(self):
123127
assert (make_zero + make_zero) * v == 0
124128
assert (-make_zero) * v == 0
125129

126-
127-
class TestPdop(object):
128-
129-
def test_deprecation(self):
130-
coords = x, y, z = symbols('x y z', real=True)
131-
ga, ex, ey, ez = Ga.build('e*x|y|z', g=[1, 1, 1], coords=coords)
132-
133-
# passing `None` is a deprecate way to spell `{}`
134-
with pytest.warns(DeprecationWarning):
135-
p = Pdop(None, ga=ga)
136-
assert p == Pdop({}, ga=ga)
137-
138130
def test_associativity_and_distributivity(self):
139131
coords = x, y, z = symbols('x y z', real=True)
140132
ga, ex, ey, ez = Ga.build('e*x|y|z', g=[1, 1, 1], coords=coords)
@@ -152,3 +144,48 @@ def test_associativity_and_distributivity(self):
152144
# check multiplication is associative
153145
assert (20 * laplacian) * v == 20 * (laplacian * v) != 0
154146
assert (laplacian * laplacian) * v == laplacian * (laplacian * v) != 0
147+
148+
149+
def test_misc(self):
150+
""" Other miscellaneous tests """
151+
coords = x, y, z = symbols('x y z', real=True)
152+
ga, ex, ey, ez = Ga.build('e*x|y|z', g=[1, 1, 1], coords=coords)
153+
laplacian = ga.sdop((ga.grad * ga.grad).terms)
154+
lap2 = laplacian*laplacian
155+
156+
# test comparison
157+
assert lap2 == lap2
158+
assert not (lap2 != lap2)
159+
assert lap2 != laplacian
160+
assert not (lap2 == laplacian)
161+
assert lap2 != object()
162+
assert not (lap2 == object())
163+
164+
165+
class TestPdop(object):
166+
167+
def test_deprecation(self):
168+
coords = x, y, z = symbols('x y z', real=True)
169+
ga, ex, ey, ez = Ga.build('e*x|y|z', g=[1, 1, 1], coords=coords)
170+
171+
# passing `None` is a deprecate way to spell `{}`
172+
with pytest.warns(DeprecationWarning):
173+
p = Pdop(None, ga=ga)
174+
assert p == Pdop({}, ga=ga)
175+
176+
def test_misc(self):
177+
""" Other miscellaneous tests """
178+
coords = x, y, z = symbols('x y z', real=True)
179+
ga, ex, ey, ez = Ga.build('e*x|y|z', g=[1, 1, 1], coords=coords)
180+
181+
pxa = ga.pdop({x: 1})
182+
pxb = ga.pdop({x: 1})
183+
p1 = ga.pdop({})
184+
185+
# test comparison
186+
assert pxa == pxb
187+
assert not (pxa != pxb)
188+
assert p1 != pxa
189+
assert not (p1 == pxa)
190+
assert pxa != object()
191+
assert not (pxa == object())

0 commit comments

Comments
 (0)