示例#1
0
EigendecompositionResult eigendecomposition_impl_dense(const MatrixType& wm, IndexType target_dimension, unsigned int skip)
{
	timed_context context("Eigen library dense eigendecomposition");

	DenseMatrix dense_wm = wm;
	DenseSelfAdjointEigenSolver solver(dense_wm);

	if (solver.info() == Eigen::Success)
	{
		if (MatrixOperationType::largest)
		{
			assert(skip==0);
			DenseMatrix selected_eigenvectors = solver.eigenvectors().rightCols(target_dimension);
			return EigendecompositionResult(selected_eigenvectors,solver.eigenvalues().tail(target_dimension));
		} 
		else
		{
			DenseMatrix selected_eigenvectors = solver.eigenvectors().leftCols(target_dimension+skip).rightCols(target_dimension);
			return EigendecompositionResult(selected_eigenvectors,solver.eigenvalues().segment(skip,skip+target_dimension));
		}
	}
	else
	{
		throw eigendecomposition_error("eigendecomposition failed");
	}
	return EigendecompositionResult();
}
EigendecompositionResult generalized_eigendecomposition_impl_dense(const LMatrixType& lhs,
		const RMatrixType& rhs, IndexType target_dimension, unsigned int skip)
{
	timed_context context("Eigen dense generalized eigendecomposition");

	DenseMatrix dense_lhs = lhs;
	DenseMatrix dense_rhs = rhs;
	Eigen::GeneralizedSelfAdjointEigenSolver<DenseMatrix> solver(dense_lhs, dense_rhs);
	if (solver.info() == Eigen::Success)
	{
		if (MatrixOperationType::largest)
		{
			assert(skip==0);
			DenseMatrix selected_eigenvectors = solver.eigenvectors().rightCols(target_dimension);
			return EigendecompositionResult(selected_eigenvectors,solver.eigenvalues().tail(target_dimension));
		} 
		else
		{
			DenseMatrix selected_eigenvectors = solver.eigenvectors().leftCols(target_dimension+skip).rightCols(target_dimension);
			return EigendecompositionResult(selected_eigenvectors,solver.eigenvalues().segment(skip,skip+target_dimension));
		}
	}
	else
	{
		throw eigendecomposition_error("eigendecomposition failed");
	}

	return EigendecompositionResult();
}
示例#3
0
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();
}
EigendecompositionResult generalized_eigendecomposition(EigenMethod method, const LMatrixType& lhs,
                                                        const RMatrixType& rhs,
                                                        IndexType target_dimension, unsigned int skip)
{
	LoggingSingleton::instance().message_info("Using the " + get_eigen_method_name(method) + " eigendecomposition method.");
	switch (method)
	{
#ifdef TAPKEE_WITH_ARPACK
		case Arpack: 
			return generalized_eigendecomposition_impl_arpack<LMatrixType, RMatrixType, MatrixOperationType>(lhs, rhs, target_dimension, skip);
#endif
		case Dense:
			return generalized_eigendecomposition_impl_dense<LMatrixType, RMatrixType, MatrixOperationType>(lhs, rhs, target_dimension, skip);
		case Randomized:
			throw unsupported_method_error("Randomized method is not supported for generalized eigenproblems");
			return EigendecompositionResult();
		default: break;
	}
	return EigendecompositionResult();
}
EigendecompositionResult generalized_eigendecomposition_impl_arpack(const LMatrixType& lhs,
		const RMatrixType& rhs, IndexType target_dimension, unsigned int skip)
{
	timed_context context("ARPACK DSXUPD generalized eigendecomposition");

	ArpackGeneralizedSelfAdjointEigenSolver<LMatrixType, RMatrixType, MatrixOperationType>
		arpack(lhs,rhs,target_dimension+skip,"SM");

	if (arpack.info() == Eigen::Success)
	{
		std::string message = formatting::format("Took {} iterations.", arpack.getNbrIterations());
		LoggingSingleton::instance().message_info(message);
		DenseMatrix selected_eigenvectors = (arpack.eigenvectors()).rightCols(target_dimension);
		return EigendecompositionResult(selected_eigenvectors,arpack.eigenvalues().tail(target_dimension));
	}
	else
	{
		throw eigendecomposition_error("eigendecomposition failed");
	}
	return EigendecompositionResult();
}
示例#6
0
EigendecompositionResult eigendecomposition_impl_arpack(const MatrixType& wm, IndexType target_dimension, unsigned int skip)
{
	timed_context context("ARPACK eigendecomposition");

	ArpackGeneralizedSelfAdjointEigenSolver<MatrixType, MatrixType, MatrixOperationType> 
		arpack(wm,target_dimension+skip,MatrixOperationType::ARPACK_CODE);

	if (arpack.info() == Eigen::Success)
	{
		std::stringstream ss;
		ss << "Took " << arpack.getNbrIterations() << " iterations.";
		LoggingSingleton::instance().message_info(ss.str());
		DenseMatrix selected_eigenvectors = arpack.eigenvectors().rightCols(target_dimension);
		return EigendecompositionResult(selected_eigenvectors,arpack.eigenvalues().tail(target_dimension));
	}
	else
	{
		throw eigendecomposition_error("eigendecomposition failed");
	}
	return EigendecompositionResult();
}
	EigendecompositionResult arpack(const SparseWeightMatrix& lhs, const DenseDiagonalMatrix& rhs,
                                    const ComputationStrategy& strategy,
                                    const EigendecompositionStrategy& eigen_strategy,
                                    IndexType target_dimension)
	{
		if (strategy.is(HomogeneousCPUStrategy))
		{
			if (eigen_strategy.is(SmallestEigenvalues))
				return generalized_eigendecomposition_impl_arpack
					<SparseWeightMatrix,DenseDiagonalMatrix,SparseInverseMatrixOperation>
					(lhs,rhs,target_dimension,eigen_strategy.skip());
			unsupported();
		}
		unsupported();
		return EigendecompositionResult();
	}
	EigendecompositionResult dense(const DenseMatrix& lhs, const DenseMatrix& rhs,
                                   const ComputationStrategy& strategy,
                                   const EigendecompositionStrategy& eigen_strategy,
                                   IndexType target_dimension)
	{
		if (strategy.is(HomogeneousCPUStrategy))
		{
			if (eigen_strategy.is(SmallestEigenvalues))
				return generalized_eigendecomposition_impl_dense
					<DenseMatrix,DenseMatrix,DenseInverseMatrixOperation>
					(lhs,rhs,target_dimension,0);
			unsupported();
		}
		unsupported();
		return EigendecompositionResult();
	}
EigendecompositionResult generalized_eigendecomposition(const EigenMethod& method, const ComputationStrategy& strategy,
                                                        const EigendecompositionStrategy& eigen_strategy,
                                                        const LMatrixType& lhs, const RMatrixType& rhs, IndexType target_dimension)
{
	LoggingSingleton::instance().message_info(formatting::format("Using the {} eigendecomposition method.",
		get_eigen_method_name(method)));
#ifdef TAPKEE_WITH_ARPACK
	if (method.is(Arpack))
		return generalized_eigendecomposition_impl<LMatrixType, RMatrixType>()
			.arpack(lhs, rhs, strategy, eigen_strategy, target_dimension);
#endif
	if (method.is(Dense))
		return generalized_eigendecomposition_impl<LMatrixType, RMatrixType>()
			.dense(lhs, rhs, strategy, eigen_strategy, target_dimension);
	if (method.is(Randomized))
		throw unsupported_method_error("Randomized method is not supported for generalized eigenproblems");
	return EigendecompositionResult();
}
示例#10
0
EigendecompositionResult eigendecomposition(EigenMethod method, const MatrixType& m, 
                                            IndexType target_dimension, unsigned int skip)
{
	LoggingSingleton::instance().message_info("Using the " + get_eigen_method_name(method) + " eigendecomposition method.");
	switch (method)
	{
#ifdef TAPKEE_WITH_ARPACK
		case Arpack: 
			return eigendecomposition_impl_arpack<MatrixType, MatrixOperationType>(m, target_dimension, skip);
#endif
		case Randomized: 
			return eigendecomposition_impl_randomized<MatrixType, MatrixOperationType>(m, target_dimension, skip);
		case Dense:
			return eigendecomposition_impl_dense<MatrixType, MatrixOperationType>(m, target_dimension, skip);
		default: break;
	}
	return EigendecompositionResult();
}