On Tue, Mar 30, 2021 at 9:39 AM 'B A' via sympy <sympy@googlegroups.com> wrote: > > Here is one solution that seems to work. To simplify Z I use Z.replace(Abs, > MyAbs) with > > def MyAbs(x): > x1=symbols('x1',real=True,positive=True) > x1 = x.evalf(subs={a:0.573}) > if x1 < 0.0: > return S(-1)*x > else: > return x > Is this a reasonable way to go, or are there gotchas that I should be aware > of?
A few minor points. - Defining x1 as a symbol does nothing in this code, as you immediately overwrite it with x.evalf(...). - S(-1) is unnecessary. You can just use -x. - Your code assumes that the expression is a function in the variable a (and only a). But perhaps that assumption is fine for your use-case. The main gotcha however is that the code is wrong if the abs is positive for that specific value of a but not for the general domain of a. A more robust way would be to use the maximum() and minimum() functions to get the maximum and minimum values of the abs argument on the interval [0, 1]: >>> maximum(2*a**2 - 1, a, Interval(0, 1)) 1 >>> minimum(2*a**2 - 1, a, Interval(0, 1)) -1 This tells you that abs(2*a**2 - 1) cannot be simplified like this for a in [0, 1], because it is both positive and negative on that interval. To simplify it, you would need to factor it or write it as a piecewise. Aaron Meurer > On Sunday, March 28, 2021 at 11:14:57 AM UTC+2 B A wrote: >> >> I am a sympy beginner, and fairly new to python, so I suspect that my >> question has a simple answer, but have not been able to figure it out >> myself. >> >> I have sympy expressions containing the built-in Abs function. The arguments >> of Abs() are polynomials in a=symbol('a', real=True,positive=True) . Here >> are a three examples: >> >> Abs(a**2 + 2) >> sqrt(2)*Abs(2*a**2 - 1)/3 >> sqrt(2)*(a + 1)*Abs(a - 1)/3 >> >> Here's the point: I know that 'a' is approximately 0.6. So in cases where >> the argument of Abs has an unambiguous sign (within floating-point >> precision) I would like to simplify the absolute value. For example in the >> three cases above I would like: >> >> Abs(a**2 + 2) -> a**2 + 2 >> sqrt(2)*Abs(2*a**2 - 1)/3 -> sqrt(2)*(1- 2*a**2)/3 >> sqrt(2)*(a + 1)*Abs(a - 1)/3 -> sqrt(2)*(a + 1)*(1-a)/3 >> >> where the right arrow '->' indicates replacement or simplification. Note >> the change of sign in the second and third examples, because (for example) I >> know that (a-1) is negative. >> >> Is there a (simple) way to implement this? >> >> Thank you! >> Bruce > > -- > 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 view this discussion on the web visit > https://groups.google.com/d/msgid/sympy/5c6a7de4-e709-4a8c-88f1-ce3f44ee277an%40googlegroups.com. -- 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 view this discussion on the web visit https://groups.google.com/d/msgid/sympy/CAKgW%3D6LBxw1%2B8qnwTcVo1s9ozNVi2U9%3D%3DPUnyTUMj_YxDJ34Aw%40mail.gmail.com.