diff --git a/src/cli/main.cpp b/src/cli/main.cpp index 62fc928..78115ed 100644 --- a/src/cli/main.cpp +++ b/src/cli/main.cpp @@ -139,24 +139,14 @@ int run(int argc, const char **argv) ) ( either("m", METHOD_KEYWORD), - "Dimension reduction method (default locally_linear_embedding). \n One of the following: \n" - "locally_linear_embedding (lle), neighborhood_preserving_embedding (npe), \n" - "local_tangent_space_alignment (ltsa), linear_local_tangent_space_alignment (lltsa), \n" - "hessian_locally_linear_embedding (hlle), laplacian_eigenmaps (la), locality_preserving_projections (lpp), \n" - "diffusion_map (dm), isomap, landmark_isomap (l-isomap), multidimensional_scaling (mds), \n" - "landmark_multidimensional_scaling (l-mds), stochastic_proximity_embedding (spe), \n" - "kernel_pca (kpca), pca, random_projection (ra), factor_analysis (fa), \n" - "t-stochastic_neighborhood_embedding (t-sne), manifold_sculpting (ms).", + "Dimension reduction method. One of the following: " + + comma_separated_keys(DIMENSION_REDUCTION_METHODS.begin(), DIMENSION_REDUCTION_METHODS.end()), with_default("locally_linear_embedding"s) ) ( either("nm", NEIGHBORS_METHOD_KEYWORD), - "Neighbors search method (default is 'covertree' if available, 'vptree' otherwise). One of the following: " - "brute,vptree" -#ifdef TAPKEE_USE_LGPL_COVERTREE - ",covertree" -#endif - ".", + "Neighbors search method. One of the following: " + + comma_separated_keys(NEIGHBORS_METHODS.begin(), NEIGHBORS_METHODS.end()), #ifdef TAPKEE_USE_LGPL_COVERTREE with_default("covertree"s) #else @@ -165,11 +155,8 @@ int run(int argc, const char **argv) ) ( either("em", EIGEN_METHOD_KEYWORD), - "Eigendecomposition method (default is 'arpack' if available, 'dense' otherwise). One of the following: " -#ifdef TAPKEE_WITH_ARPACK - "arpack, " -#endif - "randomized, dense.", + "Eigendecomposition method. One of the following: " + + comma_separated_keys(EIGEN_METHODS.begin(), EIGEN_METHODS.end()), #ifdef TAPKEE_WITH_ARPACK with_default("arpack"s) #else @@ -178,11 +165,8 @@ int run(int argc, const char **argv) ) ( either("cs", COMPUTATION_STRATEGY_KEYWORD), - "Computation strategy (default is 'cpu'). One of the following: " -#ifdef TAPKEE_WITH_VIENNACL - "opencl, " -#endif - "cpu.", + "Computation strategy. One of the following: " + + comma_separated_keys(COMPUTATION_STRATEGIES.begin(), COMPUTATION_STRATEGIES.end()), with_default("cpu"s) ) ( diff --git a/src/cli/util.hpp b/src/cli/util.hpp index 5a5531f..489d8ba 100644 --- a/src/cli/util.hpp +++ b/src/cli/util.hpp @@ -22,6 +22,20 @@ inline bool is_wrong_char(char c) return false; } +template +std::string comma_separated_keys(Iterator begin, Iterator end) { + std::ostringstream oss; + for (Iterator it = begin; it != end; ++it) + { + oss << it->first; + if (std::next(it) != end) + { + oss << ", "; + } + } + return oss.str(); +} + tapkee::DenseMatrix read_data(ifstream& ifs, char delimiter) { string str; @@ -95,92 +109,86 @@ void write_vector(tapkee::DenseVector* matrix, ofstream& of) } } +static const std::map DIMENSION_REDUCTION_METHODS = { + {"local_tangent_space_alignment", tapkee::KernelLocalTangentSpaceAlignment}, + {"ltsa", tapkee::KernelLocalTangentSpaceAlignment}, + {"locally_linear_embedding", tapkee::KernelLocallyLinearEmbedding}, + {"lle", tapkee::KernelLocallyLinearEmbedding}, + {"hessian_locally_linear_embedding", tapkee::HessianLocallyLinearEmbedding}, + {"hlle", tapkee::HessianLocallyLinearEmbedding}, + {"multidimensional_scaling", tapkee::MultidimensionalScaling}, + {"mds", tapkee::MultidimensionalScaling}, + {"landmark_multidimensional_scaling", tapkee::LandmarkMultidimensionalScaling}, + {"l-mds", tapkee::LandmarkMultidimensionalScaling}, + {"isomap", tapkee::Isomap}, + {"landmark_isomap", tapkee::LandmarkIsomap}, + {"l-isomap", tapkee::LandmarkIsomap}, + {"diffusion_map", tapkee::DiffusionMap}, + {"dm", tapkee::DiffusionMap}, + {"kernel_pca", tapkee::KernelPrincipalComponentAnalysis}, + {"kpca", tapkee::KernelPrincipalComponentAnalysis}, + {"pca", tapkee::PrincipalComponentAnalysis}, + {"random_projection", tapkee::RandomProjection}, + {"ra", tapkee::RandomProjection}, + {"laplacian_eigenmaps", tapkee::LaplacianEigenmaps}, + {"la", tapkee::LaplacianEigenmaps}, + {"locality_preserving_projections", tapkee::LocalityPreservingProjections}, + {"lpp", tapkee::LocalityPreservingProjections}, + {"neighborhood_preserving_embedding", tapkee::NeighborhoodPreservingEmbedding}, + {"npe", tapkee::NeighborhoodPreservingEmbedding}, + {"linear_local_tangent_space_alignment", tapkee::LinearLocalTangentSpaceAlignment}, + {"lltsa", tapkee::LinearLocalTangentSpaceAlignment}, + {"stochastic_proximity_embedding", tapkee::StochasticProximityEmbedding}, + {"spe", tapkee::StochasticProximityEmbedding}, + {"passthru", tapkee::PassThru}, + {"factor_analysis", tapkee::FactorAnalysis}, + {"fa", tapkee::FactorAnalysis}, + {"t-stochastic_proximity_embedding", tapkee::tDistributedStochasticNeighborEmbedding}, + {"t-sne", tapkee::tDistributedStochasticNeighborEmbedding}, + {"manifold_sculpting", tapkee::ManifoldSculpting}, +}; + tapkee::DimensionReductionMethod parse_reduction_method(const char* str) { - if (!strcmp(str, "local_tangent_space_alignment") || !strcmp(str, "ltsa")) - return tapkee::KernelLocalTangentSpaceAlignment; - if (!strcmp(str, "locally_linear_embedding") || !strcmp(str, "lle")) - return tapkee::KernelLocallyLinearEmbedding; - if (!strcmp(str, "hessian_locally_linear_embedding") || !strcmp(str, "hlle")) - return tapkee::HessianLocallyLinearEmbedding; - if (!strcmp(str, "multidimensional_scaling") || !strcmp(str, "mds")) - return tapkee::MultidimensionalScaling; - if (!strcmp(str, "landmark_multidimensional_scaling") || !strcmp(str, "l-mds")) - return tapkee::LandmarkMultidimensionalScaling; - if (!strcmp(str, "isomap")) - return tapkee::Isomap; - if (!strcmp(str, "landmark_isomap") || !strcmp(str, "l-isomap")) - return tapkee::LandmarkIsomap; - if (!strcmp(str, "diffusion_map") || !strcmp(str, "dm")) - return tapkee::DiffusionMap; - if (!strcmp(str, "kernel_pca") || !strcmp(str, "kpca")) - return tapkee::KernelPrincipalComponentAnalysis; - if (!strcmp(str, "pca")) - return tapkee::PrincipalComponentAnalysis; - if (!strcmp(str, "random_projection") || !strcmp(str, "ra")) - return tapkee::RandomProjection; - if (!strcmp(str, "laplacian_eigenmaps") || !strcmp(str, "la")) - return tapkee::LaplacianEigenmaps; - if (!strcmp(str, "locality_preserving_projections") || !strcmp(str, "lpp")) - return tapkee::LocalityPreservingProjections; - if (!strcmp(str, "neighborhood_preserving_embedding") || !strcmp(str, "npe")) - return tapkee::NeighborhoodPreservingEmbedding; - if (!strcmp(str, "linear_local_tangent_space_alignment") || !strcmp(str, "lltsa")) - return tapkee::LinearLocalTangentSpaceAlignment; - if (!strcmp(str, "stochastic_proximity_embedding") || !strcmp(str, "spe")) - return tapkee::StochasticProximityEmbedding; - if (!strcmp(str, "passthru")) - return tapkee::PassThru; - if (!strcmp(str, "factor_analysis") || !strcmp(str, "fa")) - return tapkee::FactorAnalysis; - if (!strcmp(str, "t-stochastic_neighbor_embedding") || !strcmp(str, "t-sne")) - return tapkee::tDistributedStochasticNeighborEmbedding; - if (!strcmp(str, "manifold_sculpting") || !strcmp(str, "ms")) - return tapkee::ManifoldSculpting; - - throw std::exception(); - return tapkee::PassThru; + return DIMENSION_REDUCTION_METHODS.at(str); } -tapkee::NeighborsMethod parse_neighbors_method(const char* str) -{ - if (!strcmp(str, "brute")) - return tapkee::Brute; - if (!strcmp(str, "vptree")) - return tapkee::VpTree; +static const std::map NEIGHBORS_METHODS = { + {"brute", tapkee::Brute}, + {"vptree", tapkee::VpTree}, #ifdef TAPKEE_USE_LGPL_COVERTREE - if (!strcmp(str, "covertree")) - return tapkee::CoverTree; + {"covertree", tapkee::CoverTree}, #endif +}; - throw std::exception(); - return tapkee::Brute; +tapkee::NeighborsMethod parse_neighbors_method(const char* str) +{ + return NEIGHBORS_METHODS.at(str); } -tapkee::EigenMethod parse_eigen_method(const char* str) -{ +static const std::map EIGEN_METHODS = { + {"dense", tapkee::Dense}, + {"randomized", tapkee::Randomized}, #ifdef TAPKEE_WITH_ARPACK - if (!strcmp(str, "arpack")) - return tapkee::Arpack; + {"arpack", tapkee::Arpack}, #endif - if (!strcmp(str, "randomized")) - return tapkee::Randomized; - if (!strcmp(str, "dense")) - return tapkee::Dense; +}; - throw std::exception(); - return tapkee::Dense; +tapkee::EigenMethod parse_eigen_method(const char* str) +{ + return EIGEN_METHODS.at(str); } -tapkee::ComputationStrategy parse_computation_strategy(const char* str) -{ - if (!strcmp(str, "cpu")) - return tapkee::HomogeneousCPUStrategy; +static const std::map COMPUTATION_STRATEGIES = { + {"cpu", tapkee::HomogeneousCPUStrategy}, #ifdef TAPKEE_WITH_VIENNACL - if (!strcmp(str, "opencl")) - return tapkee::HeterogeneousOpenCLStrategy; + {"opencl", tapkee::HeterogeneousOpenCLStrategy}, #endif - return tapkee::HomogeneousCPUStrategy; +}; + +tapkee::ComputationStrategy parse_computation_strategy(const char* str) +{ + return COMPUTATION_STRATEGIES.at(str); } template