@Jason: Already done :) @ Aaron: Thanks for the code review. A generator expression is much cleaner, I need to use those more often. I looked through the sympy codebase first trying to find a reusable tool for this, but couldn't. There's preorder_traversal, but that doesn't help with recursive code. There's also the strategies submodule that Matthew added which looks useful, but I couldn't figure out how to use it.
On Thursday, July 3, 2014 11:12:55 AM UTC-5, James Crist wrote: > > Checking for these conditions in general would prove extremely tricky. > I've updated the gist with my code for limited checking. If you have a > chance, it would be nice to get review of the whole thing. Right now I > think it's the best I can do without some significant work. > > The algorithm I'm using requires two traversals > > *First pass:* > Replace all `tan` with `sin/cos`. This makes checking for the divide by 0 > conditions easier, as there is a visible fraction > > *Second pass:* > If the node is a fraction, evaluate the denominator first. If the > denominator evaluates to 0, apply simplify to the fraction expression, and > then continue on with subs as before. This is simple, but works for most of > the expressions I've tried it on. It doesn't work on anything that can't be > simplified down to a something that won't result in nan, but for mechanics > this seems to work out fine. It also only simplifies bad sub expressions, > reducing the amount of computation needed. > > On Thursday, July 3, 2014 10:42:49 AM UTC-5, Aaron Meurer wrote: >> >> This is considered expected behavior. You can't get limit values just >> by substituting in values. You either need to rewrite the expression >> so that you do not have an indeterminant, or else use the limit >> algorithm. >> >> Using heuristics is also a bad idea. limit() itself used to use a lot >> of heuristics (maybe it even still does), and it had a ton of wrong >> results. >> >> You might be able to structure your mechanics algorithms so that they >> avoid expressions like that. An idea for this particular case is to >> never use tan, only sin/cos. I don't know if that generalizes, though. >> >> Aaron Meurer >> >> On Thu, Jul 3, 2014 at 8:05 AM, Jason Moore <moore...@gmail.com> wrote: >> > Also, >> > >> >>>> sin(a)/tan(a).subs(a, 0) >> > nan >> >>>> simplify(sin(a)/tan(a)).subs(a, 0) >> > 1 >> > >> > needs to be solved for SymPy in general I believe. That seems like a >> > bug on face value. But I guess could be expected behavior...? Not >> > sure. Would ensuring that numerators get subbed before denominators >> > solve that? Or would the limit as a goes to zero be the only way to >> > get the correct answer? >> > >> > >> > Jason >> > moorepants.info >> > +01 530-601-9791 >> > >> > >> > On Thu, Jul 3, 2014 at 9:00 AM, Jason Moore <moore...@gmail.com> >> wrote: >> >> Yeah, it looks good. I've totally been needing this for some work I'm >> doing >> >> too. The fact that mechanics expressions are a small subset of sympy >> >> expressions is a good reason to optimize stuff like this. >> >> >> >> In the docstring 3.) trig_funcs aren't the only type of functions. I >> think >> >> you will need to assume that any function (standard sympy ones or >> custom >> >> funcs) can be present in expressions. Just something to keep in mind. >> >> >> >> >> >> Jason >> >> moorepants.info >> >> +01 530-601-9791 >> >> >> >> >> >> On Wed, Jul 2, 2014 at 11:55 PM, Aaron Meurer <asme...@gmail.com> >> wrote: >> >>> >> >>> I think it looks good. You can probably can probably do better by >> >>> creating a generator comprehension rather than creating and indexing >> >>> into a list (and it's also more pythonic). crawl() is a pretty >> common >> >>> pattern. I'm sure you could find an existing version in the SymPy >> code >> >>> already. >> >>> >> >>> Also, at line 54, you don't need to assign to val. Just return >> >>> sub_dict[expr]. >> >>> >> >>> At line 56, I think what you really want is "if not expr.args". There >> >>> are more types of expressions without args than just Symbol and >> >>> Number. >> >>> >> >>> The important thing is to avoid walking the expression tree multiple >> >>> times. Ideally, you would walk it only once. I think you are here. >> >>> >> >>> Aaron Meurer >> >>> >> >>> On Wed, Jul 2, 2014 at 9:10 PM, James Crist <cris...@umn.edu> wrote: >> >>> > I wrote this up today. In physics.mechanics we often have to sub >> symbols >> >>> > for >> >>> > values (or a smaller subset of symbols, i.e. the "operating >> point"). For >> >>> > the >> >>> > huge expressions generated, `subs` is extremely slow. Also, it subs >> >>> > inside >> >>> > derivatives, which is not ideal (we are currently using a hacky >> >>> > work-around). It also seems to be overkill for what's needed. More >> >>> > details >> >>> > are in the docstring of the attached gist. >> >>> > >> >>> > https://gist.github.com/jcrist/8ce1a79dfe0b42723550 >> >>> > >> >>> > I'd like some serious code design review of this. Is what I'm doing >> >>> > (direct >> >>> > naive replacement) bad? Is there a better way, that doesn't >> sacrifice >> >>> > speed? >> >>> > Note that for expressions of this size, xreplace, replace, and subs >> all >> >>> > perform equally poorly. >> >>> > >> >>> > >> >>> > -- >> >>> > You received this message because you are subscribed to the Google >> >>> > Groups >> >>> > "PyDy" group. >> >>> > To unsubscribe from this group and stop receiving emails from it, >> send >> >>> > an >> >>> > email to pydy+uns...@googlegroups.com. >> >>> > To post to this group, send email to py...@googlegroups.com. >> >>> > Visit this group at http://groups.google.com/group/pydy. >> >>> > For more options, visit https://groups.google.com/d/optout. >> >>> >> >>> -- >> >>> You received this message because you are subscribed to the Google >> Groups >> >>> "PyDy" group. >> >>> To unsubscribe from this group and stop receiving emails from it, >> send an >> >>> email to pydy+uns...@googlegroups.com. >> >>> To post to this group, send email to py...@googlegroups.com. >> >>> Visit this group at http://groups.google.com/group/pydy. >> >>> For more options, visit https://groups.google.com/d/optout. >> >> >> >> >> > >> > -- >> > You received this message because you are subscribed to the Google >> Groups "PyDy" group. >> > To unsubscribe from this group and stop receiving emails from it, send >> an email to pydy+uns...@googlegroups.com. >> > To post to this group, send email to py...@googlegroups.com. >> > Visit this group at http://groups.google.com/group/pydy. >> > For more options, visit https://groups.google.com/d/optout. >> > -- You received this message because you are subscribed to the Google Groups "sympy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sympy+unsubscr...@googlegroups.com. To post to this group, send email to sympy@googlegroups.com. Visit this group at http://groups.google.com/group/sympy. To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/b771b35e-cd5d-43b0-b5eb-62110bfa1338%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.