Tengo una matriz de covarianza similar a ~ 3000x3000 en la que calculo la descomposición eigenvalue-eigenvector (es una matriz OpenCV, y uso cv::eigen()
para hacer el trabajo).descomposición de vector propio/vector de C++, solo necesito primero n vectores rápido
Sin embargo, en realidad solo necesito, por ejemplo, los primeros 30 valores propios/vectores, no me importa el resto. Teóricamente, esto debería permitir acelerar el cálculo significativamente, ¿verdad? Quiero decir, eso significa que tiene 2970 autovectores menos que necesitan ser calculados.
¿Qué biblioteca C++ me permitirá hacer eso? Tenga en cuenta que el método de OpenCV eigen()
tiene los parámetros para eso, sino que la documentación dice que son ignorados, y yo probado yo mismo, son de hecho ignorados: D
ACTUALIZACIÓN: he conseguido hacerlo con ARPACK. Pude compilarlo para Windows e incluso para usarlo. Los resultados parecen prometedores, una ilustración se puede ver en este ejemplo de juguete:
#include "ardsmat.h"
#include "ardssym.h"
int n = 3; // Dimension of the problem.
double* EigVal = NULL; // Eigenvalues.
double* EigVec = NULL; // Eigenvectors stored sequentially.
int lowerHalfElementCount = (n*n+n)/2;
//whole matrix:
/*
2 3 8
3 9 -7
8 -7 19
*/
double* lower = new double[lowerHalfElementCount]; //lower half of the matrix
//to be filled with COLUMN major (i.e. one column after the other, always starting from the diagonal element)
lower[0] = 2; lower[1] = 3; lower[2] = 8; lower[3] = 9; lower[4] = -7; lower[5] = 19;
//params: dimensions (i.e. width/height), array with values of the lower or upper half (sequentially, row major), 'L' or 'U' for upper or lower
ARdsSymMatrix<double> mat(n, lower, 'L');
// Defining the eigenvalue problem.
int noOfEigVecValues = 2;
//int maxIterations = 50000000;
//ARluSymStdEig<double> dprob(noOfEigVecValues, mat, "LM", 0, 0.5, maxIterations);
ARluSymStdEig<double> dprob(noOfEigVecValues, mat);
// Finding eigenvalues and eigenvectors.
int converged = dprob.EigenValVectors(EigVec, EigVal);
for (int eigValIdx = 0; eigValIdx < noOfEigVecValues; eigValIdx++) {
std::cout << "Eigenvalue: " << EigVal[eigValIdx] << "\nEigenvector: ";
for (int i = 0; i < n; i++) {
int idx = n*eigValIdx+i;
std::cout << EigVec[idx] << " ";
}
std::cout << std::endl;
}
Los resultados son:
9.4298, 24.24059
para los valores propios, y
-0.523207, -0.83446237, -0.17299346
0.273269, -0.356554, 0.893416
para los 2 vectores propios, respectivamente (un eigenvector por fila) El código no puede encontrar 3 vectores propios (solo puede encontrar 1-2 en este caso, un assert() se asegura de eso, pero bueno, eso no es un problema).
por los 'primeros 30 valores propios/vectores', ¿quiere decir que los valores propios con los módulos más grandes, más grandes partes real, o algo más? Después de googlear, parece que [SLEPc] (http://www.grycap.upv.es/slepc/) puede tener lo que estás buscando. – James
Estoy buscando los 30 vectores propios que corresponden a los 30 autovalores reales más grandes, resultantes de una autodescomposición de una matriz simétrica real. – NameZero912
Usaría ARPACK para esto. Obtendrá sus 30 autovectores al instante. –