Le samedi 09 juillet 2011 à 10:29 -0700, Brian Granger a écrit :
> > As many of you may know, the main thing blocking the merge of my work
> > on the Risch algorithm (see my integration3 branch) is not any
> > deficiency in the algorithm, though there are several parts that are
> > still not implemented, but the lack of a so called "atomic
> > substitution" framework.  The relevant issue here is 2026
> > (http://code.google.com/p/sympy/issues/detail?id=2026).
> >
> > Basically, the following breaks the preprocessing code in risch_integrate:
> >
> > In [1]: exp(2*x).subs(exp(x), y)
> > Out[1]:
> >  2
> > y
> >
> > I need a way for subs to behave exactly, so the above would return
> > exp(2*x).   Thus, I have disabled this completely in my integration3
> > branch, but this is only a temporary solution, as there is a lot of
> > code that relies on this behavior (especially in the series/limits
> > code), and it would be a regression anyway.
> 
> I have always thought that subs should not know about any mathematical
> relationships, but should behave as you are proposing (atomic or
> exact=True).  In my mind, subs is a foundation that can be used to
> build more advanced pattern matching and rule capabilities.  But those
> more advanced rules (such as done by power) should be in subs itself,
> but in that higher level.  Thus.

I agree. We need some way of performing direct replacements, based only
on the structure of the expression. We also need a way to transform
expressions while preserving their mathematical meaning. Currently,
subs() tries to do both, which causes most of the problems with it. 
> 
> I am +1 on the exact or atomic keyword to subs (I prefer exact).
> 
> I am ++1 on having that be the default behavior

-1 on adding keyword arguments. These are different operations that
require different interfaces and implementations. Lumping together
distinct functions under the same name via keyword switches always
creates a mess.
> 
> Cheers,
> 
> Brian
> 
> > So there needs to be a way to do
> >
> >>>> exp(2*x).subs(exp(x), y, atomic=True)
> > exp(2*x)
> >
> > Now, as it turns out, it has come up in other places that people want
> > control over the way that subs works in other ways.  In the issue, I
> > talk about something called integer_powers, which would work like
> >
> >>>> exp(2*x).subs(exp(x), y, integer_powers=True)
> > y**2
> >>>> exp(x).subs(exp(2*x), y, integer_powers=True)
> > exp(x)
> >
> > In other words, it does not do power manipulation in the replacement
> > unless the resulting power is an integer.  This is needed in some
> > places such as the heurisch algorithm to ensure that the resulting
> > expression will be a polynomial (actually, a rational function) in the
> > substitution variable.  In addition, there is also some concern about
> > the assumptions validity of certain algebraic substitution rules.  See
> > issues 2081 and 2552.
> >
> > So in the interest of doing this right, I think there needs to be some
> > kind of hints mechanism to subs.  My question is, what do you think
> > would be the best way to implement this?  Presently the expand
> > function has something like this, but I'm not really convinced that
> > the way that it's implemented is a very good one.
> >
> > Here's (roughly) the way that subs works now:  Basic defines two
> > methods, .subs and ._eval_subs.  Basic.subs() is of course the user
> > level function that everyone calls, and pretty much no subclass of
> > Basic overrides it.  The actual substitution happens in ._eval_subs,
> > which is also responsible for recursing the substitution down the
> > .args.  Basic has a simple implementation, but most classes end up
> > overriding it (for example, exp has overridden it to allow the above
> > fancy algebraic substitution).
> >
> > What's the best way to implement the various hints I want to add to
> > .subs()?  A few things to take into consideration:
> >
> > - .expand() works, as I mentioned earlier, by having
> > ._eval_expand_hint() methods.  I don't think this is the best way, so
> > that's why I'm asking here to see if anyone has any better ideas.
> >
> > - It should remain backwards compatible with any class that defines
> > ._eval_subs(self, old, new).  Unfortunately, there wasn't much
> > foresight when this was originally designed, so the protocol does not
> > call for any *args or **kwargs.  However, that doesn't necessarily
> > weigh those options out, as we could easily make Basic.subs() check
> > for an old style definition and ignore hints in that case.
> >
> > - I haven't looked at it, but we might be able to implement at least
> > atomic substitution entirely in Basic (no class need override any
> > methods to get it to work).  This is because it is so simple that the
> > default agnostic method might be able to do it entirely.  The rule for
> > atomic substitution by the way is that expr.subs(old, new,
> > atomic=True) should replace old with new in expr if and only if old is
> > in expr.atoms(old.__class__).
> >
> > So I'm open to any ideas on how to implement this, API-wise.
> >
> > Also, Chris, did you start this at all in any of your branches and/or
> > are you willing to help with this?
> >
> > 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.
> >
> >
> 
> 
> 
> -- 
> Brian E. Granger
> Cal Poly State University, San Luis Obispo
> bgran...@calpoly.edu and 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 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