On Thu, Jul 4, 2013 at 12:09 PM, Ronan Lamy <[email protected]> wrote:
> 2013/7/4 Ondřej Čertík <[email protected]>
>>
>> On Wed, Jul 3, 2013 at 4:40 PM, Ronan Lamy <[email protected]> wrote:
>> > 2013/7/3 Ondřej Čertík <[email protected]>
>> >>
>> >> On Wed, Jul 3, 2013 at 1:48 PM, Aaron Meurer <[email protected]>
>> >> wrote:
>> >>
>> >> Why wouldn't simple type based dispatch work?
>> >> You might be right, I just want to understand the problem more.
>> >>
>> >> To answer Aaron's question:
>> >>
>> >> On Wed, Jul 3, 2013 at 12:58 PM, Aaron Meurer <[email protected]>
>> >> wrote:
>> >> > So, going back to what we discussed the first time we met in Los
>> >> > Alamos, how would you reimplement something like the oo logic so that
>> >> > it lives entirely in the Infinity class, not in Add.flatten (say for
>> >> > simplicity, oo + 3 should go to oo, but oo + 3*I should remain as oo
>> >> > +
>> >> > 3*I)?
>> >>
>> >> This, and another example is x + O(x). Let's stick to oo + 3.
>> >
>> >
>> > x + O(x) is a bad example, because it should really not be represented
>> > by an
>> > Add.
>>
>> So the Order class would simply contain both the expression and the
>> "x", so for example to put this into sympy:
>>
>> x^2 + x + O(x)
>>
>> the user would write:
>>
>> Order(x^2 + x, x)
>>
>> ? I think that's a good idea.
>
>
> It would rather be something like AsymptoticExpansion(expr, order,
> variable), but the user would still write x**2 + x + O(x). ( O(x) would mean
> AsymptoticExpansion(0, x, x) )
>
>>
>> >
>> >> This is a very good question and it is one of the details that I don't
>> >> know the answer 100% yet.
>> >> But I feel it is solvable.
>> >>
>> >> I think the best would be to create a demo (from scratch) where we can
>> >> play with these ideas. Hopefully I'll get to this eventually.
>> >
>> >
>> > How about this: https://github.com/rlamy/sympy/commits/binop ?
>>
>> Yes! Thanks. Here is how to view changes once you are in this branch:
>>
>> git diff c84e5df
>>
>>
>> So I can see that you defined the __pow__ operator in Expr to return
>> power(a, b) instead of the Power(a, b) class directly. The power(a, b)
>> is just a function, double dispatched. Then you change all Pow(a, b)
>> occurrences in sympy to a**b, which gets dispatched to power(a, b)
>> then. I assume you could have also just changed Power -> power?
>
>
> No, because pow(x, 2) needs to return something, i.e. a Pow object. If Pow
> called pow(), we'd have a circular logic requiring a lot of work to avoid
> infinite recursion.
>
>> Finally power() is then defined as follows:
>>
>> [email protected](Expr, Expr)
>> +def _power_basecase(x, y):
>> +    return Pow(x, y)
>>
>> [email protected](Expr, One)
>> +def _pow_Expr_One(x, one):
>> +    return x
>>
>> [email protected](One, Expr)
>> [email protected](One, NaN)
>> [email protected](One, One)
>> [email protected](One, Zero)
>> +def _pow_One_Expr(one, x):
>> +    return one
>>
>> etc. (there are some more rules, not important here)
>>
>> So from this it is clear that power(Expr, One) is used first if
>> available, otherwise pow(Expr, Expr) is used as a backup plan.
>>
>> Here are my questions:
>>
>> * how is performance doing?
>
> I don't know. IIRC, I didn't find any benchmark where the speed of pow()
> itself made much of a difference.
>
>>
>>
>> * currently your dispatch implementation uses issubclass(c_left, left)
>> etc., which potentially might be quite slow. Is there any way to just
>> check the types in a dictionary and only if it is not there, only then
>> do the slow dispatch that you implemented based on inheritance?
>>
>> So for example if you put in (Add, One), then on the first run it
>> would figure out that it should call (Expr, One), and this first run
>> might be slower, that's ok. But on subsequent runs it would simply
>> return it from the dictionary directly, so this should be very fast?
>
>
> Yes, it would be possible to cache the dispatch. There are two problems with
> this:
> * the cache needs to remain consistent when the dispatch dictionary is
> updated - the simplest solution being to clear it every time the dict is
> modified.
> * the cache could grow quite big, because we have many classes that can be
> combined in many ways
>
> The first issue is just a small matter of programming, but the second one
> may be more fundamental and would need to be tested (particularly with add
> and mul).
>>
>>
>> Currently we can't use __class__ for it, because:
>>
>> In [9]: Symbol.__class__
>> Out[9]: sympy.core.assumptions.ManagedProperties
>>
>> In [10]: Zero.__class__
>> Out[10]: sympy.core.singleton.Singleton
>>
>> In [11]: One.__class__
>> Out[11]: sympy.core.singleton.Singleton
>>
>> Due to some sympy metaclasses machinery or something.
>> But we can create some attribute like _sympy_class_, which would be a
>> string or a number, unique for each sympy class. User defined types
>> would write there the name of the class, so that Expr, One, Zero, NaN
>> would all return unique name.
>
>
> What we need to use is the class of objects, not their metaclass. Expr, One,
> Zero, NaN are unique, hashable objects so we can use them as dictionary
> keys.

To clarify something here, Symbol, One, and Zero already *are*
classes. You want something like x.__class__ or S(1).__class__.
Getting the class of the class does indeed give you the metaclass
(that's what metaclasses are).

Aaron Meurer

>
>>
>>
>> * What are your other conclusions or impressions from implementing it?
>>
>> Ondrej
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "sympy" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to [email protected].
>> To post to this group, send email to [email protected].
>> Visit this group at http://groups.google.com/group/sympy.
>> For more options, visit https://groups.google.com/groups/opt_out.
>>
>>
>
> --
> You received this message because you are subscribed to the Google Groups
> "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/sympy.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sympy.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to