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.

Reply via email to