Forma canonica

Consiste nella rappresentazione della forma quadratica mediante un polinomio omogeneo di secondo grado che sia privo di termini misti. Una forma quadratica si rappresenta in forma canonica rispetto ad una base \(\beta'\) se

\(Q(v) = \lambda_1 x_1' + \lambda_2 x_2' + ... + \lambda_n x_n'\)

dove \(\lambda_i\) sono gli scalari e \(x_i'\) sono le cordinate del vettore \(v\) rispetto alla base \(\beta'\).

La sua esistenza è garantita dal teorema degli assi principali: data una forma quadratica \(Q\) e una matrice \(A\) che la rappresenta rispetto ad una determinata base, esiste allora una base ortonormale \(\beta'\) formata da autovettori di \(A\) rispetto alla quale la base canonica si presenta in forma canonica:

\(Q(x_1',x_2',..,x_n') = \lambda_1 x_1'^2 + \lambda_2 x_2'^2 + ... + \lambda_n x_n'^2\)

dove \(x_i'\) sono le coordinate della base e \(\lambda_i\) sono gli autovalori della matrice \(A\) riportati riportati con la relativa molteplicità algebrica.

Riduzione alla forma canonica

  • Calcolare la matrice rappresentativa \(A\) della forma quadratica
  • Calcolarne gli autovalori di \(A\) (\(\lambda_i\)) e riportarli con la rispettiva molteplicità algebrica ottenendo:

\(Q(x_1',x_2',..,x_n') = \lambda_1 x_1'^2 + \lambda_2 x_2'^2 + ... + \lambda_n x_n'^2\)

  • Trovata la forma canonquadratica, calcolare la base \(\beta'\) ortonormale composta dagli autovettori di \(A\):
    • trovare gli autovettori degli autovalori che costituiranno la base \(\beta'\) (vedi sezione "Autovalori e autovettori")
    • ortogonalizzare la base \(\beta'\) tramite il processo di ortogonalizzazione di Gram-Shmidt (vedi sezione "Ortogonalizzazione di Gram-Shmidt"21)
    • ortonormalizzare la base dividendo ciascun vettore per la sua norma (vedi sezione "20 - Norma indotta da un prodotto scalare")

Forma normale

Consiste nella rappresentazione della forma quadratica mediante un polinomio omogeneo di secondo grado che sia privo di termini misti e tale che i coefficienti siano tutti pari a 1 o -1.

Una forma quadratica si rappresenta in forma normale rispetto ad una base \(\delta'\) se

\(Q(v) = x_1'^2 + x_2'^2 + ... + x_r'^2 - x_{r+1}'^2-...-x_{p}'^2\)

dove \(p\) e \(r \in \mathbb{N}\), \(0 \le r\), \(p \le n\), \(r+p \le n\) rappresentano rispettivamente il numero di coefficienti uguali a 1 e il numero di coefficienti uguali a -1. Se \(r+p < n\) allora i restanti \(n-r-p\) coefficienti sono necessariamente nulli.

Riduzione alla forma normale

  • Calcolare la matrice rappresentativa \(A\) della forma quadratica
  • Calcolarne gli autovalori di \(A\) (\(\lambda_i\))
  • Disporre sulla formula di sopra la forma normale in base al valore degli autovalori (positivi in somma e successivamente i negativi in sottrazione)
  • Trovare \(\beta'\) (base che realizza la forma canonica) (vedi riduzione alla forma canonica)
  • Si ricava la base che realizza la forma normale \(\delta\) facendo:

\(u_i = \frac{1}{\sqrt{\lambda_i}}v'_i\)

per ogni vettore della base dove \(u_i \in \delta\), \(v' \in \beta'\) e \(\lambda_i\) è il rispettivo autovalore.

Funzione riassumibile - Riduzione in forma canonica

def riduzioneInFormaCanonicaEBase(Q: Callable, forma_bilineare: List[tuple], base: sp.Matrix) -> dict:
    gamma = formaPolareDiFormaQuadratica(Q, forma_bilineare)
    A = matriceAssociataDiFormaBilineare(forma_bilineare, gamma, base)

    """Autovalori per le loro molteplicita per costruzione forma canonica"""
    eigen = autovaloriMolteplicita(A)
    forma_canonica = 0
    rix = 0
    for i, val in enumerate(eigen["autovalori"]):
        for j in range(eigen["molteplicitaAlgebriche"][i]):
            forma_canonica += val * forma_bilineare[0][rix]**2
            rix += 1

    """Ricerca base ortogonale rispetto agli autovettori"""
    base_autovettori = []
    for baseAutospazio in eigen["basiAutospazi"]:
        for i in range(baseAutospazio.shape[0]):
            base_autovettori.append(baseAutospazio.row(i))

    """Ortogonalizzazione di Gram Shmidt secondo prodotto scalare euclideo e successiva ortonormalizzazione"""
    definizione_prodotto_scalare_euclideo = 0
    for i in range(len(forma_bilineare[0])):
        definizione_prodotto_scalare_euclideo += forma_bilineare[0][i]*forma_bilineare[1][i]

    result = ortogonalizzazioneGramShmidt(forma_bilineare, definizione_prodotto_scalare_euclideo, base_autovettori)

    return {
        "formaCanonica": forma_canonica,
        "baseOrtonormale": result["baseOrtonormale"]
    }

Esempio

x1,x2,x3,y1,y2,y3 = sp.symbols("x1 x2 x3 y1 y2 y3")
forma_bilineare = [(x1,x2,x3),(y1,y2,y3)]
base = sp.eye(3)

def Q(_x1, _x2, _x3):
    return _x1**2 - 2*_x2**2 + _x3**2 + 6*_x1*_x3

result = riduzioneInFormaCanonicaEBase(Q, forma_bilineare, base)
pprint.pprint(result)

{'baseOrtonormale': [Matrix([[0, 0, 1]]), Matrix([[1, 0, 0]])], 'formaCanonica': 4*x12 - 2*x2*2 - 2x32}

La forma canonica corrisponde all'esercizio, mentre la base è differente a causa di un possibile errore nell'esercizio di riferimento a livello di costruzione della tabella sistema lineare per ottenere gli autovettori (un -2-4 diventa un 2 anziché diventare un -6). Sostituendo i vettori calcolati con quelli riscontrati nell'esercizio (base_autovettori = [sp.Matrix([[1,0,1]]),sp.Matrix([[-1,0,1]]),sp.Matrix([[0,1,0]])]) il risultato è:

{'baseOrtonormale': [Matrix([[sqrt(2)/2, 0, sqrt(2)/2]]), Matrix([[-sqrt(2)/2, 0, sqrt(2)/2]]), Matrix([[0, 1, 0]])], 'formaCanonica': 4*x12 - 2*x2*2 - 2x32}

la soluzione corrisponde.

Funzione riassumibile - Riduzione in forma normale

def riduzioneInFormaNormaleEBase(Q: Callable, forma_bilineare: List[tuple], base: sp.Matrix) -> sp.Expr:
    gamma = formaPolareDiFormaQuadratica(Q, forma_bilineare)
    A = matriceAssociataDiFormaBilineare(forma_bilineare, gamma, base)

    """Autovalori per le loro molteplicita"""
    eigen = autovaloriMolteplicita(A)
    scalari_forma_normale = []
    for i, val in enumerate(eigen["autovalori"]):
        for j in range(eigen["molteplicitaAlgebriche"][i]):
            scalari_forma_normale.append(val)

    """Costruzione forma normale"""
    forma_normale = 0
    for i, scalare in enumerate(scalari_forma_normale):
        forma_normale += forma_bilineare[0][i]**2 if scalare > 0 else -(forma_bilineare[0][i]**2)

    """Costruzione base realizzante la forma normale"""
    base_realizzante_forma_canonica = riduzioneInFormaCanonicaEBase(Q, forma_bilineare, base)["baseOrtonormale"]

    base_realizzante_forma_normale = sp.zeros(0,base_realizzante_forma_canonica[0].shape[1])
    rix = 0
    for i, val in enumerate(eigen["autovalori"]):
        for j in range(eigen["molteplicitaAlgebriche"][i]):
            u = (1/sp.sqrt(abs(val))) * base_realizzante_forma_canonica[rix]
            base_realizzante_forma_normale = base_realizzante_forma_normale.row_insert(rix, u)
            rix += 1

    return {
        "formaNormale": forma_normale,
        "baseOrtonormale": base_realizzante_forma_normale
    }

Esempio

x1,x2,x3,y1,y2,y3 = sp.symbols("x1 x2 x3 y1 y2 y3")
forma_bilineare = [(x1,x2,x3),(y1,y2,y3)]
base = sp.eye(3)

def Q(_x1, _x2, _x3):
    return _x1**2 - 2*_x2**2 + _x3**2 + 6*_x1*_x3

result = riduzioneInFormaNormaleEBase(Q, forma_bilineare, base)
pprint.pprint(result)

La forma normale corrisponde all'esercizio, c'è un possibile errore nel riferimento (vedasi sopra). Pertanto, sostituendo i vettori calcolati con quelli riscontrati (errati) nell'esercizio (base_autovettori = [sp.Matrix([[1,0,1]]),sp.Matrix([[-1,0,1]]),sp.Matrix([[0,1,0]])]) il risultato è:

{'baseOrtonormale': Matrix([ [sqrt(2)/4, 0, sqrt(2)/4], [ -1/2, 0, 1/2], [ 0, sqrt(2)/2, 0]]), 'formaNormale': x12 - x22 - x3**2}

la soluzione corrisponde.

Problemi

Diverse cose non tornano nei passaggi eseguiti nel riferimento. TODO: tornare successivamente per verificare in modo corretto l'effettivo funzionamento delle funzioni apportando eventuali correttivi.

Riferimenti

  • https://www.youmath.it/lezioni/algebra-lineare/applicazioni-lineari/3988-forma-canonica-e-forma-normale-di-una-forma-quadratica.html