On Mon, May 9, 2011 at 6:39 PM, Ondrej Certik <ond...@certik.cz> wrote: > 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?
For usage, see: sympy/core/tests/test_priority.py 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.