On Wed, Jul 21, 2010 at 2:11 PM, Ondrej Certik <ond...@certik.cz> wrote:
> Hi,
>
> On Wed, Jul 21, 2010 at 1:15 PM, Aaron S. Meurer <asmeu...@gmail.com> wrote:
>> First off, pragmatically speaking, is there a reason why you need to use the 
>> core Mul instead of writing your own custom Mul for the quantum stuff?  I am 
>> just saying this because even though I agree that we need this change, 
>> changing anything in the core is very difficult and time consuming, because 
>> the code is so fragile, and you also have to pay close attention to speed 
>> concerns.
>>
>> Also, Mul is optimized for commutative arguments, with non-commutatives 
>> special cased (read "hacked in").  I am thinking it might be smarter to have 
>> separate NCMul for general non-commutatives anyway.
>>
>> So basically, these suggestions are on how to fix issue 1941, because as I 
>> see it, validating whether two objects can be multiplied together is just a 
>> special case of objects that combine with each other specially.
>>
>> On Jul 21, 2010, at 1:34 PM, Brian Granger wrote:
>>
>>> Hi,
>>>
>>> We are running into some issues with Mul in the quantum stuff.  There
>>> are two main things:
>>>
>>> 1.  How Mul combines adjacent args.
>>
>> This one may prove to be the more difficult of the two to solve, because of 
>> the way Python evaluates expressions like a*b*c.  Also, you have to consider 
>> that no matter how you try to make things work with __mul__ and __rmul__, it 
>> can always be thrown off with something like a*(b*c).  Option 1 alone might 
>> not work for this reason.
>>
>>> 2.  How Mul decides if two adjacent args can be multiplied.
>>>
>>> For now, let's focus on the second of these.  The difficulty right now
>>> is that Mul allow any two Exprs to be multiplied.  But in quantum
>>> mechanics, certain things can't be multiplied.  For example, the
>>> following don't make sense:
>>>
>>> Ket('a')*Operator('O)
>>> Operator('O')*Bra('a')
>>>
>>> We would like to add logic to check for these cases into the
>>> __mul__/__rmul__ methods of Operator and State.  But, this logic will
>>> never be triggered in situations like this:
>>>
>>> Bra('a')*Ket('a')*Operator('O) = Mul(Bra('a'), Ket('a'))*Operator('O')
>>>
>>> Because the Mul*Operator triggers Mul.__mul__ (which has no validation
>>> for Operators or States) rather than Operator.__rmul__.
>>>
>>> I see two ways out of this:
>>>
>>> 1.  Handle this like numpy arrays that have an __array_priority__
>>> attribute.  The idea is that the array having the highest numeric
>>> value of the __array_priority__ attribute would have its __mul__ or
>>> __rmul__ method called.  This would make it possible for:
>>>
>>> Mul(Bra('a'), Ket('a'))*Operator('O') to trigger Operator.__rmul__
>>>
>>> This solution would not required changes to Mul, only to the __mul__
>>> and __rmul__ methods of Expr.  It would also require going through
>>> sympy and adding the priority atttributes to relevant classes.
>>>
>>> 2.  To add a new set of methods to Expr that are used by Mul to
>>> validate if two things could be multiplied.  This is more flexible.  I
>>> propose methods like:
>>>
>>> _validate_mul(self, other)
>>> _validate_rmul(self, other)
>>>
>>
>> It seems to me like you would have to have both options.  The _validate_mul 
>> (or combine_mul, as Ondrej called it in 
>> http://github.com/certik/sympyx/commits/handler) would have to be there to 
>> handle the special multiplication behaviors.  But I think you also need some 
>> kind of priority system to break ties of more than one object in the Mul has 
>> such a method.  If you just do validation (no combining), then maybe you 
>> could do without option 1, except you will have to accept the fact that 
>> _validate_mul will always be called before _validate_rmul.
>>
>> By the way, it is more general to send to the combination method the whole 
>> list of objects that have been gathered together already.  This is for 
>> things that combine into each other, such as infinities and Order, so they 
>> can pull everything into themselves.
>>
>>> The end of Mul.flatten would check for these attributes and then
>>> validate adjacent objects to make sure they could really be
>>> multiplied.  This would help us with symbolic Matrices and Tensors for
>>> example, because these methods could do shape compatibility tests.
>>>
>>> This issue is also related to how combines are done in Mul.flatten,
>>> but I think we might be able to resolve this by itself.  Thoughts?
>>
>> Maybe for now you could do validation separate from combination, if it's 
>> easier to handle.  Ultimately, I would like to see both separated out into 
>> the objects. The validation is a trivial special case of the combination, 
>> but not the other way around, because combination requires handling all 
>> args, not just adjacent ones.  On the other hand, the issue #1 you name 
>> above could cause efficiency problems for the combination, so might need to 
>> be solved concurrently.
>
>
> Aaron, you essentially summarized it all, thanks!
>
> Some points:
>
> 1) Problem with extending the Mul is that if it's not done right, it
> slows things down a lot.

Definitely.  I may play with this some.

> 2) a*b and Mul(a, b) should be equivalent

I don't see how this can be the case, but maybe I am misunderstanding
you.  Are you saying that the __mul__ and __rmul__ methods must always
return Mul and never custom subclasses?  Different mathematical
entities have different multiplication rules and this goes beyond mere
commutativity.  A perfect example is Matric/vector/tensor
multiplication.  If we ever want to have these classes inhert from
Basic and be used in symbolic contexts, we really need a custom Mul
that is created by A*B.

> However, what you raised is a real problem and we need to figure out
> some solution to that.
>
> Ondrej
>
> --
> You received this message because you are subscribed to the Google Groups 
> "sympy" group.
> To post to this group, send email to sy...@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 sy...@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