# Why SageMath cannot inverte this matrix?

Here is a list of three self-adjoint commuting matrices I would like to simultaneously diagonalize:

SageMath version 8.9, Release Date: 2019-09-29
sage:  kk=QQ.algebraic_closure()
sage: L=[[[0,1,0,0,0,0,0,0],[1,4,0,1,1,1,1,0],[0,0,1,1,1,1,1,2],[0,1,1,1,1,1,1,2],[0,1,1,1,1,1,1,2],[0,1,1,1,1,1,1,2],[0,1,1,1,1,1,1,2],[0,0,2,2,2,2,2,3]],[[0,0,1,0,0,0,0,0],[0,0,1,1,1,1,1,2],[1,1,1,1,1,1,1,2],[0,1,1,2,1,1,1,2],[0,1,1,1,2,1,1,2],[0,1,1,1,1,2,1,2],[0,1,1,1,1,1,2,2],[0,2,2,2,2,2,2,3]], [[0,0,0,1,0,0,0,0],[0,1,1,1,1,1,1,2],[0,1,1,2,1,1,1,2],[1,1,2,0,0,2,3,2],[0,1,1,0,2,2,2,2],[0,1,1,2,2,1,1,2],[0,1,1,3,2,1,0,2],[0,2,2,2,2,2,2,4]]]
sage: M=[matrix(kk,l) for l in L]
sage: M
[
[0 1 0 0 0 0 0 0]  [0 0 1 0 0 0 0 0]  [0 0 0 1 0 0 0 0]
[1 4 0 1 1 1 1 0]  [0 0 1 1 1 1 1 2]  [0 1 1 1 1 1 1 2]
[0 0 1 1 1 1 1 2]  [1 1 1 1 1 1 1 2]  [0 1 1 2 1 1 1 2]
[0 1 1 1 1 1 1 2]  [0 1 1 2 1 1 1 2]  [1 1 2 0 0 2 3 2]
[0 1 1 1 1 1 1 2]  [0 1 1 1 2 1 1 2]  [0 1 1 0 2 2 2 2]
[0 1 1 1 1 1 1 2]  [0 1 1 1 1 2 1 2]  [0 1 1 2 2 1 1 2]
[0 1 1 1 1 1 1 2]  [0 1 1 1 1 1 2 2]  [0 1 1 3 2 1 0 2]
[0 0 2 2 2 2 2 3], [0 2 2 2 2 2 2 3], [0 2 2 2 2 2 2 4]
]


I applied the following process to find the appropriate change of basis matrix p:

sage: p=identity_matrix(kk,8)
sage: q=~p
sage: for m in M:
....:     a=q*m*p
....:     da, pa = a.jordan_form(transformation=True)
....:     p=p*pa
....:     q=~p


But the process does not finish (quickly enough, as expected), if I break it (Ctrl+C) after 5 minutes, I get:

sage: p
[1  1  1  1  1  1  1.000000000000000?  1]
[0  0  0 -0.2360679774997897?  4.236067977499789?  -1  0  9]
[1  1  1  -1  -1  0  1.000000000000000?  10]
[-3.959901309262505? -0.4551399712853820? -0.3198201782016355? 0 0 1 1.734861458749522? 11]
[-1.747468453907949?  0.1971262975999527?  1.126757059617217? 0 0 1 -2.576414903309221? 11]
[1.441290910412462?  0.5668886275946296? -2.523095590631670? 0 0 1 -0.4850839473754211? 11]
[3.266078852757992?  -1.308874953909201?  0.7161587092160885? 0 0 1 0.3266373919351204? 11]
[0  0  0  0.618033988749895?  -1.618033988749895?  -2  0  18]


[I removed spaces between entries for p being more readable]
and in fact the problem is that SageMath cannot inverte p, the following does not finish (after several hours):

sage: q=~p


whereas the matrix p is invertible:

sage: det(p)
97930.0?


Questions: What is the problem? How to solve it?

By applying the answer of @rburing I get the following:

sage: sigma=K.embeddings(QQbar)[0]
sage: P=p.apply_map(sigma)
sage: P
[    1     1     1     1     1     1     1     1]
[    9    -1     0     0     0     0 0.?e7 0.?e7]
[   10     0     1     1     1     1    -1    -1]
[   11     1 0.?e7 0.?e7 0.?e6 0.?e8     0     0]
[   11     1 0.?e8 0.?e7 0.?e7 0.?e7     0     0]
[   11     1 0.?e8 0.?e7 0.?e8 0.?e7     0     0]
[   11     1 0.?e8 0.?e7 0.?e7 0.?e8     0     0]
[   18    -2     0     0     0     0 0.?e7 0.?e7]
sage: Q=q.apply_map(sigma)
sage: Q*M[0]*P
[    9     0     0     0     0     0     0     0]
[    0    -1     0     0     0     0     0     0]
[    0     0     0     0     0     0     0     0]
[    0     0     0     0     0     0     0     0]
[    0     0     0     0     0     0     0     0]
[    0     0     0     0     0     0     0     0]
[    0     0     0     0     0     0 0.?e7     0]
[    0     0     0     0     0     0     0 0.?e7]


whereas

sage: M[0].eigenvalues()
[9, -1, 0, 0, 0, 0, -0.2360679774997897?, 4.236067977499789?]


How to make this method working better?

edit retag close merge delete

Sort by » oldest newest most voted

Since $\bar{\mathbb{Q}}$ is a little big, try instead working in a number field $K$ that's big enough but as small as possible:

M = [matrix(QQ,l) for l in L]
K,_,_ = number_field_elements_from_algebraics(sum([m.eigenvalues() for m in M], []), minimal=True)
print(K)
p = identity_matrix(K,8)
q = ~p
for m in M:
a = q*m*p
da, pa = a.change_ring(K).jordan_form(transformation=True)
p = p*pa
q = ~p


Here $K$ is an abstract number field of degree $48$ with several (i.e. $48$) different embeddings into $\bar{\mathbb{Q}}$.

sage: set([sigma(p.det()) for sigma in K.embeddings(QQbar)])
{-97929.96732359303?, 97929.96732359303?}


For a given sigma in K.embeddings(QQbar), you can embed p and q by p.apply_map(sigma) and q.apply_map(sigma); those matrices are defined over QQbar and they simultaneously diagonalize all m in M.

more

It does not work well in practice for me (see my edit).

( 2019-11-16 17:25:34 +0200 )edit
1

It is working, but there seems to be some kind of bug in displaying the algebraic numbers. For example if you define S = Q*M[0]*P then set(S.diagonal()) == set(M[0].eigenvalues()) is True, and the workaround S.apply_map(lambda z: z.interval(CIF)) shows the matrix correctly.

( 2019-11-16 17:39:38 +0200 )edit

Yes it works well using CIF. Thanks! Now I did not really understood why SageMath was not able to invert that matrix p initially. You wrote "$\bar{\mathbb{Q}}$ is little big", ok, but what really happened with this specific matrix p? [because the inversion worked in many similar looking matrices]

( 2019-11-16 19:50:17 +0200 )edit

You're welcome. That it takes a long time doesn't mean SageMath is not able to do it. Your original code works on my machine; it took 1 hour and 12 minutes.

( 2019-11-20 12:33:03 +0200 )edit