On Mon, May 9, 2011 at 6:33 PM, Aaron Meurer <asmeu...@gmail.com> wrote:
> On Mon, May 9, 2011 at 7:30 PM, Ronan Lamy <ronan.l...@gmail.com> wrote:
>> Le lundi 09 mai 2011 à 17:30 -0700, Luke a écrit :
>>> Here is a more explicit example of what Gilbert is talking about:
>>> In [1]: from sympy import *
>>> In [2]: from pydy import *
>>> In [3]: x = symbols('x')
>>> In [4]: N = ReferenceFrame('N')
>>> In [5]: type(N[1])
>>> Out[5]: pydy.pydy.UnitVector
>>> In [9]: test = x*N[1] + x*x*N[2]
>>> In [10]: type(test)
>>> Out[10]: sympy.core.add.Add
>>> In [11]: test2 = Vector(test)
>>> In [12]: test2
>>> Out[12]: x*n1> + x**2*n2>
>>> In [13]: type(test2)
>>> Out[13]: pydy.pydy.Vector
>>> In [14]: test3 = x*test2
>>> In [15]: test3
>>> Out[15]: x*x*n1> + x**2*n2>
>>> In [16]: type(test3)
>>> Out[16]: sympy.core.mul.Mul
>>>
>>> As you can see, in Out[15], the multiplication of x and test2 is being
>>> printed in a way that doesn't make sense, and in Out[16] we can see
>>> that this multiplication isn't resulting in another Vector object,
>>> instead it is of type Mul.
>>>
>>> Currently, to create a Vector object, you need to explicitly call
>>> Vector on a sympy expression that is composed from terms that have
>>> UnitVectors in them, or pass a dictionary with UnitVectors as the keys
>>> and sympy expressions as the values.
>>>
>>> Once you have that Vector object, you might want to multiply it by a
>>> scalar (sympy expression) and have it return another Vector object.
>>> This could be done using a somewhat user unfriendly approach:
>>>
>>> In [22]: Vector(dict([(k, x*v) for k, v in test2.dict.items()]))
>>> Out[22]: x**2*n1> + x**3*n2>
>>>
>>> This gets the job done, but it isn't very convenient.
>>>
>>> So basically, the question is whether
>>> 1)  Is it easy enough in Sympy to make something like x*aVectorObject
>>> evaluate to another Vector object?  Where the x is a "scalar part"
>>> (probably a sympy Expression) and aVectorObject is of type Vector
>>> (which currently subclasses from Basic)?
>>
>> No, currently, it's not possible to do it correctly. Expr objects don't
>> expect to be multiplied by non-Expr objects. However, changing this
>> should be possible: you'd have to add to all relevant __mul__ methods
>> something like 'if not isinstance(other, Expr): return NotImplemented'.
>> And then, you'll only have to fight Python's labyrinthine model for
>> double-dispatch inside your vector classes.
>
> Oh, OK, so you were thinking the same thing that I was.  Yes, let's do
> this then.  It seems to make the most sense.  Expr is supposed to be
> only mathematical objects, like things that can be part of a Mul, so
> allowing non-Exprs to multiply Exprs doesn't make much sense.

That'd be great to allow people to extend sympy with their own objects.

So is the proposal to try to coerce an object to an Expr instance, so
things like Symbol, Python int, etc. would succeed, and if so, Expr
will take over. Otherwise the other non Expr instance will be given a
chance to take over the operation (no matter which side you operate on
the Expr object)? If this can be implemented, that'd be great.

But I thought that exactly this was already implemented using the
_op_priority, see sympy/core/expr.py, line 22:

    # Expr and its sublcasses use _op_priority to determine which object
    # passed to a binary special method (__mul__, etc.) will handle the
    # operation. In general, the 'call_highest_priority' decorator will choose
    # the object with the highest _op_priority to handle the call.
    # Custom subclasses that want to define their own binary special methods
    # should set an _op_priority value that is higher than the default.
    _op_priority = 10.0


What am I missing?

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