What's the best practice for using simplify
?
#26217
-
Hi, I have a short code that computes the catacaustic of a circle, which should return a cardioid: from sympy import *
t, X, Y = symbols("t X Y")
x = cos(t)
y = sin(t)
curve = Matrix([x, y])
light_source = Matrix([1, 0])
ray = curve - light_source
dx = diff(x, t)
dy = diff(y, t)
n = Matrix([dy, -dx])
reflected_ray = simplify(ray - 2 * ray.dot(n) * n / n.dot(n))
F = (Y - y) * reflected_ray[0] - (X - x) * reflected_ray[1]
dF = diff(F, t)
result = solve((F, dF), X, Y)
print(f"X(t)={simplify(result[X])}")
print(f"Y(t)={simplify(result[Y])}") sympy returns the following result: X(t)=(-3*cos(t) + cos(3*t) + 2)/(6*(cos(t) - 1))
Y(t)=2*sin(t)**3/(3 - 3*cos(t)) The result is correct but it's not in the most simplified form, which should be I verified manually that the above is equivalent to the result by sympy. My question is, is there any possible improvement of my usage of sympy, so that I can get a more simplified form of the result? For example, to eliminate the denominator? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 3 replies
-
simplify() tries various simplification functions, but not all of them. To get better trig simplification you should use In this case, the >>> pprint(fu(result[X]))
2
2⋅sin(2⋅t) + sin(4⋅t) (cos(2⋅t) + 1) ⋅sin(2⋅t) 5⋅sin(2⋅t) sin(6⋅t) 4⋅sin(t)
──────────────────────── - ──────────────────────── - ──────────────────────── + ───────────────────────── + ───────────────────────
2⋅(-2⋅sin(t) + sin(2⋅t)) 3⋅(-2⋅sin(t) + sin(2⋅t)) 4⋅(-2⋅sin(t) + sin(2⋅t)) 12⋅(-2⋅sin(t) + sin(2⋅t)) -12⋅sin(t) + 6⋅sin(2⋅t) But the >>> pprint(trigsimp(result[X], method='groebner'))
2⋅cos(t) cos(2⋅t)
──────── + ────────
3 3 No doubt fu could be improved here. I would say this is a pretty catastrophic failure in its default heuristics. |
Beta Was this translation helpful? Give feedback.
-
I guess to be fair,
|
Beta Was this translation helpful? Give feedback.
-
Here is one possibility: In [19]: result[X].simplify().expand(trig=True).factor().trigsimp().factor()
Out[19]:
2⋅cos(t) + cos(2⋅t)
───────────────────
3 |
Beta Was this translation helpful? Give feedback.
simplify() tries various simplification functions, but not all of them. To get better trig simplification you should use
trigsimp
directly, and try the different options documented in themethod
argument https://docs.sympy.org/latest/modules/simplify/simplify.html#module-sympy.simplify.trigsimp. You can also use the exact simplification functions from the fu module if you know which ones you want. https://docs.sympy.org/latest/modules/simplify/fu.htmlIn this case, the
fu
function does a pretty bad job at simplifying this function: