Skip to content

Commit

Permalink
Add "did you mean" for better experience
Browse files Browse the repository at this point in the history
  • Loading branch information
lisitsyn committed May 19, 2024
1 parent 82cb8e2 commit 0d4250d
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 26 deletions.
10 changes: 5 additions & 5 deletions src/cli/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,9 +282,9 @@ int run(int argc, const char **argv)
string method = opt[METHOD_KEYWORD].as<std::string>();
try
{
tapkee_method = parse_reduction_method(method.c_str());
tapkee_method = parse_multiple(DIMENSION_REDUCTION_METHODS, method);
}
catch (const std::exception &)
catch (const std::exception & ex)
{
tapkee::Logging::instance().message_error(string("Unknown method ") + method);
return 1;
Expand All @@ -296,7 +296,7 @@ int run(int argc, const char **argv)
string method = opt[NEIGHBORS_METHOD_KEYWORD].as<std::string>();
try
{
tapkee_neighbors_method = parse_neighbors_method(method.c_str());
tapkee_neighbors_method = parse_multiple(NEIGHBORS_METHODS, method);
}
catch (const std::exception &)
{
Expand All @@ -309,7 +309,7 @@ int run(int argc, const char **argv)
string method = opt[EIGEN_METHOD_KEYWORD].as<std::string>();
try
{
tapkee_eigen_method = parse_eigen_method(method.c_str());
tapkee_eigen_method = parse_multiple(EIGEN_METHODS, method);
}
catch (const std::exception &)
{
Expand All @@ -322,7 +322,7 @@ int run(int argc, const char **argv)
string method = opt[COMPUTATION_STRATEGY_KEYWORD].as<std::string>();
try
{
tapkee_computation_strategy = parse_computation_strategy(method.c_str());
tapkee_computation_strategy = parse_multiple(COMPUTATION_STRATEGIES, method);
}
catch (const std::exception &)
{
Expand Down
76 changes: 55 additions & 21 deletions src/cli/util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <ostream>

#include <tapkee/defines.hpp>
#include <tapkee/utils/logging.hpp>

using namespace std;

Expand All @@ -22,6 +23,38 @@ inline bool is_wrong_char(char c)
return false;
}

int levenshtein_distance(const std::string& s1, const std::string& s2)
{
const auto len1 = s1.size();
const auto len2 = s2.size();

std::vector<std::vector<unsigned int>> d(len1 + 1, std::vector<unsigned int>(len2 + 1));

d[0][0] = 0;
for (unsigned int i = 1; i <= len1; ++i)
{
d[i][0] = i;
}
for (unsigned int j = 1; j <= len2; ++j)
{
d[0][j] = j;
}

for (unsigned int i = 1; i <= len1; ++i)
{
for (unsigned int j = 1; j <= len2; ++j)
{
d[i][j] = std::min({
d[i - 1][j] + 1,
d[i][j - 1] + 1,
d[i - 1][j - 1] + (s1[i - 1] == s2[j - 1] ? 0 : 1)
});
}
}

return d[len1][len2];
}

template <typename Iterator>
std::string comma_separated_keys(Iterator begin, Iterator end) {
std::ostringstream oss;
Expand Down Expand Up @@ -109,7 +142,7 @@ void write_vector(tapkee::DenseVector* matrix, ofstream& of)
}
}

static const std::map<const char*, tapkee::DimensionReductionMethod> DIMENSION_REDUCTION_METHODS = {
static const std::map<std::string, tapkee::DimensionReductionMethod> DIMENSION_REDUCTION_METHODS = {
{"local_tangent_space_alignment", tapkee::KernelLocalTangentSpaceAlignment},
{"ltsa", tapkee::KernelLocalTangentSpaceAlignment},
{"locally_linear_embedding", tapkee::KernelLocallyLinearEmbedding},
Expand Down Expand Up @@ -148,47 +181,48 @@ static const std::map<const char*, tapkee::DimensionReductionMethod> DIMENSION_R
{"manifold_sculpting", tapkee::ManifoldSculpting},
};

tapkee::DimensionReductionMethod parse_reduction_method(const char* str)
{
return DIMENSION_REDUCTION_METHODS.at(str);
}

static const std::map<const char*, tapkee::NeighborsMethod> NEIGHBORS_METHODS = {
static const std::map<std::string, tapkee::NeighborsMethod> NEIGHBORS_METHODS = {
{"brute", tapkee::Brute},
{"vptree", tapkee::VpTree},
#ifdef TAPKEE_USE_LGPL_COVERTREE
{"covertree", tapkee::CoverTree},
#endif
};

tapkee::NeighborsMethod parse_neighbors_method(const char* str)
{
return NEIGHBORS_METHODS.at(str);
}

static const std::map<const char*, tapkee::EigenMethod> EIGEN_METHODS = {
static const std::map<std::string, tapkee::EigenMethod> EIGEN_METHODS = {
{"dense", tapkee::Dense},
{"randomized", tapkee::Randomized},
#ifdef TAPKEE_WITH_ARPACK
{"arpack", tapkee::Arpack},
#endif
};

tapkee::EigenMethod parse_eigen_method(const char* str)
{
return EIGEN_METHODS.at(str);
}

static const std::map<const char*, tapkee::ComputationStrategy> COMPUTATION_STRATEGIES = {
static const std::map<std::string, tapkee::ComputationStrategy> COMPUTATION_STRATEGIES = {
{"cpu", tapkee::HomogeneousCPUStrategy},
#ifdef TAPKEE_WITH_VIENNACL
{"opencl", tapkee::HeterogeneousOpenCLStrategy},
#endif
};

tapkee::ComputationStrategy parse_computation_strategy(const char* str)
template <class Mapping>
typename Mapping::mapped_type parse_multiple(Mapping mapping, const std::string& str)
{
return COMPUTATION_STRATEGIES.at(str);
auto it = mapping.find(str);
if (it != mapping.end())
{
return it->second;
}

auto closest = std::min_element(mapping.begin(), mapping.end(),
[&str] (const auto &a, const auto &b) {
return levenshtein_distance(str, a.first) < levenshtein_distance(str, b.first);
});
if (closest != mapping.end())
{
tapkee::Logging::instance().message_info(fmt::format("Unknown parameter value `{}`. Did you mean `{}`?", str, closest->first));
}

throw std::logic_error(str);
}

template <class PairwiseCallback>
Expand Down

0 comments on commit 0d4250d

Please sign in to comment.