On Wed, Jul 18, 2012 at 4:05 PM, Aaron Meurer <[email protected]> wrote: > Going back to TensorProduct, this is what I get in my branch: > > In [58]: TensorProduct(x, y + z).expand() > Out[58]: x⋅y⋅1⨂ 1 + x⋅z⋅1⨂ 1
This is correct if x,y,z are scalars. If they are operators (or I think other non-commuting symbols) you would get: TensorProduct(x,y) + TensorProduct(x,z) => x⨂ y + x⨂ z Cheers, Brian > (I hope you mean the TensorProduct in sympy.physics.quantum). Is that > what you would expect? If, not, could you be more explicit about what > you are asking? > > On Wed, Jul 18, 2012 at 4:44 PM, [email protected] > <[email protected]> wrote: >>> It uses is_Atom for the base case. >> >> Why is is_Atom preferable to (not hasattr(obj, 'args') or not obj.args)? >> Is not is_Atom redundant (i.e. mostly the same as args==(,)), and with >> limited scope (i.e. breaks when args contain non-Basic)? > > It works just fine with non-Basic args (I know this for a fact because > I had to make it work for OracleGate, which has a lambda in its args). > > Let me go ahead and paste what I've been using: > > def _eval_expand_hint(self, deep=True, **hints): > if not deep or self.is_Atom: > return self > sargs, terms = self.args, [] > for term in sargs: > if hasattr(term, "_eval_expand_hint"): > newterm = term._eval_expand_hint(deep=deep, **hints) > else: > newterm = term > terms.append(newterm) > return self.func(*terms) > > This is defined on Expr for each hint (actually a little more > generally using __getattr__, but that's external to the discussion). > > I *suppose* self.is_Atom could be replaced with not self.args. I'm > not sure what the benefits of either way are. I do know there are > classes with empty .args that are not Atoms (like Tuple()). I don't > know of any classes that are recursion base cases but don't have args. > > I think the key point about Atom is not that it has empty .args, but > that it has empty .args *and* it cannot be rebuilt from it's args (the > empty args part is only because this only works if it is always a leaf > in the expression tree). So Tuple().args == () but Tuple.is_Atom == > False is fine because Tuple(*()) == Tuple() holds. But Symbol(*()) == > Symbol('x') or Rational(*()) == Rational(1, 2) do not hold. > > Note however that there's no way that .is_Atom or .args could not be > defined, because this is defined on Expr, so any class that uses it > will be a subclass of Expr and will have those properties. > > Aaron Meurer > > -- > You received this message because you are subscribed to the Google Groups > "sympy" group. > To post to this group, send email to [email protected]. > To unsubscribe from this group, send email to > [email protected]. > 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 [email protected] and [email protected] -- You received this message because you are subscribed to the Google Groups "sympy" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/sympy?hl=en.
