auntyellow
auntyellow

Reputation: 2573

how can I tell SymPy that some terms are positive then make SymPy simplify `sqrt(x^2)` to `x` where `x` may be a complicated term?

I'm solving the problem is in section Auxiliary Elements in Polya's How to Solve It:

Construct a triangle, being given one angle (A), the altitude (h) drawn from the vertex of the given angle, and the perimeter (p) of the triangle.

I get the solution below, and try to verify it by SymPy:

from sympy import *

h, p, A = symbols("h p A", positive=True)
u = sqrt(h * p * p / 2 / (h + h * cos(A) + p * sin(A)))
v = (p - u * u * sin(A) / h) / 2
y = v + sqrt(v * v - u * u)
z = v - sqrt(v * v - u * u)
x = sqrt(y * y + z * z - 2 * y * z * cos(A))
# x, y, z are solutions

# now verify them:
print("x + y + z =", simplify(x + y + z))

The expected result should be x + y + z = p but the actual output is a bit complicated:

x + y + z = (-p**2*sin(A)/2 + (4*p + 2*sqrt(p**4*sin(A)**2/(h*cos(A) + h + p*sin(A))**2))*(h*cos(A) + h + p*sin(A))/4)/(h*cos(A) + h + p*sin(A))

Here I notice that sqrt(p**4*sin(A)**2/(h*cos(A) + h + p*sin(A))**2) are not simplified to p**2*sin(A)/(h*cos(A) + h + p*sin(A)) because SymPy doesn't know whether sin(A) and h*cos(A) + h + p*sin(A) are positive.

How could I set some parameter to simplify() method to make SymPy do the reasonable simplification with some condition (e.g. some terms are positive so that sqrt() can be simplified)?

I refer Sympy - Simplify expression within domain but it doesn't seem to work.

Upvotes: 2

Views: 71

Answers (1)

Oscar Benjamin
Oscar Benjamin

Reputation: 14530

One way to do this would be to make positive symbols for sin(A) and cos(A) e.g.:

sinA, cosA = symbols('sinA, cosA', positive=True)

You could use those while simplifying and substitute for them after.

Another way that will work for some cases is to use refine e.g.:

In [8]: res = simplify(x + y + z)

In [9]: res
Out[9]: 
  ⎛            ⎛  │         sin(A)        │    ⎞                          ⎞
p⋅⎜-p⋅sin(A) + ⎜p⋅│───────────────────────│ + 2⎟⋅(h⋅cos(A) + h + p⋅sin(A))⎟
  ⎝            ⎝  │h⋅cos(A) + h + p⋅sin(A)│    ⎠                          ⎠
───────────────────────────────────────────────────────────────────────────
                        2⋅(h⋅cos(A) + h + p⋅sin(A))                        

In [10]: refine(res, Q.positive(sin(A)) & Q.positive(cos(A)))
Out[10]: 
  ⎛            ⎛        p⋅sin(A)           ⎞                          ⎞
p⋅⎜-p⋅sin(A) + ⎜─────────────────────── + 2⎟⋅(h⋅cos(A) + h + p⋅sin(A))⎟
  ⎝            ⎝h⋅cos(A) + h + p⋅sin(A)    ⎠                          ⎠
───────────────────────────────────────────────────────────────────────
                      2⋅(h⋅cos(A) + h + p⋅sin(A)) 

Upvotes: 3

Related Questions