From ba25f264b5d309efcf77a6b72d1b784ae97f741f Mon Sep 17 00:00:00 2001 From: Arnur Nigmetov Date: Wed, 6 Feb 2019 22:45:18 +0100 Subject: Switch to opts, tolerate max-iterations-exceeded. 1. Use opts.h for command-line parsing in wasserstein_dist. 2. Real relative error at the end of auction is stored in params, params is passed by reference. 3. If -e command line option is given to wasserstein_dist, relative error will be printed. 4. If -t option is given to wasserstein_dist, no exception will be thrown, if maximum number of iterations is exceeded. 5. Run wasserstein_dist -h to see all options. --- geom_matching/wasserstein/include/opts/opts.h | 353 ++++++++++++++++++++++++++ 1 file changed, 353 insertions(+) create mode 100755 geom_matching/wasserstein/include/opts/opts.h (limited to 'geom_matching/wasserstein/include/opts') diff --git a/geom_matching/wasserstein/include/opts/opts.h b/geom_matching/wasserstein/include/opts/opts.h new file mode 100755 index 0000000..74e788b --- /dev/null +++ b/geom_matching/wasserstein/include/opts/opts.h @@ -0,0 +1,353 @@ +/** + * Author: Dmitriy Morozov + * The interface is heavily influenced by GetOptPP (https://code.google.com/p/getoptpp/). + */ + +#ifndef OPTS_OPTS_H +#define OPTS_OPTS_H + +#include +#include +#include +#include +#include + +namespace opts { + +// Converters +template +struct Converter +{ + Converter() {} + static + T convert(const std::string& val) { std::istringstream iss(val); T res; iss >> res; return res; } +}; + +// Type +template +struct Traits +{ + static std::string type_string() { return "UNKNOWN TYPE"; } +}; + +template<> +struct Traits +{ + static std::string type_string() { return "INT"; } +}; + +template<> +struct Traits +{ + static std::string type_string() { return "SHORT INT"; } +}; + +template<> +struct Traits +{ + static std::string type_string() { return "UNSIGNED INT"; } +}; + +template<> +struct Traits +{ + static std::string type_string() { return "SHORT UNSIGNED INT"; } +}; + +template<> +struct Traits +{ + static std::string type_string() { return "FLOAT"; } +}; + +template<> +struct Traits +{ + static std::string type_string() { return "DOUBLE"; } +}; + +template<> +struct Traits +{ + static std::string type_string() { return "STRING"; } +}; + + +struct BasicOption +{ + BasicOption(char s_, + std::string l_, + std::string default_, + std::string type_, + std::string help_): + s(s_), l(l_), d(default_), t(type_), help(help_) {} + + int long_size() const { return l.size() + 1 + t.size(); } + + void output(std::ostream& out, int max_long) const + { + out << " "; + if (s) + out << '-' << s << ", "; + else + out << " "; + + out << "--" << l << ' '; + + if (!t.empty()) + out << t; + + for (int i = long_size(); i < max_long; ++i) + out << ' '; + + out << " " << help; + + if (!d.empty()) + { + out << " [default: " << d << "]"; + } + out << '\n'; + } + + char s; + std::string l; + std::string d; + std::string t; + std::string help; +}; + +// Option +template +struct OptionContainer: public BasicOption +{ + OptionContainer(char s_, + const std::string& l_, + T& var_, + const std::string& help_, + const std::string& type_ = Traits::type_string()): + BasicOption(s_, l_, default_value(var_), type_, help_), + var(&var_) {} + + static + std::string default_value(const T& def) + { + std::ostringstream oss; + oss << def; + return oss.str(); + } + + void parse(std::list& args) const + { + std::string short_opt = "-"; short_opt += s; + std::string long_opt = "--" + l; + for (std::list::iterator cur = args.begin(); cur != args.end(); ++cur) + { + if (*cur == short_opt || *cur == long_opt) + { + cur = args.erase(cur); + if (cur != args.end()) + { + *var = Converter::convert(*cur); + cur = args.erase(cur); + break; // finds first occurrence + } + else + break; // if the last option's value is missing, it remains default + + } + } + } + + T* var; +}; + +template +struct OptionContainer< std::vector >: public BasicOption +{ + OptionContainer(char s_, + const std::string& l_, + std::vector& var_, + const std::string& help_, + const std::string& type_ = "SEQUENCE"): + BasicOption(s_, l_, default_value(var_), type_, help_), + var(&var_) { } + + static + std::string default_value(const std::vector& def) + { + std::ostringstream oss; + oss << "("; + if (def.size()) + oss << def[0]; + for (int i = 1; i < def.size(); ++i) + oss << ", " << def[i]; + oss << ")"; + return oss.str(); + } + + void parse(std::list& args) const + { + std::string short_opt = "-"; short_opt += s; + std::string long_opt = "--" + l; + for (std::list::iterator cur = args.begin(); cur != args.end(); ++cur) + { + if (*cur == short_opt || *cur == long_opt) + { + cur = args.erase(cur); + if (cur != args.end()) + { + var->push_back(Converter::convert(*cur)); + cur = args.erase(cur); + } + --cur; + } + } + } + + std::vector* var; +}; + + +template +OptionContainer +Option(char s, const std::string& l, T& var, const std::string& help) { return OptionContainer(s, l, var, help); } + +template +OptionContainer +Option(char s, const std::string& l, T& var, + const std::string& type, const std::string& help) { return OptionContainer(s, l, var, help, type); } + +template +OptionContainer +Option(const std::string& l, T& var, const std::string& help) { return OptionContainer(0, l, var, help); } + +template +OptionContainer +Option(const std::string& l, T& var, + const std::string& type, const std::string& help) { return OptionContainer(0, l, var, help, type); } + +// Present +struct PresentContainer: public BasicOption +{ + PresentContainer(char s, const std::string& l, const std::string& help): + BasicOption(s,l,"","",help) {} +}; + +inline +PresentContainer +Present(char s, const std::string& l, const std::string& help) { return PresentContainer(s, l, help); } + +inline +PresentContainer +Present(const std::string& l, const std::string& help) { return PresentContainer(0, l, help); } + +// PosOption +template +struct PosOptionContainer +{ + PosOptionContainer(T& var_): + var(&var_) {} + + bool parse(std::list& args) const + { + if (args.empty()) + return false; + + *var = Converter::convert(args.front()); + args.pop_front(); + return true; + } + + T* var; +}; + +template +PosOptionContainer +PosOption(T& var) { return PosOptionContainer(var); } + + +// Options +struct Options +{ + Options(int argc_, char** argv_): + args(argv_ + 1, argv_ + argc_), + failed(false) {} + + template + Options& operator>>(const OptionContainer& oc); + bool operator>>(const PresentContainer& pc); + template + Options& operator>>(const PosOptionContainer& poc); + + operator bool() { return !failed; } + + + friend + std::ostream& + operator<<(std::ostream& out, const Options& ops) + { + int max_long = 0; + for (std::list::const_iterator cur = ops.options.begin(); + cur != ops.options.end(); + ++cur) + { + int cur_long = cur->long_size(); + if (cur_long > max_long) + max_long = cur_long; + } + + out << "Options:\n"; + for (std::list::const_iterator cur = ops.options.begin(); + cur != ops.options.end(); + ++cur) + cur->output(out, max_long); + + return out; + } + + + private: + std::list args; + std::list options; + bool failed; +}; + +template +Options& +Options::operator>>(const OptionContainer& oc) +{ + options.push_back(oc); + oc.parse(args); + return *this; +} + +inline +bool +Options::operator>>(const PresentContainer& pc) +{ + options.push_back(pc); + + for(std::list::iterator cur = args.begin(); cur != args.end(); ++cur) + { + std::string short_opt = "-"; short_opt += pc.s; + std::string long_opt = "--" + pc.l; + if (*cur == short_opt || *cur == long_opt) + { + args.erase(cur); + return true; + } + } + return false; +} + +template +Options& +Options::operator>>(const PosOptionContainer& poc) +{ + failed = !poc.parse(args); + return *this; +} + +} + +#endif -- cgit v1.2.3