On Tue, Feb 23, 2016 at 5:43 PM, Nolan Dyck <[email protected]> wrote: > Great. Thanks Aaron and Brombo for your replies. I have a few follow up > questions: > > I'd like to add in those checks into the assumptions system for hyperbolic > functions at least. Is that a reasonable entry level task?
Yes. It's pretty much just what I showed here. > I noticed that code sample you gave checks the is_real field on the first > argument. Is there an is_positive field I could check so that sinh and > other functions could also be simplified in some cases (i.e. x is positive, > Abs(sinh(x)) -> sinh(x))? Yes. These are all the assumptions http://docs.sympy.org/latest/modules/core.html?highlight=assumptions#module-sympy.core.assumptions. Aaron Meurer > > Nolan > > > On Tuesday, February 23, 2016 at 3:19:09 PM UTC-5, Aaron Meurer wrote: >> >> For cosh, it should just be handled by the assumptions system. That >> is, cosh should have >> >> def _eval_is_nonnegative(self): >> if self.args[0].is_real: >> return True >> >> (and similar for the new assumptions _eval_refine). >> >> On Mon, Feb 22, 2016 at 9:44 PM, Nolan Dyck <[email protected]> wrote: >> > Hi Everyone, >> > >> > I've been poking around in the sympy source, and I've noticed that the >> > `simplify` command does not deal with expressions like the following: >> > >> >>>> from sympy import * >> >>>> from sympy.abc import x >> >>>> simplify(abs(cosh(x))) >> > Abs(cosh(x)) >> > >> > A simple glance at the graph of cosh(x) reveals that Abs(cosh(x)) == >> > cosh(x). So, in case it's not obvious the above expression should >> > return: >> > >> > cosh(x) >> > >> > I'd like to take a stab at implementing this but I need some direction. >> > I >> > hope this isn't duplicating something I have stupidly missed (the >> > inequality >> > solvers don't seem to identify cases where absolute value brackets are >> > unnecessary. There are three key cases (as far as I can see): >> >> To do anything nontrivial in this area the inequality solvers will >> definitely need to be improved. >> >> > >> > The argument within the abs brackets is non-negative over all >> > combinations >> > of all independent variables. Therefore, the absolute value brackets >> > redundant / unnecessary and may be removed. >> > The argument within the abs brackets is non-positive over all >> > combinations >> > of all independent variables. Therefore, the absolute value brackets may >> > be >> > removed and the expression may be multiplied by -1 for the same effect. >> > The argument within the abs brackets contains both positive and negative >> > values depending on the values of the independent variables. >> > >> > Ok, so to implement the above rules in the general sense it makes sense >> > to >> > me to perform the following steps given the expression >> > Abs(f(x_1,x_2,...x_n)): >> > >> > Determine the number of real roots of f(x). >> > >> > If there are one or more real roots then for each root: >> > >> > Determine whether the gradient of f(x) is zero: >> > >> > If non-zero slope at root, then argument expression obtains opposite >> > signed >> > value at some point, so return Abs(f(x)) >> > >> > Slope of f(x) at root is 0. >> > Determine if the root is an inflection point (need to figure out exactly >> > how >> > to test for this over multiple variables in the expression) >> > >> > If at inflection point then the expression will still become opposite >> > signed >> > on either side of the root, so return Abs(f(x)) >> > >> > Any and all roots coincide with extrema values of f(x). Therefore f(x) >> > may >> > be represented without absolute value brackets. >> > >> > If f(x) >= 0 remove the absolute value brackets and return the argument >> > expression. >> > If f(x) < 0 remove the absolute value brackets, multiply the expression >> > by >> > -1 and return it. >> > >> > There are a few things which I'm not sure how it will work out: >> >> This algorithm only works if the function is real and differentiable >> over the given domain. >> >> > >> > Imaginary numbers. Does anyone know if I will need to write special code >> > for >> > this, or should the above procedure work out anyway? >> > The case where a symbol in the expression has been defined with the >> > positive >> > flag: >> > >> >>>> y = Symbol('y') >> >>>> simplify(abs(sinh(y))) >> > Abs(sinh(y)) >> > >> >>>> y = Symbol('y',positive=True) >> >>>> simplify(abs(sinh(y))) >> > sinh(y) >> > >> > Are there sneaky ways of determining in a precise manner whether a >> > function >> > which cannot be reduced (e.g. cosh(x)+cos(x)) has real roots, even if >> > finding those roots would only be possible numerically? Is there another >> > sympy module which can help with this? >> >> solveset aims to give a full set of solutions to an equation over an >> equation (compared with solve(), which makes no guarantees about >> giving all solutions). It's a difficult problem, though, and so far it >> is limited in what it can do. >> >> > What about variables which produce no real roots over a given range? Is >> > there a way to handle those? E.g. >> > >> >>>> y = Symbol('y',range=[0,pi]) >> >>>> simplify(abs(sin(y))) >> > sin(y) >> >> For a continuous function, you only need to check the intervals >> between the zeros. You can find all the zeros of sin(y) in the range >> [0, pi] (0 and pi), so you only have to check a value between them. >> >> I don't know if this is necessarily the best way to implement this in >> SymPy (one needs the ability to determine if a function is continuous, >> and to find all its roots). At any rate, Symbol doesn't have a "range" >> argument currently. You can use solveset(sin(y), y, domain=Interval(0, >> pi)) (note there is a bug with this in master >> https://github.com/sympy/sympy/issues/10671). >> >> > >> > Redundant absolute value brackets are removed somewhere. Can anyone tell >> > me >> > where exactly in the code this happens in the simplify function? I can't >> > seem to find it: >> >> It happens in the Abs constructor, i.e., when you create the Abs. Abs >> is defined in sympy.functions.elementary.complexes. >> >> > >> >>>> from sympy.abc import x >> >>>> simplify(abs(abs(x)+1)) >> > Abs(x) + 1 >> >>>> simplify(abs(x+1)) >> > Abs(x + 1) >> > >> > So, right now I have forked the sympy repo (see here) and set up my own >> > little function in sympy.symplify called abssimp.py (just copied >> > combsimp.py >> > and started from there), and added an appropriate if-absolute check in >> > the >> > main simplify function. Is this the right way to go about adding such a >> > feature? Would the code that I write here also be used in solve or >> > something? >> > >> > Any guidance / advice would be appreciated. >> > >> > Thanks! >> > Nolan Dyck >> > >> > -- >> > 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 [email protected]. >> > To post to this group, send email to [email protected]. >> > Visit this group at https://groups.google.com/group/sympy. >> > To view this discussion on the web visit >> > >> > https://groups.google.com/d/msgid/sympy/aeb34566-d4b8-46f4-8eb5-f7acabbd12f4%40googlegroups.com. >> > 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 [email protected]. > To post to this group, send email to [email protected]. > Visit this group at https://groups.google.com/group/sympy. > To view this discussion on the web visit > https://groups.google.com/d/msgid/sympy/f41292b5-6d52-4ae5-b7bb-87b7c6d9b807%40googlegroups.com. > > 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 [email protected]. To post to this group, send email to [email protected]. Visit this group at https://groups.google.com/group/sympy. To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/CAKgW%3D6K%3D9%2BgGHoCwhWRaE0cKbmw27wYAZZeKsi9ByPhwLZ6iGA%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.
