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
-~----------~----~----~----~------~----~------~--~---

Reply via email to