In a project I'm working on I'm dealing with expressions containing complex exponentials such as the one below, which I aim to simplify as much as possible:
from sympy import Rational, exp, I, pi, pretty, cos, sin
E = Rational(1,20) + (Rational(1,4) + exp(2*I*pi/5)/4)*exp(-4*I*pi/5)/5 + exp(-2*I*pi/5)/20 + (exp(4*I*pi/5)/4 + exp(2*I*pi/5)/4)*exp(2*I*pi/5)/5 + (exp(-2*I*pi/5)/4 + exp(-4*I*pi/5)/4)*exp(4*I*pi/5)/5 + (exp(-4*I*pi/5)/4 + exp(4*I*pi/5)/4)*exp(-2*I*pi/5)/5
print(pretty(E))
⎛ 2⋅ⅈ⋅π⎞ ⎛ 4⋅ⅈ⋅π 2⋅ⅈ⋅π⎞ ⎛ -2⋅ⅈ⋅π -4⋅ⅈ⋅π ⎞ ⎛ -4⋅ⅈ⋅π 4⋅ⅈ⋅π⎞
⎜ ─────⎟ -4⋅ⅈ⋅π ⎜ ───── ─────⎟ 2⋅ⅈ⋅π ⎜ ─────── ───────⎟ 4⋅ⅈ⋅π ⎜ ─────── ─────⎟ -2⋅ⅈ⋅π
⎜ 5 ⎟ ─────── -2⋅ⅈ⋅π ⎜ 5 5 ⎟ ───── ⎜ 5 5 ⎟ ───── ⎜ 5 5 ⎟ ───────
⎜1 ℯ ⎟ 5 ─────── ⎜ℯ ℯ ⎟ 5 ⎜ℯ ℯ ⎟ 5 ⎜ℯ ℯ ⎟ 5
⎜─ + ──────⎟⋅ℯ 5 ⎜────── + ──────⎟⋅ℯ ⎜──────── + ────────⎟⋅ℯ ⎜──────── + ──────⎟⋅ℯ
1 ⎝4 4 ⎠ ℯ ⎝ 4 4 ⎠ ⎝ 4 4 ⎠ ⎝ 4 4 ⎠
── + ───────────────────── + ──────── + ──────────────────────── + ──────────────────────────── + ────────────────────────────
20 5 20 5 5 5
I managed to simplify it a bit (mostly by trial-and-error using different functions described on https://docs.sympy.org/latest/modules/simplify/simplify.html):
E.rewrite(cos).expand().simplify()
-sqrt(-10 - 2*sqrt(5))/64 - sqrt(-10 + 2*sqrt(5))/64 + sqrt(-50 + 10*sqrt(5))/320 + 3*sqrt(-50 - 10*sqrt(5))/320
print(pretty(_))
____________ ____________ _____________ _____________
╲╱ -10 - 2⋅√5 ╲╱ -10 + 2⋅√5 ╲╱ -50 + 10⋅√5 3⋅╲╱ -50 - 10⋅√5
- ────────────── - ────────────── + ─────────────── + ─────────────────
64 64 320 320
However, the resulting expression can still be simplified further, and in fact vanishes altogether — the question is how to do/show this in Sympy. I've tried using sqrtdenest
to "denest" the square roots, but so far no luck.
Likewise, another expression rather similar to the first one simplifies to
print(pretty(-cos(pi/7)/7 - sin(pi/14)/7 + Rational(1,14) + sin(3*pi/14)/7))
⎛π⎞ ⎛π ⎞ ⎛3⋅π⎞
cos⎜─⎟ sin⎜──⎟ sin⎜───⎟
⎝7⎠ ⎝14⎠ 1 ⎝ 14⎠
- ────── - ─────── + ── + ────────
7 7 14 7
Again, this expression vanishes, though I'm not getting to that point in Sympy. Any directions on how to proceed would be most welcome.
Firstly the simplest check for situations like this is to use approximate numerical evaluation:
In [2]: E.evalf()
Out[2]: -0.e-130 - 0.e-132⋅ⅈ
That strongly suggests that the result is zero.
This is used internally by the nsimplify
function:
In [3]: nsimplify(E)
Out[3]: 0
Another way to verify that the expression is zero without approximation is to compute its minimal polynomial:
In [4]: minpoly(E)
Out[4]: x
E must be a root of that polynomial and it only has one root (zero):
In [5]: roots(_)
Out[5]: {0: 1}
This expression does seem to be particularly awkward for normal manipulation so many possible ways to simplify it don't seem to work. This one does though:
In [25]: E.expand().rewrite(cos)
Out[25]: 0
I think that the main difficulty for most methods of simplification is the automatic evaluation of trig functions:
In [34]: exp(2*I*pi/5).rewrite(cos)
Out[34]:
________
1 √5 ╱ √5 5
- ─ + ── + ⅈ⋅ ╱ ── + ─
4 4 ╲╱ 8 8
If we use symbols in place of numbers then we can prevent that:
In [65]: En = E.subs(exp(2*I*pi/5), exp(n*I*pi/5))
In [66]: En.rewrite(cos).simplify().subs(n, 2)
Out[66]: 0