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();
}
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();
}
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();
}