On Wed, Jul 3, 2013 at 2:42 PM, Ondřej Čertík <[email protected]> wrote:
> On Wed, Jul 3, 2013 at 3:19 PM, Brian Granger <[email protected]> wrote:
>> On Wed, Jul 3, 2013 at 1:42 PM, Ondřej Čertík <[email protected]> 
>> wrote:
>>> On Wed, Jul 3, 2013 at 1:48 PM, Aaron Meurer <[email protected]> wrote:
>>>> Brian, I think you dropped off list. Forwarding to sympy.
>>>>
>>>> Aaron Meurer
>>>>
>>>> On Wed, Jul 3, 2013 at 2:29 PM, Brian Granger <[email protected]> wrote:
>>>>> I think that having multiple dispatch is something that is needed within
>>>>> SymPy.  Multiple people have run into the difficulties with providing 
>>>>> custom
>>>>> Add/Mul logic for their new types.  In quantum, we just punted and used 
>>>>> the
>>>>> builtin Add/Mul logic, but it was a bad compromise to make.
>>>>>
>>>>> For this, I think looking at Mathematica is really important.  This is
>>>>> handled by Mathematica's Rules and Patterns which are documented here:
>>>>>
>>>>> http://reference.wolfram.com/mathematica/guide/RulesAndPatterns.html
>>>>> http://reference.wolfram.com/mathematica/tutorial/Introduction-Patterns.html
>>>>>
>>>>> If we don't have first class, nested and general pattern matching, we 
>>>>> can't
>>>>> do multiple dispatch.  The case in point is classes that accept *args such
>>>>> as Add and Mul.  Good fast pattern matching would also allow us to do much
>>>>> of the logic in Add/Mul constructors using patterns:
>>>>>
>>>>> Add(x_, x_) -> 2*x_
>>>>> Mul(x_, x_)  -> x**2
>>>
>>> Pattern matching is another way to implement CAS, but I am actually not
>>> sure this is how Mathematica works inside. Also in pure Python, this might
>>> be really slow (I don't know). I don't see all the little details for
>>> pattern matching
>>> approach. I think I can see more of the details for the sympy approach 
>>> though.
>>>
>>>>>
>>>>> etc.
>>>>>
>>>>> Summary - simple type based dispatch won't do - we need full blown pattern
>>>>> matching and transformation logic.
>>>
>>> Why wouldn't simple type based dispatch work?
>>> You might be right, I just want to understand the problem more.
>>
>> For example take a quantum time evolution operator exp(-I*t*H).  What
>> if I wanted to develop custom logic for that operator.  Simply
>> matching on type type (exp) won't work.  You need to be able to say:
>>
>> exp(-I*Numer(x_)*HermitianOperator(y_))
>>
>> That requires pattern matching...
>
> So first of all, since H does not commute, H will not be a Symbol, but
> rather an NCSymbol.
> Then the "*" in there will not be Mul but NCMul, thanks to our binary 
> dispatch.
> exp can in principle be NCFunction or something.

But that is besides the point - there are infinitely other examples
where you need to apply pattern matching logic that is not merely type
based.

> What kind of custom logic are you thinking of? The automatic canonical
> simplification should only be very simple things, most probably in
> this case just things that NCMul can do.

I am thinking that the automatic canonical simplification logic
everywhere in sympy would be replaced by rules+patterns.

> Anything more advanced (like perturbation expansion of "exp") should
> be implemented as an extra function.

I completely agree...

>>
>>>
>>>
>>> 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.
>>>
>>> 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.
>>>
>>> The general idea is that you create a new type, let's say Infinity and
>>> register mul, add, div, sub, pow using dispatch, which specify how
>>> your new type should be handled.
>>>
>>> In particular, it would look something like:
>>>
>>> @dispatch(Infinity, Basic)
>>> def mul(a, b):
>>>     if isinstance(b, Integer):
>>>         return a
>>>     else:
>>>         return Add(a, b)
>>
>> But Mul is not a binary operator in SymPy - we could make it so and
>> build the overall *args version by repeatedly calling the binary
>> version.  That would be nice... and would somewhat help our
>> situation...
>
> Roughly that's how it works internally, that you take each term and
> try to apply/combine it with all the previous ones. The actual
> implementation in sympy has gotten quite complicated over the years.
>
> 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.
>
>



--
Brian E. Granger
Cal Poly State University, San Luis Obispo
[email protected] and [email protected]

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