Vamos aqui implementar o processo de ortonormalização de Gram-Schmidt numa linguagem de programação. Vamos admitir fixada uma base ortonormal e que os vetores são dados em coordenadas nessa base.
a) Escreva uma função que recebe dois vetores e retorna o produto escalar entre eles.
b) Escreva uma função que recebe um vetor e retorna seu comprimento.
c) Usando as funções acima, escreva uma função que recebe dois vetores e determina a projeção ortogonal do primeiro vetor sobre o segundo.
d) Com tudo isso, escreva uma função que recebe três vetores, supostamente L.I., que devolve uma base para
com vetores mutuamente ortogonais, com pelo menos um deles paralelo a algum dos vetores originais.
Discussão: O que você espera como resultado, caso os vetores dados sejam linearmente dependentes? Justifique.
e) Escreva agora uma função que retorna uma base ortonormal de
a partir de três vetores dados, supostamente L.I.
Discussão: O que você espera como resultado, caso os vetores fornecidos sejam L.D.? Justifique.
a) Escreva uma função que recebe dois vetores e retorna o produto escalar entre eles.
b) Escreva uma função que recebe um vetor e retorna seu comprimento.
c) Usando as funções acima, escreva uma função que recebe dois vetores e determina a projeção ortogonal do primeiro vetor sobre o segundo.
d) Com tudo isso, escreva uma função que recebe três vetores, supostamente L.I., que devolve uma base para
Discussão: O que você espera como resultado, caso os vetores dados sejam linearmente dependentes? Justifique.
e) Escreva agora uma função que retorna uma base ortonormal de
Discussão: O que você espera como resultado, caso os vetores fornecidos sejam L.D.? Justifique.
Passo 1
O enunciado pede para implementar o processo de Gram–Schmidt em cinco funções, cada uma correspondendo a um ponto (a)–(e). O conteúdo é Álgebra Linear (produto escalar, norma, projeção e ortonormalização). Vamos precisar das seguintes ideias:
. Produto escalar em
:
.
. Norma (comprimento):
.
. Projeção ortogonal:
.
. Gram–Schmidt para três vetores:
,
,
.
. Normalização:
.
Nas próximas etapas vamos definir cada função em pseudocódigo Python-like e discutir o que acontece se os vetores forem linearmente dependentes (LD).
Passo 2
Definindo a função do produto escalar:
def dot(u, v):
"""
Retorna o produto escalar \(\langle u, v \rangle\) \(=\) sum(\(u_i\) * \(v_i\)).
"""
assert len(u) \(==\) len(v), "Dimensões incompatíveis"
total \(=0.0\)
for ui, vi in zip(u, v):
total \(+=\) ui * vi
return total
Aqui usamos a definição de produto escalar em coordenadas de uma base ortonormal.
Passo 3
Definindo a função para o comprimento (norma):
import math
def norm(v):
"""
Retorna a norma \(\|v\|\) \(=\) sqrt(\(\langle v,v \rangle\)).
"""
return math.sqrt(dot(v, v))
Isso aplica a fórmula
.
Passo 4
Definindo a projeção ortogonal de
sobre
:
def proj(u, v):
"""
Retorna \(\operatorname{proj}_v(u)\) \(=\) \(\frac{\langle u,v \rangle}{\langle v,v \rangle} \cdot v\).
Se \(v\) for o vetor zero, lança erro de divisão por zero.
"""
denom \(=\) dot(v, v)
if denom \(==0\):
raise ValueError("Não é possível projetar sobre vetor zero")
coef \(=\) dot(u, v) / denom
return [coef * vi for vi in v]
Usamos a fórmula padrão de projeção e detectamos o caso
, que ocorre se os vetores forem LD e gerarem um
nulo.
Passo 5
Função que, dados três vetores
supostamente LI, retorna vetores ortogonais
:
def \(gs_orth\)(v\(1\), v\(2\), v\(3\)):
"""
Gram–Schmidt ortogonal (não normaliza):
w\(1=\) v\(1\)
w\(2=\) v\(2\) - \(proj_w1\)(v\(2\))
w\(3=\) v\(3\) - \(proj_w1\)(v\(3\)) - \(proj_w2\)(v\(3\))
Se algum \(w_i\) for zero, sinal de LD.
"""
w\(1=\) v\(1\)
w\(2=\) [v\(2\)i - pi for v\(2\)i, pi in zip(v\(2\), proj(v\(2\), w\(1\)))]
if norm(w\(2\)) \(==0\):
raise ValueError("v\(1\) e v\(2\) são LD; não há base ortogonal completa")
w\(3=\) [v\(3\)i - p\(1\)i - p\(2\)i
for v\(3\)i, p\(1\)i, p\(2\)i in zip(v\(3\), proj(v\(3\), w\(1\)), proj(v\(3\), w\(2\)))]
if norm(w\(3\)) \(==0\):
raise ValueError("v\(1\), v\(2\) e v\(3\) são LD; não há base ortogonal completa")
return w\(1\), w\(2\), w\(3\)
Discussão d): se os vetores fornecidos forem LD, então pelo menos um dos
fica zero e a função detecta divisão por zero ou norma zero, indicando que não se pode formar uma base de
. Em vez de uma base de dimensão
, obtém-se apenas uma base para o subespaço gerado (dimensão menor).
Passo 6
Função que retorna base ortonormal a partir de três vetores LI:
def \(gs_orthonormal\)(v\(1\), v\(2\), v\(3\)):
"""
Gram–Schmidt completo com normalização:
Primeiro obtém w\(1\), w\(2\), w\(3\) ortogonais (via \(gs_orth\)),
depois normaliza cada um: ui \(=\) wi / ||wi||.
"""
w\(1\), w\(2\), w\(3= gs_orth\)(v\(1\), v\(2\), v\(3\))
u\(1=\) [wi / norm(w\(1\)) for wi in w\(1\)]
u\(2=\) [wi / norm(w\(2\)) for wi in w\(2\)]
u\(3=\) [wi / norm(w\(3\)) for wi in w\(3\)]
return u\(1\), u\(2\), u\(3\)
Discussão e): se os vetores forem LD, a chamada a . O algoritmo indica a dependência linear.
\(gs_orth\)
já falha, e portanto não há como produzir uma base ortonormal completa em
Resposta
def dot(u, v):
assert len(u) \(==\) len(v), "Dimensões incompatíveis"
total \(=0.0\)
for ui, vi in zip(u, v):
total \(+=\) ui * vi
return total
import math
def norm(v):
return math.sqrt(dot(v, v))
def proj(u, v):
denom \(=\) dot(v, v)
if denom \(==0\):
raise ValueError("Não é possível projetar sobre vetor zero")
coef \(=\) dot(u, v) / denom
return [coef * vi for vi in v]
def \(gs_orth\)(v\(1\), v\(2\), v\(3\)):
w\(1=\) v\(1\)
w\(2=\) [v\(2\)i - pi for v\(2\)i, pi in zip(v\(2\), proj(v\(2\), w\(1\)))]
if norm(w\(2\)) \(==0\):
raise ValueError("v\(1\) e v\(2\) são LD; não há base ortogonal completa")
w\(3=\) [v\(3\)i - p\(1\)i - p\(2\)i
for v\(3\)i, p\(1\)i, p\(2\)i in zip(v\(3\), proj(v\(3\), w\(1\)), proj(v\(3\), w\(2\)))]
if norm(w\(3\)) \(==0\):
raise ValueError("v\(1\), v\(2\) e v\(3\) são LD; não há base ortogonal completa")
return w\(1\), w\(2\), w\(3\)
def \(gs_orthonormal\)(v\(1\), v\(2\), v\(3\)):
w\(1\), w\(2\), w\(3= gs_orth\)(v\(1\), v\(2\), v\(3\))
u\(1=\) [wi / norm(w\(1\)) for wi in w\(1\)]
u\(2=\) [wi / norm(w\(2\)) for wi in w\(2\)]
u\(3=\) [wi / norm(w\(3\)) for wi in w\(3\)]
return u\(1\), u\(2\), u\(3\)