Ailurus
Ailurus

Reputation: 731

How to simplify expressions containing complex exponentials in Sympy

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.

Upvotes: 1

Views: 884

Answers (1)

Oscar Benjamin
Oscar Benjamin

Reputation: 14480

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

Upvotes: 4

Related Questions