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.