On Fri, Jul 8, 2011 at 10:09 AM, Vinzent Steinberg <[email protected]> wrote: > On Jul 8, 6:51 am, Aaron Meurer <[email protected]> wrote: >> expand() does this, with a lot of hints, and it's not a very good >> system in my opinion. > > I think the problem with expand it that it does a lot more at once > than it should be doing, and that it is hard to use otherwise. I don't > think the interface is fundamentally broken.
Well, that problem would not show up here, since subs should only do one pass, whereas expand does a pass for each expansion hint. Indeed, we need to be careful that it does indeed only do exactly one pass, so we don't get stuff like >>> sin(x).subs(sin(x), 2*sin(x), **somehints) 4*sin(x) But the problem with the way expand works with the _eval_expand_hint methods is that each _eval_expand_hint method is responsible for passing all the hints through recursively, and in such a way that it's own hint is stopped from being passed through at the base case, to prevent infinite recursion. The deep keyword also causes a lot of problems here if it is not handled very carefully (if we ever decide to implement a deep hint to subs, it should be implemented just the same as any other hint). If we do _eval_subs_hint() methods, there would be exactly the same problem. To me, it's a very unclean way of doing things, and since I'm implementing these hints almost from scratch, I'd like to do it better. I say almost from scratch because we would need to maintain backwards compatibility with older _eval_subs(old, new) (no **kwargs) methods, which is perhaps another reason that we cannot use the expand method here. There's got to be a better object oriented way to do this. > >> Unlike expand(), subs wouldn't be called in >> multiple passes for each hint, but nonetheless, I still see the system >> as one that could be improved (though how, I am still not yet sure). > > subs() could have a "method='method'" keyword argument. > > Vinzent > I don't think that would be general enough. It needs to be subs(**hints). I listed four types of substitution in the OP (including the catch-all "algebraic", which tries to be as smart as possible), but I could easily imagine more fine grained control. For example, suppose we implement a substitution method that first tries to rewrite expr in terms of old before substituting. This would require making rewrite smarter, but it would work something like: >>> cos(x).subs(sin(x), y, rewrite=True) (1 - y**2)**(1/2) But rewrite=True should be mutually exclusive to some other option, say integer_powers: >>> sqrt(1 - sin(x)**2).subs(cos(x)**2, y, rewrite=True, integer_powers=False) sqrt(y) >>> sqrt(1 - sin(x)**2).subs(cos(x)**2, y, rewrite=True, integer_powers=True) sqrt(1 - sin(x)**2) The only hint that I think might not make sense to combine with other hints is exact, which should turn all other hints off. Because of this, and the fact that I think exact substitution can be implemented entirely in Basic without any method overriding necessary in subclasses (basically, use the current Basic._eval_subs), I think maybe exact should be completely separate from the rest of the subs hints. Or maybe it would make sense to use some kind of hints manager for subs like Chris started to implement for expand(). 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.
