TEST(EigenEmbedding, ArpackSparseSmallestEigenvector) { const int N = 3; tapkee::tapkee_internal::SparseTriplets sparse_triplets; for (int i=0; i<N; i++) sparse_triplets.push_back(tapkee::tapkee_internal::SparseTriplet(i,i,tapkee::ScalarType(i+1))); #ifdef EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET Eigen::DynamicSparseMatrix<tapkee::ScalarType> dynamic_weight_matrix(N,N); dynamic_weight_matrix.reserve(sparse_triplets.size()); for (tapkee::tapkee_internal::SparseTriplets::const_iterator it=sparse_triplets.begin(); it!=sparse_triplets.end(); ++it) dynamic_weight_matrix.coeffRef(it->col(),it->row()) += it->value(); tapkee::SparseWeightMatrix mat(dynamic_weight_matrix); #else tapkee::SparseWeightMatrix mat(N,N); mat.setFromTriplets(sparse_triplets.begin(),sparse_triplets.end()); #endif tapkee::tapkee_internal::EmbeddingResult result = tapkee::tapkee_internal::eigen_embedding<tapkee::SparseWeightMatrix,tapkee::tapkee_internal::SparseInverseMatrixOperation> (tapkee::Arpack, mat, 1, 0); ASSERT_EQ(1,result.second.size()); // smallest eigenvalue is 1 ASSERT_NEAR(1,result.second[0],PRECISION); ASSERT_EQ(1,result.first.cols()); ASSERT_EQ(3,result.first.rows()); // check if it is an eigenvector ASSERT_NEAR(0.0,(mat*result.first - result.second[0]*result.first).norm(),PRECISION); }
SparseMatrix sparse_matrix_from_triplets(const SparseTriplets& sparse_triplets, IndexType m, IndexType n) { #ifdef EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET Eigen::DynamicSparseMatrix<ScalarType> dynamic_weight_matrix(m, n); dynamic_weight_matrix.reserve(sparse_triplets.size()); for (SparseTriplets::const_iterator it=sparse_triplets.begin(); it!=sparse_triplets.end(); ++it) dynamic_weight_matrix.coeffRef(it->col(),it->row()) += it->value(); SparseMatrix matrix(dynamic_weight_matrix); #else SparseMatrix matrix(m, n); matrix.setFromTriplets(sparse_triplets.begin(),sparse_triplets.end()); #endif return matrix; }
Laplacian compute_laplacian(RandomAccessIterator begin, RandomAccessIterator end,const Neighbors& neighbors, DistanceCallback callback, ScalarType width) { SparseTriplets sparse_triplets; timed_context context("Laplacian computation"); const IndexType k = neighbors[0].size(); sparse_triplets.reserve((k+1)*(end-begin)); DenseVector D = DenseVector::Zero(end-begin); for (RandomAccessIterator iter=begin; iter!=end; ++iter) { const LocalNeighbors& current_neighbors = neighbors[iter-begin]; for (IndexType i=0; i<k; ++i) { ScalarType distance = callback(*iter,begin[current_neighbors[i]]); ScalarType heat = exp(-distance*distance/width); D(iter-begin) += heat; D(current_neighbors[i]) += heat; sparse_triplets.push_back(SparseTriplet(current_neighbors[i],(iter-begin),-heat)); sparse_triplets.push_back(SparseTriplet((iter-begin),current_neighbors[i],-heat)); } } for (IndexType i=0; i<(end-begin); ++i) sparse_triplets.push_back(SparseTriplet(i,i,D(i))); #ifdef EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET Eigen::DynamicSparseMatrix<ScalarType> dynamic_weight_matrix(end-begin,end-begin); dynamic_weight_matrix.reserve(sparse_triplets.size()); for (SparseTriplets::const_iterator it=sparse_triplets.begin(); it!=sparse_triplets.end(); ++it) dynamic_weight_matrix.coeffRef(it->col(),it->row()) += it->value(); SparseWeightMatrix weight_matrix(dynamic_weight_matrix); #else SparseWeightMatrix weight_matrix(end-begin,end-begin); weight_matrix.setFromTriplets(sparse_triplets.begin(),sparse_triplets.end()); #endif return Laplacian(weight_matrix,DenseDiagonalMatrix(D)); }