Gram-Schmidt clássico e modificado
Nas duas versões, cada qj é normalizado no seu passo. No passo j, elas partem do vetor v = aj, subtraem de v as projeções sobre os vetores q1, …, qj−1 já calculados e terminam com qj = v/‖v‖. A diferença está no cálculo dos coeficientes dessas projeções:
- o clássico calcula todos os coeficientes com o vetor original, rij = qiTaj para i < j, e faz v = aj − r1jq1 − ⋯ − rj−1,jqj−1;
- o modificado, para i = 1, …, j − 1, nessa ordem, calcula rij = qiTv com o vetor v já corrigido e troca v por v − rijqi.
Em aritmética exata, as duas versões dão os mesmos vetores: quando chega a vez de qi, o modificado só subtraiu de aj múltiplos de q1, …, qi−1, que são ortogonais a qi, e por isso qiTv = qiTaj.
O que se mede. Com as colunas calculadas q1, …, qn numa matriz Q, a entrada (i, j) de QTQ − I é qiTqj se i ≠ j e qiTqi − 1 se i = j. Em aritmética exata, todas seriam 0. A perda de ortogonalidade é medida pelo maior valor absoluto dessas entradas, que chamamos de desvio de ortogonalidade.
Por que o clássico acumula erros. Em ponto flutuante de 64 bits, cada operação tem erro relativo de até cerca de 10−16, e os vetores q1, …, qj−1 já calculados não são exatamente ortonormais. Diremos que aj é quase combinação linear dos vetores anteriores quando a distância de aj ao subespaço gerado por eles é muito menor que ‖aj‖. Nesse caso, v é a diferença entre dois vetores quase iguais, aj e a sua projeção, e ‖v‖ é muito menor que ‖aj‖. Os erros dessas contas, da ordem de 10−16‖aj‖, deixam em v componentes nas direções de q1, …, qj−1, e a normalização divide essas componentes por ‖v‖. No clássico, nenhum passo remove essas componentes: os produtos internos de qj com q1, …, qj−1 ficam muito maiores que 10−16, e os passos seguintes partem desses vetores. Com as potências de t da bancada, o desvio de ortogonalidade do clássico cresce com o número n de vetores até ficar perto de 1.
No modificado, cada coeficiente qiTv inclui a componente que v tem naquele momento na direção de qi, seja qual for a sua origem, e essa componente é subtraída. O modificado também perde ortogonalidade com vetores quase linearmente dependentes, mas muito mais devagar: com as potências de t e n = 16, o desvio dele é cerca de 10−6, contra cerca de 1 no clássico.
Exemplo
Com ε = 10−8, sejam a1 = (1, ε, 0, 0)T, a2 = (1, 0, ε, 0)T e a3 = (1, 0, 0, ε)T. Em ponto flutuante, ‖a1‖2 = 1 + ε2 = 1 + 10−16 é arredondado para 1, e as duas versões calculam
q1 = (1, ε, 0, 0)T,
q2 = (0, −1, 1, 0)T/√2.
A primeira entrada de q2, que em aritmética exata é cerca de ε/√2, saiu 0. No passo de a3, as duas versões chegam a v = a3 − q1 = (0, −ε, 0, ε)T e diferem no coeficiente de q2:
- o clássico calcula q2Ta3 = 0, em vez de cerca de ε/√2, e obtém q3 = (0, −1, 0, 1)T/√2, com q2Tq3 = 1/2: um ângulo de 60° entre q2 e q3, em vez de 90°;
- o modificado calcula q2Tv = ε/√2, pois a primeira entrada de v já é 0, e obtém q3 = (0, −1, −1, 2)T/√6, com q2Tq3 = 0.
A base de cossenos e a compressão
Definição
Para i = 0, 1, …, n − 1, seja qi ∈ ℝn o vetor de entradas
(qi)j = si cos(πi(2j − 1)/(2n)),
para j = 1, …, n, com s0 = 1/√n e si = √(2/n) para i ≥ 1. Pode-se mostrar que esses n vetores são ortonormais. Eles formam a base de cossenos de ℝn, usada na transformada discreta de cossenos. O índice i se chama frequência de qi: quando j vai de 1 a n, o argumento do cosseno vai de πi/(2n) a πi − πi/(2n), e as entradas de qi descrevem cerca de i/2 períodos do cosseno.
Um sinal de n amostras é um vetor x ∈ ℝn, cuja entrada xj é a amostra j. A energia do sinal é ‖x‖2 = x12 + ⋯ + xn2.
Seja Q = [q0 ⋯ qn−1] a matriz da base de cossenos. As coordenadas de x nessa base, que aqui se chamam coeficientes, são y = QTx, isto é, yi = qiTx, e x = Qy = y0q0 + ⋯ + yn−1qn−1. Como Q é ortogonal, ‖y‖ = ‖x‖: a energia do sinal é a soma dos quadrados dos coeficientes. Guardando só alguns coeficientes e trocando os outros por 0, obtemos a reconstrução x̃, a soma dos termos yiqi guardados. O erro x − x̃ é a soma dos termos yiqi descartados e, como os vetores qi são ortonormais, ‖x − x̃‖2 é a soma dos yi2 descartados. Por isso, para guardar k coeficientes com o menor erro, basta escolher os k de maior valor absoluto. Quando o sinal varia pouco de uma amostra para a seguinte, a maior parte da energia costuma ficar nos coeficientes de frequência baixa: no sinal Temperatura da bancada, com n = 64, os 6 coeficientes de frequência 0 a 5 guardam 99,96% da energia. A compressão de imagens no formato JPEG usa essa ideia, com a versão bidimensional dessa base em blocos de 8 × 8 pixels.
Exemplo
Para n = 2, a base de cossenos é formada por q0 = (1, 1)T/√2 e q1 = (1, −1)T/√2, os vetores do exemplo da guia Vetores ortonormais, lá chamados de q1 e q2. Para x = (3, 1)T:
y0 = q0Tx = 4/√2 = 2√2,
y1 = q1Tx = 2/√2 = √2,
‖y‖2 = 8 + 2 = 10 = ‖x‖2.
Guardando só y0, a reconstrução é x̃ = y0q0 = (2, 2)T, que guarda 8/10, ou 80%, da energia. O erro é ‖x − x̃‖2 = ‖(1, −1)T‖2 = 2, igual a y12.
Na bancada: na parte Em dimensão n, com o experimento Gram-Schmidt em ponto flutuante escolhido no painel Experimento, escolha Quase iguais e n = 3 para ver o exemplo acima no quadro As entradas de QᵀQ − I, ou Potências de t para comparar as duas versões no quadro Perda de ortogonalidade. Com o experimento Compressão de sinais, escolha um sinal no painel Sinal e compressão e mude o controle Coeficientes guardados k.