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.