\(A\) (matrice quadrata) è triangolarizzabile se e sole se esiste una matrice invertibile \(P\) dello stesso ordine tale che \(P^{-1}AP = T\), dove \(T\) è matrice triangolare superiore. \(P\) è la matrice triangolarizzante di \(A\). \(A\) è triangolarizzabile se i suoi autovalori appartengono allo stesso campo \(\mathbb{K}\) della matrice (per intenderci se degli autovalori hanno valore radice di -1, ossia l'unità immaginaria, allora non è triangolarizzabile in \(\mathbb{R}\)).
Se \(A\) è una matrice diagonalizzabile nel campo \(\mathbb{K}\) allora \(A\) è anche triangolarizzabile in \(\mathbb{K}\) e ne risulta che
def matriceTriangolare(A):
def dimensioneSottratta(basiAutospazi):
r = 0
for base in basiAutospazi:
r += base.shape[0]
return r
Avals = autovaloriMolteplicita(A)
if sp.I in Avals["autovalori"] or -sp.I in Avals["autovalori"]:
return {
"triangolarizzabile": False
}
"""Completamento: integra gli autovettori con la base canonica"""
beta = completamentoABase(Avals["basiAutospazi"], A.shape[1])
r = dimensioneSottratta(Avals["basiAutospazi"])
"""Matrice cambiamento base M da beta a base canonica"""
M = matriceCambiamentoBase(beta, sp.eye(A.shape[1]))
T = M**-1*A*M
if isUpperTriangular(T):
return {
"triangolarizzabile": True,
"matriceTriangolare": T,
"matriceTriangolarizzante": M
}
else:
def iterazoneMatriceBlocchi(T, M, r):
A1 = T.copy()
for i in range(r):
A1.col_del(0)
A1.row_del(0)
dim = A1.shape[1]
A1vals = autovaloriMolteplicita(A1)
if sp.I in Avals["autovalori"] or -sp.I in Avals["autovalori"]:
return {
"triangolarizzabile": False
}
"""Completamento: integra gli autovettori con la base canonica"""
beta1 = completamentoABase(A1vals["basiAutospazi"], A1.shape[1])
r1 = dimensioneSottratta(A1vals["basiAutospazi"])
"""Matrice cambiamento base M da beta a base canonica"""
M1 = matriceCambiamentoBase(beta1, sp.eye(dim))
"""C matrice a blocchi"""
C = sp.Matrix([[sp.eye(dim-1), sp.zeros(dim-1,dim)], [sp.zeros(dim,dim-1), M1]])
P1 = M*C
T1 = P1**-1*A*P1
if isUpperTriangular(T1):
return {
"triangolarizzabile": True,
"matriceTriangolare": T1,
"matriceTriangolarizzante": P1
}
else:
return iterazoneMatriceBlocchi(T1, M1, r1)
return iterazoneMatriceBlocchi(T, M, r)
A = sp.Matrix([[6,1,-3], [-2,9,-7], [-2,1,9]])
result = matriceTriangolare(A)
print(result)
{'matriceTriangolare': Matrix([ [8, -8, -1], [0, 8, -1], [0, 0, 8]]), 'matriceTriangolarizzante': Matrix([ [1, 1, 1], [2, 0, 0], [0, 2, 0]]), 'triangolarizzabile': True}
Come da esercizio
A = sp.Matrix([[1,0,0], [1,0,1], [1,-1,2]])
result = matriceTriangolare(A)
pprint.pprint(result)
{'matriceTriangolare': Matrix([ [1, 0, 0], [0, 1, 1], [0, 0, 1]]), 'matriceTriangolarizzante': Matrix([ [1, 0, 1], [1, 1, 0], [0, 1, 0]]), 'triangolarizzabile': True}
A = sp.Matrix([[1,2,0], [-1,-1,0], [2,3,1]])
result = matriceTriangolare(A)
pprint.pprint(result)
{'triangolarizzabile': False}