Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

evalf() returns symbolic expression or sum of complex conjugates #19615

Open
step135 opened this issue Jun 22, 2020 · 2 comments
Open

evalf() returns symbolic expression or sum of complex conjugates #19615

step135 opened this issue Jun 22, 2020 · 2 comments

Comments

@step135
Copy link

step135 commented Jun 22, 2020

M=sqrt(Matrix([
 [ 1, 1],
 [-1, 1]]))
print (M.evalf())

sqrt is not evaluated symbolically and neither evalf() is transforming it to numbers.

Compared to:

M=Matrix([
 [ 1, 1],
 [-1, 1]])**(1./2)
print (M.evalf())

Output here contains (1 - I)**0.5/2 + (1 + I)**0.5/2. That should be automatically simplified as it is possible: = sqrt(sqrt(2))*cos(pi/8) = sqrt(sqrt(2))*sqrt(sqrt(2)/4 + 1/2)

So according to examples there are three not related bugs by themselves:

  1. sqrt on Matrix doesn't count symbolic result, but **(1./2) does it
  2. evalf() doesn't transform symbolic expressions into numbers in some cases
  3. evalf() is providing sum of complex conjugates that is easy to simplify in many cases into real number, but it shows more complicated complex result
@oscarbenjamin
Copy link
Contributor

You need doit for the symbolic matrix square root:

In [29]: M=sqrt(Matrix([ 
    ...:  [ 1, 1], 
    ...:  [-1, 1]]))                                                                                                                           

In [30]: M                                                                                                                                     
Out[30]: 
         1/2
⎛⎡1   1⎤⎞   
⎜⎢     ⎥⎟   
⎝⎣-1  1⎦⎠   

In [31]: M.doit()                                                                                                                              
Out[31]: 
⎡     _______     _______           _______       _______⎤
⎢   ╲╱ 1 - ⅈ    ╲╱ 1 + ⅈ        ⅈ╲╱ 1 + ⅈ    ⅈ╲╱ 1 - ⅈ ⎥
⎢   ───────── + ─────────     - ─────────── + ───────────⎥
⎢       2           2                2             2     ⎥
⎢                                                        ⎥
⎢      _______       _______       _______     _______   ⎥
⎢  ⅈ╲╱ 1 - ⅈ    ⅈ╲╱ 1 + ⅈ      ╲╱ 1 - ⅈ    ╲╱ 1 + ⅈ    ⎥
⎢- ─────────── + ───────────     ───────── + ─────────   ⎥
⎣       2             2              2           2       ⎦

In [32]: M.doit().rewrite(exp)                                                                                                                 
Out[32]:-π           ⅈπ                ⅈπ            -π ⎤
⎢          ─────          ───                ───            ─────⎥
⎢   4 ___    8     4 ___   8        4 ___     8    4 ___      8  ⎥
⎢   ╲╱ 2 ℯ        ╲╱ 2 ℯ          ╲╱ 2 ℯ      ╲╱ 2 ℯ     ⎥
⎢   ──────────── + ──────────     - ──────────── + ──────────────⎥
⎢        2             2                 2               2       ⎥
⎢                                                                ⎥
⎢           -π             ⅈπ            -π           ⅈπ   ⎥
⎢           ─────            ───            ─────          ───   ⎥
⎢  4 ___      8     4 ___     8      4 ___    8     4 ___   8    ⎥
⎢  ╲╱ 2 ℯ        ╲╱ 2 ℯ        ╲╱ 2 ℯ        ╲╱ 2 ℯ      ⎥
⎢- ────────────── + ────────────     ──────────── + ──────────   ⎥
⎣        2               2                2             2

Unfortunately it isn't possible to rewrite that as cos because cos(pi/8) evaluates automatically:

In [36]: exp(I*pi/8)                                                                                                                           
Out[36]:π
 ───
  8 
ℯ   

In [37]: exp(I*pi/8).rewrite(cos)                                                                                                              
Out[37]: 
    ________         ________
   ╱ 2   11   2 
  ╱  ── ++  ╱  ─ - ── 
╲╱   4    2      ╲╱   2   4  

In [38]: cos(pi/8)                                                                                                                             
Out[38]: 
    ________
   ╱ 2   1 
  ╱  ── + ─ 
╲╱   4    2 

@step135
Copy link
Author

step135 commented Jun 22, 2020

Thanks, I just realized that sqrt compared to ** doesn't evaluate symbolically.

So points 2) and 3) refers still to bugs.
To 2) evalf() should evaluate expression even without doit().
To 3) the matrix is diagonalizable so there is sqrt on eigenvalues that are complex.

Sympy doesn't symbolically evaluate expressions of types (1+i)**(1./2). Eigenvalues are 1 + i and 1 - i.

It could learn to solve it automatically as = (sqrt(2)*exp(i*atan(1))**(1./2) = (sqrt(2)*exp(i*pi/4))**(1./2) = sqrt(sqrt(2))*exp(i*pi/8), because it knows all following identities needed: atan(1) = pi/4, exp(i*pi/4) = sqrt(2)/2*(1+i) and also cos(2*x) = 2*cos(x)^2 - 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants