EmbeddingResult embed(const MatrixType& wm, IndexType target_dimension, unsigned int skip) { timed_context context("Randomized eigendecomposition"); DenseMatrix O(wm.rows(), target_dimension+skip); for (IndexType i=0; i<O.rows(); ++i) { IndexType j=0; for ( ; j+1 < O.cols(); j+= 2) { ScalarType v1 = (ScalarType)(rand()+1.f)/((float)RAND_MAX+2.f); ScalarType v2 = (ScalarType)(rand()+1.f)/((float)RAND_MAX+2.f); ScalarType len = sqrt(-2.f*log(v1)); O(i,j) = len*cos(2.f*M_PI*v2); O(i,j+1) = len*sin(2.f*M_PI*v2); } for ( ; j < O.cols(); j++) { ScalarType v1 = (ScalarType)(rand()+1.f)/((float)RAND_MAX+2.f); ScalarType v2 = (ScalarType)(rand()+1.f)/((float)RAND_MAX+2.f); ScalarType len = sqrt(-2.f*log(v1)); O(i,j) = len*cos(2.f*M_PI*v2); } } MatrixTypeOperation operation(wm); DenseMatrix Y = operation(O); for (IndexType i=0; i<Y.cols(); i++) { for (IndexType j=0; j<i; j++) { ScalarType r = Y.col(i).dot(Y.col(j)); Y.col(i) -= r*Y.col(j); } ScalarType norm = Y.col(i).norm(); if (norm < 1e-4) { for (int k = i; k<Y.cols(); k++) Y.col(k).setZero(); } Y.col(i) *= (1.f / norm); } DenseMatrix B1 = operation(Y); DenseMatrix B = Y.householderQr().solve(B1); DenseSelfAdjointEigenSolver eigenOfB(B); if (eigenOfB.info() == Eigen::Success) { DenseMatrix embedding = (Y*eigenOfB.eigenvectors()).block(0, skip, wm.cols(), target_dimension); return EmbeddingResult(embedding,eigenOfB.eigenvalues()); } else { throw eigendecomposition_error("eigendecomposition failed"); } return EmbeddingResult(); }
EigendecompositionResult eigendecomposition_impl_randomized(const MatrixType& wm, IndexType target_dimension, unsigned int skip) { timed_context context("Randomized eigendecomposition"); DenseMatrix O(wm.rows(), target_dimension+skip); for (IndexType i=0; i<O.rows(); ++i) { for (IndexType j=0; j<O.cols(); j++) { O(i,j) = tapkee::gaussian_random(); } } MatrixOperationType operation(wm); DenseMatrix Y = operation(O); for (IndexType i=0; i<Y.cols(); i++) { for (IndexType j=0; j<i; j++) { ScalarType r = Y.col(i).dot(Y.col(j)); Y.col(i) -= r*Y.col(j); } ScalarType norm = Y.col(i).norm(); if (norm < 1e-4) { for (int k = i; k<Y.cols(); k++) Y.col(k).setZero(); } Y.col(i) *= (1.f / norm); } DenseMatrix B1 = operation(Y); DenseMatrix B = Y.householderQr().solve(B1); DenseSelfAdjointEigenSolver eigenOfB(B); if (eigenOfB.info() == Eigen::Success) { if (MatrixOperationType::largest) { assert(skip==0); DenseMatrix selected_eigenvectors = (Y*eigenOfB.eigenvectors()).rightCols(target_dimension); return EigendecompositionResult(selected_eigenvectors,eigenOfB.eigenvalues()); } else { DenseMatrix selected_eigenvectors = (Y*eigenOfB.eigenvectors()).leftCols(target_dimension+skip).rightCols(target_dimension); return EigendecompositionResult(selected_eigenvectors,eigenOfB.eigenvalues()); } } else { throw eigendecomposition_error("eigendecomposition failed"); } return EigendecompositionResult(); }