Le basi ortogonali ma non ortonormali possono essere rese ortonormali dividendo i vettori della base per la loro norma.
Per il teorema di ortogonalizzazione di Gram-Shmidt: dato un prodotto scalare definito positivo \(\langle , \rangle: V \times V \to \mathbb{R}\) e un insieme di vettori linearmente indipendenti: \(v_1, v_2, ..,v_n \in V\)
Allora esistono altri vettori \(w_1,w_2,..,w_n \in V\) tali che:
Inoltre ogni spazio vettoriale di dimensione finita ammette almeno una base ortogonale rispetto ad un prodotto scalare definito positivo.
Corollario Questo deriva dal fatto che i vettori di una base \(\beta = \{v_n..\}\) sono linearmente indipendenti, quindi ne deriva, nei confronti di un prod.scal.def.posit., per il teorema di sopra l'insieme \(\{w_n..\}\) che è insieme ortogonale, e dato che \(Span(v_n..)=Span(w_n..)\) allora l'insieme \(\{w_n..\}\) è anche una base, oltre ad essere ortogonale.
Deriva dalla dimostrazione del teorema che:
\(w_1=v_1\)
\(w_2 = v_2 - \frac{\langle v_2,w_1\rangle}{\langle w_1,w_1\rangle}w_1\)
\(...\)
\(w_n = v_n - \frac{\langle v_n,w_1\rangle}{\langle w_1,w_1\rangle}w_1 - \frac{\langle v_n,w_2\rangle}{\langle w_2,w_2\rangle}w_2 - ... - \frac{\langle v_n,w_{n-1}\rangle}{\langle w_{n-1},w_{n-1}\rangle}w_{n-1}\)
In forma compatta:
\(w_1 = v_1\)
\(w_i = v_i - \sum_{j=1}^{i-1} \frac{\langle v_i,w_j \rangle}{\langle w_j,w_j \rangle}w_j\)
con \(i \in {2,3,..,n}\)
I vettori orrenuti \(\{w_1,..,w_n\}\) formano una base di \(V\) se \(\{v_1,..,v_n\}\) è una base di \(V\) (vedi corollario teorema). Può quindi essere ortonormalizzata dividendo i vettori per la norma.
Dati dei vettori di uno spazio \(V\), per determinare una base ortonormale di \(W\):
Matrice ortogonale: vedi sezione "Matrice ortogonale".
def ortogonalizzazioneGramShmidt(forma_bilineare, definizione, vettori):
base_ortogonale = []
if indipendenzaLineare(vettori):
w_1 = vettori[0]
base_ortogonale.append(w_1)
for i in range(1, len(vettori)):
v_n = vettori[i]
w_n0 = base_ortogonale[i-1]
vn_wn0 = definizione
for j in range(len(forma_bilineare[1])):
vn_wn0 = vn_wn0.subs(forma_bilineare[0][j], list(v_n)[j])
vn_wn0 = vn_wn0.subs(forma_bilineare[1][j], list(w_n0)[j])
wn0_wn0 = definizione
for j in range(len(forma_bilineare[1])):
wn0_wn0 = wn0_wn0.subs(forma_bilineare[0][j], list(w_n0)[j])
wn0_wn0 = wn0_wn0.subs(forma_bilineare[1][j], list(w_n0)[j])
w_n = v_n - (vn_wn0 / wn0_wn0) * w_n0
base_ortogonale.append(w_n)
base_ortonormale = []
for wn in base_ortogonale:
wn_norm = vettoreNormalizzato(forma_bilineare, definizione, wn, list(wn))
base_ortonormale.append(wn_norm)
return {
"baseOrtogonale": base_ortogonale,
"baseOrtonormale": base_ortonormale
}
else:
return False
x1,x2,x3,x4,y1,y2,y3,y4 = sp.symbols("x1 x2 x3 x4 y1 y2 y3 y4")
forma_bilineare = [(x1,x2,x3,x4), (y1,y2,y3,y4)]
definizione = x1*y1 + x2*y2 + x3*y3 + x4*y4
vettori = [
sp.Matrix([[1,1,0,0]]),
sp.Matrix([[1,0,0,0]]),
sp.Matrix([[0,0,0,1]])
]
result = ortogonalizzazioneGramShmidt(forma_bilineare, definizione, vettori)
pprint.pprint(result)
{'baseOrtogonale': [Matrix([[1, 1, 0, 0]]), Matrix([[1/2, -1/2, 0, 0]]), Matrix([[0, 0, 0, 1]])], 'baseOrtonormale': [Matrix([[sqrt(2)/2, sqrt(2)/2, 0, 0]]), Matrix([[sqrt(2)/2, -sqrt(2)/2, 0, 0]]), Matrix([[0, 0, 0, 1]])]}
Come da esercizio.
x1,x2,x3,x4,y1,y2,y3,y4 = sp.symbols("x1 x2 x3 x4 y1 y2 y3 y4")
forma_bilineare = [(x1,x2,x3), (y1,y2,y3)]
definizione = x1*y1 + x1*y3 + x2*y2 + x3*y1 + 2*x3*y3
vettori = [
sp.Matrix([[0,0,1]]),
sp.Matrix([[2,0,0]]),
sp.Matrix([[0,-1,0]])
]
result = ortogonalizzazioneGramShmidt(forma_bilineare, definizione, vettori)
pprint.pprint(result)
{'baseOrtogonale': [Matrix([[0, 0, 1]]), Matrix([[2, 0, -1]]), Matrix([[0, -1, 0]])], 'baseOrtonormale': [Matrix([[0, 0, sqrt(2)/2]]), Matrix([[sqrt(2), 0, -sqrt(2)/2]]), Matrix([[0, -1, 0]])]}
Come da esercizio.
def ortogonalizzazioneVettoreColonna(forma_bilineare, definizione, vettore_colonna):
base = completamentoABase([vettore_colonna.T], 3)
lista_base = []
for r in range(base.shape[0]):
lista_base.append(base.row(r))
base_ortogonale = ortogonalizzazioneGramShmidt(forma_bilineare, definizione, lista_base)["baseOrtonormale"]
matrice_risultante = sp.zeros(base_ortogonale[0].shape[1], len(base_ortogonale))
for i in range(base_ortogonale[0].shape[1]):
for j in range(len(base_ortogonale)):
matrice_risultante[i,j] = base_ortogonale[i][0, j]
if isMatriceOrtogonale(matrice_risultante) is True:
return matrice_risultante
else:
raise Exception("Il risultato non corrisponde ad una matrice ortogonale", matrice_risultante)
x1,x2,x3,x4,y1,y2,y3,y4 = sp.symbols("x1 x2 x3 x4 y1 y2 y3 y4")
forma_bilineare = [(x1,x2,x3), (y1,y2,y3)]
definizione = x1*y1 + x2*y2 + x3*y3
vettore_colonna = sp.Matrix([[sp.Rational('3/5'),sp.Rational('4/5'),0]]).T
result = ortogonalizzazioneVettoreColonna(forma_bilineare, definizione, vettore_colonna)
pprint.pprint(result)
Matrix([ [3/5, 4/5, 0], [4/5, -3/5, 0], [ 0, 0, 1]])
Come da esercizio.