I'm working on equality comparisons for a class I call 'Vector'. Really this class is to represent Vectors in R^3, but in a way that allows for both symbolic and numeric evaluation, and to allow for Vectors to be defined as linear combinations of UnitVectors (another class) that a fixed in ReferenceFrames (another class, oriented through rotations). Anyway, Ondrej and I have had some discussion of how to check for equality between a Vector/UnitVector and another Vector/UnitVector. Below is the discussion Ondrej and I were having.
Here is my question: How should the ._args attribute be implemented in the Vector class? Ondrej mentioned making it a list of all the aruguments, but I'm a little confused about this. The way I have implemented the Vector class is to have an attribute .dict which is a dictionary that contains as the keys all the UnitVectors and for the corresponding values, the coefficient of the UnitVector which is the key of that value. For example: A = ReferenceFrame('A') v1 = Vector(5*A[1] + 6*A[2]) then: v1.dict == {A[1]: 5, A[2]: 6} Perhaps this isn't the best way to do things, but in my mind this made sense so this is how I implemented it. Should the ._args list for the above example then be: v1._args == [5*A[1], 6*A[2]] ? Thanks, ~Luke ---------- Forwarded message ---------- From: Ondrej Certik <ond...@certik.cz> Date: Thu, Apr 16, 2009 at 9:37 PM Subject: Re: Confused about something To: Luke <hazelnu...@gmail.com> On Thu, Apr 16, 2009 at 8:00 PM, Luke <hazelnu...@gmail.com> wrote: > Ondrej, > My responses below. > > On Thu, Apr 16, 2009 at 6:57 PM, Ondrej Certik <ond...@certik.cz> wrote: >> On Thu, Apr 16, 2009 at 4:51 PM, Luke <hazelnu...@gmail.com> wrote: >>> Ondrej, >>> I'm a little confused about this: >>> >>> assert cross(A[1], A[3]) == Vector(-A[2]) >>> AssertionError: >>> -------------------- >> begin captured stdout << --------------------- >>> cross(A[1], A[3]): -a2> <class 'pydy.Vector'> {a2>: -1} >>> Vector(-A[2]): -a2> <class 'pydy.Vector'> {a2>: -1} >> >> ^^^ well, those two results above are the same, aren't they? >> >> So it should return True. > > I agree. But it doesn't, even though they are the same. I am not > sure why. If I implement a __eq__() method, I can do quick comparison > of the dictionaries and return the result, but I was under the > impression I shouldn't define my own __eq__() method, but rather a > separate equal() method. I think I know why -- you need to store all the arguments of the Vector in ._args list. Then the standard sympy comparisons will automatically compare this list and it should start working. I think it has to be hashable though, so just store the dict in some variable as it is now and create a list out of the dict and store that in the ._args. All should work because the dict is never modified once the Vector instance is created. > > >> >>> -A[2] -a2> <class 'sympy.core.mul.Mul'> >>> >>> This is the case when the Vector class has no __eq__() method. My >>> guess is that since Vector is subclassed from Basic, it tries to >>> compare them that way and somehow fails. I'm not sure if I should >>> bother trying to get this to be True, since I already have: >>> (cross(A[1], A[3])).equal(-A[2]) == True >> >>> This is fine, it just means I need to rewrite a lot of tests if this >>> is the case. What do you think? >> >> I think that the == (or __eq__) should return quickly True/False and >> it should just compare the expressions (no matter their mathematical >> equivalence). And then you can have .equal() or simplify() or >> whatever, that will try to convert the vectors to the same frame and >> simplify them and compare them. > > So I should write my own __eq__() for both the UnitVector class and > the Vector class? For comparisons between two Vectors or between two See above, just implement ._args. > UnitVectors, this fast comparison would be fairly trivial, and the > .equal() one isn't much worse. In fact, I have already implemented > the code for this, but I just am unclear where I should put it. > >> >> does: >> >> cross(A[1], A[3])) == -A[2] > > No. cross(A[1], A[3]) returns a UnitVector object. -A[2] is a sympy > expression, a Mul object. I could however, implement in the __eq__() Then it it ok that it returns False. Imho. > of the UnitVector and Vector classes the ability to check if the RHS > of the == is a sympy expression, and if so, make it a Vector, which > then can be compared by comparing the dictionaries. > >> >> work? >> >> and what about >> >> -A[2] == Vector(-A[2]) >> > > Nope. Same reasons as above. Here, __eq__() is being called for a Then it it ok that it returns False, same reasons. > Mul Object, so unless we put code in there that knows about the Vector > class, I don't think we can make the above statement work. Or am I > wrong on this? sympy expression and a Vector should always compare as False, because it's a different thing. For mathematical comparison, let's implement the .equal(). Btw, let's discuss this on the sympy list from now on. So that other people can join in and we can build a community. Thanks, Ondrej --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "sympy" group. To post to this group, send email to sympy@googlegroups.com To unsubscribe from this group, send email to sympy+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sympy?hl=en -~----------~----~----~----~------~----~------~--~---