Me gustaría calcular una aproximación de bajo rango a una matriz que sea óptima según la norma Frobenius. La forma trivial de hacer esto es calcular la descomposición SVD de la matriz, establecer los valores singulares más pequeños a cero y calcular la matriz de bajo rango multiplicando los factores. ¿Hay una manera simple y más eficiente de hacer esto en MATLAB?Epopoximación eficiente de bajo rango en MATLAB
Respuesta
Si su matriz es escasa, use svds
.
Suponiendo que no es escaso pero es grande, puede usar proyecciones aleatorias para una aproximación rápida de bajo rango.
Desde un tutorial:
Un óptimo bajo aproximación rango se puede calcular fácilmente usando la SVD de A en O (mn^2 ). Usando proyecciones aleatorias mostramos cómo lograr una aproximación de rango bajo "casi óptima" en O (mn log (n)).
código Matlab de un blog:
clear
% preparing the problem
% trying to find a low approximation to A, an m x n matrix
% where m >= n
m = 1000;
n = 900;
%// first let's produce example A
A = rand(m,n);
%
% beginning of the algorithm designed to find alow rank matrix of A
% let us define that rank to be equal to k
k = 50;
% R is an m x l matrix drawn from a N(0,1)
% where l is such that l > c log(n)/ epsilon^2
%
l = 100;
% timing the random algorithm
trand =cputime;
R = randn(m,l);
B = 1/sqrt(l)* R' * A;
[a,s,b]=svd(B);
Ak = A*b(:,1:k)*b(:,1:k)';
trandend = cputime-trand;
% now timing the normal SVD algorithm
tsvd = cputime;
% doing it the normal SVD way
[U,S,V] = svd(A,0);
Aksvd= U(1:m,1:k)*S(1:k,1:k)*V(1:n,1:k)';
tsvdend = cputime -tsvd;
Además, recuerda el parámetro econ
de svd
.
¿Es este un método exacto o una aproximación? ¿Es numéricamente estable hacia atrás? –
@Victor, no es óptimo. Ver editar. – cyborg
He hecho algunos benchmarking y los svds de la función pueden ser (significativamente) más rápidos que svd para matrices densas también, para un rango lo suficientemente bajo. Si incluyes eso en la respuesta, lo aceptaré. –
Puede calcular rápidamente una aproximación de bajo rango basada en SVD, utilizando la función svds
.
[U,S,V] = svds(A,r); %# only first r singular values are computed
svds
utiliza para calcular eigs
un subconjunto de los valores singulares - será especialmente rápido para matrices grandes y dispersas. Ver la documentación; puede establecer la tolerancia y el número máximo de iteraciones o elegir calcular pequeños valores singulares en lugar de grandes.
pensé svds
y eigs
podría ser más rápido que svd
y eig
para matrices densas, pero luego he hecho un poco de evaluación comparativa. Son sólo es más rápido para grandes matrices cuando se solicitan suficientemente pocos valores:
n k svds svd eigs eig comment
10 1 4.6941e-03 8.8188e-05 2.8311e-03 7.1699e-05 random matrices
100 1 8.9591e-03 7.5931e-03 4.7711e-03 1.5964e-02 (uniform dist)
1000 1 3.6464e-01 1.8024e+00 3.9019e-02 3.4057e+00
2 1.7184e+00 1.8302e+00 2.3294e+00 3.4592e+00
3 1.4665e+00 1.8429e+00 2.3943e+00 3.5064e+00
4 1.5920e+00 1.8208e+00 1.0100e+00 3.4189e+00
4000 1 7.5255e+00 8.5846e+01 5.1709e-01 1.2287e+02
2 3.8368e+01 8.6006e+01 1.0966e+02 1.2243e+02
3 4.1639e+01 8.4399e+01 6.0963e+01 1.2297e+02
4 4.2523e+01 8.4211e+01 8.3964e+01 1.2251e+02
10 1 4.4501e-03 1.2028e-04 2.8001e-03 8.0108e-05 random pos. def.
100 1 3.0927e-02 7.1261e-03 1.7364e-02 1.2342e-02 (uniform dist)
1000 1 3.3647e+00 1.8096e+00 4.5111e-01 3.2644e+00
2 4.2939e+00 1.8379e+00 2.6098e+00 3.4405e+00
3 4.3249e+00 1.8245e+00 6.9845e-01 3.7606e+00
4 3.1962e+00 1.9782e+00 7.8082e-01 3.3626e+00
4000 1 1.4272e+02 8.5545e+01 1.1795e+01 1.4214e+02
2 1.7096e+02 8.4905e+01 1.0411e+02 1.4322e+02
3 2.7061e+02 8.5045e+01 4.6654e+01 1.4283e+02
4 1.7161e+02 8.5358e+01 3.0066e+01 1.4262e+02
Con reducción de tamaño n
matrices cuadradas, k
singular/eigen valores y tiempos de ejecución en segundos. Utilicé la función de intercambio de archivos de Steve Eddins timeit
para la evaluación comparativa, que intenta dar cuenta de las variaciones generales y de tiempo de ejecución.
svds
y eigs
son más rápidos si quiere algunos valores de una matriz muy grande. También depende de las propiedades de la matriz en cuestión (edit svds
debería darle alguna idea de por qué).
Es interesante escuchar que 'svds' funciona más rápido que' svd' para algunas matrices densas al buscar los primeros valores singulares. ¿Es porque 500x100 no es lo suficientemente grande? – cyborg
Cuanto más grande sea la matriz, más rápido 'svds' y' eigs' * pueden * ser. Tuve que comer un poco mis palabras, ver mi última edición anterior. –
- 1. ¿Cálculo de superposición de rango de fechas eficiente en python?
- 2. Normalización en el rango variable [x, y] en Matlab
- 3. Usando vector como rango en for-loop En Matlab
- 4. inversión de la matriz más eficiente en MATLAB
- 5. Multiplicación eficiente de matrices muy grandes en MATLAB
- 6. Calcula área bajo el gráfico FFT en MATLAB
- 7. ¿Existe un equivalente de la función de rango de Python en MATLAB?
- 8. Método eficiente para calcular el vector de rango de una lista en Python
- 9. Lógica eficiente para obtener valores distintos de un rango de valores en C# 2.0
- 10. SCOPE_IDENTITY en C# - rango
- 11. ¿Cómo puedo compilar e incluir archivos de Matlab en Python bajo Ubuntu
- 12. Generando vectores en MATLAB
- 13. ¿Cuál es la forma más eficiente/elegante de eliminar elementos de una matriz en MATLAB?
- 14. La manera más eficiente de dibujar un grupo de líneas 3d en matlab
- 15. ¿Cómo se puede normalizar un vector en MATLAB de manera eficiente? ¿Alguna función incorporada relacionada?
- 16. Recuperación eficiente de registros de rango de IP superpuestos a través de un solo punto
- 17. Rendimiento bajo usando funciones anónimas en MATLAB ... ¿otros han notado esto?
- 18. MATLAB: aplique un filtro de paso bajo o de paso alto a una matriz
- 19. Comparación de rango de fecha múltiple para superposición: ¿cómo hacerlo de manera eficiente?
- 20. ¿Lectura de cadenas en Matlab desde excel?
- 21. etiquetado de Matlab, gráficos, leyendas
- 22. Rango de implícita Linq rango variable
- 23. de MATLAB en Python
- 24. Java: forma más eficiente de copiar de manera defensiva un int []?
- 25. Equivalente de Matlab 'ismember' en numpy (Python)?
- 26. cómo combinar de manera eficiente rangos int en una secuencia?
- 27. comportamiento de las variables persistentes en MATLAB
- 28. Función de rango en MySQL
- 29. Búsqueda de rango en Java
- 30. MySQL seleccionar EN rango
¿Qué quiere decir con "simple", "eficiente"? – Oli
por simple quiero decir que una referencia a un documento de investigación de 30 páginas cuya implementación requiere escribir 500 líneas de código no es la respuesta que estoy buscando. Por eficiente quiero decir que me gustaría mejorar el tiempo de ejecución sobre el enfoque trivial. –
Dudo que haya una respuesta trivial ... Después de todo, si fuera así, ¿por qué Mathworks "se olvidaría" de eso? –