After attempting various ways of handling custom Mul/Add/etc logic
last summer my conclusions were:

1) Implementing my own versions of Mul/Add/etc and using _op_priority
was not a good way to proceed.  There are two reasons for this:  i)
the dispatch of _op_priority is easily subverted by the many calls to
Mul/Add/Pow in the core.  ii) Even if we fixed all of that, anyone who
wants to implement a cuatom Mul/Add/Pow has to reimplement most of the
entire sympy core to get basic things to work.  Any everytime a new
class needs custom Mul/Add/Pow, all of that has to be reimplemented
*again*.  That is a waste of time.

2) The best approach would be to *remove* most of the logic from
Mul/Add/Pow etc and replace it by a type of rule system the allows
individual object to declare how they are multiplied/added/etc.

The problem with 2) is that it would be a huge project that touches
most of the code base.

Cheers,

Brian


On Sun, May 22, 2011 at 6:52 PM, Andy Ray Terrel <andy.ter...@gmail.com> wrote:
> On Sun, May 22, 2011 at 7:32 PM, Aaron S. Meurer <asmeu...@gmail.com> wrote:
>>
>> On May 22, 2011, at 5:16 PM, Andy Ray Terrel wrote:
>>
>>> On Sun, May 22, 2011 at 1:49 PM, Andy Ray Terrel <andy.ter...@gmail.com> 
>>> wrote:
>>>> On Sun, May 22, 2011 at 1:12 PM, Mateusz Paprocki <matt...@gmail.com> 
>>>> wrote:
>>>>> Hi,
>>>>>
>>>>> On 22 May 2011 18:17, Aaron S. Meurer <asmeu...@gmail.com> wrote:
>>>>>>
>>>>>> Is it possible to implement x*y*z as reduce(operator.mul, [x, y, z])?
>>>>>
>>>>> It works:
>>>>> In [2]: import operator
>>>>> In [3]: reduce(operator.mul, [x, y, z])
>>>>> Out[3]: x⋅y⋅z
>>>>> In [4]: type(_)
>>>>> Out[4]: <class 'sympy.core.mul.Mul'>
>>>>> but I wouldn't use it on large examples because it takes O(n**2) steps to
>>>>> canonicalize the inputs (similar problem with sum([x,y,z]), we have even 
>>>>> an
>>>>> issue open for this).
>>>>>
>>>>
>>>> Yes this was my fear. Maybe Ronan's comment on the double dispatch
>>>> will work better.
>>>
>>>
>>> Just to be clear, the problem is not so much when the class Mul calls
>>> the Mul constructor but when other classes (like Add or simplify) call
>>> Mul directly instead of the operators.  The style in sympy seems to
>>> prefer this to using the algebraic operators. These calls will
>>> basically always route around *any* dispatch system unless it is tied
>>> into the expression constructors.
>>>
>>> One solution would be to have _op_priority checked inside the
>>> constructor, that way the canonicalization could remain O(n) but the
>>> correct constructor could then be called.  Mul's internals could call a
>>> private constructor to side step check every call.
>>>
>>> — Andy
>>
>> Even if we used the double dispatch, we could make Mul check the arguments 
>> to see if they are dispatchable before canonizing them.  The only problem 
>> here might be the performance, because you would have to call __mul__ or 
>> __rmul__ on each object to see if it returns something or returns 
>> NotImplemented.  Maybe we could require objects to implement some 
>> obj.__has_mul(other) that would quickly indicate whether obj.__mul__(other) 
>> would return NotImplemented or something else (and the same for __mul__).  
>> We could probably implement further optimizations for regular sympy objects 
>> that will always just combine in the Mul, like some property of those 
>> objects that would just be set to True and you don't have to call the 
>> function.
>>
>> Does that sound like it would work?  Does it make sense?
>
> Well you would need to have the priority of the objects to know which
> algebraic op to call anyways. And catching exceptions is very slow.
>
> Another scheme would be to give each operator a resolution dictionary
> where each class that wants to overload the operator can register
> itself.  Then the operator can look up each of its args in the dict
> and tell which is the highest priority.  This is how multiple dispatch
> usually works anyways, just at the compiler level.
>
> The meta_expr could take care of this:
> 1) detect if _op_priority is defined:
> 2) then for each operator defined register it
>
> This would allow for the class lookup to happen at import time and
> keep canonicalization to O(n).
>
> -- Andy
>
>>
>> Aaron Meurer
>>
>>>
>>>>
>>>> -- Andy
>>>>
>>>>>>
>>>>>> Aaron Meurer
>>>>>>
>>>>>>
>>>>>> On May 21, 2011, at 9:11 PM, Andy Ray Terrel <andy.ter...@gmail.com>
>>>>>> wrote:
>>>>>>
>>>>>>> My experience with developing languages in Ignition, is largely the
>>>>>>> same as what Brian outlined.  Another solution though is to instead of
>>>>>>> doing much of the Mul(args) in the core, to do reduce(operator.mul,
>>>>>>> args).  Since things get expanded into Mul objects they don't hit my
>>>>>>> own mul objects.  Right now I have to do ugly hack that fix things up
>>>>>>> after the fact.
>>>>>>>
>>>>>>> -- Andy
>>>>>>>
>>>>>>> On Sun, Jul 25, 2010 at 1:04 PM, Brian Granger <elliso...@gmail.com>
>>>>>>> wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>> On Sat, Jul 24, 2010 at 5:14 PM, Ronan Lamy <ronan.l...@gmail.com>
>>>>>>>> wrote:
>>>>>>>>>
>>>>>>>>> Le samedi 24 juillet 2010 à 13:10 -0700, Brian Granger a écrit :
>>>>>>>>>>
>>>>>>>>>> I written tests for this now.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Brian
>>>>>>>>>>
>>>>>>>>>> On Sat, Jul 24, 2010 at 10:07 AM, Brian Granger <elliso...@gmail.com>
>>>>>>>>>> wrote:
>>>>>>>>>>        Here is an addition patch that adds this capability to all
>>>>>>>>>>        binary special methods in Expr:
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> http://github.com/ellisonbg/sympy/commit/116acd6ef2bde6d0d0aa8c2f2ec1f380abbabab1
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>        The performance penalty is still around 1%.  If there is
>>>>>>>>>>        support for this approach, I would like to merge it to trunk
>>>>>>>>>>        soon as this issue is holding up the quantum stuff.  Also I
>>>>>>>>>>        was thinking that in the long run this could improve
>>>>>>>>>>        performance.  Here is the idea.  Currently, all of the basic
>>>>>>>>>>        operation classes (Mul, Add, Pow) have to have custom logic to
>>>>>>>>>>        non commutative entities.  With the new priority based binary
>>>>>>>>>>        operations, we could implement an NCMul, and NCPow classes
>>>>>>>>>>        that have all of that logic.  The result is that the work Mul
>>>>>>>>>>        and Pow have to do decreases.  It would also be much simpler.
>>>>>>>>>
>>>>>>>>> I'm not sure this is the best design, but it's better than the current
>>>>>>>>> situation, so +1 on the idea. Two remarks though:
>>>>>>>>
>>>>>>>> Any other ideas of different approaches?  I followed this one because 
>>>>>>>> it
>>>>>>>> has
>>>>>>>> been well tested in numpy.
>>>>>>>>
>>>>>>>>>
>>>>>>>>> * Since the whole point of this is to untie binary operators from 
>>>>>>>>> Expr,
>>>>>>>>> the mechanism (i.e. call_other()) shouldn't be implemented in expr.py.
>>>>>>>>
>>>>>>>> OK
>>>>>>>>
>>>>>>>>>
>>>>>>>>> * The repetitiveness of the code should be abstracted away in a
>>>>>>>>> decorator.
>>>>>>>>>
>>>>>>>>
>>>>>>>> I was thinking that as well.  This is especially true because people 
>>>>>>>> who
>>>>>>>> want to define their won special methods that respect the priority will
>>>>>>>> need
>>>>>>>> to use the decorator.
>>>>>>>> Cheers,
>>>>>>>> Brian
>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> 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.
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> Brian E. Granger, Ph.D.
>>>>>>>> Assistant Professor of Physics
>>>>>>>> Cal Poly State University, San Luis Obispo
>>>>>>>> bgran...@calpoly.edu
>>>>>>>> elliso...@gmail.com
>>>>>>>>
>>>>>>>> --
>>>>>>>> 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.
>>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> 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.
>>>>>>>
>>>>>>
>>>>>> --
>>>>>> 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.
>>>>>>
>>>>>
>>>>> Mateusz
>>>>>
>>>>> --
>>>>> 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.
>>>>>
>>>>
>>>
>>> --
>>> 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.
>>>
>>
>> --
>> 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.
>>
>>
>
> --
> 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.
>
>



-- 
Brian E. Granger
Cal Poly State University, San Luis Obispo
bgran...@calpoly.edu and elliso...@gmail.com

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