# Revision history [back]

If the matrix is diagonalizable, the following works:

sage: def pow(D,k):
...       return diagonal_matrix([l^k for l in D.diagonal()])

sage: D,P=M.jordan_form(transformation=True)
sage: show(P*pow(D,k)*~P)


It gets more messy if the matrix admits a jordan form in Q, and it needs some patching if some eigenvalues are in QQbar\QQ, because there are no canonical coercions between QQbar and SR, the likely parent of the final result. Code like the following did the trick:

sage: D,P = M.base_extend(QQbar).jordan_form(transformation = True)
sage: matriz = (P.apply_map(lambda l:SR(l))*powJordan(D,k).apply_map(lambda l:SR(l))*(~P).apply_map(lambda l:SR(l)))


apply_map is used because base_extend does not work, for the reasons mentioned above.

powJordan could be for example like this:

sage: def powJordan(D, k):
...       '''Eleva una matriz de Jordan (no necesariamente diagonal) a una variable simbolica'''
...
...       dim = D.ncols()
...       M = matrix(SR, dim, dim)
...
...       i = 0
...       while i<=dim-1:
...           #Autovalores simples, o con multiplicidad algebraica == multiplicidad geometrica
...           if (i== dim-1) or D[i,i+1] == 0:
...               M[i,i] = SR(D[i,i])^k
...               i = i + 1
...           else: #buscamos la dimension del subespacio invariante
...               counter = 1
...               for j in range(i, dim-1):
...                   if D[j,j+1] == 0:
...                       break
...                   counter += 1
...               for j in srange(i, i+counter):
...                   for t in srange(j,(i+counter)):
...                       M[j,t] = binomial(k, t-j)*SR(D[i,i])^(k-(t-j))
...               i += counter
...
...       return M


I have to say, I'm not fully satisfied with the solution, but it might work for you as it did for me.