On Fri, Jul 8, 2011 at 10:09 AM, Vinzent Steinberg
<vinzent.steinb...@googlemail.com> wrote:
> On Jul 8, 6:51 am, Aaron Meurer <asmeu...@gmail.com> 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 sympy@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