固有値-固有ベクトル分解を計算する〜3000x3000の共分散に似たマトリックスがあります(これはOpenCVマトリックスでありcv::eigen()
、仕事を完了するために使用します)。
ただし、実際には最初の 30 個の固有値/ベクトルだけが必要であり、残りは気にしません。理論的には、これにより計算が大幅に高速化されるはずですよね? つまり、計算する必要がある固有ベクトルが 2970 個少ないということです。
それを可能にする C++ ライブラリはどれですか? OpenCVのeigen()
メソッドにはそのためのパラメーターがありますが、ドキュメントにはそれらが無視されると書かれており、私は自分でテストしましたが、実際には無視されます:D
更新: ARPACK でなんとかできました。Windows用にコンパイルし、使用することさえできました。結果は有望に見えます。このおもちゃの例で説明を確認できます。
#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;
}
結果は次のとおりです。
9.4298, 24.24059
固有値の場合、および
-0.523207, -0.83446237, -0.17299346
0.273269, -0.356554, 0.893416
それぞれ 2 つの固有ベクトルに対して (行ごとに 1 つの固有ベクトル) コードは 3 つの固有ベクトルを見つけることができません (この場合、1-2 しか見つけることができません。assert() はそれを確認しますが、それは問題ではありません)。