Um problema comum em estatística é calcular a raiz quadrada inversa de uma matriz definida positiva simétrica. Qual seria a maneira mais eficiente de calcular isso?
Encontrei alguma literatura (que ainda não li) e algum código R incidental aqui , que reproduzirei aqui por conveniência
# function to compute the inverse square root of a matrix
fnMatSqrtInverse = function(mA) {
ei = eigen(mA)
d = ei$values
d = (d+abs(d))/2
d2 = 1/sqrt(d)
d2[d == 0] = 0
return(ei$vectors %*% diag(d2) %*% t(ei$vectors))
}
Não tenho muita certeza de entender a linha d = (d+abs(d))/2
. Existe uma maneira mais eficiente de calcular a raiz quadrada da matriz inversa? A eigen
função R chama LAPACK .
linear-algebra
numerical-analysis
matrix
tchakravarty
fonte
fonte
d[d<0] = 0
, que é mais expressiva.Respostas:
O código que você postou usa a decomposição de autovalor da matriz simétrica para calcular .A−1/2
A declaração
d = (d + abs (d)) / 2
efetivamente pega qualquer entrada negativa em d e a define como 0, deixando apenas as entradas não negativas. Ou seja, qualquer autovalor negativo de é tratado como se fosse 0. Na teoria, os autovalores de A devem ser todos não negativos, mas na prática é comum ver autovalores negativos pequenos quando você calcula os autovalores de um valor definido supostamente positivo. matriz de covariância quase singular.A
Se você realmente precisa do inverso da raiz quadrada da matriz simétrica de , e é razoavelmente pequeno (não maior que 1.000 por 1.000), então isso é tão bom quanto qualquer método que você possa usar. AA A
Em muitos casos, você pode usar um fator de Cholesky do inverso da matriz de covariância (ou praticamente o mesmo, o fator de Cholesky da própria matriz de covariância.) A computação do fator de Cholesky é tipicamente uma ordem de magnitude mais rápida que a decomposição de matrizes densas e muito mais eficientes (tanto em tempo computacional quanto no armazenamento necessário) para matrizes grandes e esparsas. Assim, o uso da fatoração de Cholesky se torna muito desejável quando é grande e escasso.A
fonte
Na minha experiência, o método polar-Newton de Higham funciona muito mais rápido (ver Capítulo 6 de Funções de matrizes por N. Higham). Em esta pequena nota da mina há parcelas que comparam esse método para métodos de primeira ordem. Além disso, são apresentadas citações para várias outras abordagens de matriz quadrada-raiz, embora a iteração de Newton polar pareça funcionar melhor (e evita cálculos de vetor próprio).
fonte
Otimize seu código:
Opção 1 - Otimize seu código R:
a. Você pode
apply()
uma função parad
que ambosmax(d,0)
ed2[d==0]=0
em um loop.b. Tente operar
ei$values
diretamente.Opção 2 - Use C ++:
Reescreva toda a função em C ++ com
RcppArmadillo
. Você ainda poderá chamá-lo de R.fonte