From 3fc0fbfba3aa1dfe1911110135bcda071b583666 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 12 Jul 2016 14:55:11 -0400 Subject: [PATCH 01/21] Refactor to support input and output parameters. --- src/mlpack/core/util/cli.cpp | 64 ++-- src/mlpack/core/util/cli.hpp | 346 +--------------------- src/mlpack/core/util/cli_impl.hpp | 20 +- src/mlpack/core/util/option.hpp | 8 +- src/mlpack/core/util/option_impl.hpp | 11 +- src/mlpack/core/util/param.hpp | 426 +++++++++++++++++++++++++++ src/mlpack/tests/cli_test.cpp | 2 +- 7 files changed, 508 insertions(+), 369 deletions(-) create mode 100644 src/mlpack/core/util/param.hpp diff --git a/src/mlpack/core/util/cli.cpp b/src/mlpack/core/util/cli.cpp index 0eaf5430807..1f6dd299ad5 100644 --- a/src/mlpack/core/util/cli.cpp +++ b/src/mlpack/core/util/cli.cpp @@ -99,11 +99,14 @@ CLI::~CLI() * @param description Short string description of the parameter. * @param alias An alias for the parameter. * @param required Indicates if parameter must be set on command line. + * @param input If true, the parameter is an input parameter (not an output + * parameter). */ void CLI::Add(const std::string& path, - const std::string& description, - const std::string& alias, - bool required) + const std::string& description, + const std::string& alias, + const bool required, + const bool input) { po::options_description& desc = CLI::GetSingleton().desc; @@ -132,6 +135,13 @@ void CLI::Add(const std::string& path, if (required) GetSingleton().requiredOptions.push_front(path); + // Depending on whether the option is input or output, add it to the list of + // input or output options. + if (input) + GetSingleton().inputOptions.push_front(path); + else + GetSingleton().outputOptions.push_front(path); + return; } @@ -600,7 +610,7 @@ void CLI::PrintHelp(const std::string& param) else std::cout << "[undocumented program]" << std::endl << std::endl; - for (size_t pass = 0; pass < 2; ++pass) + for (size_t pass = 0; pass < 4; ++pass) { bool printedHeader = false; @@ -613,29 +623,40 @@ void CLI::PrintHelp(const std::string& param) std::string alias = AliasReverseLookup(key); alias = alias.length() ? " (-" + alias + ")" : alias; - // Is the option required or not? - bool required = false; - std::list::iterator iter; - std::list& rOpt = GetSingleton().requiredOptions; - for (iter = rOpt.begin(); iter != rOpt.end(); ++iter) - if ((*iter) == key) - required = true; - - if ((pass == 0) && !required) - continue; // Don't print this one. - if ((pass == 1) && required) - continue; // Don't print this one. + // Is the option required or not? And is it an input option or not? + const std::list& requiredOptions = + GetSingleton().requiredOptions; + const std::list& inputOptions = GetSingleton().inputOptions; + + const bool required = (std::find(std::begin(requiredOptions), + std::end(requiredOptions), key) != std::end(requiredOptions)); + const bool input = (std::find(std::begin(inputOptions), + std::end(inputOptions), key) != std::end(inputOptions)); + + // Filter un-printed options. + if ((pass == 0) && !(required && input)) // Required input options only. + continue; + if ((pass == 1) && !(required && !input)) // Required output options only. + continue; + if ((pass == 2) && !(!required && input)) // Optional input options only. + continue; + if ((pass == 3) && (required || input)) // Optional output options only. + continue; if (!printedHeader) { printedHeader = true; if (pass == 0) - std::cout << "Required options:" << std::endl << std::endl; - else - std::cout << "Options: " << std::endl << std::endl; + std::cout << "Required input options:" << std::endl << std::endl; + else if (pass == 1) + std::cout << "Required output options:" << std::endl << std::endl; + else if (pass == 2) + std::cout << "Optional input options: " << std::endl << std::endl; + else if (pass == 3) + std::cout << "Optional output options: " << std::endl << std::endl; } - if (pass == 1) // Append default value to description. + if (pass >= 2) // Append default value to description. { desc += " Default value "; std::stringstream tmp; @@ -679,7 +700,6 @@ void CLI::PrintHelp(const std::string& param) } std::cout << std::endl; - } // Helpful information at the bottom of the help output, to point the user to @@ -751,7 +771,7 @@ void CLI::UpdateGmap() // Add help parameter. PARAM_FLAG("help", "Default help info.", "h"); -PARAM_STRING("info", "Get help on a specific module or option.", "", ""); +PARAM_STRING_IN("info", "Get help on a specific module or option.", "", ""); PARAM_FLAG("verbose", "Display informational messages and the full list of " "parameters and timers at the end of execution.", "v"); PARAM_FLAG("version", "Display the version of mlpack.", "V"); diff --git a/src/mlpack/core/util/cli.hpp b/src/mlpack/core/util/cli.hpp index f6ec7dcbf4f..56c12021b97 100644 --- a/src/mlpack/core/util/cli.hpp +++ b/src/mlpack/core/util/cli.hpp @@ -20,336 +20,7 @@ #include "timers.hpp" #include "cli_deleter.hpp" // To make sure we can delete the singleton. #include "version.hpp" - -/** - * Document an executable. Only one instance of this macro should be - * present in your program! Therefore, use it in the main.cpp - * (or corresponding executable) in your program. - * - * @see mlpack::CLI, PARAM_FLAG(), PARAM_INT(), PARAM_DOUBLE(), PARAM_STRING(), - * PARAM_VECTOR(), PARAM_INT_REQ(), PARAM_DOUBLE_REQ(), PARAM_STRING_REQ(), - * PARAM_VECTOR_REQ(). - * - * @param NAME Short string representing the name of the program. - * @param DESC Long string describing what the program does and possibly a - * simple usage example. Newlines should not be used here; this is taken - * care of by CLI (however, you can explicitly specify newlines to denote - * new paragraphs). - */ -#define PROGRAM_INFO(NAME, DESC) static mlpack::util::ProgramDoc \ - io_programdoc_dummy_object = mlpack::util::ProgramDoc(NAME, DESC); - -/** - * Define a flag parameter. - * - * @param ID Name of the parameter. - * @param DESC Quick description of the parameter (1-2 sentences). - * @param ALIAS An alias for the parameter (one letter). - * - * @see mlpack::CLI, PROGRAM_INFO() - * - * @bug - * The __COUNTER__ variable is used in most cases to guarantee a unique global - * identifier for options declared using the PARAM_*() macros. However, not all - * compilers have this support--most notably, gcc < 4.3. In that case, the - * __LINE__ macro is used as an attempt to get a unique global identifier, but - * collisions are still possible, and they produce bizarre error messages. See - * https://github.com/mlpack/mlpack/issues/100 for more information. - */ -#define PARAM_FLAG(ID, DESC, ALIAS) \ - PARAM_FLAG_INTERNAL(ID, DESC, ALIAS); - -/** - * Define an integer parameter. - * - * The parameter can then be specified on the command line with - * --ID=value. - * - * @param ID Name of the parameter. - * @param DESC Quick description of the parameter (1-2 sentences). - * @param ALIAS An alias for the parameter (one letter). - * @param DEF Default value of the parameter. - * - * @see mlpack::CLI, PROGRAM_INFO() - * - * @bug - * The __COUNTER__ variable is used in most cases to guarantee a unique global - * identifier for options declared using the PARAM_*() macros. However, not all - * compilers have this support--most notably, gcc < 4.3. In that case, the - * __LINE__ macro is used as an attempt to get a unique global identifier, but - * collisions are still possible, and they produce bizarre error messages. See - * https://github.com/mlpack/mlpack/issues/100 for more information. - */ -#define PARAM_INT(ID, DESC, ALIAS, DEF) \ - PARAM(int, ID, DESC, ALIAS, DEF, false) - -/** - * Define a floating-point parameter. You should use PARAM_DOUBLE instead. - * - * The parameter can then be specified on the command line with - * --ID=value. - * - * @param ID Name of the parameter. - * @param DESC Quick description of the parameter (1-2 sentences). - * @param ALIAS An alias for the parameter (one letter). - * @param DEF Default value of the parameter. - * - * @see mlpack::CLI, PROGRAM_INFO() - * - * @bug - * The __COUNTER__ variable is used in most cases to guarantee a unique global - * identifier for options declared using the PARAM_*() macros. However, not all - * compilers have this support--most notably, gcc < 4.3. In that case, the - * __LINE__ macro is used as an attempt to get a unique global identifier, but - * collisions are still possible, and they produce bizarre error messages. See - * https://github.com/mlpack/mlpack/issues/100 for more information. - */ -#define PARAM_FLOAT(ID, DESC, ALIAS, DEF) \ - PARAM(float, ID, DESC, ALIAS, DEF, false) - -/** - * Define a double parameter. - * - * The parameter can then be specified on the command line with - * --ID=value. - * - * @param ID Name of the parameter. - * @param DESC Quick description of the parameter (1-2 sentences). - * @param ALIAS An alias for the parameter (one letter). - * @param DEF Default value of the parameter. - * - * @see mlpack::CLI, PROGRAM_INFO() - * - * @bug - * The __COUNTER__ variable is used in most cases to guarantee a unique global - * identifier for options declared using the PARAM_*() macros. However, not all - * compilers have this support--most notably, gcc < 4.3. In that case, the - * __LINE__ macro is used as an attempt to get a unique global identifier, but - * collisions are still possible, and they produce bizarre error messages. See - * https://github.com/mlpack/mlpack/issues/100 for more information. - */ -#define PARAM_DOUBLE(ID, DESC, ALIAS, DEF) \ - PARAM(double, ID, DESC, ALIAS, DEF, false) - -/** - * Define a string parameter. - * - * The parameter can then be specified on the command line with - * --ID=value. If ALIAS is equal to DEF_MOD (which is set using the - * PROGRAM_INFO() macro), the parameter can be specified with just --ID=value. - * - * @param ID Name of the parameter. - * @param DESC Quick description of the parameter (1-2 sentences). - * @param ALIAS An alias for the parameter (one letter). - * @param DEF Default value of the parameter. - * - * @see mlpack::CLI, PROGRAM_INFO() - * - * @bug - * The __COUNTER__ variable is used in most cases to guarantee a unique global - * identifier for options declared using the PARAM_*() macros. However, not all - * compilers have this support--most notably, gcc < 4.3. In that case, the - * __LINE__ macro is used as an attempt to get a unique global identifier, but - * collisions are still possible, and they produce bizarre error messages. See - * https://github.com/mlpack/mlpack/issues/100 for more information. - */ -#define PARAM_STRING(ID, DESC, ALIAS, DEF) \ - PARAM(std::string, ID, DESC, ALIAS, DEF, false) - -/** - * Define a vector parameter. - * - * The parameter can then be specified on the command line with - * --ID=value. - * - * @param ID Name of the parameter. - * @param DESC Quick description of the parameter (1-2 sentences). - * @param ALIAS An alias for the parameter (one letter). - * @param DEF Default value of the parameter. - * - * @see mlpack::CLI, PROGRAM_INFO() - * - * @bug - * The __COUNTER__ variable is used in most cases to guarantee a unique global - * identifier for options declared using the PARAM_*() macros. However, not all - * compilers have this support--most notably, gcc < 4.3. In that case, the - * __LINE__ macro is used as an attempt to get a unique global identifier, but - * collisions are still possible, and they produce bizarre error messages. See - * https://github.com/mlpack/mlpack/issues/100 for more information. - */ -#define PARAM_VECTOR(T, ID, DESC, ALIAS) \ - PARAM(std::vector, ID, DESC, ALIAS, std::vector(), false) - -// A required flag doesn't make sense and isn't given here. - -/** - * Define a required integer parameter. - * - * The parameter must then be specified on the command line with - * --ID=value. - * - * @param ID Name of the parameter. - * @param DESC Quick description of the parameter (1-2 sentences). - * @param ALIAS An alias for the parameter (one letter). - * - * @see mlpack::CLI, PROGRAM_INFO() - * - * @bug - * The __COUNTER__ variable is used in most cases to guarantee a unique global - * identifier for options declared using the PARAM_*() macros. However, not all - * compilers have this support--most notably, gcc < 4.3. In that case, the - * __LINE__ macro is used as an attempt to get a unique global identifier, but - * collisions are still possible, and they produce bizarre error messages. See - * https://github.com/mlpack/mlpack/issues/100 for more information. - */ -#define PARAM_INT_REQ(ID, DESC, ALIAS) PARAM(int, ID, DESC, ALIAS, 0, true) - -/** - * Define a required floating-point parameter. You should probably use a double - * instead. - * - * The parameter must then be specified on the command line with - * --ID=value. If ALIAS is equal to DEF_MOD (which is set using the - * PROGRAM_INFO() macro), the parameter can be specified with just --ID=value. - * - * @param ID Name of the parameter. - * @param DESC Quick description of the parameter (1-2 sentences). - * @param ALIAS An alias for the parameter (one letter). - * - * @see mlpack::CLI, PROGRAM_INFO() - * - * @bug - * The __COUNTER__ variable is used in most cases to guarantee a unique global - * identifier for options declared using the PARAM_*() macros. However, not all - * compilers have this support--most notably, gcc < 4.3. In that case, the - * __LINE__ macro is used as an attempt to get a unique global identifier, but - * collisions are still possible, and they produce bizarre error messages. See - * https://github.com/mlpack/mlpack/issues/100 for more information. - */ -#define PARAM_FLOAT_REQ(ID, DESC, ALIAS) PARAM(float, ID, DESC, ALIAS, 0.0f, \ - true) - -/** - * Define a required double parameter. - * - * The parameter must then be specified on the command line with - * --ID=value. - * - * @param ID Name of the parameter. - * @param DESC Quick description of the parameter (1-2 sentences). - * @param ALIAS An alias for the parameter (one letter). - * - * @see mlpack::CLI, PROGRAM_INFO() - * - * @bug - * The __COUNTER__ variable is used in most cases to guarantee a unique global - * identifier for options declared using the PARAM_*() macros. However, not all - * compilers have this support--most notably, gcc < 4.3. In that case, the - * __LINE__ macro is used as an attempt to get a unique global identifier, but - * collisions are still possible, and they produce bizarre error messages. See - * https://github.com/mlpack/mlpack/issues/100 for more information. - */ -#define PARAM_DOUBLE_REQ(ID, DESC, ALIAS) PARAM(double, ID, DESC, ALIAS, \ - 0.0f, true) - -/** - * Define a required string parameter. - * - * The parameter must then be specified on the command line with - * --ID=value. - * - * @param ID Name of the parameter. - * @param DESC Quick description of the parameter (1-2 sentences). - * @param ALIAS An alias for the parameter (one letter). - * - * @see mlpack::CLI, PROGRAM_INFO() - * - * @bug - * The __COUNTER__ variable is used in most cases to guarantee a unique global - * identifier for options declared using the PARAM_*() macros. However, not all - * compilers have this support--most notably, gcc < 4.3. In that case, the - * __LINE__ macro is used as an attempt to get a unique global identifier, but - * collisions are still possible, and they produce bizarre error messages. See - * https://github.com/mlpack/mlpack/issues/100 for more information. - */ -#define PARAM_STRING_REQ(ID, DESC, ALIAS) PARAM(std::string, ID, DESC, \ - ALIAS, "", true); - -/** - * Define a required vector parameter. - * - * The parameter must then be specified on the command line with - * --ID=value. - * - * @param ID Name of the parameter. - * @param DESC Quick description of the parameter (1-2 sentences). - * @param ALIAS An alias for the parameter (one letter). - * - * @see mlpack::CLI, PROGRAM_INFO() - * - * @bug - * The __COUNTER__ variable is used in most cases to guarantee a unique global - * identifier for options declared using the PARAM_*() macros. However, not all - * compilers have this support--most notably, gcc < 4.3. In that case, the - * __LINE__ macro is used as an attempt to get a unique global identifier, but - * collisions are still possible, and they produce bizarre error messages. See - * https://github.com/mlpack/mlpack/issues/100 for more information. - */ -#define PARAM_VECTOR_REQ(T, ID, DESC, ALIAS) PARAM(std::vector, ID, DESC, \ - ALIAS, std::vector(), true); - -/** - * @cond - * Don't document internal macros. - */ - -// These are ugly, but necessary utility functions we must use to generate a -// unique identifier inside of the PARAM() module. -#define JOIN(x, y) JOIN_AGAIN(x, y) -#define JOIN_AGAIN(x, y) x ## y -/** @endcond */ - -/** - * Define an input parameter. Don't use this function; use the other ones above - * that call it. Note that we are using the __LINE__ macro for naming these - * actual parameters when __COUNTER__ does not exist, which is a bit of an ugly - * hack... but this is the preprocessor, after all. We don't have much choice - * other than ugliness. - * - * @param T Type of the parameter. - * @param ID Name of the parameter. - * @param DESC Description of the parameter (1-2 sentences). - * @param ALIAS Alias for this parameter (one letter). - * @param DEF Default value of the parameter. - * @param REQ Whether or not parameter is required (boolean value). - */ -#ifdef __COUNTER__ - #define PARAM(T, ID, DESC, ALIAS, DEF, REQ) static mlpack::util::Option \ - JOIN(io_option_dummy_object_, __COUNTER__) \ - (false, DEF, ID, DESC, ALIAS, REQ); - - /** @cond Don't document internal macros. */ - #define PARAM_FLAG_INTERNAL(ID, DESC, ALIAS) static \ - mlpack::util::Option JOIN(__io_option_flag_object_, __COUNTER__) \ - (ID, DESC, ALIAS); - /** @endcond */ - -#else - // We have to do some really bizarre stuff since __COUNTER__ isn't defined. I - // don't think we can absolutely guarantee success, but it should be "good - // enough". We use the __LINE__ macro and the type of the parameter to try - // and get a good guess at something unique. - #define PARAM(T, ID, DESC, ALIAS, DEF, REQ) static mlpack::util::Option \ - JOIN(JOIN(io_option_dummy_object_, __LINE__), opt) (false, DEF, ID, \ - DESC, ALIAS, REQ); - - /** @cond Don't document internal macros. */ - #define PARAM_FLAG_INTERNAL(ID, DESC, ALIAS) static \ - mlpack::util::Option JOIN(__io_option_flag_object_, __LINE__) \ - (ID, DESC, ALIAS); - /** @endcond */ - -#endif +#include "param.hpp" /** * The TYPENAME macro is used internally to convert a type into a string. @@ -384,7 +55,7 @@ struct ParamData boost::any value; //! True if this parameter was passed in via command line or file. bool wasPassed; - //! True if the wasPassed value should not be ignored + //! True if the wasPassed value should not be ignored. bool isFlag; }; @@ -526,11 +197,13 @@ class CLI * @param alias An alias for the parameter, defaults to "" which is no alias. * (""). * @param required Indicates if parameter must be set on command line. + * @param input If true, the parameter is an input (not output) parameter. */ static void Add(const std::string& path, const std::string& description, const std::string& alias = "", - bool required = false); + const bool required = false, + const bool input = true); /** * Adds a parameter to the hierarchy; use the PARAM_*() macros instead of this @@ -542,12 +215,14 @@ class CLI * @param description Short string description of the parameter. * @param alias An alias for the parameter, defaults to "" which is no alias. * @param required Indicates if parameter must be set on command line. + * @param input If true, the parameter is an input (not output) parameter. */ template static void Add(const std::string& identifier, const std::string& description, const std::string& alias = "", - bool required = false); + const bool required = false, + const bool input = true); /** * Adds a flag parameter to the hierarchy; use PARAM_FLAG() instead of this. @@ -676,6 +351,11 @@ class CLI //! Pathnames of required options. std::list requiredOptions; + //! Pathnames of input options. + std::list inputOptions; + //! Pathnames of output options. + std::list outputOptions; + //! Map of global values. typedef std::map gmap_t; gmap_t globalValues; diff --git a/src/mlpack/core/util/cli_impl.hpp b/src/mlpack/core/util/cli_impl.hpp index 72f4be2c338..45926504d57 100644 --- a/src/mlpack/core/util/cli_impl.hpp +++ b/src/mlpack/core/util/cli_impl.hpp @@ -22,16 +22,19 @@ namespace mlpack { * @tparam T The type of the parameter. * @param identifier The name of the parameter, eg foo in bar/foo. * @param description A string description of the parameter. - * @param parent The name of the parent of the parameter, - * eg bar/foo in bar/foo/buzz. - * @param required If required, the program will refuse to run - * unless the parameter is specified. + * @param parent The name of the parent of the parameter, e.g. bar/foo in + * bar/foo/buzz. + * @param required If required, the program will refuse to run unless the + * parameter is specified. + * @param input If true, the parameter is an input parameter (not an output + * parameter). */ template void CLI::Add(const std::string& path, const std::string& description, const std::string& alias, - bool required) + const bool required, + const bool input) { po::options_description& desc = CLI::GetSingleton().desc; @@ -61,6 +64,13 @@ void CLI::Add(const std::string& path, // If the option is required, add it to the required options list. if (required) GetSingleton().requiredOptions.push_front(path); + + // Depending on whether or not the option is input or output, add it to the + // appropriate list. + if (input) + GetSingleton().inputOptions.push_front(path); + else + GetSingleton().outputOptions.push_front(path); } // We specialize this in cli.cpp. diff --git a/src/mlpack/core/util/option.hpp b/src/mlpack/core/util/option.hpp index cf640790e84..1efef14914e 100644 --- a/src/mlpack/core/util/option.hpp +++ b/src/mlpack/core/util/option.hpp @@ -41,13 +41,15 @@ class Option * @param parent Full pathname of the parent module that "owns" this option. * The default is the root node (an empty string). * @param required Whether or not the option is required at runtime. + * @param input Whether or not the option is an input option. */ - Option(bool ignoreTemplate, - N defaultValue, + Option(const bool ignoreTemplate, + const N defaultValue, const std::string& identifier, const std::string& description, const std::string& parent = std::string(""), - bool required = false); + const bool required = false, + const bool input = true); /** * Constructs an Option object. When constructed, it will register a flag diff --git a/src/mlpack/core/util/option_impl.hpp b/src/mlpack/core/util/option_impl.hpp index 6684c1aaa6e..56a812853bc 100644 --- a/src/mlpack/core/util/option_impl.hpp +++ b/src/mlpack/core/util/option_impl.hpp @@ -17,20 +17,21 @@ namespace util { * Registers a parameter with CLI. */ template -Option::Option(bool ignoreTemplate, - N defaultValue, +Option::Option(const bool ignoreTemplate, + const N defaultValue, const std::string& identifier, const std::string& description, const std::string& alias, - bool required) + const bool required, + const bool input) { if (ignoreTemplate) { - CLI::Add(identifier, description, alias, required); + CLI::Add(identifier, description, alias, required, input); } else { - CLI::Add(identifier, description, alias, required); + CLI::Add(identifier, description, alias, required, input); CLI::GetParam(identifier) = defaultValue; } } diff --git a/src/mlpack/core/util/param.hpp b/src/mlpack/core/util/param.hpp new file mode 100644 index 00000000000..77569087966 --- /dev/null +++ b/src/mlpack/core/util/param.hpp @@ -0,0 +1,426 @@ +/** + * @file param.hpp + * @author Matthew Amidon + * @author Ryan Curtin + * + * Definition of PARAM_*_IN() and PARAM_*_OUT() macros, as well as the + * PROGRAM_INFO() macro, which are used to define input and output parameters of + * command-line programs and bindings to other languages. + */ +#ifndef MLPACK_CORE_UTIL_PARAM_HPP +#define MLPACK_CORE_UTIL_PARAM_HPP + +/** + * Document an executable. Only one instance of this macro should be + * present in your program! Therefore, use it in the main.cpp + * (or corresponding executable) in your program. + * + * @see mlpack::CLI, PARAM_FLAG(), PARAM_INT_IN(), PARAM_DOUBLE_IN(), + * PARAM_STRING_IN(), PARAM_VECTOR_IN(), PARAM_INT_OUT(), PARAM_DOUBLE_OUT(), + * PARAM_VECTOR_OUT(), PARAM_INT_IN_REQ(), PARAM_DOUBLE_IN_REQ(), + * PARAM_STRING_IN_REQ(), PARAM_VECTOR_IN_REQ(), PARAM_INT_OUT_REQ(), + * PARAM_DOUBLE_OUT_REQ(), PARAM_VECTOR_OUT_REQ(), PARAM_STRING_OUT_REQ(). + * + * @param NAME Short string representing the name of the program. + * @param DESC Long string describing what the program does and possibly a + * simple usage example. Newlines should not be used here; this is taken + * care of by CLI (however, you can explicitly specify newlines to denote + * new paragraphs). + */ +#define PROGRAM_INFO(NAME, DESC) static mlpack::util::ProgramDoc \ + cli_programdoc_dummy_object = mlpack::util::ProgramDoc(NAME, DESC); + +/** + * Define a flag parameter. + * + * @param ID Name of the parameter. + * @param DESC Quick description of the parameter (1-2 sentences). + * @param ALIAS An alias for the parameter (one letter). + * + * @see mlpack::CLI, PROGRAM_INFO() + * + * @bug + * The __COUNTER__ variable is used in most cases to guarantee a unique global + * identifier for options declared using the PARAM_*() macros. However, not all + * compilers have this support--most notably, gcc < 4.3. In that case, the + * __LINE__ macro is used as an attempt to get a unique global identifier, but + * collisions are still possible, and they produce bizarre error messages. See + * https://github.com/mlpack/mlpack/issues/100 for more information. + */ +#define PARAM_FLAG(ID, DESC, ALIAS) \ + PARAM_FLAG_INTERNAL(ID, DESC, ALIAS); + +/** + * Define an integer input parameter. + * + * The parameter can then be specified on the command line with + * --ID=value. + * + * @param ID Name of the parameter. + * @param DESC Quick description of the parameter (1-2 sentences). + * @param ALIAS An alias for the parameter (one letter). + * @param DEF Default value of the parameter. + * + * @see mlpack::CLI, PROGRAM_INFO() + * + * @bug + * The __COUNTER__ variable is used in most cases to guarantee a unique global + * identifier for options declared using the PARAM_*() macros. However, not all + * compilers have this support--most notably, gcc < 4.3. In that case, the + * __LINE__ macro is used as an attempt to get a unique global identifier, but + * collisions are still possible, and they produce bizarre error messages. See + * https://github.com/mlpack/mlpack/issues/100 for more information. + */ +#define PARAM_INT_IN(ID, DESC, ALIAS, DEF) \ + PARAM_IN(int, ID, DESC, ALIAS, DEF, false) + +/** + * Define an integer output parameter. This parameter will be printed on stdout + * at the end of the program; for instance, if the parameter name is "number" + * and the value is 5, the output on stdout would be of the following form: + * + * @code + * number: 5 + * @endcode + * + * If the parameter is not set by the end of the program, a fatal runtime error + * will be issued. + * + * @param ID Name of the parameter. + * @param DESC Quick description of the parameter (1-2 sentences). + * + * @see mlpack::CLI, PROGRAM_INFO() + * + * @bug + * The __COUNTER__ variable is used in most cases to guarantee a unique global + * identifier for options declared using the PARAM_*() macros. However, not all + * compilers have this support--most notably, gcc < 4.3. In that case, the + * __LINE__ macro is used as an attempt to get a unique global identifier, but + * collisions are still possible, and they produce bizarre error messages. See + * https://github.com/mlpack/mlpack/issues/100 for more information. + */ +#define PARAM_INT_OUT(ID, DESC) \ + PARAM_IN(int, ID, DESC, "", 0, false) + +/** + * Define a double input parameter. + * + * The parameter can then be specified on the command line with + * --ID=value. + * + * @param ID Name of the parameter. + * @param DESC Quick description of the parameter (1-2 sentences). + * @param ALIAS An alias for the parameter (one letter). + * @param DEF Default value of the parameter. + * + * @see mlpack::CLI, PROGRAM_INFO() + * + * @bug + * The __COUNTER__ variable is used in most cases to guarantee a unique global + * identifier for options declared using the PARAM_*() macros. However, not all + * compilers have this support--most notably, gcc < 4.3. In that case, the + * __LINE__ macro is used as an attempt to get a unique global identifier, but + * collisions are still possible, and they produce bizarre error messages. See + * https://github.com/mlpack/mlpack/issues/100 for more information. + */ +#define PARAM_DOUBLE_IN(ID, DESC, ALIAS, DEF) \ + PARAM_IN(double, ID, DESC, ALIAS, DEF, false) + +/** + * Define a double output parameter. This parameter will be printed on stdout + * at the end of the program; for instance, if the parameter name is "number" + * and the value is 5.012, the output on stdout would be of the following form: + * + * @code + * number: 5.012 + * @endcode + * + * If the parameter is not set by the end of the program, a fatal runtime error + * will be issued. + * + * @param ID Name of the parameter. + * @param DESC Quick description of the parameter (1-2 sentences). + * + * @see mlpack::CLI, PROGRAM_INFO() + * + * @bug + * The __COUNTER__ variable is used in most cases to guarantee a unique global + * identifier for options declared using the PARAM_*() macros. However, not all + * compilers have this support--most notably, gcc < 4.3. In that case, the + * __LINE__ macro is used as an attempt to get a unique global identifier, but + * collisions are still possible, and they produce bizarre error messages. See + * https://github.com/mlpack/mlpack/issues/100 for more information. + */ +#define PARAM_DOUBLE_OUT(ID, DESC) \ + PARAM_OUT(double, ID, DESC, "", 0.0d, false) + +/** + * Define a string input parameter. + * + * The parameter can then be specified on the command line with + * --ID=value. If ALIAS is equal to DEF_MOD (which is set using the + * PROGRAM_INFO() macro), the parameter can be specified with just --ID=value. + * + * @param ID Name of the parameter. + * @param DESC Quick description of the parameter (1-2 sentences). + * @param ALIAS An alias for the parameter (one letter). + * @param DEF Default value of the parameter. + * + * @see mlpack::CLI, PROGRAM_INFO() + * + * @bug + * The __COUNTER__ variable is used in most cases to guarantee a unique global + * identifier for options declared using the PARAM_*() macros. However, not all + * compilers have this support--most notably, gcc < 4.3. In that case, the + * __LINE__ macro is used as an attempt to get a unique global identifier, but + * collisions are still possible, and they produce bizarre error messages. See + * https://github.com/mlpack/mlpack/issues/100 for more information. + */ +#define PARAM_STRING_IN(ID, DESC, ALIAS, DEF) \ + PARAM_IN(std::string, ID, DESC, ALIAS, DEF, false) + +/** + * Define a string output parameter. + * + * If the parameter name does not end in "_file" (i.e. "output_file", + * "predictions_file", etc.), then the string will be printed to stdout at the + * end of the program. For instance, if there was a string output parameter + * called "something" with value "hello", at the end of the program the output + * would be of the following form: + * + * @code + * something: "hello" + * @endcode + * + * If the parameter is not set by the end of the program, a fatal runtime error + * will be issued. + * + * An alias is still allowed for string output parameters, because if the + * parameter name ends in "_file", then the user must be able to specify it as + * input. The default value will always be the empty string. + * + * @param ID Name of the parameter. + * @param DESC Quick description of the parameter (1-2 sentences). + * @param ALIAS An alias for the parameter (one letter). + * + * @see mlpack::CLI, PROGRAM_INFO() + * + * @bug + * The __COUNTER__ variable is used in most cases to guarantee a unique global + * identifier for options declared using the PARAM_*() macros. However, not all + * compilers have this support--most notably, gcc < 4.3. In that case, the + * __LINE__ macro is used as an attempt to get a unique global identifier, but + * collisions are still possible, and they produce bizarre error messages. See + * https://github.com/mlpack/mlpack/issues/100 for more information. + */ +#define PARAM_STRING_OUT(ID, DESC, ALIAS) \ + PARAM_OUT(std::string, ID, DESC, ALIAS, "", false) + +/** + * Define a vector input parameter. + * + * The parameter can then be specified on the command line with + * --ID=value1,value2,value3. + * + * @param ID Name of the parameter. + * @param DESC Quick description of the parameter (1-2 sentences). + * @param ALIAS An alias for the parameter (one letter). + * @param DEF Default value of the parameter. + * + * @see mlpack::CLI, PROGRAM_INFO() + * + * @bug + * The __COUNTER__ variable is used in most cases to guarantee a unique global + * identifier for options declared using the PARAM_*() macros. However, not all + * compilers have this support--most notably, gcc < 4.3. In that case, the + * __LINE__ macro is used as an attempt to get a unique global identifier, but + * collisions are still possible, and they produce bizarre error messages. See + * https://github.com/mlpack/mlpack/issues/100 for more information. + */ +#define PARAM_VECTOR_IN(T, ID, DESC, ALIAS) \ + PARAM_IN(std::vector, ID, DESC, ALIAS, std::vector(), false) + +/** + * Define a vector output parameter. This vector will be printed on stdout at + * the end of the program; for instance, if the parameter name is "vector" and + * the vector holds the array { 1, 2, 3, 4 }, the output on stdout would be of + * the following form: + * + * @code + * vector: 1, 2, 3, 4 + * @endcode + * + * If the parameter is not set by the end of the program, a fatal runtime error + * will be issued. + * + * @param ID Name of the parameter. + * @param DESC Quick description of the parameter (1-2 sentences). + * + * @see mlpack::CLI, PROGRAM_INFO() + * + * @bug + * The __COUNTER__ variable is used in most cases to guarantee a unique global + * identifier for options declared using the PARAM_*() macros. However, not all + * compilers have this support--most notably, gcc < 4.3. In that case, the + * __LINE__ macro is used as an attempt to get a unique global identifier, but + * collisions are still possible, and they produce bizarre error messages. See + * https://github.com/mlpack/mlpack/issues/100 for more information. + */ +#define PARAM_VECTOR_OUT(T, ID) \ + PARAM_OUT(std::vector, ID, DESC, "", std::vector(), false) + +/** + * Define a required integer input parameter. + * + * The parameter must then be specified on the command line with --ID=value. + * + * @param ID Name of the parameter. + * @param DESC Quick description of the parameter (1-2 sentences). + * @param ALIAS An alias for the parameter (one letter). + * + * @see mlpack::CLI, PROGRAM_INFO() + * + * @bug + * The __COUNTER__ variable is used in most cases to guarantee a unique global + * identifier for options declared using the PARAM_*() macros. However, not all + * compilers have this support--most notably, gcc < 4.3. In that case, the + * __LINE__ macro is used as an attempt to get a unique global identifier, but + * collisions are still possible, and they produce bizarre error messages. See + * https://github.com/mlpack/mlpack/issues/100 for more information. + */ +#define PARAM_INT_IN_REQ(ID, DESC, ALIAS) \ + PARAM_IN(int, ID, DESC, ALIAS, 0, true) + +/** + * Define a required double parameter. + * + * The parameter must then be specified on the command line with --ID=value. + * + * @param ID Name of the parameter. + * @param DESC Quick description of the parameter (1-2 sentences). + * @param ALIAS An alias for the parameter (one letter). + * + * @see mlpack::CLI, PROGRAM_INFO() + * + * @bug + * The __COUNTER__ variable is used in most cases to guarantee a unique global + * identifier for options declared using the PARAM_*() macros. However, not all + * compilers have this support--most notably, gcc < 4.3. In that case, the + * __LINE__ macro is used as an attempt to get a unique global identifier, but + * collisions are still possible, and they produce bizarre error messages. See + * https://github.com/mlpack/mlpack/issues/100 for more information. + */ +#define PARAM_DOUBLE_IN_REQ(ID, DESC, ALIAS) \ + PARAM_IN(double, ID, DESC, ALIAS, 0.0d, true) + +/** + * Define a required string parameter. + * + * The parameter must then be specified on the command line with --ID=value. + * + * @param ID Name of the parameter. + * @param DESC Quick description of the parameter (1-2 sentences). + * @param ALIAS An alias for the parameter (one letter). + * + * @see mlpack::CLI, PROGRAM_INFO() + * + * @bug + * The __COUNTER__ variable is used in most cases to guarantee a unique global + * identifier for options declared using the PARAM_*() macros. However, not all + * compilers have this support--most notably, gcc < 4.3. In that case, the + * __LINE__ macro is used as an attempt to get a unique global identifier, but + * collisions are still possible, and they produce bizarre error messages. See + * https://github.com/mlpack/mlpack/issues/100 for more information. + */ +#define PARAM_STRING_IN_REQ(ID, DESC, ALIAS) \ + PARAM_IN(std::string, ID, DESC, ALIAS, "", true) + +/** + * Define a required vector parameter. + * + * The parameter must then be specified on the command line with + * --ID=value1,value2,value3. + * + * @param ID Name of the parameter. + * @param DESC Quick description of the parameter (1-2 sentences). + * @param ALIAS An alias for the parameter (one letter). + * + * @see mlpack::CLI, PROGRAM_INFO() + * + * @bug + * The __COUNTER__ variable is used in most cases to guarantee a unique global + * identifier for options declared using the PARAM_*() macros. However, not all + * compilers have this support--most notably, gcc < 4.3. In that case, the + * __LINE__ macro is used as an attempt to get a unique global identifier, but + * collisions are still possible, and they produce bizarre error messages. See + * https://github.com/mlpack/mlpack/issues/100 for more information. + */ +#define PARAM_VECTOR_IN_REQ(T, ID, DESC, ALIAS) \ + PARAM_IN(std::vector, ID, DESC, ALIAS, std::vector(), true); + +/** + * @cond + * Don't document internal macros. + */ + +// These are ugly, but necessary utility functions we must use to generate a +// unique identifier inside of the PARAM() module. +#define JOIN(x, y) JOIN_AGAIN(x, y) +#define JOIN_AGAIN(x, y) x ## y +/** @endcond */ + +/** + * Define an input parameter. Don't use this function; use the other ones above + * that call it. Note that we are using the __LINE__ macro for naming these + * actual parameters when __COUNTER__ does not exist, which is a bit of an ugly + * hack... but this is the preprocessor, after all. We don't have much choice + * other than ugliness. + * + * @param T Type of the parameter. + * @param ID Name of the parameter. + * @param DESC Description of the parameter (1-2 sentences). + * @param ALIAS Alias for this parameter (one letter). + * @param DEF Default value of the parameter. + * @param REQ Whether or not parameter is required (boolean value). + */ +#ifdef __COUNTER__ + #define PARAM_IN(T, ID, DESC, ALIAS, DEF, REQ) \ + static mlpack::util::Option \ + JOIN(cli_option_dummy_object_in_, __COUNTER__) \ + (false, DEF, ID, DESC, ALIAS, REQ, true); + + #define PARAM_OUT(T, ID, DESC, ALIAS, DEF, REQ) \ + static mlpack::util::Option \ + JOIN(cli_option_dummy_object_out_, __COUNTER__) \ + (false, DEF, ID, DESC, ALIAS, REQ, false); + + /** @cond Don't document internal macros. */ + #define PARAM_FLAG_INTERNAL(ID, DESC, ALIAS) static \ + mlpack::util::Option JOIN(__io_option_flag_object_, __COUNTER__) \ + (ID, DESC, ALIAS); + /** @endcond */ + +#else + // We have to do some really bizarre stuff since __COUNTER__ isn't defined. I + // don't think we can absolutely guarantee success, but it should be "good + // enough". We use the __LINE__ macro and the type of the parameter to try + // and get a good guess at something unique. + #define PARAM_IN(T, ID, DESC, ALIAS, DEF, REQ) \ + static mlpack::util::Option \ + JOIN(JOIN(io_option_dummy_object_in_, __LINE__), opt) \ + (false, DEF, ID, DESC, ALIAS, REQ, true); + + #define PARAM_OUT(T, ID, DESC, ALIAS, DEF, REQ) \ + static mlpack::util::Option \ + JOIN(JOIN(io_option_dummy_object_out_, __LINE__), opt) \ + (false, DEF, ID, DESC, ALIAS, REQ, false); + + /** @cond Don't document internal macros. */ + #define PARAM_FLAG_INTERNAL(ID, DESC, ALIAS) static \ + mlpack::util::Option JOIN(__io_option_flag_object_, __LINE__) \ + (ID, DESC, ALIAS); + /** @endcond */ + +#endif + +#endif diff --git a/src/mlpack/tests/cli_test.cpp b/src/mlpack/tests/cli_test.cpp index d0ebbd3a6e0..7e8157e2374 100644 --- a/src/mlpack/tests/cli_test.cpp +++ b/src/mlpack/tests/cli_test.cpp @@ -98,7 +98,7 @@ BOOST_AUTO_TEST_CASE(TestOption) { // This test will involve creating an option, and making sure CLI reflects // this. - PARAM(int, "test_parent/test", "test desc", "", DEFAULT_INT, false); + PARAM_IN(int, "test_parent/test", "test desc", "", DEFAULT_INT, false); BOOST_REQUIRE_EQUAL(CLI::GetDescription("test_parent/test"), "test desc"); BOOST_REQUIRE_EQUAL(CLI::GetParam("test_parent/test"), DEFAULT_INT); From 6ff92c99b6f83554d7a66b3840137f9bd8f9d423 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 12 Jul 2016 14:55:31 -0400 Subject: [PATCH 02/21] Refactor programs to support input and output parameters. In many places, output parameters with defaults have been modified to default to nothing, and warnings are now issued when those parameters are not specified. --- src/mlpack/methods/adaboost/adaboost_main.cpp | 31 +++++----- src/mlpack/methods/cf/cf_main.cpp | 32 +++++------ .../decision_stump/decision_stump_main.cpp | 23 ++++---- src/mlpack/methods/det/det_main.cpp | 37 ++++++------ src/mlpack/methods/emst/emst_main.cpp | 23 ++++---- src/mlpack/methods/fastmks/fastmks_main.cpp | 33 +++++------ src/mlpack/methods/gmm/gmm_generate_main.cpp | 16 ++++-- .../methods/gmm/gmm_probability_main.cpp | 14 +++-- src/mlpack/methods/gmm/gmm_train_main.cpp | 26 ++++----- src/mlpack/methods/hmm/hmm_generate_main.cpp | 21 ++++--- src/mlpack/methods/hmm/hmm_loglik_main.cpp | 8 ++- src/mlpack/methods/hmm/hmm_train_main.cpp | 22 ++++---- src/mlpack/methods/hmm/hmm_viterbi_main.cpp | 14 +++-- .../hoeffding_trees/hoeffding_tree_main.cpp | 36 ++++++------ .../methods/kernel_pca/kernel_pca_main.cpp | 24 ++++---- src/mlpack/methods/kmeans/kmeans_main.cpp | 37 ++++++------ src/mlpack/methods/lars/lars_main.cpp | 23 ++++---- .../linear_regression_main.cpp | 31 ++++++---- .../local_coordinate_coding_main.cpp | 32 ++++++----- .../logistic_regression_main.cpp | 48 ++++++++-------- src/mlpack/methods/lsh/lsh_main.cpp | 35 ++++++------ .../methods/mean_shift/mean_shift_main.cpp | 25 +++++---- src/mlpack/methods/mvu/mvu_main.cpp | 12 ++-- src/mlpack/methods/naive_bayes/nbc_main.cpp | 17 +++--- src/mlpack/methods/nca/nca_main.cpp | 46 +++++++-------- .../methods/neighbor_search/kfn_main.cpp | 28 +++++----- .../methods/neighbor_search/knn_main.cpp | 27 ++++----- src/mlpack/methods/nmf/nmf_main.cpp | 36 +++++++----- src/mlpack/methods/pca/pca_main.cpp | 20 ++++--- .../methods/perceptron/perceptron_main.cpp | 32 ++++++----- .../preprocess/preprocess_split_main.cpp | 19 ++++--- src/mlpack/methods/radical/radical_main.cpp | 28 ++++++---- .../range_search/range_search_main.cpp | 27 ++++----- src/mlpack/methods/rann/allkrann_main.cpp | 31 +++++----- src/mlpack/methods/rmva/rmva_main.cpp | 37 ++++++------ .../softmax_regression_main.cpp | 32 +++++------ .../sparse_coding/sparse_coding_main.cpp | 56 +++++++++---------- 37 files changed, 554 insertions(+), 485 deletions(-) diff --git a/src/mlpack/methods/adaboost/adaboost_main.cpp b/src/mlpack/methods/adaboost/adaboost_main.cpp index ceed0a87aa3..b4dc309b5ca 100644 --- a/src/mlpack/methods/adaboost/adaboost_main.cpp +++ b/src/mlpack/methods/adaboost/adaboost_main.cpp @@ -64,27 +64,28 @@ PROGRAM_INFO("AdaBoost", "This program implements the AdaBoost (or Adaptive " "a file specified by the --output_model_file (-M) parameter."); // Input for training. -PARAM_STRING("training_file", "A file containing the training set.", "t", ""); -PARAM_STRING("labels_file", "A file containing labels for the training set.", - "l", ""); +PARAM_STRING_IN("training_file", "A file containing the training set.", "t", + ""); +PARAM_STRING_IN("labels_file", "A file containing labels for the training set.", + "l", ""); // Loading/saving of a model. -PARAM_STRING("input_model_file", "File containing input AdaBoost model.", "m", - ""); -PARAM_STRING("output_model_file", "File to save trained AdaBoost model to.", - "M", ""); +PARAM_STRING_IN("input_model_file", "File containing input AdaBoost model.", + "m", ""); +PARAM_STRING_OUT("output_model_file", "File to save trained AdaBoost model to.", + "M"); // Classification options. -PARAM_STRING("test_file", "A file containing the test set.", "T", ""); -PARAM_STRING("output_file", "The file in which the predicted labels for the " - "test set will be written.", "o", ""); +PARAM_STRING_IN("test_file", "A file containing the test set.", "T", ""); +PARAM_STRING_OUT("output_file", "The file in which the predicted labels for the" + " test set will be written.", "o"); // Training options. -PARAM_INT("iterations", "The maximum number of boosting iterations to be run. " - "(0 will run until convergence.)", "i", 1000); -PARAM_DOUBLE("tolerance", "The tolerance for change in values of the weighted " - "error during training.", "e", 1e-10); -PARAM_STRING("weak_learner", "The type of weak learner to use: " +PARAM_INT_IN("iterations", "The maximum number of boosting iterations to be run" + " (0 will run until convergence.)", "i", 1000); +PARAM_DOUBLE_IN("tolerance", "The tolerance for change in values of the " + "weighted error during training.", "e", 1e-10); +PARAM_STRING_IN("weak_learner", "The type of weak learner to use: " "'decision_stump', or 'perceptron'.", "w", "decision_stump"); /** diff --git a/src/mlpack/methods/cf/cf_main.cpp b/src/mlpack/methods/cf/cf_main.cpp index bc46876f657..599b86a90e7 100644 --- a/src/mlpack/methods/cf/cf_main.cpp +++ b/src/mlpack/methods/cf/cf_main.cpp @@ -56,38 +56,38 @@ PROGRAM_INFO("Collaborating Filtering", "This program performs collaborative " "parameter."); // Parameters for training a model. -PARAM_STRING("training_file", "Input dataset to perform CF on.", "t", ""); -PARAM_STRING("algorithm", "Algorithm used for matrix factorization.", "a", +PARAM_STRING_IN("training_file", "Input dataset to perform CF on.", "t", ""); +PARAM_STRING_IN("algorithm", "Algorithm used for matrix factorization.", "a", "NMF"); -PARAM_INT("neighborhood", "Size of the neighborhood of similar users to " +PARAM_INT_IN("neighborhood", "Size of the neighborhood of similar users to " "consider for each query user.", "n", 5); -PARAM_INT("rank", "Rank of decomposed matrices (if 0, a heuristic is used to " - "estimate the rank).", "R", 0); -PARAM_STRING("test_file", "Test set to calculate RMSE on.", "T", ""); +PARAM_INT_IN("rank", "Rank of decomposed matrices (if 0, a heuristic is used to" + " estimate the rank).", "R", 0); +PARAM_STRING_IN("test_file", "Test set to calculate RMSE on.", "T", ""); // Offer the user the option to set the maximum number of iterations, and // terminate only based on the number of iterations. -PARAM_INT("max_iterations", "Maximum number of iterations.", "N", 1000); +PARAM_INT_IN("max_iterations", "Maximum number of iterations.", "N", 1000); PARAM_FLAG("iteration_only_termination", "Terminate only when the maximum " "number of iterations is reached.", "I"); -PARAM_DOUBLE("min_residue", "Residue required to terminate the factorization " - "(lower values generally mean better fits).", "r", 1e-5); +PARAM_DOUBLE_IN("min_residue", "Residue required to terminate the factorization" + " (lower values generally mean better fits).", "r", 1e-5); // Load/save a model. -PARAM_STRING("input_model_file", "File to load trained CF model from.", "m", +PARAM_STRING_IN("input_model_file", "File to load trained CF model from.", "m", ""); -PARAM_STRING("output_model_file", "File to save trained CF model to.", "M", ""); +PARAM_STRING_OUT("output_model_file", "File to save trained CF model to.", "M"); // Query settings. -PARAM_STRING("query_file", "List of users for which recommendations are to " +PARAM_STRING_IN("query_file", "List of users for which recommendations are to " "be generated.", "q", ""); PARAM_FLAG("all_user_recommendations", "Generate recommendations for all " "users.", "A"); -PARAM_STRING("output_file","File to save output recommendations to.", "o", ""); -PARAM_INT("recommendations", "Number of recommendations to generate for each " - "query user.", "n", 5); +PARAM_STRING_OUT("output_file","File to save output recommendations to.", "o"); +PARAM_INT_IN("recommendations", "Number of recommendations to generate for each" + " query user.", "c", 5); -PARAM_INT("seed", "Set the random seed (0 uses std::time(NULL)).", "s", 0); +PARAM_INT_IN("seed", "Set the random seed (0 uses std::time(NULL)).", "s", 0); void ComputeRecommendations(CF& cf, const size_t numRecs, diff --git a/src/mlpack/methods/decision_stump/decision_stump_main.cpp b/src/mlpack/methods/decision_stump/decision_stump_main.cpp index e0828af9226..9ca428d485f 100644 --- a/src/mlpack/methods/decision_stump/decision_stump_main.cpp +++ b/src/mlpack/methods/decision_stump/decision_stump_main.cpp @@ -51,23 +51,24 @@ PROGRAM_INFO("Decision Stump", "program (or others)."); // Datasets we might load. -PARAM_STRING("training_file", "A file containing the training set.", "t", ""); -PARAM_STRING("labels_file", "A file containing labels for the training set. If " - "not specified, the labels are assumed to be the last row of the training " - "data.", "l", ""); -PARAM_STRING("test_file", "A file containing the test set.", "T", ""); +PARAM_STRING_IN("training_file", "A file containing the training set.", "t", + ""); +PARAM_STRING_IN("labels_file", "A file containing labels for the training set." + "If not specified, the labels are assumed to be the last row of the " + "training data.", "l", ""); +PARAM_STRING_IN("test_file", "A file containing the test set.", "T", ""); // Output. -PARAM_STRING("predictions_file", "The file in which the predicted labels for " - "the test set will be written.", "p", "predictions.csv"); +PARAM_STRING_OUT("predictions_file", "The file in which the predicted labels " + "for the test set will be written.", "p"); // We may load or save a model. -PARAM_STRING("input_model_file", "File containing decision stump model to " +PARAM_STRING_IN("input_model_file", "File containing decision stump model to " "load.", "m", ""); -PARAM_STRING("output_model_file", "File to save trained decision stump model " - "to.", "M", ""); +PARAM_STRING_OUT("output_model_file", "File to save trained decision stump " + "model to.", "M"); -PARAM_INT("bucket_size", "The minimum number of training points in each " +PARAM_INT_IN("bucket_size", "The minimum number of training points in each " "decision stump bucket.", "b", 6); /** diff --git a/src/mlpack/methods/det/det_main.cpp b/src/mlpack/methods/det/det_main.cpp index 87446d56840..45d5faac877 100644 --- a/src/mlpack/methods/det/det_main.cpp +++ b/src/mlpack/methods/det/det_main.cpp @@ -1,10 +1,9 @@ /** - * @file dt_main.cpp - * @ Parikshit Ram (pram@cc.gatech.edu) + * @file det_main.cpp + * @author Parikshit Ram (pram@cc.gatech.edu) * - * This file provides an example use of the DET + * This file runs density estimation trees. */ - #include #include "dt_utils.hpp" @@ -33,32 +32,32 @@ PROGRAM_INFO("Density Estimation With Density Estimation Trees", "into the file specified with the --test_set_estimates_file (-E) option."); // Input data files. -PARAM_STRING("training_file", "The data set on which to build a density " +PARAM_STRING_IN("training_file", "The data set on which to build a density " "estimation tree.", "t", ""); // Input or output model. -PARAM_STRING("input_model_file", "File containing already trained density " +PARAM_STRING_IN("input_model_file", "File containing already trained density " "estimation tree.", "m", ""); -PARAM_STRING("output_model_file", "File to save trained density estimation tree" - " to.", "M", ""); +PARAM_STRING_OUT("output_model_file", "File to save trained density estimation " + "tree to.", "M"); // Output data files. -PARAM_STRING("test_file", "A set of test points to estimate the density of.", +PARAM_STRING_IN("test_file", "A set of test points to estimate the density of.", "T", ""); -PARAM_STRING("training_set_estimates_file", "The file in which to output the " - "density estimates on the training set from the final optimally pruned " - "tree.", "e", ""); -PARAM_STRING("test_set_estimates_file", "The file in which to output the " - "estimates on the test set from the final optimally pruned tree.", "E", ""); -PARAM_STRING("vi_file", "The file to output the variable importance values " - "for each feature.", "i", ""); +PARAM_STRING_OUT("training_set_estimates_file", "The file in which to output " + "the density estimates on the training set from the final optimally pruned " + "tree.", "e"); +PARAM_STRING_OUT("test_set_estimates_file", "The file in which to output the " + "estimates on the test set from the final optimally pruned tree.", "E"); +PARAM_STRING_OUT("vi_file", "The file to output the variable importance values " + "for each feature.", "i"); // Parameters for the training algorithm. -PARAM_INT("folds", "The number of folds of cross-validation to perform for the " +PARAM_INT_IN("folds", "The number of folds of cross-validation to perform for the " "estimation (0 is LOOCV)", "f", 10); -PARAM_INT("min_leaf_size", "The minimum size of a leaf in the unpruned, fully " +PARAM_INT_IN("min_leaf_size", "The minimum size of a leaf in the unpruned, fully " "grown DET.", "l", 5); -PARAM_INT("max_leaf_size", "The maximum size of a leaf in the unpruned, fully " +PARAM_INT_IN("max_leaf_size", "The maximum size of a leaf in the unpruned, fully " "grown DET.", "L", 10); /* PARAM_FLAG("volume_regularization", "This flag gives the used the option to use" diff --git a/src/mlpack/methods/emst/emst_main.cpp b/src/mlpack/methods/emst/emst_main.cpp index 828693e3372..f9b5a69c372 100644 --- a/src/mlpack/methods/emst/emst_main.cpp +++ b/src/mlpack/methods/emst/emst_main.cpp @@ -19,7 +19,6 @@ * } * @endcode */ - #include "dtb.hpp" #include @@ -33,12 +32,12 @@ PROGRAM_INFO("Fast Euclidean Minimum Spanning Tree", "This program can compute " "second column corresponds to the greater index of the edge; and the third " "column corresponds to the distance between the two points."); -PARAM_STRING_REQ("input_file", "Data input file.", "i"); -PARAM_STRING("output_file", "Data output file. Stored as an edge list.", "o", - "emst_output.csv"); +PARAM_STRING_IN_REQ("input_file", "Data input file.", "i"); +PARAM_STRING_OUT("output_file", "Data output file. Stored as an edge list.", + "o"); PARAM_FLAG("naive", "Compute the MST using O(n^2) naive algorithm.", "n"); -PARAM_INT("leaf_size", "Leaf size in the kd-tree. One-element leaves give the " - "empirically best performance, but at the cost of greater memory " +PARAM_INT_IN("leaf_size", "Leaf size in the kd-tree. One-element leaves give " + "the empirically best performance, but at the cost of greater memory " "requirements.", "l", 1); using namespace mlpack; @@ -51,6 +50,10 @@ int main(int argc, char* argv[]) { CLI::ParseCommandLine(argc, argv); + if (!CLI::HasParam("output_file")) + Log::Warn << "--output_file is not specified, so no output will be saved!" + << endl; + const string dataFilename = CLI::GetParam("input_file"); arma::mat dataPoints; @@ -67,8 +70,8 @@ int main(int argc, char* argv[]) naive.ComputeMST(naiveResults); const string outputFilename = CLI::GetParam("output_file"); - - data::Save(outputFilename, naiveResults, true); + if (outputFilename != "") + data::Save(outputFilename, naiveResults, true); } else { @@ -122,7 +125,7 @@ int main(int argc, char* argv[]) // Output the results. const string outputFilename = CLI::GetParam("output_file"); - - data::Save(outputFilename, unmappedResults, true); + if (outputFilename != "") + data::Save(outputFilename, unmappedResults, true); } } diff --git a/src/mlpack/methods/fastmks/fastmks_main.cpp b/src/mlpack/methods/fastmks/fastmks_main.cpp index 73d81bdc955..9ebbefeaed6 100644 --- a/src/mlpack/methods/fastmks/fastmks_main.cpp +++ b/src/mlpack/methods/fastmks/fastmks_main.cpp @@ -41,34 +41,35 @@ PROGRAM_INFO("FastMKS (Fast Max-Kernel Search)", "build the cover tree can be specified with the --base option."); // Model-building parameters. -PARAM_STRING("reference_file", "File containing the reference dataset.", "r", +PARAM_STRING_IN("reference_file", "File containing the reference dataset.", "r", ""); -PARAM_STRING("kernel", "Kernel type to use: 'linear', 'polynomial', 'cosine', " - "'gaussian', 'epanechnikov', 'triangular', 'hyptan'.", "K", "linear"); -PARAM_DOUBLE("base", "Base to use during cover tree construction.", "b", 2.0); +PARAM_STRING_IN("kernel", "Kernel type to use: 'linear', 'polynomial', " + "'cosine', 'gaussian', 'epanechnikov', 'triangular', 'hyptan'.", "K", + "linear"); +PARAM_DOUBLE_IN("base", "Base to use during cover tree construction.", "b", + 2.0); // Kernel parameters. -PARAM_DOUBLE("degree", "Degree of polynomial kernel.", "d", 2.0); -PARAM_DOUBLE("offset", "Offset of kernel (for polynomial and hyptan kernels).", - "o", 0.0); -PARAM_DOUBLE("bandwidth", "Bandwidth (for Gaussian, Epanechnikov, and " +PARAM_DOUBLE_IN("degree", "Degree of polynomial kernel.", "d", 2.0); +PARAM_DOUBLE_IN("offset", "Offset of kernel (for polynomial and hyptan " + "kernels).", "o", 0.0); +PARAM_DOUBLE_IN("bandwidth", "Bandwidth (for Gaussian, Epanechnikov, and " "triangular kernels).", "w", 1.0); -PARAM_DOUBLE("scale", "Scale of kernel (for hyptan kernel).", "s", 1.0); +PARAM_DOUBLE_IN("scale", "Scale of kernel (for hyptan kernel).", "s", 1.0); // Load/save models. -PARAM_STRING("input_model_file", "File containing FastMKS model.", "m", ""); -PARAM_STRING("output_model_file", "File to save FastMKS model to.", "M", ""); +PARAM_STRING_IN("input_model_file", "File containing FastMKS model.", "m", ""); +PARAM_STRING_OUT("output_model_file", "File to save FastMKS model to.", "M"); // Search preferences. -PARAM_STRING("query_file", "File containing the query dataset.", "q", ""); -PARAM_INT("k", "Number of maximum kernels to find.", "k", 0); +PARAM_STRING_IN("query_file", "File containing the query dataset.", "q", ""); +PARAM_INT_IN("k", "Number of maximum kernels to find.", "k", 0); PARAM_FLAG("naive", "If true, O(n^2) naive mode is used for computation.", "N"); PARAM_FLAG("single", "If true, single-tree search is used (as opposed to " "dual-tree search.", "S"); -PARAM_STRING("kernels_file", "File to save kernels into.", "p", ""); -PARAM_STRING("indices_file", "File to save indices of kernels into.", - "i", ""); +PARAM_STRING_OUT("kernels_file", "File to save kernels into.", "p"); +PARAM_STRING_OUT("indices_file", "File to save indices of kernels into.", "i"); int main(int argc, char** argv) { diff --git a/src/mlpack/methods/gmm/gmm_generate_main.cpp b/src/mlpack/methods/gmm/gmm_generate_main.cpp index 7fcf2e1bd20..7c90ab8f8a7 100644 --- a/src/mlpack/methods/gmm/gmm_generate_main.cpp +++ b/src/mlpack/methods/gmm/gmm_generate_main.cpp @@ -19,13 +19,13 @@ PROGRAM_INFO("GMM Sample Generator", "The output samples are saved in the file specified by --output_file " "(-o)."); -PARAM_STRING_REQ("input_model_file", "File containing input GMM model.", "m"); -PARAM_INT_REQ("samples", "Number of samples to generate.", "n"); +PARAM_STRING_IN_REQ("input_model_file", "File containing input GMM model.", + "m"); +PARAM_INT_IN_REQ("samples", "Number of samples to generate.", "n"); -PARAM_STRING("output_file", "File to save output samples in.", "o", - "output.csv"); +PARAM_STRING_OUT("output_file", "File to save output samples in.", "o"); -PARAM_INT("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0); +PARAM_INT_IN("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0); int main(int argc, char** argv) { @@ -48,5 +48,9 @@ int main(int argc, char** argv) for (size_t i = 0; i < length; ++i) samples.col(i) = gmm.Random(); - data::Save(CLI::GetParam("output_file"), samples); + if (CLI::HasParam("output_file")) + data::Save(CLI::GetParam("output_file"), samples); + else + Log::Warn << "--output_file is not specified, so no output will be saved!" + << endl; } diff --git a/src/mlpack/methods/gmm/gmm_probability_main.cpp b/src/mlpack/methods/gmm/gmm_probability_main.cpp index b771aa2891a..035ea95987c 100644 --- a/src/mlpack/methods/gmm/gmm_probability_main.cpp +++ b/src/mlpack/methods/gmm/gmm_probability_main.cpp @@ -18,11 +18,11 @@ PROGRAM_INFO("GMM Probability Calculator", "--input_file option. The output probabilities are stored in the file " "specified by the --output_file option."); -PARAM_STRING_REQ("input_model_file", "File containing input GMM.", "m"); -PARAM_STRING_REQ("input_file", "File containing points.", "i"); +PARAM_STRING_IN_REQ("input_model_file", "File containing input GMM.", "m"); +PARAM_STRING_IN_REQ("input_file", "File containing points.", "i"); -PARAM_STRING("output_file", "File to save calculated probabilities to.", "o", - "output.csv"); +PARAM_STRING_OUT("output_file", "File to save calculated probabilities to.", + "o"); int main(int argc, char** argv) { @@ -41,5 +41,9 @@ int main(int argc, char** argv) probabilities[i] = gmm.Probability(dataset.unsafe_col(i)); // And save the result. - data::Save(CLI::GetParam("output_file"), probabilities); + if (CLI::HasParam("output_file")) + data::Save(CLI::GetParam("output_file"), probabilities); + else + Log::Warn << "--output_file was not specified, so no output will be saved!" + << endl; } diff --git a/src/mlpack/methods/gmm/gmm_train_main.cpp b/src/mlpack/methods/gmm/gmm_train_main.cpp index 914fbe548a4..ee271b1242d 100644 --- a/src/mlpack/methods/gmm/gmm_train_main.cpp +++ b/src/mlpack/methods/gmm/gmm_train_main.cpp @@ -40,38 +40,38 @@ PROGRAM_INFO("Gaussian Mixture Model (GMM) Training", "option. The model with greatest log-likelihood will be taken."); // Parameters for training. -PARAM_STRING_REQ("input_file", "File containing the data on which the model " +PARAM_STRING_IN_REQ("input_file", "File containing the data on which the model " "will be fit.", "i"); -PARAM_INT_REQ("gaussians", "Number of Gaussians in the GMM.", "g"); +PARAM_INT_IN_REQ("gaussians", "Number of Gaussians in the GMM.", "g"); -PARAM_INT("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0); -PARAM_INT("trials", "Number of trials to perform in training GMM.", "t", 1); +PARAM_INT_IN("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0); +PARAM_INT_IN("trials", "Number of trials to perform in training GMM.", "t", 1); // Parameters for EM algorithm. -PARAM_DOUBLE("tolerance", "Tolerance for convergence of EM.", "T", 1e-10); +PARAM_DOUBLE_IN("tolerance", "Tolerance for convergence of EM.", "T", 1e-10); PARAM_FLAG("no_force_positive", "Do not force the covariance matrices to be " "positive definite.", "P"); -PARAM_INT("max_iterations", "Maximum number of iterations of EM algorithm " +PARAM_INT_IN("max_iterations", "Maximum number of iterations of EM algorithm " "(passing 0 will run until convergence).", "n", 250); // Parameters for dataset modification. -PARAM_DOUBLE("noise", "Variance of zero-mean Gaussian noise to add to data.", +PARAM_DOUBLE_IN("noise", "Variance of zero-mean Gaussian noise to add to data.", "N", 0); // Parameters for k-means initialization. PARAM_FLAG("refined_start", "During the initialization, use refined initial " "positions for k-means clustering (Bradley and Fayyad, 1998).", "r"); -PARAM_INT("samplings", "If using --refined_start, specify the number of " +PARAM_INT_IN("samplings", "If using --refined_start, specify the number of " "samplings used for initial points.", "S", 100); -PARAM_DOUBLE("percentage", "If using --refined_start, specify the percentage of" - " the dataset used for each sampling (should be between 0.0 and 1.0).", +PARAM_DOUBLE_IN("percentage", "If using --refined_start, specify the percentage" + " of the dataset used for each sampling (should be between 0.0 and 1.0).", "p", 0.02); // Parameters for model saving/loading. -PARAM_STRING("input_model_file", "File containing initial input GMM model.", +PARAM_STRING_IN("input_model_file", "File containing initial input GMM model.", "m", ""); -PARAM_STRING("output_model_file", "File to save trained GMM model to.", "M", - ""); +PARAM_STRING_OUT("output_model_file", "File to save trained GMM model to.", + "M"); int main(int argc, char* argv[]) { diff --git a/src/mlpack/methods/hmm/hmm_generate_main.cpp b/src/mlpack/methods/hmm/hmm_generate_main.cpp index 5240d553bc5..352c98d4138 100644 --- a/src/mlpack/methods/hmm/hmm_generate_main.cpp +++ b/src/mlpack/methods/hmm/hmm_generate_main.cpp @@ -19,15 +19,13 @@ PROGRAM_INFO("Hidden Markov Model (HMM) Sequence Generator", "This " "parameters, saving them to the specified files (--output_file and " "--state_file)"); -PARAM_STRING_REQ("model_file", "File containing HMM.", "m"); -PARAM_INT_REQ("length", "Length of sequence to generate.", "l"); +PARAM_STRING_IN_REQ("model_file", "File containing HMM.", "m"); +PARAM_INT_IN_REQ("length", "Length of sequence to generate.", "l"); -PARAM_INT("start_state", "Starting state of sequence.", "t", 0); -PARAM_STRING("output_file", "File to save observation sequence to.", "o", - "output.csv"); -PARAM_STRING("state_file", "File to save hidden state sequence to (may be left " - "unspecified.", "S", ""); -PARAM_INT("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0); +PARAM_INT_IN("start_state", "Starting state of sequence.", "t", 0); +PARAM_STRING_OUT("output_file", "File to save observation sequence to.", "o"); +PARAM_STRING_OUT("state_file", "File to save hidden state sequence to.", "S"); +PARAM_INT_IN("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0); using namespace mlpack; using namespace mlpack::hmm; @@ -62,12 +60,17 @@ struct Generate // Now save the output. const string outputFile = CLI::GetParam("output_file"); - data::Save(outputFile, observations, true); + if (outputFile != "") + data::Save(outputFile, observations, true); // Do we want to save the hidden sequence? const string sequenceFile = CLI::GetParam("state_file"); if (sequenceFile != "") data::Save(sequenceFile, sequence, true); + + if (outputFile == "" && sequenceFile == "") + Log::Warn << "Neither --output_file nor --state_file are specified; no " + << "output will be saved." << endl; } }; diff --git a/src/mlpack/methods/hmm/hmm_loglik_main.cpp b/src/mlpack/methods/hmm/hmm_loglik_main.cpp index 2692a170421..8be43f01eb5 100644 --- a/src/mlpack/methods/hmm/hmm_loglik_main.cpp +++ b/src/mlpack/methods/hmm/hmm_loglik_main.cpp @@ -16,8 +16,10 @@ PROGRAM_INFO("Hidden Markov Model (HMM) Sequence Log-Likelihood", "This " "log-likelihood of a given sequence of observations (--input_file). The " "computed log-likelihood is given directly to stdout."); -PARAM_STRING_REQ("input_file", "File containing observations,", "i"); -PARAM_STRING_REQ("model_file", "File containing HMM.", "m"); +PARAM_STRING_IN_REQ("input_file", "File containing observations,", "i"); +PARAM_STRING_IN_REQ("model_file", "File containing HMM.", "m"); + +PARAM_DOUBLE_OUT("log_likelihood", "Log-likelihood of the sequence."); using namespace mlpack; using namespace mlpack::hmm; @@ -55,7 +57,7 @@ struct Loglik const double loglik = hmm.LogLikelihood(dataSeq); - cout << loglik << endl; + CLI::GetParam("log_likelihood") = loglik; } }; diff --git a/src/mlpack/methods/hmm/hmm_train_main.cpp b/src/mlpack/methods/hmm/hmm_train_main.cpp index 546fb3c9197..2635421ed50 100644 --- a/src/mlpack/methods/hmm/hmm_train_main.cpp +++ b/src/mlpack/methods/hmm/hmm_train_main.cpp @@ -32,23 +32,23 @@ PROGRAM_INFO("Hidden Markov Model (HMM) Training", "This program allows a " "transition matrix and emission probabilities; this is specifiable with " "--model_file."); -PARAM_STRING_REQ("input_file", "File containing input observations.", "i"); -PARAM_STRING_REQ("type", "Type of HMM: discrete | gaussian | gmm.", "t"); +PARAM_STRING_IN_REQ("input_file", "File containing input observations.", "i"); +PARAM_STRING_IN_REQ("type", "Type of HMM: discrete | gaussian | gmm.", "t"); PARAM_FLAG("batch", "If true, input_file (and if passed, labels_file) are " "expected to contain a list of files to use as input observation sequences " "(and label sequences).", "b"); -PARAM_INT("states", "Number of hidden states in HMM (necessary, unless " +PARAM_INT_IN("states", "Number of hidden states in HMM (necessary, unless " "model_file is specified.", "n", 0); -PARAM_INT("gaussians", "Number of gaussians in each GMM (necessary when type is" - " 'gmm'.", "g", 0); -PARAM_STRING("model_file", "Pre-existing HMM model (optional).", "m", ""); -PARAM_STRING("labels_file", "Optional file of hidden states, used for " +PARAM_INT_IN("gaussians", "Number of gaussians in each GMM (necessary when type" + " is 'gmm'.", "g", 0); +PARAM_STRING_IN("model_file", "Pre-existing HMM model file.", "m", ""); +PARAM_STRING_IN("labels_file", "Optional file of hidden states, used for " "labeled training.", "l", ""); -PARAM_STRING("output_model_file", "File to save trained HMM to.", "o", - "output_hmm.xml"); -PARAM_INT("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0); -PARAM_DOUBLE("tolerance", "Tolerance of the Baum-Welch algorithm.", "T", 1e-5); +PARAM_STRING_OUT("output_model_file", "File to save trained HMM to.", "o"); +PARAM_INT_IN("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0); +PARAM_DOUBLE_IN("tolerance", "Tolerance of the Baum-Welch algorithm.", "T", + 1e-5); PARAM_FLAG("random_initialization", "Initialize emissions and transition " "matrices with a uniform random distribution.", "r"); diff --git a/src/mlpack/methods/hmm/hmm_viterbi_main.cpp b/src/mlpack/methods/hmm/hmm_viterbi_main.cpp index 2e6328b810a..474e23e60a6 100644 --- a/src/mlpack/methods/hmm/hmm_viterbi_main.cpp +++ b/src/mlpack/methods/hmm/hmm_viterbi_main.cpp @@ -18,10 +18,10 @@ PROGRAM_INFO("Hidden Markov Model (HMM) Viterbi State Prediction", "This " "(--input_file), using the Viterbi algorithm. The computed state sequence " "is saved to the specified output file (--output_file)."); -PARAM_STRING_REQ("input_file", "File containing observations,", "i"); -PARAM_STRING_REQ("model_file", "File containing HMM.", "m"); -PARAM_STRING("output_file", "File to save predicted state sequence to.", "o", - "output.csv"); +PARAM_STRING_IN_REQ("input_file", "File containing observations,", "i"); +PARAM_STRING_IN_REQ("model_file", "File containing HMM.", "m"); +PARAM_STRING_OUT("output_file", "File to save predicted state sequence to.", + "o"); using namespace mlpack; using namespace mlpack::hmm; @@ -63,7 +63,11 @@ struct Viterbi // Save output. const string outputFile = CLI::GetParam("output_file"); - data::Save(outputFile, sequence, true); + if (outputFile != "") + data::Save(outputFile, sequence, true); + else + Log::Warn << "--output_file not specified; no output will be saved." + << endl; } }; diff --git a/src/mlpack/methods/hoeffding_trees/hoeffding_tree_main.cpp b/src/mlpack/methods/hoeffding_trees/hoeffding_tree_main.cpp index 073c00b3c28..2db517ad099 100644 --- a/src/mlpack/methods/hoeffding_trees/hoeffding_tree_main.cpp +++ b/src/mlpack/methods/hoeffding_trees/hoeffding_tree_main.cpp @@ -41,39 +41,39 @@ PROGRAM_INFO("Hoeffding trees", "probabilities for each predictions will be stored in the file specified by" " the --probabilities_file (-P) option."); -PARAM_STRING("training_file", "Training dataset file.", "t", ""); -PARAM_STRING("labels_file", "Labels for training dataset.", "l", ""); +PARAM_STRING_IN("training_file", "Training dataset file.", "t", ""); +PARAM_STRING_IN("labels_file", "Labels for training dataset.", "l", ""); -PARAM_DOUBLE("confidence", "Confidence before splitting (between 0 and 1).", +PARAM_DOUBLE_IN("confidence", "Confidence before splitting (between 0 and 1).", "c", 0.95); -PARAM_INT("max_samples", "Maximum number of samples before splitting.", "n", +PARAM_INT_IN("max_samples", "Maximum number of samples before splitting.", "n", 5000); -PARAM_INT("min_samples", "Minimum number of samples before splitting.", "I", +PARAM_INT_IN("min_samples", "Minimum number of samples before splitting.", "I", 100); -PARAM_STRING("input_model_file", "File to load trained tree from.", "m", ""); -PARAM_STRING("output_model_file", "File to save trained tree to.", "M", ""); +PARAM_STRING_IN("input_model_file", "File to load trained tree from.", "m", ""); +PARAM_STRING_OUT("output_model_file", "File to save trained tree to.", "M"); -PARAM_STRING("test_file", "File of testing data.", "T", ""); -PARAM_STRING("test_labels_file", "Labels of test data.", "L", ""); -PARAM_STRING("predictions_file", "File to output label predictions for test " - "data into.", "p", ""); -PARAM_STRING("probabilities_file", "In addition to predicting labels, provide " - "prediction probabilities in this file.", "P", ""); +PARAM_STRING_IN("test_file", "File of testing data.", "T", ""); +PARAM_STRING_IN("test_labels_file", "Labels of test data.", "L", ""); +PARAM_STRING_OUT("predictions_file", "File to output label predictions for " + "test data into.", "p"); +PARAM_STRING_OUT("probabilities_file", "In addition to predicting labels, " + "provide prediction probabilities in this file.", "P"); -PARAM_STRING("numeric_split_strategy", "The splitting strategy to use for " +PARAM_STRING_IN("numeric_split_strategy", "The splitting strategy to use for " "numeric features: 'domingos' or 'binary'.", "N", "binary"); PARAM_FLAG("batch_mode", "If true, samples will be considered in batch instead " "of as a stream. This generally results in better trees but at the cost of" " memory usage and runtime.", "b"); PARAM_FLAG("info_gain", "If set, information gain is used instead of Gini " "impurity for calculating Hoeffding bounds.", "i"); -PARAM_INT("passes", "Number of passes to take over the dataset.", "s", 1); +PARAM_INT_IN("passes", "Number of passes to take over the dataset.", "s", 1); -PARAM_INT("bins", "If the 'domingos' split strategy is used, this specifies " +PARAM_INT_IN("bins", "If the 'domingos' split strategy is used, this specifies " "the number of bins for each numeric split.", "B", 10); -PARAM_INT("observations_before_binning", "If the 'domingos' split strategy is " - "used, this specifies the number of samples observed before binning is " +PARAM_INT_IN("observations_before_binning", "If the 'domingos' split strategy " + "is used, this specifies the number of samples observed before binning is " "performed.", "o", 100); // Helper function for once we have chosen a tree type. diff --git a/src/mlpack/methods/kernel_pca/kernel_pca_main.cpp b/src/mlpack/methods/kernel_pca/kernel_pca_main.cpp index c0e963de102..a8610518078 100644 --- a/src/mlpack/methods/kernel_pca/kernel_pca_main.cpp +++ b/src/mlpack/methods/kernel_pca/kernel_pca_main.cpp @@ -29,11 +29,9 @@ PROGRAM_INFO("Kernel Principal Components Analysis", "For the case where a linear kernel is used, this reduces to regular " "PCA." "\n\n" - "For example, the following will perform KPCA on the 'input.csv' file using" " the gaussian kernel and store the transformed date in the " "'transformed.csv' file." - "\n\n" "$ kernel_pca -i input.csv -k gaussian -o transformed.csv" "\n\n" @@ -72,12 +70,12 @@ PROGRAM_INFO("Kernel Principal Components Analysis", " for the nystr\u00F6m method can be chosen from the following list: kmeans," " random, ordered."); -PARAM_STRING_REQ("input_file", "Input dataset to perform KPCA on.", "i"); -PARAM_STRING_REQ("output_file", "File to save modified dataset to.", "o"); -PARAM_STRING_REQ("kernel", "The kernel to use; see the above documentation for " - "the list of usable kernels.", "k"); +PARAM_STRING_IN_REQ("input_file", "Input dataset to perform KPCA on.", "i"); +PARAM_STRING_OUT("output_file", "File to save modified dataset to.", "o"); +PARAM_STRING_IN_REQ("kernel", "The kernel to use; see the above documentation " + "for the list of usable kernels.", "k"); -PARAM_INT("new_dimensionality", "If not 0, reduce the dimensionality of " +PARAM_INT_IN("new_dimensionality", "If not 0, reduce the dimensionality of " "the output dataset by ignoring the dimensions with the smallest " "eigenvalues.", "d", 0); @@ -86,15 +84,15 @@ PARAM_FLAG("center", "If set, the transformed data will be centered about the " PARAM_FLAG("nystroem_method", "If set, the nystroem method will be used.", "n"); -PARAM_STRING("sampling", "Sampling scheme to use for the nystroem method: " +PARAM_STRING_IN("sampling", "Sampling scheme to use for the nystroem method: " "'kmeans', 'random', 'ordered'", "s", "kmeans"); -PARAM_DOUBLE("kernel_scale", "Scale, for 'hyptan' kernel.", "S", 1.0); -PARAM_DOUBLE("offset", "Offset, for 'hyptan' and 'polynomial' kernels.", "O", +PARAM_DOUBLE_IN("kernel_scale", "Scale, for 'hyptan' kernel.", "S", 1.0); +PARAM_DOUBLE_IN("offset", "Offset, for 'hyptan' and 'polynomial' kernels.", "O", 0.0); -PARAM_DOUBLE("bandwidth", "Bandwidth, for 'gaussian' and 'laplacian' kernels.", - "b", 1.0); -PARAM_DOUBLE("degree", "Degree of polynomial, for 'polynomial' kernel.", "D", +PARAM_DOUBLE_IN("bandwidth", "Bandwidth, for 'gaussian' and 'laplacian' " + "kernels.", "b", 1.0); +PARAM_DOUBLE_IN("degree", "Degree of polynomial, for 'polynomial' kernel.", "D", 1.0); //! Run RunKPCA on the specified dataset for the given kernel type. diff --git a/src/mlpack/methods/kmeans/kmeans_main.cpp b/src/mlpack/methods/kmeans/kmeans_main.cpp index 110774e17a1..24226cbc8a2 100644 --- a/src/mlpack/methods/kmeans/kmeans_main.cpp +++ b/src/mlpack/methods/kmeans/kmeans_main.cpp @@ -47,39 +47,40 @@ PROGRAM_INFO("K-Means Clustering", "This program performs K-Means clustering " "https://github.com/mlpack/mlpack/ or get in touch through another means."); // Required options. -PARAM_STRING_REQ("input_file", "Input dataset to perform clustering on.", "i"); -PARAM_INT_REQ("clusters", "Number of clusters to find (0 autodetects from " +PARAM_STRING_IN_REQ("input_file", "Input dataset to perform clustering on.", + "i"); +PARAM_INT_IN_REQ("clusters", "Number of clusters to find (0 autodetects from " "initial centroids).", "c"); // Output options. PARAM_FLAG("in_place", "If specified, a column containing the learned cluster " "assignments will be added to the input dataset file. In this case, " "--outputFile is overridden.", "P"); -PARAM_STRING("output_file", "File to write output labels or labeled data to.", - "o", ""); -PARAM_STRING("centroid_file", "If specified, the centroids of each cluster will" - " be written to the given file.", "C", ""); +PARAM_STRING_OUT("output_file", "File to write output labels or labeled data " + "to.", "o"); +PARAM_STRING_OUT("centroid_file", "If specified, the centroids of each cluster " + "will be written to the given file.", "C"); // k-means configuration options. PARAM_FLAG("allow_empty_clusters", "Allow empty clusters to be created.", "e"); PARAM_FLAG("labels_only", "Only output labels into output file.", "l"); -PARAM_INT("max_iterations", "Maximum number of iterations before K-Means " +PARAM_INT_IN("max_iterations", "Maximum number of iterations before k-means " "terminates.", "m", 1000); -PARAM_INT("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0); -PARAM_STRING("initial_centroids", "Start with the specified initial centroids.", - "I", ""); +PARAM_INT_IN("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0); +PARAM_STRING_IN("initial_centroids", "Start with the specified initial " + "centroids.", "I", ""); // Parameters for "refined start" k-means. PARAM_FLAG("refined_start", "Use the refined initial point strategy by Bradley " "and Fayyad to choose initial points.", "r"); -PARAM_INT("samplings", "Number of samplings to perform for refined start (use " - "when --refined_start is specified).", "S", 100); -PARAM_DOUBLE("percentage", "Percentage of dataset to use for each refined start" - " sampling (use when --refined_start is specified).", "p", 0.02); - -PARAM_STRING("algorithm", "Algorithm to use for the Lloyd iteration ('naive', " - "'pelleg-moore', 'elkan', 'hamerly', 'dualtree', or 'dualtree-covertree').", - "a", "naive"); +PARAM_INT_IN("samplings", "Number of samplings to perform for refined start " + "(use when --refined_start is specified).", "S", 100); +PARAM_DOUBLE_IN("percentage", "Percentage of dataset to use for each refined " + "start sampling (use when --refined_start is specified).", "p", 0.02); + +PARAM_STRING_IN("algorithm", "Algorithm to use for the Lloyd iteration " + "('naive', 'pelleg-moore', 'elkan', 'hamerly', 'dualtree', or " + "'dualtree-covertree').", "a", "naive"); // Given the type of initial partition policy, figure out the empty cluster // policy and run k-means. diff --git a/src/mlpack/methods/lars/lars_main.cpp b/src/mlpack/methods/lars/lars_main.cpp index 7981ca0cb33..3de6f4ccbba 100644 --- a/src/mlpack/methods/lars/lars_main.cpp +++ b/src/mlpack/methods/lars/lars_main.cpp @@ -42,21 +42,21 @@ PROGRAM_INFO("LARS", "An implementation of LARS: Least Angle Regression " "predictions from a test file can be saved into the file specified by the " "--output_predictions option."); -PARAM_STRING("input_file", "File containing covariates (X).", "i", ""); -PARAM_STRING("responses_file", "File containing y (responses/observations).", +PARAM_STRING_IN("input_file", "File containing covariates (X).", "i", ""); +PARAM_STRING_IN("responses_file", "File containing y (responses/observations).", "r", ""); -PARAM_STRING("input_model_file", "File to load model from.", "m", ""); -PARAM_STRING("output_model_file", "File to save model to.", "M", ""); +PARAM_STRING_IN("input_model_file", "File to load model from.", "m", ""); +PARAM_STRING_OUT("output_model_file", "File to save model to.", "M"); -PARAM_STRING("test_file", "File containing points to regress on (test points).", - "t", ""); -PARAM_STRING("output_predictions", "If --test_file is specified, this file is " - "where the predicted responses will be saved.", "o", "predictions.csv"); +PARAM_STRING_IN("test_file", "File containing points to regress on (test " + "points).", "t", ""); +PARAM_STRING_OUT("output_predictions", "If --test_file is specified, this file " + "is where the predicted responses will be saved.", "o"); -PARAM_DOUBLE("lambda1", "Regularization parameter for l1-norm penalty.", "l", +PARAM_DOUBLE_IN("lambda1", "Regularization parameter for l1-norm penalty.", "l", 0); -PARAM_DOUBLE("lambda2", "Regularization parameter for l2-norm penalty.", "L", +PARAM_DOUBLE_IN("lambda2", "Regularization parameter for l2-norm penalty.", "L", 0); PARAM_FLAG("use_cholesky", "Use Cholesky decomposition during computation " "rather than explicitly computing the full Gram matrix.", "c"); @@ -161,7 +161,8 @@ int main(int argc, char* argv[]) lars.Predict(testPoints.t(), predictions, false); // Save test predictions. One per line, so, don't transpose on save. - data::Save(outputPredictionsFile, predictions, true, false); + if (outputPredictionsFile != "") + data::Save(outputPredictionsFile, predictions, true, false); } if (CLI::HasParam("output_model_file")) diff --git a/src/mlpack/methods/linear_regression/linear_regression_main.cpp b/src/mlpack/methods/linear_regression/linear_regression_main.cpp index 9f008505e90..7fd51ee8c0f 100644 --- a/src/mlpack/methods/linear_regression/linear_regression_main.cpp +++ b/src/mlpack/methods/linear_regression/linear_regression_main.cpp @@ -25,22 +25,22 @@ PROGRAM_INFO("Simple Linear Regression and Prediction", "(--output_predictions). This type of regression is related to least-angle" " regression, which mlpack implements with the 'lars' executable."); -PARAM_STRING("training_file", "File containing training set X (regressors).", +PARAM_STRING_IN("training_file", "File containing training set X (regressors).", "t", ""); -PARAM_STRING("training_responses", "Optional file containing y (responses). If " - "not given, the responses are assumed to be the last row of the input " +PARAM_STRING_IN("training_responses", "Optional file containing y (responses). " + "If not given, the responses are assumed to be the last row of the input " "file.", "r", ""); -PARAM_STRING("input_model_file", "File containing existing model (parameters).", - "m", ""); -PARAM_STRING("output_model_file", "File to save trained model to.", "M", ""); +PARAM_STRING_IN("input_model_file", "File containing existing model " + "(parameters).", "m", ""); +PARAM_STRING_OUT("output_model_file", "File to save trained model to.", "M"); -PARAM_STRING("test_file", "File containing X' (test regressors).", "T", ""); -PARAM_STRING("output_predictions", "If --test_file is specified, this file is " - "where the predicted responses will be saved.", "p", "predictions.csv"); +PARAM_STRING_IN("test_file", "File containing X' (test regressors).", "T", ""); +PARAM_STRING_OUT("output_predictions", "If --test_file is specified, this file " + "is where the predicted responses will be saved.", "p"); -PARAM_DOUBLE("lambda", "Tikhonov regularization for ridge regression. If 0, " - "the method reduces to linear regression.", "l", 0.0); +PARAM_DOUBLE_IN("lambda", "Tikhonov regularization for ridge regression. If 0," + " the method reduces to linear regression.", "l", 0.0); using namespace mlpack; using namespace mlpack::regression; @@ -102,6 +102,12 @@ int main(int argc, char* argv[]) Log::Warn << "--lambda ignored because no model is being trained." << endl; } + if (outputModelFile == "" && outputPredictions == "") + { + Log::Warn << "Neither --output_model_file nor --output_predictions are " + << "specified; no output will be saved!" << endl; + } + // An input file was given and we need to generate the model. if (computeModel) { @@ -175,6 +181,7 @@ int main(int argc, char* argv[]) Timer::Stop("prediction"); // Save predictions. - data::Save(outputPredictions, predictions, true, false); + if (outputPredictions != "") + data::Save(outputPredictions, predictions, true, false); } } diff --git a/src/mlpack/methods/local_coordinate_coding/local_coordinate_coding_main.cpp b/src/mlpack/methods/local_coordinate_coding/local_coordinate_coding_main.cpp index f10d6c85b50..d61937ab0f2 100644 --- a/src/mlpack/methods/local_coordinate_coding/local_coordinate_coding_main.cpp +++ b/src/mlpack/methods/local_coordinate_coding/local_coordinate_coding_main.cpp @@ -40,29 +40,31 @@ PROGRAM_INFO("Local Coordinate Coding", "the -N option."); // Training parameters. -PARAM_STRING("training_file", "Filename of the training data (X).", "t", ""); -PARAM_INT("atoms", "Number of atoms in the dictionary.", "k", 0); -PARAM_DOUBLE("lambda", "Weighted l1-norm regularization parameter.", "l", 0.0); -PARAM_INT("max_iterations", "Maximum number of iterations for LCC (0 indicates " - "no limit).", "n", 0); -PARAM_STRING("initial_dictionary", "Filename for optional initial dictionary.", - "i", ""); +PARAM_STRING_IN("training_file", "Filename of the training data (X).", "t", ""); +PARAM_INT_IN("atoms", "Number of atoms in the dictionary.", "k", 0); +PARAM_DOUBLE_IN("lambda", "Weighted l1-norm regularization parameter.", "l", + 0.0); +PARAM_INT_IN("max_iterations", "Maximum number of iterations for LCC (0 " + "indicates no limit).", "n", 0); +PARAM_STRING_IN("initial_dictionary", "Filename for optional initial " + "dictionary.", "i", ""); PARAM_FLAG("normalize", "If set, the input data matrix will be normalized " "before coding.", "N"); -PARAM_DOUBLE("tolerance", "Tolerance for objective function.", "o", 0.01); +PARAM_DOUBLE_IN("tolerance", "Tolerance for objective function.", "o", 0.01); // Load/save a model. -PARAM_STRING("input_model_file", "File containing input LCC model.", "m", ""); -PARAM_STRING("output_model_file", "File to save trained LCC model to.", "M", +PARAM_STRING_IN("input_model_file", "File containing input LCC model.", "m", ""); +PARAM_STRING_OUT("output_model_file", "File to save trained LCC model to.", + "M"); // Test on another dataset. -PARAM_STRING("test_file", "File of test points to encode.", "T", ""); -PARAM_STRING("dictionary_file", "Filename to save the output dictionary to.", - "d", ""); -PARAM_STRING("codes_file", "Filename to save the output codes to.", "c", ""); +PARAM_STRING_IN("test_file", "File of test points to encode.", "T", ""); +PARAM_STRING_OUT("dictionary_file", "Filename to save the output dictionary " + "to.", "d"); +PARAM_STRING_OUT("codes_file", "Filename to save the output codes to.", "c"); -PARAM_INT("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0); +PARAM_INT_IN("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0); using namespace arma; using namespace std; diff --git a/src/mlpack/methods/logistic_regression/logistic_regression_main.cpp b/src/mlpack/methods/logistic_regression/logistic_regression_main.cpp index d2ffd9d3c51..0c33ccaaf81 100644 --- a/src/mlpack/methods/logistic_regression/logistic_regression_main.cpp +++ b/src/mlpack/methods/logistic_regression/logistic_regression_main.cpp @@ -69,36 +69,38 @@ PROGRAM_INFO("L2-regularized Logistic Regression and Prediction", "be either 0 or 1."); // Training parameters. -PARAM_STRING("training_file", "A file containing the training set (the matrix " - "of predictors, X).", "t", ""); -PARAM_STRING("labels_file", "A file containing labels (0 or 1) for the points " - "in the training set (y).", "l", ""); +PARAM_STRING_IN("training_file", "A file containing the training set (the " + "matrix of predictors, X).", "t", ""); +PARAM_STRING_IN("labels_file", "A file containing labels (0 or 1) for the " + "points in the training set (y).", "l", ""); // Optimizer parameters. -PARAM_DOUBLE("lambda", "L2-regularization parameter for training.", "L", 0.0); -PARAM_STRING("optimizer", "Optimizer to use for training ('lbfgs' or 'sgd').", - "O", "lbfgs"); -PARAM_DOUBLE("tolerance", "Convergence tolerance for optimizer.", "e", 1e-10); -PARAM_INT("max_iterations", "Maximum iterations for optimizer (0 indicates no " - "limit).", "n", 10000); -PARAM_DOUBLE("step_size", "Step size for SGD and mini-batch SGD optimizers.", +PARAM_DOUBLE_IN("lambda", "L2-regularization parameter for training.", "L", + 0.0); +PARAM_STRING_IN("optimizer", "Optimizer to use for training ('lbfgs' or " + "'sgd').", "O", "lbfgs"); +PARAM_DOUBLE_IN("tolerance", "Convergence tolerance for optimizer.", "e", + 1e-10); +PARAM_INT_IN("max_iterations", "Maximum iterations for optimizer (0 indicates " + "no limit).", "n", 10000); +PARAM_DOUBLE_IN("step_size", "Step size for SGD and mini-batch SGD optimizers.", "s", 0.01); -PARAM_INT("batch_size", "Batch size for mini-batch SGD.", "b", 50); +PARAM_INT_IN("batch_size", "Batch size for mini-batch SGD.", "b", 50); // Model loading/saving. -PARAM_STRING("input_model_file", "File containing existing model (parameters).", - "m", ""); -PARAM_STRING("output_model_file", "File to save trained logistic regression " - "model to.", "M", ""); +PARAM_STRING_IN("input_model_file", "File containing existing model " + "(parameters).", "m", ""); +PARAM_STRING_OUT("output_model_file", "File to save trained logistic regression" + " model to.", "M"); // Testing. -PARAM_STRING("test_file", "File containing test dataset.", "T", ""); -PARAM_STRING("output_file", "If --test_file is specified, this file is " - "where the predictions for the test set will be saved.", "o", ""); -PARAM_STRING("output_probabilities_file", "If --test_file is specified, this " - "file is where the class probabilities for the test set will be saved.", - "p", ""); -PARAM_DOUBLE("decision_boundary", "Decision boundary for prediction; if the " +PARAM_STRING_IN("test_file", "File containing test dataset.", "T", ""); +PARAM_STRING_OUT("output_file", "If --test_file is specified, this file is " + "where the predictions for the test set will be saved.", "o"); +PARAM_STRING_OUT("output_probabilities_file", "If --test_file is specified, " + "this file is where the class probabilities for the test set will be " + "saved.", "p"); +PARAM_DOUBLE_IN("decision_boundary", "Decision boundary for prediction; if the " "logistic function for a point is less than the boundary, the class is " "taken to be 0; otherwise, the class is 1.", "d", 0.5); diff --git a/src/mlpack/methods/lsh/lsh_main.cpp b/src/mlpack/methods/lsh/lsh_main.cpp index 2894411cece..ad60a46468d 100644 --- a/src/mlpack/methods/lsh/lsh_main.cpp +++ b/src/mlpack/methods/lsh/lsh_main.cpp @@ -44,30 +44,31 @@ PROGRAM_INFO("All K-Approximate-Nearest-Neighbor Search with LSH", "set the random seed."); // Define our input parameters that this program will take. -PARAM_STRING("reference_file", "File containing the reference dataset.", "r", +PARAM_STRING_IN("reference_file", "File containing the reference dataset.", "r", ""); -PARAM_STRING("distances_file", "File to output distances into.", "d", ""); -PARAM_STRING("neighbors_file", "File to output neighbors into.", "n", ""); +PARAM_STRING_OUT("distances_file", "File to output distances into.", "d"); +PARAM_STRING_OUT("neighbors_file", "File to output neighbors into.", "n"); // We can load or save models. -PARAM_STRING("input_model_file", "File to load LSH model from. (Cannot be " +PARAM_STRING_IN("input_model_file", "File to load LSH model from. (Cannot be " "specified with --reference_file.)", "m", ""); -PARAM_STRING("output_model_file", "File to save LSH model to.", "M", ""); +PARAM_STRING_OUT("output_model_file", "File to save LSH model to.", "M"); -PARAM_INT("k", "Number of nearest neighbors to find.", "k", 0); -PARAM_STRING("query_file", "File containing query points (optional).", "q", ""); +PARAM_INT_IN("k", "Number of nearest neighbors to find.", "k", 0); +PARAM_STRING_IN("query_file", "File containing query points (optional).", "q", + ""); -PARAM_INT("projections", "The number of hash functions for each table", "K", +PARAM_INT_IN("projections", "The number of hash functions for each table", "K", 10); -PARAM_INT("tables", "The number of hash tables to be used.", "L", 30); -PARAM_DOUBLE("hash_width", "The hash width for the first-level hashing in the " - "LSH preprocessing. By default, the LSH class automatically estimates a " - "hash width for its use.", "H", 0.0); -PARAM_INT("second_hash_size", "The size of the second level hash table.", "S", - 99901); -PARAM_INT("bucket_size", "The size of a bucket in the second level hash.", "B", - 500); -PARAM_INT("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0); +PARAM_INT_IN("tables", "The number of hash tables to be used.", "L", 30); +PARAM_DOUBLE_IN("hash_width", "The hash width for the first-level hashing in " + "the LSH preprocessing. By default, the LSH class automatically estimates " + "a hash width for its use.", "H", 0.0); +PARAM_INT_IN("second_hash_size", "The size of the second level hash table.", + "S", 99901); +PARAM_INT_IN("bucket_size", "The size of a bucket in the second level hash.", + "B", 500); +PARAM_INT_IN("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0); int main(int argc, char *argv[]) { diff --git a/src/mlpack/methods/mean_shift/mean_shift_main.cpp b/src/mlpack/methods/mean_shift/mean_shift_main.cpp index d59148453fc..b5485e1276e 100644 --- a/src/mlpack/methods/mean_shift/mean_shift_main.cpp +++ b/src/mlpack/methods/mean_shift/mean_shift_main.cpp @@ -21,24 +21,25 @@ PROGRAM_INFO("Mean Shift Clustering", "This program performs mean shift " "in a separate file."); // Required options. -PARAM_STRING_REQ("inputFile", "Input dataset to perform clustering on.", "i"); +PARAM_STRING_IN_REQ("inputFile", "Input dataset to perform clustering on.", + "i"); // Output options. PARAM_FLAG("in_place", "If specified, a column containing the learned cluster " - "assignments will be added to the input dataset file. In this case," - " --outputFile is overridden.", "P"); -PARAM_STRING("output_file", "File to write output labels or labeled data to.", - "o", ""); -PARAM_STRING("centroid_file", "If specified, the centroids of each cluster will" - " be written to the given file.", "C", ""); + "assignments will be added to the input dataset file. In this case, " + "--output_file is overridden.", "P"); +PARAM_STRING_OUT("output_file", "File to write output labels or labeled data " + "to.", "o"); +PARAM_STRING_OUT("centroid_file", "If specified, the centroids of each cluster " + "will be written to the given file.", "C"); // Mean shift configuration options. -PARAM_INT("max_iterations", "Maximum number of iterations before mean shift " - "terminates.", "m", 1000); +PARAM_INT_IN("max_iterations", "Maximum number of iterations before mean shift " + "terminates.", "m", 1000); -PARAM_DOUBLE("radius", "If distance of two centroids is less than the given " - "radius, one will be removed. A radius of 0 or less means an estimate will" - " be calculated and used.", "r", 0); +PARAM_DOUBLE_IN("radius", "If the distance between two centroids is less than " + "the given radius, one will be removed. A radius of 0 or less means an " + "estimate will be calculated and used for the radius.", "r", 0); int main(int argc, char** argv) { diff --git a/src/mlpack/methods/mvu/mvu_main.cpp b/src/mlpack/methods/mvu/mvu_main.cpp index 1cff076003f..6cf30a60266 100644 --- a/src/mlpack/methods/mvu/mvu_main.cpp +++ b/src/mlpack/methods/mvu/mvu_main.cpp @@ -15,12 +15,11 @@ PROGRAM_INFO("Maximum Variance Unfolding (MVU)", "This program implements " "such that the distances to the nearest neighbors of each point are held " "constant."); -PARAM_STRING_REQ("input_file", "Filename of input dataset.", "i"); -PARAM_INT_REQ("new_dim", "New dimensionality of dataset.", "d"); +PARAM_STRING_IN_REQ("input_file", "Filename of input dataset.", "i"); +PARAM_INT_IN_REQ("new_dim", "New dimensionality of dataset.", "d"); -PARAM_STRING("output_file", "Filename to save unfolded dataset to.", "o", - "output.csv"); -PARAM_INT("num_neighbors", "Number of nearest neighbors to consider while " +PARAM_STRING_OUT("output_file", "Filename to save unfolded dataset to.", "o"); +PARAM_INT_IN("num_neighbors", "Number of nearest neighbors to consider while " "unfolding.", "k", 5); using namespace mlpack; @@ -67,5 +66,6 @@ int main(int argc, char **argv) // Save results to file. const string outputFile = CLI::GetParam("output_file"); - data::Save(outputFile, output, true); + if (outputFile != "") + data::Save(outputFile, output, true); } diff --git a/src/mlpack/methods/naive_bayes/nbc_main.cpp b/src/mlpack/methods/naive_bayes/nbc_main.cpp index 3565a5b3c4a..10fff587f53 100644 --- a/src/mlpack/methods/naive_bayes/nbc_main.cpp +++ b/src/mlpack/methods/naive_bayes/nbc_main.cpp @@ -32,22 +32,23 @@ PROGRAM_INFO("Parametric Naive Bayes Classifier", "should be given."); // Model loading/saving. -PARAM_STRING("input_model_file", "File containing input Naive Bayes model.", +PARAM_STRING_IN("input_model_file", "File containing input Naive Bayes model.", "m", ""); -PARAM_STRING("output_model_file", "File to save trained Naive Bayes model to.", - "M", ""); +PARAM_STRING_OUT("output_model_file", "File to save trained Naive Bayes model " + "to.", "M"); // Training parameters. -PARAM_STRING("training_file", "A file containing the training set.", "t", ""); -PARAM_STRING("labels_file", "A file containing labels for the training set.", +PARAM_STRING_IN("training_file", "A file containing the training set.", "t", + ""); +PARAM_STRING_IN("labels_file", "A file containing labels for the training set.", "l", ""); PARAM_FLAG("incremental_variance", "The variance of each class will be " "calculated incrementally.", "I"); // Test parameters. -PARAM_STRING("test_file", "A file containing the test set.", "T", ""); -PARAM_STRING("output_file", "The file in which the predicted labels for the " - "test set will be written.", "o", ""); +PARAM_STRING_IN("test_file", "A file containing the test set.", "T", ""); +PARAM_STRING_OUT("output_file", "The file in which the predicted labels for the" + " test set will be written.", "o"); using namespace mlpack; using namespace mlpack::naive_bayes; diff --git a/src/mlpack/methods/nca/nca_main.cpp b/src/mlpack/methods/nca/nca_main.cpp index de16626cfd6..583872d5c24 100644 --- a/src/mlpack/methods/nca/nca_main.cpp +++ b/src/mlpack/methods/nca/nca_main.cpp @@ -70,38 +70,40 @@ PROGRAM_INFO("Neighborhood Components Analysis (NCA)", "\n\n" "By default, the SGD optimizer is used."); -PARAM_STRING_REQ("input_file", "Input dataset to run NCA on.", "i"); -PARAM_STRING_REQ("output_file", "Output file for learned distance matrix.", +PARAM_STRING_IN_REQ("input_file", "Input dataset to run NCA on.", "i"); +PARAM_STRING_IN_REQ("output_file", "Output file for learned distance matrix.", "o"); -PARAM_STRING("labels_file", "File of labels for input dataset.", "l", ""); -PARAM_STRING("optimizer", "Optimizer to use; 'sgd', 'minibatch-sgd', or " +PARAM_STRING_IN("labels_file", "File of labels for input dataset.", "l", ""); +PARAM_STRING_IN("optimizer", "Optimizer to use; 'sgd', 'minibatch-sgd', or " "'lbfgs'.", "O", "sgd"); PARAM_FLAG("normalize", "Use a normalized starting point for optimization. This" " is useful for when points are far apart, or when SGD is returning NaN.", "N"); -PARAM_INT("max_iterations", "Maximum number of iterations for SGD or L-BFGS (0 " - "indicates no limit).", "n", 500000); -PARAM_DOUBLE("tolerance", "Maximum tolerance for termination of SGD or L-BFGS.", - "t", 1e-7); +PARAM_INT_IN("max_iterations", "Maximum number of iterations for SGD or L-BFGS " + "(0 indicates no limit).", "n", 500000); +PARAM_DOUBLE_IN("tolerance", "Maximum tolerance for termination of SGD or " + "L-BFGS.", "t", 1e-7); -PARAM_DOUBLE("step_size", "Step size for stochastic gradient descent (alpha).", - "a", 0.01); +PARAM_DOUBLE_IN("step_size", "Step size for stochastic gradient descent " + "(alpha).", "a", 0.01); PARAM_FLAG("linear_scan", "Don't shuffle the order in which data points are " "visited for SGD or mini-batch SGD.", "L"); -PARAM_INT("batch_size", "Batch size for mini-batch SGD.", "b", 50); - -PARAM_INT("num_basis", "Number of memory points to be stored for L-BFGS.", "B", - 5); -PARAM_DOUBLE("armijo_constant", "Armijo constant for L-BFGS.", "A", 1e-4); -PARAM_DOUBLE("wolfe", "Wolfe condition parameter for L-BFGS.", "w", 0.9); -PARAM_INT("max_line_search_trials", "Maximum number of line search trials for " - "L-BFGS.", "T", 50); -PARAM_DOUBLE("min_step", "Minimum step of line search for L-BFGS.", "m", 1e-20); -PARAM_DOUBLE("max_step", "Maximum step of line search for L-BFGS.", "M", 1e20); - -PARAM_INT("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0); +PARAM_INT_IN("batch_size", "Batch size for mini-batch SGD.", "b", 50); + +PARAM_INT_IN("num_basis", "Number of memory points to be stored for L-BFGS.", + "B", 5); +PARAM_DOUBLE_IN("armijo_constant", "Armijo constant for L-BFGS.", "A", 1e-4); +PARAM_DOUBLE_IN("wolfe", "Wolfe condition parameter for L-BFGS.", "w", 0.9); +PARAM_INT_IN("max_line_search_trials", "Maximum number of line search trials " + "for L-BFGS.", "T", 50); +PARAM_DOUBLE_IN("min_step", "Minimum step of line search for L-BFGS.", "m", + 1e-20); +PARAM_DOUBLE_IN("max_step", "Maximum step of line search for L-BFGS.", "M", + 1e20); + +PARAM_INT_IN("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0); using namespace mlpack; using namespace mlpack::nca; diff --git a/src/mlpack/methods/neighbor_search/kfn_main.cpp b/src/mlpack/methods/neighbor_search/kfn_main.cpp index d6807400e79..3e08fbb0e35 100644 --- a/src/mlpack/methods/neighbor_search/kfn_main.cpp +++ b/src/mlpack/methods/neighbor_search/kfn_main.cpp @@ -1,5 +1,4 @@ /** -w * @file kfn_main.cpp * @author Ryan Curtin * @@ -43,30 +42,31 @@ PROGRAM_INFO("All K-Furthest-Neighbors", "corresponds to the distance between those two points."); // Define our input parameters that this program will take. -PARAM_STRING("reference_file", "File containing the reference dataset.", "r", +PARAM_STRING_IN("reference_file", "File containing the reference dataset.", "r", ""); -PARAM_STRING("distances_file", "File to output distances into.", "d", ""); -PARAM_STRING("neighbors_file", "File to output neighbors into.", "n", ""); +PARAM_STRING_OUT("distances_file", "File to output distances into.", "d"); +PARAM_STRING_OUT("neighbors_file", "File to output neighbors into.", "n"); // The option exists to load or save models. -PARAM_STRING("input_model_file", "File containing pre-trained kFN model.", "m", - ""); -PARAM_STRING("output_model_file", "If specified, the kFN model will be saved to" - " the given file.", "M", ""); +PARAM_STRING_IN("input_model_file", "File containing pre-trained kFN model.", + "m", ""); +PARAM_STRING_OUT("output_model_file", "If specified, the kFN model will be " + "saved to the given file.", "M"); // The user may specify a query file of query points and a number of furthest // neighbors to search for. -PARAM_STRING("query_file", "File containing query points (optional).", "q", ""); -PARAM_INT("k", "Number of furthest neighbors to find.", "k", 0); +PARAM_STRING_IN("query_file", "File containing query points (optional).", "q", + ""); +PARAM_INT_IN("k", "Number of furthest neighbors to find.", "k", 0); // The user may specify the type of tree to use, and a few pararmeters for tree // building. -PARAM_STRING("tree_type", "Type of tree to use: 'kd', 'cover', 'r', 'r-star', " - "'x', 'ball'.", "t", "kd"); -PARAM_INT("leaf_size", "Leaf size for tree building.", "l", 20); +PARAM_STRING_IN("tree_type", "Type of tree to use: 'kd', 'cover', 'r', " + "'r-star', 'x', 'ball'.", "t", "kd"); +PARAM_INT_IN("leaf_size", "Leaf size for tree building.", "l", 20); PARAM_FLAG("random_basis", "Before tree-building, project the data onto a " "random orthogonal basis.", "R"); -PARAM_INT("seed", "Random seed (if 0, std::time(NULL) is used).", "s", 0); +PARAM_INT_IN("seed", "Random seed (if 0, std::time(NULL) is used).", "s", 0); // Search settings. PARAM_FLAG("naive", "If true, O(n^2) naive mode is used for computation.", "N"); diff --git a/src/mlpack/methods/neighbor_search/knn_main.cpp b/src/mlpack/methods/neighbor_search/knn_main.cpp index 4957e88ebe7..3cd37ac93d0 100644 --- a/src/mlpack/methods/neighbor_search/knn_main.cpp +++ b/src/mlpack/methods/neighbor_search/knn_main.cpp @@ -44,31 +44,32 @@ PROGRAM_INFO("k-Nearest-Neighbors", "corresponds to the distance between those two points."); // Define our input parameters that this program will take. -PARAM_STRING("reference_file", "File containing the reference dataset.", "r", +PARAM_STRING_IN("reference_file", "File containing the reference dataset.", "r", ""); -PARAM_STRING("distances_file", "File to output distances into.", "d", ""); -PARAM_STRING("neighbors_file", "File to output neighbors into.", "n", ""); +PARAM_STRING_OUT("distances_file", "File to output distances into.", "d"); +PARAM_STRING_OUT("neighbors_file", "File to output neighbors into.", "n"); // The option exists to load or save models. -PARAM_STRING("input_model_file", "File containing pre-trained kNN model.", "m", - ""); -PARAM_STRING("output_model_file", "If specified, the kNN model will be saved " - "to the given file.", "M", ""); +PARAM_STRING_IN("input_model_file", "File containing pre-trained kNN model.", + "m", ""); +PARAM_STRING_OUT("output_model_file", "If specified, the kNN model will be " + "saved to the given file.", "M"); // The user may specify a query file of query points and a number of nearest // neighbors to search for. -PARAM_STRING("query_file", "File containing query points (optional).", "q", ""); -PARAM_INT("k", "Number of nearest neighbors to find.", "k", 0); +PARAM_STRING_IN("query_file", "File containing query points (optional).", "q", + ""); +PARAM_INT_IN("k", "Number of nearest neighbors to find.", "k", 0); // The user may specify the type of tree to use, and a few parameters for tree // building. -PARAM_STRING("tree_type", "Type of tree to use: 'kd', 'cover', 'r', 'r-star', " - "'x', 'ball'.", "t", "kd"); -PARAM_INT("leaf_size", "Leaf size for tree building (used for kd-trees, R " +PARAM_STRING_IN("tree_type", "Type of tree to use: 'kd', 'cover', 'r', " + "'r-star', 'x', 'ball'.", "t", "kd"); +PARAM_INT_IN("leaf_size", "Leaf size for tree building (used for kd-trees, R " "trees, and R* trees).", "l", 20); PARAM_FLAG("random_basis", "Before tree-building, project the data onto a " "random orthogonal basis.", "R"); -PARAM_INT("seed", "Random seed (if 0, std::time(NULL) is used).", "s", 0); +PARAM_INT_IN("seed", "Random seed (if 0, std::time(NULL) is used).", "s", 0); // Search settings. PARAM_FLAG("naive", "If true, O(n^2) naive mode is used for computation.", "N"); diff --git a/src/mlpack/methods/nmf/nmf_main.cpp b/src/mlpack/methods/nmf/nmf_main.cpp index 621f972830f..97b5ecb0ec8 100644 --- a/src/mlpack/methods/nmf/nmf_main.cpp +++ b/src/mlpack/methods/nmf/nmf_main.cpp @@ -44,18 +44,18 @@ PROGRAM_INFO("Non-negative Matrix Factorization", "This program performs " "--min_residue."); // Parameters for program. -PARAM_STRING_REQ("input_file", "Input dataset to perform NMF on.", "i"); -PARAM_STRING_REQ("w_file", "File to save the calculated W matrix to.", "W"); -PARAM_STRING_REQ("h_file", "File to save the calculated H matrix to.", "H"); -PARAM_INT_REQ("rank", "Rank of the factorization.", "r"); - -PARAM_INT("max_iterations", "Number of iterations before NMF terminates (0 runs" - " until convergence.", "m", 10000); -PARAM_INT("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0); -PARAM_DOUBLE("min_residue", "The minimum root mean square residue allowed for " - "each iteration, below which the program terminates.", "e", 1e-5); - -PARAM_STRING("update_rules", "Update rules for each iteration; ( multdist | " +PARAM_STRING_IN_REQ("input_file", "Input dataset to perform NMF on.", "i"); +PARAM_STRING_OUT("w_file", "File to save the calculated W matrix to.", "W"); +PARAM_STRING_OUT("h_file", "File to save the calculated H matrix to.", "H"); +PARAM_INT_IN_REQ("rank", "Rank of the factorization.", "r"); + +PARAM_INT_IN("max_iterations", "Number of iterations before NMF terminates (0 " + "runs until convergence.", "m", 10000); +PARAM_INT_IN("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0); +PARAM_DOUBLE_IN("min_residue", "The minimum root mean square residue allowed " + "for each iteration, below which the program terminates.", "e", 1e-5); + +PARAM_STRING_IN("update_rules", "Update rules for each iteration; ( multdist | " "multdiv | als ).", "u", "multdist"); int main(int argc, char** argv) @@ -93,6 +93,12 @@ int main(int argc, char** argv) << "multdist', 'multdiv', or 'als'." << std::endl; } + if (hOutputFile == "" && wOutputFile == "") + { + Log::Warn << "Neither --h_file nor --w_file are specified, so no output " + << "will be saved!" << endl; + } + // Load input dataset. arma::mat V; data::Load(inputFile, V, true); @@ -132,6 +138,8 @@ int main(int argc, char** argv) } // Save results. - data::Save(wOutputFile, W, false); - data::Save(hOutputFile, H, false); + if (wOutputFile != "") + data::Save(wOutputFile, W, false); + if (hOutputFile != "") + data::Save(hOutputFile, H, false); } diff --git a/src/mlpack/methods/pca/pca_main.cpp b/src/mlpack/methods/pca/pca_main.cpp index 6277c5b47f8..5bfaacda53f 100644 --- a/src/mlpack/methods/pca/pca_main.cpp +++ b/src/mlpack/methods/pca/pca_main.cpp @@ -20,12 +20,12 @@ PROGRAM_INFO("Principal Components Analysis", "This program performs principal " "eigenvalues."); // Parameters for program. -PARAM_STRING_REQ("input_file", "Input dataset to perform PCA on.", "i"); -PARAM_STRING_REQ("output_file", "File to save modified dataset to.", "o"); -PARAM_INT("new_dimensionality", "Desired dimensionality of output dataset. If " - "0, no dimensionality reduction is performed.", "d", 0); -PARAM_DOUBLE("var_to_retain", "Amount of variance to retain; should be between " - "0 and 1. If 1, all variance is retained. Overrides -d.", "V", 0); +PARAM_STRING_IN_REQ("input_file", "Input dataset to perform PCA on.", "i"); +PARAM_STRING_OUT("output_file", "File to save modified dataset to.", "o"); +PARAM_INT_IN("new_dimensionality", "Desired dimensionality of output dataset. " + "If 0, no dimensionality reduction is performed.", "d", 0); +PARAM_DOUBLE_IN("var_to_retain", "Amount of variance to retain; should be " + "between 0 and 1. If 1, all variance is retained. Overrides -d.", "V", 0); PARAM_FLAG("scale", "If set, the data will be scaled before running PCA, such " "that the variance of each feature is 1.", "s"); @@ -40,6 +40,11 @@ int main(int argc, char** argv) arma::mat dataset; data::Load(inputFile, dataset); + // Issue a warning if the user did not specify an output file. + if (!CLI::HasParam("output_file")) + Log::Warn << "--output_file is not specified; no output will be " + << "saved." << endl; + // Find out what dimension we want. size_t newDimension = dataset.n_rows; // No reduction, by default. if (CLI::GetParam("new_dimensionality") != 0) @@ -79,5 +84,6 @@ int main(int argc, char** argv) // Now save the results. string outputFile = CLI::GetParam("output_file"); - data::Save(outputFile, dataset); + if (outputFile != "") + data::Save(outputFile, dataset); } diff --git a/src/mlpack/methods/perceptron/perceptron_main.cpp b/src/mlpack/methods/perceptron/perceptron_main.cpp index 28a2776bd3d..875538b0b52 100644 --- a/src/mlpack/methods/perceptron/perceptron_main.cpp +++ b/src/mlpack/methods/perceptron/perceptron_main.cpp @@ -61,22 +61,23 @@ PROGRAM_INFO("Perceptron", ); // Training parameters. -PARAM_STRING("training_file", "A file containing the training set.", "t", ""); -PARAM_STRING("labels_file", "A file containing labels for the training set.", - "l", ""); -PARAM_INT("max_iterations","The maximum number of iterations the perceptron is " - "to be run", "n", 1000); +PARAM_STRING_IN("training_file", "A file containing the training set.", "t", + ""); +PARAM_STRING_IN("labels_file", "A file containing labels for the training set.", + "l", ""); +PARAM_INT_IN("max_iterations","The maximum number of iterations the perceptron " + "is to be run", "n", 1000); // Model loading/saving. -PARAM_STRING("input_model_file", "File containing input perceptron model.", "m", - ""); -PARAM_STRING("output_model_file", "File to save trained perceptron model to.", - "M", ""); +PARAM_STRING_IN("input_model_file", "File containing input perceptron model.", + "m", ""); +PARAM_STRING_OUT("output_model_file", "File to save trained perceptron model " + "to.", "M"); // Testing/classification parameters. -PARAM_STRING("test_file", "A file containing the test set.", "T", ""); -PARAM_STRING("output_file", "The file in which the predicted labels for the " - "test set will be written.", "o", "output.csv"); +PARAM_STRING_IN("test_file", "A file containing the test set.", "T", ""); +PARAM_STRING_OUT("output_file", "The file in which the predicted labels for the" + " test set will be written.", "o"); // When we save a model, we must also save the class mappings. So we use this // auxiliary structure to store both the perceptron and the mapping, and we'll @@ -123,6 +124,10 @@ int main(int argc, char** argv) Log::Warn << "Output will not be saved! (Neither --test_file nor " << "--output_model_file are specified.)" << endl; + if (testDataFile == "" && outputFile != "") + Log::Warn << "--output_file will be ignored because --test_file is not " + << "specified." << endl; + // Now, load our model, if there is one. Perceptron<>* p = NULL; Col mappings; @@ -241,7 +246,8 @@ int main(int argc, char** argv) data::RevertLabels(predictedLabels, mappings, results); // Save the predicted labels. - data::Save(outputFile, results, false /* non-fatal */); + if (outputFile != "") + data::Save(outputFile, results, false /* non-fatal */); } // Lastly, do we need to save the output model? diff --git a/src/mlpack/methods/preprocess/preprocess_split_main.cpp b/src/mlpack/methods/preprocess/preprocess_split_main.cpp index 1e063db0cda..fc41685cb30 100644 --- a/src/mlpack/methods/preprocess/preprocess_split_main.cpp +++ b/src/mlpack/methods/preprocess/preprocess_split_main.cpp @@ -45,16 +45,19 @@ PROGRAM_INFO("Split Data", "This utility takes a dataset and optionally labels " "> -L test_labels.csv"); // Define parameters for data. -PARAM_STRING_REQ("input_file", "File containing data,", "i"); +PARAM_STRING_IN_REQ("input_file", "File containing data,", "i"); + // Define optional parameters. -PARAM_STRING("input_labels_file", "File containing labels", "I", ""); -PARAM_STRING("training_file", "File name to save train data", "t", ""); -PARAM_STRING("test_file", "File name to save test data", "T", ""); -PARAM_STRING("training_labels_file", "File name to save train label", "l", ""); -PARAM_STRING("test_labels_file", "File name to save test label", "L", ""); +PARAM_STRING_IN("input_labels_file", "File containing labels", "I", ""); +PARAM_STRING_OUT("training_file", "File name to save train data", "t"); +PARAM_STRING_OUT("test_file", "File name to save test data", "T"); +PARAM_STRING_OUT("training_labels_file", "File name to save training labels " + "to.", "l"); +PARAM_STRING_OUT("test_labels_file", "File name to save test labels to.", + "L"); -// Define optional test ratio, default is 0.2 (Test 20% Train 80%) -PARAM_DOUBLE("test_ratio", "Ratio of test set, if not set," +// Define optional test ratio, default is 0.2 (Test 20% Train 80%). +PARAM_DOUBLE_IN("test_ratio", "Ratio of test set; if not set," "the ratio defaults to 0.2", "r", 0.2); using namespace mlpack; diff --git a/src/mlpack/methods/radical/radical_main.cpp b/src/mlpack/methods/radical/radical_main.cpp index 43eac6d863e..85206bb5762 100644 --- a/src/mlpack/methods/radical/radical_main.cpp +++ b/src/mlpack/methods/radical/radical_main.cpp @@ -14,22 +14,20 @@ PROGRAM_INFO("RADICAL", "An implementation of RADICAL, a method for independent" "dimensions of Y are independent components. If the algorithm is running" "particularly slowly, try reducing the number of replicates."); -PARAM_STRING_REQ("input_file", "Input dataset filename for ICA.", "i"); +PARAM_STRING_IN_REQ("input_file", "Input dataset filename for ICA.", "i"); -PARAM_STRING("output_ic", "File to save independent components to.", "o", - "output_ic.csv"); -PARAM_STRING("output_unmixing", "File to save unmixing matrix to.", "u", - "output_unmixing.csv"); +PARAM_STRING_OUT("output_ic", "File to save independent components to.", "o"); +PARAM_STRING_OUT("output_unmixing", "File to save unmixing matrix to.", "u"); -PARAM_DOUBLE("noise_std_dev", "Standard deviation of Gaussian noise.", "n", +PARAM_DOUBLE_IN("noise_std_dev", "Standard deviation of Gaussian noise.", "n", 0.175); -PARAM_INT("replicates", "Number of Gaussian-perturbed replicates to use " +PARAM_INT_IN("replicates", "Number of Gaussian-perturbed replicates to use " "(per point) in Radical2D.", "r", 30); -PARAM_INT("angles", "Number of angles to consider in brute-force search " +PARAM_INT_IN("angles", "Number of angles to consider in brute-force search " "during Radical2D.", "a", 150); -PARAM_INT("sweeps", "Number of sweeps; each sweep calls Radical2D once for " +PARAM_INT_IN("sweeps", "Number of sweeps; each sweep calls Radical2D once for " "each pair of dimensions.", "S", 0); -PARAM_INT("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0); +PARAM_INT_IN("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0); PARAM_FLAG("objective", "If set, an estimate of the final objective function " "is printed.", "O"); @@ -50,6 +48,10 @@ int main(int argc, char* argv[]) else RandomSeed((size_t) std::time(NULL)); + if (!CLI::HasParam("output_ic") && !CLI::HasParam("output_unmixing")) + Log::Warn << "Neither --output_ic nor --output_unmixing were specified; " + << "no output will be saved!" << endl; + // Load the data. const string matXFilename = CLI::GetParam("input_file"); mat matX; @@ -74,10 +76,12 @@ int main(int argc, char* argv[]) // Save results. const string matYFilename = CLI::GetParam("output_ic"); - data::Save(matYFilename, matY); + if (matYFilename != "") + data::Save(matYFilename, matY); const string matWFilename = CLI::GetParam("output_unmixing"); - data::Save(matWFilename, matW); + if (matWFilename != "") + data::Save(matWFilename, matW); if (CLI::HasParam("objective")) { diff --git a/src/mlpack/methods/range_search/range_search_main.cpp b/src/mlpack/methods/range_search/range_search_main.cpp index 3606950e2f6..c8d0fea80b6 100644 --- a/src/mlpack/methods/range_search/range_search_main.cpp +++ b/src/mlpack/methods/range_search/range_search_main.cpp @@ -50,31 +50,32 @@ PROGRAM_INFO("Range Search", "regardless of the given extension."); // Define our input parameters that this program will take. -PARAM_STRING("reference_file", "File containing the reference dataset.", "r", +PARAM_STRING_IN("reference_file", "File containing the reference dataset.", "r", ""); -PARAM_STRING("distances_file", "File to output distances into.", "d", ""); -PARAM_STRING("neighbors_file", "File to output neighbors into.", "n", ""); +PARAM_STRING_OUT("distances_file", "File to output distances into.", "d"); +PARAM_STRING_OUT("neighbors_file", "File to output neighbors into.", "n"); // The option exists to load or save models. -PARAM_STRING("input_model_file", "File containing pre-trained range search " +PARAM_STRING_IN("input_model_file", "File containing pre-trained range search " "model.", "m", ""); -PARAM_STRING("output_model_file", "If specified, the range search model will be" - " saved to the given file.", "M", ""); +PARAM_STRING_OUT("output_model_file", "If specified, the range search model " + "will be saved to the given file.", "M"); // The user may specify a query file of query points and a range to search for. -PARAM_STRING("query_file", "File containing query points (optional).", "q", ""); -PARAM_DOUBLE("max", "Upper bound in range (if not specified, +inf will be " +PARAM_STRING_IN("query_file", "File containing query points (optional).", "q", + ""); +PARAM_DOUBLE_IN("max", "Upper bound in range (if not specified, +inf will be " "used.", "U", 0.0); -PARAM_DOUBLE("min", "Lower bound in range.", "L", 0.0); +PARAM_DOUBLE_IN("min", "Lower bound in range.", "L", 0.0); // The user may specify the type of tree to use, and a few parameters for tree // building. -PARAM_STRING("tree_type", "Type of tree to use: 'kd', 'cover', 'r', 'r-star', " - "'x', 'ball'.", "t", "kd"); -PARAM_INT("leaf_size", "Leaf size for tree building.", "l", 20); +PARAM_STRING_IN("tree_type", "Type of tree to use: 'kd', 'cover', 'r', " + "'r-star', 'x', 'ball'.", "t", "kd"); +PARAM_INT_IN("leaf_size", "Leaf size for tree building.", "l", 20); PARAM_FLAG("random_basis", "Before tree-building, project the data onto a " "random orthogonal basis.", "R"); -PARAM_INT("seed", "Random seed (if 0, std::time(NULL) is used).", "s", 0); +PARAM_INT_IN("seed", "Random seed (if 0, std::time(NULL) is used).", "s", 0); // Search settings. PARAM_FLAG("naive", "If true, O(n^2) naive mode is used for computation.", "N"); diff --git a/src/mlpack/methods/rann/allkrann_main.cpp b/src/mlpack/methods/rann/allkrann_main.cpp index ce6f9f1bdcd..c434fc7ad03 100644 --- a/src/mlpack/methods/rann/allkrann_main.cpp +++ b/src/mlpack/methods/rann/allkrann_main.cpp @@ -45,36 +45,37 @@ PROGRAM_INFO("All K-Rank-Approximate-Nearest-Neighbors", "corresponds to the distance between those two points."); // Define our input parameters that this program will take. -PARAM_STRING("reference_file", "File containing the reference dataset.", +PARAM_STRING_IN("reference_file", "File containing the reference dataset.", "r", ""); -PARAM_STRING("distances_file", "File to output distances into.", "d", ""); -PARAM_STRING("neighbors_file", "File to output neighbors into.", "n", ""); +PARAM_STRING_OUT("distances_file", "File to output distances into.", "d"); +PARAM_STRING_OUT("neighbors_file", "File to output neighbors into.", "n"); // The option exists to load or save models. -PARAM_STRING("input_model_file", "File containing pre-trained kNN model.", "m", - ""); -PARAM_STRING("output_model_file", "If specified, the kNN model will be saved " - "to the given file.", "M", ""); +PARAM_STRING_IN("input_model_file", "File containing pre-trained kNN model.", + "m", ""); +PARAM_STRING_OUT("output_model_file", "If specified, the kNN model will be " + "saved to the given file.", "M"); // The user may specify a query file of query points and a number of nearest // neighbors to search for. -PARAM_STRING("query_file", "File containing query points (optional).", "q", ""); -PARAM_INT("k", "Number of nearest neighbors to find.", "k", 0); +PARAM_STRING_IN("query_file", "File containing query points (optional).", "q", + ""); +PARAM_INT_IN("k", "Number of nearest neighbors to find.", "k", 0); // The user may specify the type of tree to use, and a few parameters for tree // building. -PARAM_STRING("tree_type", "Type of tree to use: 'kd', 'cover', 'r', or " +PARAM_STRING_IN("tree_type", "Type of tree to use: 'kd', 'cover', 'r', or " "'x', 'r-star'.", "t", "kd"); -PARAM_INT("leaf_size", "Leaf size for tree building (used for kd-trees, R " +PARAM_INT_IN("leaf_size", "Leaf size for tree building (used for kd-trees, R " "trees, and R* trees).", "l", 20); PARAM_FLAG("random_basis", "Before tree-building, project the data onto a " "random orthogonal basis.", "R"); -PARAM_INT("seed", "Random seed (if 0, std::time(NULL) is used).", "s", 0); +PARAM_INT_IN("seed", "Random seed (if 0, std::time(NULL) is used).", "s", 0); // Search options. -PARAM_DOUBLE("tau", "The allowed rank-error in terms of the percentile of " +PARAM_DOUBLE_IN("tau", "The allowed rank-error in terms of the percentile of " "the data.", "t", 5); -PARAM_DOUBLE("alpha", "The desired success probability.", "a", 0.95); +PARAM_DOUBLE_IN("alpha", "The desired success probability.", "a", 0.95); PARAM_FLAG("naive", "If true, sampling will be done without using a tree.", "N"); PARAM_FLAG("single_mode", "If true, single-tree search is used (as opposed to " @@ -82,7 +83,7 @@ PARAM_FLAG("single_mode", "If true, single-tree search is used (as opposed to " PARAM_FLAG("sample_at_leaves", "The flag to trigger sampling at leaves.", "L"); PARAM_FLAG("first_leaf_exact", "The flag to trigger sampling only after " "exactly exploring the first leaf.", "X"); -PARAM_INT("single_sample_limit", "The limit on the maximum number of " +PARAM_INT_IN("single_sample_limit", "The limit on the maximum number of " "samples (and hence the largest node you can approximate).", "S", 20); // Convenience typedef. diff --git a/src/mlpack/methods/rmva/rmva_main.cpp b/src/mlpack/methods/rmva/rmva_main.cpp index 4ea2b76503e..b0486e64e36 100644 --- a/src/mlpack/methods/rmva/rmva_main.cpp +++ b/src/mlpack/methods/rmva/rmva_main.cpp @@ -42,41 +42,42 @@ PROGRAM_INFO("Recurrent Model for Visual Attention", "should be given."); // Model loading/saving. -PARAM_STRING("input_model_file", "File containing the Recurrent Model for " +PARAM_STRING_IN("input_model_file", "File containing the Recurrent Model for " "Visual Attention.", "m", ""); -PARAM_STRING("output_model_file", "File to save trained Recurrent Model for " - "Visual Attention to.", "M", ""); +PARAM_STRING_OUT("output_model_file", "File to save trained Recurrent Model for" + " Visual Attention to.", "M"); // Training parameters. -PARAM_STRING("training_file", "A file containing the training set.", "t", ""); -PARAM_STRING("labels_file", "A file containing labels for the training set.", +PARAM_STRING_IN("training_file", "A file containing the training set.", "t", + ""); +PARAM_STRING_IN("labels_file", "A file containing labels for the training set.", "l", ""); -PARAM_STRING("optimizer", "Optimizer to use; 'sgd', 'minibatch-sgd', or " +PARAM_STRING_IN("optimizer", "Optimizer to use; 'sgd', 'minibatch-sgd', or " "'lbfgs'.", "O", "minibatch-sgd"); -PARAM_INT("max_iterations", "Maximum number of iterations for SGD or RMSProp " - "(0 indicates no limit).", "n", 500000); -PARAM_DOUBLE("tolerance", "Maximum tolerance for termination of SGD or " +PARAM_INT_IN("max_iterations", "Maximum number of iterations for SGD or RMSProp" + " (0 indicates no limit).", "n", 500000); +PARAM_DOUBLE_IN("tolerance", "Maximum tolerance for termination of SGD or " "RMSProp.", "e", 1e-7); -PARAM_DOUBLE("step_size", "Step size for stochastic gradient descent (alpha).", - "a", 0.01); +PARAM_DOUBLE_IN("step_size", "Step size for stochastic gradient descent " + "(alpha),", "a", 0.01); PARAM_FLAG("linear_scan", "Don't shuffle the order in which data points are " "visited for SGD or mini-batch SGD.", "L"); -PARAM_INT("batch_size", "Batch size for mini-batch SGD.", "b", 20); +PARAM_INT_IN("batch_size", "Batch size for mini-batch SGD.", "b", 20); -PARAM_INT("rho", "Number of steps for the back-propagate through time.", "r", +PARAM_INT_IN("rho", "Number of steps for the back-propagate through time.", "r", 7); -PARAM_INT("classes", "The number of classes.", "c", 10); +PARAM_INT_IN("classes", "The number of classes.", "c", 10); -PARAM_INT("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0); +PARAM_INT_IN("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0); // Test parameters. -PARAM_STRING("test_file", "A file containing the test set.", "T", ""); -PARAM_STRING("output_file", "The file in which the predicted labels for the " - "test set will be written.", "o", ""); +PARAM_STRING_OUT("test_file", "A file containing the test set.", "T"); +PARAM_STRING_OUT("output_file", "The file in which the predicted labels for the" + " test set will be written.", "o"); int main(int argc, char** argv) { diff --git a/src/mlpack/methods/softmax_regression/softmax_regression_main.cpp b/src/mlpack/methods/softmax_regression/softmax_regression_main.cpp index af78bd2a45f..9c7eda19f5f 100644 --- a/src/mlpack/methods/softmax_regression/softmax_regression_main.cpp +++ b/src/mlpack/methods/softmax_regression/softmax_regression_main.cpp @@ -35,32 +35,32 @@ PROGRAM_INFO("Softmax Regression", "This program performs softmax regression, " "on the given test set and its corresponding labels."); // Required options. -PARAM_STRING("training_file", "A file containing the training set (the matrix " - "of predictors, X).", "t", ""); -PARAM_STRING("labels_file", "A file containing labels (0 or 1) for the points " - "in the training set (y). The labels must order as a row", "l", ""); +PARAM_STRING_IN("training_file", "A file containing the training set (the " + "matrix of predictors, X).", "t", ""); +PARAM_STRING_IN("labels_file", "A file containing labels (0 or 1) for the " + "points in the training set (y). The labels must order as a row", "l", ""); // Model loading/saving. -PARAM_STRING("input_model_file", "File containing existing model (parameters).", - "m", ""); -PARAM_STRING("output_model_file", "File to save trained softmax regression " - "model to.", "M", ""); +PARAM_STRING_IN("input_model_file", "File containing existing model " + "(parameters).", "m", ""); +PARAM_STRING_OUT("output_model_file", "File to save trained softmax regression " + "model to.", "M"); // Testing. -PARAM_STRING("test_data", "File containing test dataset.", "T", ""); -PARAM_STRING("predictions_file", "File to save predictions for test dataset " - "into.", "p", ""); -PARAM_STRING("test_labels", "File containing test labels.", "L", ""); +PARAM_STRING_IN("test_data", "File containing test dataset.", "T", ""); +PARAM_STRING_OUT("predictions_file", "File to save predictions for test dataset" + " into.", "p"); +PARAM_STRING_IN("test_labels", "File containing test labels.", "L", ""); // Softmax configuration options. -PARAM_INT("max_iterations", "Maximum number of iterations before termination.", - "n", 400); +PARAM_INT_IN("max_iterations", "Maximum number of iterations before " + "termination.", "n", 400); -PARAM_INT("number_of_classes", "Number of classes for classification; if " +PARAM_INT_IN("number_of_classes", "Number of classes for classification; if " "unspecified (or 0), the number of classes found in the labels will be " "used.", "c", 0); -PARAM_DOUBLE("lambda", "L2-regularization constant", "r", 0.0001); +PARAM_DOUBLE_IN("lambda", "L2-regularization constant", "r", 0.0001); PARAM_FLAG("no_intercept", "Do not add the intercept term to the model.", "N"); diff --git a/src/mlpack/methods/sparse_coding/sparse_coding_main.cpp b/src/mlpack/methods/sparse_coding/sparse_coding_main.cpp index 4f2324f97b5..5ab918ef054 100644 --- a/src/mlpack/methods/sparse_coding/sparse_coding_main.cpp +++ b/src/mlpack/methods/sparse_coding/sparse_coding_main.cpp @@ -45,38 +45,38 @@ PROGRAM_INFO("Sparse Coding", "An implementation of Sparse Coding with " "$ sparse_coding -m model.xml -T otherdata.csv -c codes.csv"); // Train the model. -PARAM_STRING("training_file", "Filename of the training data (X).", "t", ""); -PARAM_INT("atoms", "Number of atoms in the dictionary.", "k", 0); - -PARAM_DOUBLE("lambda1", "Sparse coding l1-norm regularization parameter.", "l", - 0); -PARAM_DOUBLE("lambda2", "Sparse coding l2-norm regularization parameter.", "L", - 0); -PARAM_INT("max_iterations", "Maximum number of iterations for sparse coding (0 " - "indicates no limit).", "n", 0); -PARAM_STRING("initial_dictionary", "Filename for optional initial dictionary.", - "i", ""); +PARAM_STRING_IN("training_file", "Filename of the training data (X).", "t", ""); +PARAM_INT_IN("atoms", "Number of atoms in the dictionary.", "k", 0); + +PARAM_DOUBLE_IN("lambda1", "Sparse coding l1-norm regularization parameter.", + "l", 0); +PARAM_DOUBLE_IN("lambda2", "Sparse coding l2-norm regularization parameter.", + "L", 0); +PARAM_INT_IN("max_iterations", "Maximum number of iterations for sparse coding " + "(0 indicates no limit).", "n", 0); +PARAM_STRING_IN("initial_dictionary", "Filename for optional initial " + "dictionary.", "i", ""); PARAM_FLAG("normalize", "If set, the input data matrix will be normalized " "before coding.", "N"); -PARAM_INT("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0); -PARAM_DOUBLE("objective_tolerance", "Tolerance for convergence of the objective" - " function.", "o", 0.01); -PARAM_DOUBLE("newton_tolerance", "Tolerance for convergence of Newton method.", - "w", 1e-6); +PARAM_INT_IN("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0); +PARAM_DOUBLE_IN("objective_tolerance", "Tolerance for convergence of the " + "objective function.", "o", 0.01); +PARAM_DOUBLE_IN("newton_tolerance", "Tolerance for convergence of Newton " + "method.", "w", 1e-6); // Load/save a model. -PARAM_STRING("input_model_file", "File containing input sparse coding model.", - "m", ""); -PARAM_STRING("output_model_file", "File to save trained sparse coding model " - "to.", "M", ""); - -PARAM_STRING("dictionary_file", "Filename to save the output dictionary to.", - "d", ""); -PARAM_STRING("codes_file", "Filename to save the output sparse codes to.", "c", - ""); - -PARAM_STRING("test_file", "File containing data matrix to be encoded by trained" - " model.", "T", ""); +PARAM_STRING_IN("input_model_file", "File containing input sparse coding " + "model.", "m", ""); +PARAM_STRING_OUT("output_model_file", "File to save trained sparse coding " + "model to.", "M"); + +PARAM_STRING_OUT("dictionary_file", "Filename to save the output dictionary " + "to.", "d"); +PARAM_STRING_OUT("codes_file", "Filename to save the output sparse codes to.", + "c"); + +PARAM_STRING_OUT("test_file", "File containing data matrix to be encoded by " + "trained model.", "T"); using namespace arma; using namespace std; From 7afd99c875a41a3dcab27c5cc8768965a8d8ea34 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Wed, 13 Jul 2016 10:56:08 -0400 Subject: [PATCH 03/21] Fix duplicate options. --- src/mlpack/methods/pca/pca_main.cpp | 6 +++--- src/mlpack/methods/rann/krann_main.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mlpack/methods/pca/pca_main.cpp b/src/mlpack/methods/pca/pca_main.cpp index f2f558cea13..981eeacfabd 100644 --- a/src/mlpack/methods/pca/pca_main.cpp +++ b/src/mlpack/methods/pca/pca_main.cpp @@ -29,7 +29,7 @@ PARAM_STRING_OUT("output_file", "File to save modified dataset to.", "o"); PARAM_INT_IN("new_dimensionality", "Desired dimensionality of output dataset. " "If 0, no dimensionality reduction is performed.", "d", 0); PARAM_DOUBLE_IN("var_to_retain", "Amount of variance to retain; should be " - "between 0 and 1. If 1, all variance is retained. Overrides -d.", "V", 0); + "between 0 and 1. If 1, all variance is retained. Overrides -d.", "r", 0); PARAM_FLAG("scale", "If set, the data will be scaled before running PCA, such " "that the variance of each feature is 1.", "s"); @@ -53,8 +53,8 @@ void RunPCA(arma::mat& dataset, if (varToRetain != 0) { if (newDimension != 0) - Log::Warn << "New dimensionality (-d) ignored because -V was specified." - << endl; + Log::Warn << "New dimensionality (-d) ignored because --var_to_retain " + << "(-r) was specified." << endl; varRetained = p.Apply(dataset, varToRetain); } diff --git a/src/mlpack/methods/rann/krann_main.cpp b/src/mlpack/methods/rann/krann_main.cpp index b8289ddca2d..9950cd2118e 100644 --- a/src/mlpack/methods/rann/krann_main.cpp +++ b/src/mlpack/methods/rann/krann_main.cpp @@ -75,7 +75,7 @@ PARAM_INT_IN("seed", "Random seed (if 0, std::time(NULL) is used).", "s", 0); // Search options. PARAM_DOUBLE_IN("tau", "The allowed rank-error in terms of the percentile of " - "the data.", "t", 5); + "the data.", "T", 5); PARAM_DOUBLE_IN("alpha", "The desired success probability.", "a", 0.95); PARAM_FLAG("naive", "If true, sampling will be done without using a tree.", "N"); From 2e740c5641856dc9d2e82615236fe6fd9c28e24a Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Wed, 13 Jul 2016 11:03:59 -0400 Subject: [PATCH 04/21] Don't print extra lines. --- src/mlpack/core/util/cli.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mlpack/core/util/cli.cpp b/src/mlpack/core/util/cli.cpp index 708f851b37f..323f2c55a9a 100644 --- a/src/mlpack/core/util/cli.cpp +++ b/src/mlpack/core/util/cli.cpp @@ -666,7 +666,8 @@ void CLI::PrintHelp(const std::string& param) std::cout << HyphenateString(desc, 32) << std::endl; } - std::cout << std::endl; + if (printedHeader) + std::cout << std::endl; } // Helpful information at the bottom of the help output, to point the user to From aac0b7fd054f9330b9345f6dc4190fd1623f0538 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Wed, 13 Jul 2016 11:16:35 -0400 Subject: [PATCH 05/21] Warn when the user does not specify a file to test but asks for output. --- src/mlpack/methods/adaboost/adaboost_main.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/mlpack/methods/adaboost/adaboost_main.cpp b/src/mlpack/methods/adaboost/adaboost_main.cpp index b4dc309b5ca..b90d7e69fda 100644 --- a/src/mlpack/methods/adaboost/adaboost_main.cpp +++ b/src/mlpack/methods/adaboost/adaboost_main.cpp @@ -275,6 +275,12 @@ int main(int argc, char *argv[]) << "no results will be saved." << endl; } + if (CLI::HasParam("output_file") && !CLI::HasParam("test_file")) + { + Log::Warn << "--output_file ignored because --test_file is not specified." + << endl; + } + AdaBoostModel m; if (CLI::HasParam("training_file")) { From 4cec0a365d223b7f045288097c3472da9dce5064 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Wed, 13 Jul 2016 13:41:28 -0400 Subject: [PATCH 06/21] Fix misspelled parameter name. --- src/mlpack/methods/neighbor_search/kfn_main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/neighbor_search/kfn_main.cpp b/src/mlpack/methods/neighbor_search/kfn_main.cpp index ccb30d3cf17..fac28b55b46 100644 --- a/src/mlpack/methods/neighbor_search/kfn_main.cpp +++ b/src/mlpack/methods/neighbor_search/kfn_main.cpp @@ -275,7 +275,7 @@ int main(int argc, char *argv[]) if (CLI::HasParam("output_model_file")) { - const string outputModelFile = CLI::GetParam("output_model_File"); + const string outputModelFile = CLI::GetParam("output_model_file"); data::Save(outputModelFile, "kfn_model", kfn); } } From fe6ad34f7f4994ab82a2b032a004775e2705be0b Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Wed, 13 Jul 2016 15:57:43 -0400 Subject: [PATCH 07/21] Fix parameter name issues. --- src/mlpack/methods/gmm/gmm_probability_main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mlpack/methods/gmm/gmm_probability_main.cpp b/src/mlpack/methods/gmm/gmm_probability_main.cpp index 0361f53e8da..4c53bdc5edd 100644 --- a/src/mlpack/methods/gmm/gmm_probability_main.cpp +++ b/src/mlpack/methods/gmm/gmm_probability_main.cpp @@ -30,7 +30,7 @@ int main(int argc, char** argv) const string inputFile = CLI::GetParam("input_file"); const string inputModelFile = CLI::GetParam("input_model_file"); - const string outputFile = CLI::GetParam("input_model_file"); + const string outputFile = CLI::GetParam("output_file"); if (CLI::HasParam("output_file")) Log::Warn << "--output_file (-o) is not specified;" @@ -38,10 +38,10 @@ int main(int argc, char** argv) // Get the GMM and the points. GMM gmm; - data::Load(inputFile, "gmm", gmm); + data::Load(inputModelFile, "gmm", gmm); arma::mat dataset; - data::Load(inputModelFile, dataset); + data::Load(inputFile, dataset); // Now calculate the probabilities. arma::rowvec probabilities(dataset.n_cols); From d665abeb62ee6813b5934603e254b328ecc99f75 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Wed, 13 Jul 2016 16:04:39 -0400 Subject: [PATCH 08/21] Better warnings when --output_file is not specified. --- src/mlpack/methods/cf/cf_main.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/mlpack/methods/cf/cf_main.cpp b/src/mlpack/methods/cf/cf_main.cpp index 599b86a90e7..2574e9117e0 100644 --- a/src/mlpack/methods/cf/cf_main.cpp +++ b/src/mlpack/methods/cf/cf_main.cpp @@ -156,7 +156,8 @@ void PerformAction(CF& c) // Save the output. const string outputFile = CLI::GetParam("output_file"); - data::Save(outputFile, recommendations); + if (outputFile != "") + data::Save(outputFile, recommendations); } if (CLI::HasParam("test_file")) @@ -262,6 +263,15 @@ int main(int argc, char** argv) Log::Fatal << "Both --query_file and --all_user_recommendations are given, " << "but only one is allowed!" << endl; + if (!CLI::HasParam("output_file") && !CLI::HasParam("output_model_file")) + Log::Warn << "Neither --output_file nor --output_model_file are specified; " + << "no output will be saved." << endl; + + if (CLI::HasParam("output_file") && (!CLI::HasParam("query_file") || + CLI::HasParam("all_user_recommendations"))) + Log::Warn << "--output_file is ignored because neither --query_file nor " + << "--all_user_recommendations are specified." << endl; + // Either load from a model, or train a model. if (CLI::HasParam("training_file")) { From 280feb567fc76b2a4687f9d0d9bb9600d3cee9dd Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Wed, 13 Jul 2016 16:04:56 -0400 Subject: [PATCH 09/21] Correct warning for no output. --- src/mlpack/methods/hmm/hmm_generate_main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm_generate_main.cpp b/src/mlpack/methods/hmm/hmm_generate_main.cpp index 739859c363a..af0e81108af 100644 --- a/src/mlpack/methods/hmm/hmm_generate_main.cpp +++ b/src/mlpack/methods/hmm/hmm_generate_main.cpp @@ -79,9 +79,9 @@ int main(int argc, char** argv) // Parse command line options. CLI::ParseCommandLine(argc, argv); - if (CLI::HasParam("output_file")) - Log::Warn << "--output_file (-o) is not specified; no results will be " - << "saved!" << endl; + if (!CLI::HasParam("output_file") && !CLI::HasParam("state_file")) + Log::Warn << "Neither --output_file nor --state_file are specified; no " + << "output will be saved!" << endl; // Set random seed. if (CLI::GetParam("seed") != 0) From 5506cbcc7c34d731c52f79f54b84c60801b98b34 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Wed, 13 Jul 2016 16:05:06 -0400 Subject: [PATCH 10/21] There is no such thing as a required output option. This commit removes printing those. --- src/mlpack/core/util/cli.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/mlpack/core/util/cli.cpp b/src/mlpack/core/util/cli.cpp index 323f2c55a9a..dcc1db46d5e 100644 --- a/src/mlpack/core/util/cli.cpp +++ b/src/mlpack/core/util/cli.cpp @@ -577,7 +577,7 @@ void CLI::PrintHelp(const std::string& param) else std::cout << "[undocumented program]" << std::endl << std::endl; - for (size_t pass = 0; pass < 4; ++pass) + for (size_t pass = 0; pass < 3; ++pass) { bool printedHeader = false; @@ -603,11 +603,9 @@ void CLI::PrintHelp(const std::string& param) // Filter un-printed options. if ((pass == 0) && !(required && input)) // Required input options only. continue; - if ((pass == 1) && !(required && !input)) // Required output options only. + if ((pass == 1) && !(!required && input)) // Optional input options only. continue; - if ((pass == 2) && !(!required && input)) // Optional input options only. - continue; - if ((pass == 3) && (required || input)) // Optional output options only. + if ((pass == 2) && input) // Output options only (always optional). continue; if (!printedHeader) @@ -616,14 +614,12 @@ void CLI::PrintHelp(const std::string& param) if (pass == 0) std::cout << "Required input options:" << std::endl << std::endl; else if (pass == 1) - std::cout << "Required output options:" << std::endl << std::endl; - else if (pass == 2) std::cout << "Optional input options: " << std::endl << std::endl; - else if (pass == 3) + else if (pass == 2) std::cout << "Optional output options: " << std::endl << std::endl; } - if (pass >= 2) // Append default value to description. + if (pass >= 1) // Append default value to description. { desc += " Default value "; std::stringstream tmp; From 156c92e82d3c6beba1d9e8a9795a0b849b15fca9 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Wed, 13 Jul 2016 16:14:10 -0400 Subject: [PATCH 11/21] Update to --output_predictions_file, but keep old version for reverse compatibility. --- src/mlpack/methods/lars/lars_main.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/mlpack/methods/lars/lars_main.cpp b/src/mlpack/methods/lars/lars_main.cpp index d4eb7018fc9..5bae11fef82 100644 --- a/src/mlpack/methods/lars/lars_main.cpp +++ b/src/mlpack/methods/lars/lars_main.cpp @@ -51,8 +51,13 @@ PARAM_STRING_OUT("output_model_file", "File to save model to.", "M"); PARAM_STRING_IN("test_file", "File containing points to regress on (test " "points).", "t", ""); + +// Kept for reverse compatibility until mlpack 3.0.0. PARAM_STRING_OUT("output_predictions", "If --test_file is specified, this file " - "is where the predicted responses will be saved.", "o"); + "is where the predicted responses will be saved.", ""); +// This is the future name of the parameter. +PARAM_STRING_OUT("output_predictions_file", "If --test_file is specified, this " + "file is where the predicted responses will be saved.", "o"); PARAM_DOUBLE_IN("lambda1", "Regularization parameter for l1-norm penalty.", "l", 0); @@ -75,6 +80,20 @@ int main(int argc, char* argv[]) double lambda2 = CLI::GetParam("lambda2"); bool useCholesky = CLI::HasParam("use_cholesky"); + // Reverse compatibility. We can remove these for mlpack 3.0.0. + if (CLI::HasParam("output_predictions") && + CLI::HasParam("output_predictions_file")) + Log::Fatal << "Cannot specify both --output_predictions and " + << "--output_predictions_file!" << endl; + + if (CLI::HasParam("output_predictions")) + { + Log::Warn << "--output_predictions is deprecated and will be removed in " + << "mlpack 3.0.0; use --output_predictions_file instead." << endl; + CLI::GetParam("output_predictions_file") = + CLI::GetParam("output_predictions"); + } + // Check parameters -- make sure everything given makes sense. if (CLI::HasParam("input_file") && !CLI::HasParam("responses_file")) Log::Fatal << "--input_file (-i) is specified, but --responses_file (-r) is" From 511596d2b3561dc93a08fe4e18baa86e3a2b76b6 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Wed, 13 Jul 2016 16:14:25 -0400 Subject: [PATCH 12/21] Only print output parameters that are strings and end with "_file". --- src/mlpack/core/util/cli.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mlpack/core/util/cli.cpp b/src/mlpack/core/util/cli.cpp index dcc1db46d5e..468f9a4058b 100644 --- a/src/mlpack/core/util/cli.cpp +++ b/src/mlpack/core/util/cli.cpp @@ -608,6 +608,11 @@ void CLI::PrintHelp(const std::string& param) if ((pass == 2) && input) // Output options only (always optional). continue; + // Only print string output options that end in "_file". + if ((pass == 2) && ((data.tname != TYPENAME(std::string)) || + (data.name.substr(data.name.size() - 5, 5) != "_file"))) + continue; + if (!printedHeader) { printedHeader = true; From 52ffd75b7f6b07b32693c7c7ea1956193b57bdff Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Wed, 13 Jul 2016 16:56:14 -0400 Subject: [PATCH 13/21] Print any output options at the end of the run. --- src/mlpack/core/util/cli.cpp | 50 ++++++++++++++++++++++++++++++++++++ src/mlpack/core/util/cli.hpp | 5 ++++ 2 files changed, 55 insertions(+) diff --git a/src/mlpack/core/util/cli.cpp b/src/mlpack/core/util/cli.cpp index 468f9a4058b..d0094665f1c 100644 --- a/src/mlpack/core/util/cli.cpp +++ b/src/mlpack/core/util/cli.cpp @@ -50,6 +50,9 @@ CLI::CLI(const CLI& other) : desc(other.desc), CLI::~CLI() { + // We need to print any output options. + PrintOutput(); + // Terminate the program timers. std::map::iterator it; for (it = timer.GetAllTimers().begin(); it != timer.GetAllTimers().end(); @@ -460,6 +463,53 @@ void CLI::RemoveDuplicateFlags(po::basic_parsed_options& bpo) } } +// Prints any output options. +void CLI::PrintOutput() +{ + gmap_t& gmap = GetSingleton().globalValues; + gmap_t::iterator iter; + + for (iter = gmap.begin(); iter != gmap.end(); ++iter) + { + std::string key = iter->first; + ParamData data = iter->second; + + const std::list& inputOptions = GetSingleton().inputOptions; + const bool input = (std::find(std::begin(inputOptions), + std::end(inputOptions), key) != std::end(inputOptions)); + + // Ignore input options. + if (input) + continue; + + // Ignore string output options that end in _file. + if ((data.tname == TYPENAME(std::string)) && + (data.name.substr(data.name.size() - 5, 5) == "_file")) + continue; + + // Now, we must print it, so figure out what the type is. + if (data.tname == TYPENAME(std::string)) + { + std::string value = GetParam(key); + std::cout << key << ": " << value << std::endl; + } + else if (data.tname == TYPENAME(int)) + { + int value = GetParam(key); + std::cout << key << ": " << value << std::endl; + } + else if (data.tname == TYPENAME(double)) + { + double value = GetParam(key); + std::cout << key << ": " << value << std::endl; + } + else + { + std::cout << key << ": unknown data type" << std::endl; + } + } +} + /* Prints out the current hierarchy. */ void CLI::Print() { diff --git a/src/mlpack/core/util/cli.hpp b/src/mlpack/core/util/cli.hpp index dd98c0f70fc..7eadf8aca24 100644 --- a/src/mlpack/core/util/cli.hpp +++ b/src/mlpack/core/util/cli.hpp @@ -310,6 +310,11 @@ class CLI */ static void RemoveDuplicateFlags(po::basic_parsed_options& bpo); + /** + * Print the value of any output options on stdout. + */ + static void PrintOutput(); + /** * Print out the current hierarchy. */ From e11fbbbbfd48360f72abde1ad442fe7e20d54899 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Wed, 13 Jul 2016 16:59:54 -0400 Subject: [PATCH 14/21] Fix wrong conditional for printing warning. --- src/mlpack/methods/hmm/hmm_viterbi_main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/hmm/hmm_viterbi_main.cpp b/src/mlpack/methods/hmm/hmm_viterbi_main.cpp index 4bb6a1cdab2..be5be85b493 100644 --- a/src/mlpack/methods/hmm/hmm_viterbi_main.cpp +++ b/src/mlpack/methods/hmm/hmm_viterbi_main.cpp @@ -73,7 +73,7 @@ int main(int argc, char** argv) // Parse command line options. CLI::ParseCommandLine(argc, argv); - if (CLI::HasParam("output_file")) + if (!CLI::HasParam("output_file")) Log::Warn << "--output_file (-o) is not specified; no results will be " << "saved!" << endl; From bbc0efc964b43adc6190800f03a77130af917068 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Wed, 13 Jul 2016 17:03:40 -0400 Subject: [PATCH 15/21] Add warning for kernel_pca when --output_file is not specified. Also allow the user to not specify that option. --- src/mlpack/methods/kernel_pca/kernel_pca_main.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/mlpack/methods/kernel_pca/kernel_pca_main.cpp b/src/mlpack/methods/kernel_pca/kernel_pca_main.cpp index a8610518078..83686f18cc5 100644 --- a/src/mlpack/methods/kernel_pca/kernel_pca_main.cpp +++ b/src/mlpack/methods/kernel_pca/kernel_pca_main.cpp @@ -144,6 +144,10 @@ int main(int argc, char** argv) // Parse command line options. CLI::ParseCommandLine(argc, argv); + if (!CLI::HasParam("output_file")) + Log::Warn << "--output_file is not specified; no output will be saved!" + << endl; + // Load input dataset. mat dataset; const string inputFile = CLI::GetParam("input_file"); @@ -234,5 +238,6 @@ int main(int argc, char** argv) // Save the output dataset. const string outputFile = CLI::GetParam("output_file"); - data::Save(outputFile, dataset, true); // Fatal on failure. + if (outputFile != "") + data::Save(outputFile, dataset, true); // Fatal on failure. } From 846af8610a10ae624e82a2b50e5cfdc3cec950d2 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Fri, 15 Jul 2016 11:41:07 -0400 Subject: [PATCH 16/21] Add reverse compatibility for some incorrectly-named parameters. In addition, the behavior and checks for some input parameters has been slightly changed in places, sometimes fixing bugs. --- src/mlpack/core/util/cli.cpp | 12 ++++ src/mlpack/methods/lars/lars_main.cpp | 22 ++++--- .../linear_regression_main.cpp | 35 +++++++++-- src/mlpack/methods/lsh/lsh_main.cpp | 10 +++- .../methods/mean_shift/mean_shift_main.cpp | 59 +++++++++++++++---- src/mlpack/methods/nca/nca_main.cpp | 9 ++- .../preprocess/preprocess_binarize_main.cpp | 14 ++--- .../preprocess/preprocess_split_main.cpp | 45 ++++++++------ src/mlpack/methods/radical/radical_main.cpp | 49 ++++++++++++--- .../softmax_regression_main.cpp | 5 +- 10 files changed, 194 insertions(+), 66 deletions(-) diff --git a/src/mlpack/core/util/cli.cpp b/src/mlpack/core/util/cli.cpp index d0094665f1c..aa8716769a2 100644 --- a/src/mlpack/core/util/cli.cpp +++ b/src/mlpack/core/util/cli.cpp @@ -487,6 +487,13 @@ void CLI::PrintOutput() (data.name.substr(data.name.size() - 5, 5) == "_file")) continue; + // Reverse compatibility; should be removed for mlpack 3.0.0. Don't print + // some options that have only been kept for reverse compatibility. + if (data.name == "output_predictions" || + data.name == "output_ic" || + data.name == "output_unmixing") + continue; + // Now, we must print it, so figure out what the type is. if (data.tname == TYPENAME(std::string)) { @@ -663,6 +670,11 @@ void CLI::PrintHelp(const std::string& param) (data.name.substr(data.name.size() - 5, 5) != "_file"))) continue; + // For reverse compatibility: this can be removed when these options are + // gone in mlpack 3.0.0. We don't want to print the deprecated options. + if (data.name == "inputFile") + continue; + if (!printedHeader) { printedHeader = true; diff --git a/src/mlpack/methods/lars/lars_main.cpp b/src/mlpack/methods/lars/lars_main.cpp index 5bae11fef82..3bb6d3d12c6 100644 --- a/src/mlpack/methods/lars/lars_main.cpp +++ b/src/mlpack/methods/lars/lars_main.cpp @@ -94,7 +94,9 @@ int main(int argc, char* argv[]) CLI::GetParam("output_predictions"); } - // Check parameters -- make sure everything given makes sense. + // Check parameters -- make sure everything given makes sense. These checks + // can be simplified to HasParam() after the reverse compatibility options are + // removed. if (CLI::HasParam("input_file") && !CLI::HasParam("responses_file")) Log::Fatal << "--input_file (-i) is specified, but --responses_file (-r) is" << " not!" << endl; @@ -112,17 +114,19 @@ int main(int argc, char* argv[]) Log::Fatal << "Both --input_file (-i) and --input_model_file (-m) are " << "specified, but only one may be specified!" << endl; - if (!CLI::HasParam("output_predictions") && + if ((CLI::GetParam("output_predictions_file") == "") && !CLI::HasParam("output_model_file")) - Log::Warn << "--output_predictions (-o) and --output_model_file (-M) " + Log::Warn << "--output_predictions_file (-o) and --output_model_file (-M) " << "are not specified; no results will be saved!" << endl; - if (CLI::HasParam("output_predictions") && !CLI::HasParam("test_file")) - Log::Warn << "--output_predictions (-o) specified, but --test_file " + if ((CLI::GetParam("output_predictions_file") == "") && + !CLI::HasParam("test_file")) + Log::Warn << "--output_predictions_file (-o) specified, but --test_file " << "(-t) is not; no results will be saved." << endl; - if (CLI::HasParam("test_file") && !CLI::HasParam("output_predictions")) - Log::Warn << "--test_file (-t) specified, but --output_predictions " + if (CLI::HasParam("test_file") && + (CLI::GetParam("output_predictions_file") == "")) + Log::Warn << "--test_file (-t) specified, but --output_predictions_file " << "(-o) is not; no results will be saved." << endl; // Initialize the object. @@ -182,10 +186,10 @@ int main(int argc, char* argv[]) lars.Predict(testPoints.t(), predictions, false); // Save test predictions. One per line, so, don't transpose on save. - if (CLI::HasParam("output_predictions")) + if (CLI::GetParam("output_predictions_file") != "") { const string outputPredictionsFile = - CLI::GetParam("output_predictions"); + CLI::GetParam("output_predictions_file"); data::Save(outputPredictionsFile, predictions, true, false); } } diff --git a/src/mlpack/methods/linear_regression/linear_regression_main.cpp b/src/mlpack/methods/linear_regression/linear_regression_main.cpp index f8336f23408..cb14a161eb2 100644 --- a/src/mlpack/methods/linear_regression/linear_regression_main.cpp +++ b/src/mlpack/methods/linear_regression/linear_regression_main.cpp @@ -37,8 +37,13 @@ PARAM_STRING_IN("input_model_file", "File containing existing model " PARAM_STRING_OUT("output_model_file", "File to save trained model to.", "M"); PARAM_STRING_IN("test_file", "File containing X' (test regressors).", "T", ""); + +// Keep for reverse compatibility. We can remove these for mlpack 3.0.0. PARAM_STRING_OUT("output_predictions", "If --test_file is specified, this file " "is where the predicted responses will be saved.", "p"); +// This is the future name of the parameter. +PARAM_STRING_OUT("output_predictions_file", "If --test_file is specified, this " + "file is where the predicted responses will be saved.", "o"); PARAM_DOUBLE_IN("lambda", "Tikhonov regularization for ridge regression. If 0," " the method reduces to linear regression.", "l", 0.0); @@ -53,16 +58,35 @@ int main(int argc, char* argv[]) // Handle parameters. CLI::ParseCommandLine(argc, argv); + // Reverse compatibility. We can remove these for mlpack 3.0.0. + if (CLI::HasParam("output_predictions") && + CLI::HasParam("output_predictions_file")) + Log::Fatal << "Cannot specify both --output_predictions and " + << "--output_predictions_file!" << endl; + + if (CLI::HasParam("output_predictions")) + { + Log::Warn << "--output_predictions (-p) is deprecated and will be removed " + << "in mlpack 3.0.0; use --output_predictions_file (-o) instead." + << endl; + CLI::GetParam("output_predictions_file") = + CLI::GetParam("output_predictions"); + } + const string inputModelFile = CLI::GetParam("input_model_file"); const string outputModelFile = CLI::GetParam("output_model_file"); const string outputPredictionsFile = - CLI::GetParam("output_predictions"); + CLI::GetParam("output_predictions_file"); const string trainingResponsesFile = CLI::GetParam("training_responses"); const string testFile = CLI::GetParam("test_file"); const string trainFile = CLI::GetParam("training_file"); const double lambda = CLI::GetParam("lambda"); + if (testFile == "" && outputPredictionsFile != "") + Log::Warn << "--output_predictions_file (-o) ignored because --test_file " + << "(-T) is not specified." << endl; + mat regressors; mat responses; @@ -92,8 +116,9 @@ int main(int argc, char* argv[]) << "both." << endl; } - if (CLI::HasParam("test_file") && !CLI::HasParam("output_predictions")) - Log::Warn << "--test_file (-t) specified, but --output_predictions " + if (CLI::HasParam("test_file") && + (CLI::GetParam("output_predictions_file") == "")) + Log::Warn << "--test_file (-t) specified, but --output_predictions_file " << "(-o) is not; no results will be saved." << endl; // If they specified a model file, we also need a test file or we @@ -111,7 +136,7 @@ int main(int argc, char* argv[]) if (outputModelFile == "" && outputPredictionsFile == "") { - Log::Warn << "Neither --output_model_file nor --output_predictions are " + Log::Warn << "Neither --output_model_file nor --output_predictions_file are " << "specified; no output will be saved!" << endl; } @@ -188,7 +213,7 @@ int main(int argc, char* argv[]) Timer::Stop("prediction"); // Save predictions. - if (CLI::HasParam("output_predictions")) + if (outputPredictionsFile != "") data::Save(outputPredictionsFile, predictions, true, false); } } diff --git a/src/mlpack/methods/lsh/lsh_main.cpp b/src/mlpack/methods/lsh/lsh_main.cpp index 9d6ceeed5ec..308f8cb344b 100644 --- a/src/mlpack/methods/lsh/lsh_main.cpp +++ b/src/mlpack/methods/lsh/lsh_main.cpp @@ -48,6 +48,10 @@ PARAM_STRING_IN("input_model_file", "File to load LSH model from. (Cannot be " "specified with --reference_file.)", "m", ""); PARAM_STRING_OUT("output_model_file", "File to save LSH model to.", "M"); +// For testing recall. +PARAM_STRING_IN("true_neighbors_file", "File of true neighbors to compute " + "recall with (the recall is printed when -v is specified).", "t", ""); + PARAM_INT_IN("k", "Number of nearest neighbors to find.", "k", 0); PARAM_STRING_IN("query_file", "File containing query points (optional).", "q", ""); @@ -58,6 +62,8 @@ PARAM_INT_IN("tables", "The number of hash tables to be used.", "L", 30); PARAM_DOUBLE_IN("hash_width", "The hash width for the first-level hashing in " "the LSH preprocessing. By default, the LSH class automatically estimates " "a hash width for its use.", "H", 0.0); +PARAM_INT_IN("num_probes", "Number of additional probes for multiprobe LSH; if " + "0, traditional LSH is used.", "T", 0); PARAM_INT_IN("second_hash_size", "The size of the second level hash table.", "S", 99901); PARAM_INT_IN("bucket_size", "The size of a bucket in the second level hash.", @@ -187,13 +193,13 @@ int main(int argc, char *argv[]) // Compute recall, if desired. if (CLI::HasParam("true_neighbors_file")) { - const string trueNeighborsFile = + const string trueNeighborsFile = CLI::GetParam("true_neighbors_file"); // Load the true neighbors. arma::Mat trueNeighbors; data::Load(trueNeighborsFile, trueNeighbors, true); - Log::Info << "Loaded true neighbor indices from '" + Log::Info << "Loaded true neighbor indices from '" << trueNeighborsFile << "'." << endl; // Compute recall and print it. diff --git a/src/mlpack/methods/mean_shift/mean_shift_main.cpp b/src/mlpack/methods/mean_shift/mean_shift_main.cpp index b5485e1276e..88de594a902 100644 --- a/src/mlpack/methods/mean_shift/mean_shift_main.cpp +++ b/src/mlpack/methods/mean_shift/mean_shift_main.cpp @@ -21,13 +21,18 @@ PROGRAM_INFO("Mean Shift Clustering", "This program performs mean shift " "in a separate file."); // Required options. -PARAM_STRING_IN_REQ("inputFile", "Input dataset to perform clustering on.", - "i"); +PARAM_STRING_IN("input_file", "Input dataset to perform clustering on.", + "i", ""); +// This is kept for reverse compatibility and may be removed in mlpack 3.0.0. +// At that time, --input_file should be made a required parameter. +PARAM_STRING_IN("inputFile", "Input dataset to perform clustering on.", "", ""); // Output options. PARAM_FLAG("in_place", "If specified, a column containing the learned cluster " "assignments will be added to the input dataset file. In this case, " "--output_file is overridden.", "P"); +PARAM_FLAG("labels_only", "If specified, only the output labels will be " + "written to the file specified by --output_file.", "l"); PARAM_STRING_OUT("output_file", "File to write output labels or labeled data " "to.", "o"); PARAM_STRING_OUT("centroid_file", "If specified, the centroids of each cluster " @@ -45,7 +50,21 @@ int main(int argc, char** argv) { CLI::ParseCommandLine(argc, argv); - const string inputFile = CLI::GetParam("inputFile"); + // This is for reverse compatibility and may be removed in mlpack 3.0.0. + if (CLI::HasParam("inputFile") && CLI::HasParam("input_file")) + Log::Fatal << "Cannot specify both --input_file and --inputFile!" << endl; + + if (CLI::HasParam("inputFile")) + { + Log::Warn << "--inputFile is deprecated and will be removed in mlpack " + << "3.0.0; use --input_file instead." << endl; + CLI::GetParam("input_file") = CLI::GetParam("inputFile"); + } + + if (CLI::GetParam("input_file") == "") + Log::Fatal << "--input_file must be specified!" << endl; + + const string inputFile = CLI::GetParam("input_file"); const double radius = CLI::GetParam("radius"); const int maxIterations = CLI::GetParam("max_iterations"); @@ -63,6 +82,10 @@ int main(int argc, char** argv) << "no results will be saved." << endl; } + if (CLI::HasParam("labels_only") && !CLI::HasParam("output_file")) + Log::Warn << "--labels_only ignored because --output_file is not specified." + << endl; + arma::mat dataset; data::Load(inputFile, dataset, true); // Fatal upon failure. arma::mat centroids; @@ -94,16 +117,26 @@ int main(int argc, char** argv) } else { - // Convert the assignments to doubles. - arma::vec converted(assignments.n_elem); - for (size_t i = 0; i < assignments.n_elem; i++) - converted(i) = (double) assignments(i); - - dataset.insert_rows(dataset.n_rows, trans(converted)); - - // Now save, in the different file. - string outputFile = CLI::GetParam("output_file"); - data::Save(outputFile, dataset); + if (!CLI::HasParam("labels_only")) + { + // Convert the assignments to doubles. + arma::vec converted(assignments.n_elem); + for (size_t i = 0; i < assignments.n_elem; i++) + converted(i) = (double) assignments(i); + + dataset.insert_rows(dataset.n_rows, trans(converted)); + + // Now save, in the different file. + string outputFile = CLI::GetParam("output_file"); + if (outputFile != "") + data::Save(outputFile, dataset); + } + else + { + string outputFile = CLI::GetParam("output_file"); + if (outputFile != "") + data::Save(outputFile, assignments, false, false); // No transpose. + } } // Should we write the centroids to a file? diff --git a/src/mlpack/methods/nca/nca_main.cpp b/src/mlpack/methods/nca/nca_main.cpp index 583872d5c24..c699c82625f 100644 --- a/src/mlpack/methods/nca/nca_main.cpp +++ b/src/mlpack/methods/nca/nca_main.cpp @@ -71,7 +71,7 @@ PROGRAM_INFO("Neighborhood Components Analysis (NCA)", "By default, the SGD optimizer is used."); PARAM_STRING_IN_REQ("input_file", "Input dataset to run NCA on.", "i"); -PARAM_STRING_IN_REQ("output_file", "Output file for learned distance matrix.", +PARAM_STRING_OUT("output_file", "Output file for learned distance matrix.", "o"); PARAM_STRING_IN("labels_file", "File of labels for input dataset.", "l", ""); PARAM_STRING_IN("optimizer", "Optimizer to use; 'sgd', 'minibatch-sgd', or " @@ -125,6 +125,10 @@ int main(int argc, char* argv[]) const string labelsFile = CLI::GetParam("labels_file"); const string outputFile = CLI::GetParam("output_file"); + if (outputFile == "") + Log::Warn << "--output_file (-o) not specified; no output will be saved!" + << endl; + const string optimizerType = CLI::GetParam("optimizer"); if ((optimizerType != "sgd") && (optimizerType != "lbfgs") && @@ -280,5 +284,6 @@ int main(int argc, char* argv[]) } // Save the output. - data::Save(CLI::GetParam("output_file"), distance, true); + if (outputFile != "") + data::Save(outputFile, distance, true); } diff --git a/src/mlpack/methods/preprocess/preprocess_binarize_main.cpp b/src/mlpack/methods/preprocess/preprocess_binarize_main.cpp index ed050f15f9a..9faa81538aa 100644 --- a/src/mlpack/methods/preprocess/preprocess_binarize_main.cpp +++ b/src/mlpack/methods/preprocess/preprocess_binarize_main.cpp @@ -29,13 +29,13 @@ PROGRAM_INFO("Binarize Data", "This utility takes a dataset and binarizes the " "$ mlpack_preprocess_binarize -i dataset.csv -t 5 -d 0 -o result.csv"); // Define parameters for data. -PARAM_STRING_IN_REQ("input_file", "File containing data,", "i"); +PARAM_STRING_IN_REQ("input_file", "File containing data.", "i"); // Define optional parameters. -PARAM_STRING_OUT("output_file", "File to save the output,", "o"); +PARAM_STRING_OUT("output_file", "File to save the output.", "o"); PARAM_INT_IN("dimension", "Dimension to apply the binarization. If not set, the" - " program will binarize every dimension by default", "d", 0); + " program will binarize every dimension by default.", "d", 0); PARAM_DOUBLE_IN("threshold", "Threshold to be applied for binarization. If not " - "set, the threshold defaults to 0.0", "t", 0.0); + "set, the threshold defaults to 0.0.", "t", 0.0); using namespace mlpack; using namespace arma; @@ -56,11 +56,11 @@ int main(int argc, char** argv) << "binarize on every dimensions." << endl; if (!CLI::HasParam("threshold")) - Log::Warn << "You did not specify --threshold, so the threshold " - << "will be automatically set to '0.0'." << endl; + Log::Warn << "You did not specify --threshold, so the threshold will be " + << "automatically set to '0.0'." << endl; if (!CLI::HasParam("output_file")) - Log::Warn << "You did not specify --output_file, so no result will be" + Log::Warn << "You did not specify --output_file, so no result will be " << "saved." << endl; // Load the data. diff --git a/src/mlpack/methods/preprocess/preprocess_split_main.cpp b/src/mlpack/methods/preprocess/preprocess_split_main.cpp index 9ecfb705b6f..6a5b1493e56 100644 --- a/src/mlpack/methods/preprocess/preprocess_split_main.cpp +++ b/src/mlpack/methods/preprocess/preprocess_split_main.cpp @@ -70,33 +70,34 @@ int main(int argc, char** argv) // Make sure the user specified output filenames. if (trainingFile == "") - Log::Fatal << "--training_file (-t) must be specified!" << endl; + Log::Warn << "--training_file (-t) is not specified; no training set will " + << "be saved!" << endl; if (testFile == "") - Log::Fatal << "--test_file (-T) must be specified!" << endl; + Log::Warn << "--test_file (-T) is not specified; no test set will be saved!" + << endl; // Check on label parameters. if (CLI::HasParam("input_labels_file")) { if (!CLI::HasParam("training_labels_file")) { - Log::Fatal << "--training_labels_file (-l) must be specified if " - << "--input_labels (-l) is specified!" << endl; + Log::Warn << "--training_labels_file (-l) is not specified; no training " + << "set labels will be saved!" << endl; } if (!CLI::HasParam("test_labels_file")) { - Log::Fatal << "--test_labels_file (-L) must be specified if " - << "--input_labels (-I) is specified!" << endl; + Log::Warn << "--test_labels_file (-L) is not specified; no test set " + << "labels will be saved!" << endl; } } else { - if (CLI::HasParam("training_labels_file") || - CLI::HasParam("test_labels_file")) - { - Log::Fatal << "When specifying --training_labels_file or " - << "--test_labels_file, you must also specify --input_labels." - << endl; - } + if (CLI::HasParam("training_labels_file")) + Log::Warn << "--training_labels_file ignored because --input_labels is " + << "not specified." << endl; + if (CLI::HasParam("test_labels_file")) + Log::Warn << "--test_labels_file ignored because --input_labels is not " + << "specified." << endl; } // Check test_ratio. @@ -131,10 +132,14 @@ int main(int argc, char** argv) Log::Info << "Test data contains " << get<1>(value).n_cols << " points." << endl; - data::Save(trainingFile, get<0>(value), false); - data::Save(testFile, get<1>(value), false); - data::Save(trainingLabelsFile, get<2>(value), false); - data::Save(testLabelsFile, get<3>(value), false); + if (trainingFile != "") + data::Save(trainingFile, get<0>(value), false); + if (testFile != "") + data::Save(testFile, get<1>(value), false); + if (trainingLabelsFile != "") + data::Save(trainingLabelsFile, get<2>(value), false); + if (testLabelsFile != "") + data::Save(testLabelsFile, get<3>(value), false); } else // We have no labels, so just split the dataset. { @@ -144,7 +149,9 @@ int main(int argc, char** argv) Log::Info << "Test data contains " << get<1>(value).n_cols << " points." << endl; - data::Save(trainingFile, get<0>(value), false); - data::Save(testFile, get<1>(value), false); + if (trainingFile != "") + data::Save(trainingFile, get<0>(value), false); + if (testFile != "") + data::Save(testFile, get<1>(value), false); } } diff --git a/src/mlpack/methods/radical/radical_main.cpp b/src/mlpack/methods/radical/radical_main.cpp index 85206bb5762..544e7bc24af 100644 --- a/src/mlpack/methods/radical/radical_main.cpp +++ b/src/mlpack/methods/radical/radical_main.cpp @@ -16,8 +16,17 @@ PROGRAM_INFO("RADICAL", "An implementation of RADICAL, a method for independent" PARAM_STRING_IN_REQ("input_file", "Input dataset filename for ICA.", "i"); -PARAM_STRING_OUT("output_ic", "File to save independent components to.", "o"); -PARAM_STRING_OUT("output_unmixing", "File to save unmixing matrix to.", "u"); +// Kept for reverse compatibility until mlpack 3.0.0. +PARAM_STRING_OUT("output_ic", "File to save independent components to " + "(deprecated: use --output_ic_file).", ""); +PARAM_STRING_OUT("output_unmixing", "File to save unmixing matrix to " + "(deprecated: use --output_unmixing_file).", ""); + +// These are the new parameter names. +PARAM_STRING_OUT("output_ic_file", "File to save independent components to.", + "o"); +PARAM_STRING_OUT("output_unmixing_file", "File to save unmixing matrix to.", + "u"); PARAM_DOUBLE_IN("noise_std_dev", "Standard deviation of Gaussian noise.", "n", 0.175); @@ -42,15 +51,41 @@ int main(int argc, char* argv[]) // Handle parameters. CLI::ParseCommandLine(argc, argv); + // Reverse compatibility. We can remove these for mlpack 3.0.0. + if (CLI::HasParam("output_ic") && CLI::HasParam("output_ic_file")) + Log::Fatal << "Cannot specify both --output_ic and --output_ic_file!" + << endl; + + if (CLI::HasParam("output_unmixing") && CLI::HasParam("output_unmixing_file")) + Log::Fatal << "Cannot specify both --output_unmixing and " + << "--output_unmixing_file!" << endl; + + if (CLI::HasParam("output_ic")) + { + Log::Warn << "--output_ic is deprecated and will be removed in mlpack " + << "3.0.0; use --output_ic_file instead." << endl; + CLI::GetParam("output_ic_file") = + CLI::GetParam("output_ic"); + } + + if (CLI::HasParam("output_unmixing")) + { + Log::Warn << "--output_unmixing is deprecated and will be removed in mlpack" + << " 3.0.0; use --output_unmixing_file instead." << endl; + CLI::GetParam("output_unmixing_file") = + CLI::GetParam("output_unmixing"); + } + // Set random seed. if (CLI::GetParam("seed") != 0) RandomSeed((size_t) CLI::GetParam("seed")); else RandomSeed((size_t) std::time(NULL)); - if (!CLI::HasParam("output_ic") && !CLI::HasParam("output_unmixing")) - Log::Warn << "Neither --output_ic nor --output_unmixing were specified; " - << "no output will be saved!" << endl; + if ((CLI::GetParam("output_ic_file") == "") && + (CLI::GetParam("output_unmixing_file") == "")) + Log::Warn << "Neither --output_ic_file nor --output_unmixing_file were " + << "specified; no output will be saved!" << endl; // Load the data. const string matXFilename = CLI::GetParam("input_file"); @@ -75,11 +110,11 @@ int main(int argc, char* argv[]) rad.DoRadical(matX, matY, matW); // Save results. - const string matYFilename = CLI::GetParam("output_ic"); + const string matYFilename = CLI::GetParam("output_ic_file"); if (matYFilename != "") data::Save(matYFilename, matY); - const string matWFilename = CLI::GetParam("output_unmixing"); + const string matWFilename = CLI::GetParam("output_unmixing_file"); if (matWFilename != "") data::Save(matWFilename, matW); diff --git a/src/mlpack/methods/softmax_regression/softmax_regression_main.cpp b/src/mlpack/methods/softmax_regression/softmax_regression_main.cpp index 701b964b700..2d8ade92378 100644 --- a/src/mlpack/methods/softmax_regression/softmax_regression_main.cpp +++ b/src/mlpack/methods/softmax_regression/softmax_regression_main.cpp @@ -38,7 +38,7 @@ PROGRAM_INFO("Softmax Regression", "This program performs softmax regression, " PARAM_STRING_IN("training_file", "A file containing the training set (the " "matrix of predictors, X).", "t", ""); PARAM_STRING_IN("labels_file", "A file containing labels (0 or 1) for the " - "points in the training set (y). The labels must order as a row", "l", ""); + "points in the training set (y). The labels must order as a row.", "l", ""); // Model loading/saving. PARAM_STRING_IN("input_model_file", "File containing existing model " @@ -104,7 +104,8 @@ int main(int argc, char** argv) Log::Fatal << "One of --input_model_file or --training_file must be specified." << endl; - if (CLI::HasParam("training_file") && CLI::HasParam("labels_file")) + if ((CLI::HasParam("training_file") || CLI::HasParam("labels_file")) && + !(CLI::HasParam("training_file") && CLI::HasParam("labels_file"))) Log::Fatal << "--labels_file must be specified with --training_file!" << endl; From 95ee8366c0bf3223d7df607a8b17c5587043fbcc Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sat, 16 Jul 2016 16:21:31 -0400 Subject: [PATCH 17/21] Fix incorrect conditionals. Thanks to Sergiu Deitsch for pointing these out. --- src/mlpack/methods/gmm/gmm_generate_main.cpp | 2 +- src/mlpack/methods/gmm/gmm_probability_main.cpp | 2 +- src/mlpack/methods/mvu/mvu_main.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mlpack/methods/gmm/gmm_generate_main.cpp b/src/mlpack/methods/gmm/gmm_generate_main.cpp index cc1e3f9943a..787b90bb50c 100644 --- a/src/mlpack/methods/gmm/gmm_generate_main.cpp +++ b/src/mlpack/methods/gmm/gmm_generate_main.cpp @@ -31,7 +31,7 @@ int main(int argc, char** argv) { CLI::ParseCommandLine(argc, argv); - if (CLI::HasParam("output_file")) + if (!CLI::HasParam("output_file")) Log::Warn << "--output_file (-o) is not specified;" << "no results will be saved!" << endl; diff --git a/src/mlpack/methods/gmm/gmm_probability_main.cpp b/src/mlpack/methods/gmm/gmm_probability_main.cpp index 4c53bdc5edd..ec39c31550a 100644 --- a/src/mlpack/methods/gmm/gmm_probability_main.cpp +++ b/src/mlpack/methods/gmm/gmm_probability_main.cpp @@ -32,7 +32,7 @@ int main(int argc, char** argv) const string inputModelFile = CLI::GetParam("input_model_file"); const string outputFile = CLI::GetParam("output_file"); - if (CLI::HasParam("output_file")) + if (!CLI::HasParam("output_file")) Log::Warn << "--output_file (-o) is not specified;" << "no results will be saved!" << endl; diff --git a/src/mlpack/methods/mvu/mvu_main.cpp b/src/mlpack/methods/mvu/mvu_main.cpp index 9b1bf0dc08b..de540489c21 100644 --- a/src/mlpack/methods/mvu/mvu_main.cpp +++ b/src/mlpack/methods/mvu/mvu_main.cpp @@ -37,7 +37,7 @@ int main(int argc, char **argv) const int newDim = CLI::GetParam("new_dim"); const int numNeighbors = CLI::GetParam("num_neighbors"); - if (CLI::HasParam("output_file")) + if (!CLI::HasParam("output_file")) Log::Warn << "--output_file (-o) is not specified; no results will be " << "saved!" << endl; From 7a34fe308372263ac661b8c159647ff77013d612 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Mon, 18 Jul 2016 11:05:31 -0400 Subject: [PATCH 18/21] Update documentation; 'parent' is very outdated; that parameter is actually 'alias'. --- src/mlpack/core/util/cli_impl.hpp | 5 ++--- src/mlpack/core/util/option.hpp | 12 +++++------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/mlpack/core/util/cli_impl.hpp b/src/mlpack/core/util/cli_impl.hpp index bc5b3664c3d..12db93e3c39 100644 --- a/src/mlpack/core/util/cli_impl.hpp +++ b/src/mlpack/core/util/cli_impl.hpp @@ -21,10 +21,9 @@ namespace mlpack { * CheckValue. * * @tparam T The type of the parameter. - * @param identifier The name of the parameter, eg foo in bar/foo. + * @param identifier The name of the parameter, eg foo. * @param description A string description of the parameter. - * @param parent The name of the parent of the parameter, e.g. bar/foo in - * bar/foo/buzz. + * @param alias Short name of the parameter. * @param required If required, the program will refuse to run unless the * parameter is specified. * @param input If true, the parameter is an input parameter (not an output diff --git a/src/mlpack/core/util/option.hpp b/src/mlpack/core/util/option.hpp index 1efef14914e..9f04cfdb860 100644 --- a/src/mlpack/core/util/option.hpp +++ b/src/mlpack/core/util/option.hpp @@ -38,8 +38,7 @@ class Option * @param identifier The name of the option (no dashes in front; for --help, * we would pass "help"). * @param description A short string describing the option. - * @param parent Full pathname of the parent module that "owns" this option. - * The default is the root node (an empty string). + * @param alias Short name of the parameter. * @param required Whether or not the option is required at runtime. * @param input Whether or not the option is an input option. */ @@ -47,7 +46,7 @@ class Option const N defaultValue, const std::string& identifier, const std::string& description, - const std::string& parent = std::string(""), + const std::string& alias, const bool required = false, const bool input = true); @@ -58,12 +57,11 @@ class Option * @param identifier The name of the option (no dashes in front); for --help * we would pass "help". * @param description A short string describing the option. - * @param parent Full pathname of the parent module that "owns" this option. - * The default is the root node (an empty string). + * @param alias Short name of the parameter. */ Option(const std::string& identifier, const std::string& description, - const std::string& parent = std::string("")); + const std::string& alias); }; /** @@ -72,7 +70,7 @@ class Option * the PROGRAM_INFO() macro to declare these objects. Only one ProgramDoc * object should ever exist. * - * @see core/io/cli.hpp, mlpack::CLI + * @see core/util/cli.hpp, mlpack::CLI */ class ProgramDoc { From c852746f32273e1e7207b866b702eaf65f82b3a2 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Mon, 18 Jul 2016 13:01:31 -0400 Subject: [PATCH 19/21] Fix --test_file: it is an input parameter. --- src/mlpack/methods/rmva/rmva_main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/rmva/rmva_main.cpp b/src/mlpack/methods/rmva/rmva_main.cpp index b0486e64e36..b76eefcf84b 100644 --- a/src/mlpack/methods/rmva/rmva_main.cpp +++ b/src/mlpack/methods/rmva/rmva_main.cpp @@ -75,7 +75,7 @@ PARAM_INT_IN("classes", "The number of classes.", "c", 10); PARAM_INT_IN("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0); // Test parameters. -PARAM_STRING_OUT("test_file", "A file containing the test set.", "T"); +PARAM_STRING_IN("test_file", "A file containing the test set.", "T", ""); PARAM_STRING_OUT("output_file", "The file in which the predicted labels for the" " test set will be written.", "o"); From b36b3df2d1e653fac9d632afdc1077cac7bc4d3d Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Mon, 18 Jul 2016 13:27:26 -0400 Subject: [PATCH 20/21] Too much Java lately: no 'd' suffix necessary. Every floating-point literal in C++ is assumed to be double unless otherwise specified, so there is no reason to specify anything here. This should fix the Windows build. --- src/mlpack/core/util/param.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/core/util/param.hpp b/src/mlpack/core/util/param.hpp index 77569087966..88c83c19691 100644 --- a/src/mlpack/core/util/param.hpp +++ b/src/mlpack/core/util/param.hpp @@ -152,7 +152,7 @@ * https://github.com/mlpack/mlpack/issues/100 for more information. */ #define PARAM_DOUBLE_OUT(ID, DESC) \ - PARAM_OUT(double, ID, DESC, "", 0.0d, false) + PARAM_OUT(double, ID, DESC, "", 0.0, false) /** * Define a string input parameter. From 5853b8a7854f19d1dd3a662acb0f2442b22d4acd Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Mon, 18 Jul 2016 13:46:21 -0400 Subject: [PATCH 21/21] Don't add unknown options for Visual Studio. (this should trigger the AppVeyor build again) --- CMakeLists.txt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 80a92a8877a..2004a12994c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,9 +76,12 @@ endif() # Debugging CFLAGS. Turn optimizations off; turn debugging symbols on. if(DEBUG) - add_definitions(-DDEBUG) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -ftemplate-backtrace-limit=0") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -g -O0") + if (NOT MSVC) + add_definitions(-DDEBUG) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -ftemplate-backtrace-limit=0") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -g -O0") + endif () + # mlpack uses it's own mlpack::backtrace class based on Binary File Descriptor # and linux Dynamic Loader and more portable version in future if(CMAKE_SYSTEM_NAME STREQUAL "Linux")