[mlpack-svn] r10774 - in mlpack/trunk/src/mlpack: . core core/data core/math core/tree core/util methods/gmm tests

fastlab-svn at coffeetalk-1.cc.gatech.edu fastlab-svn at coffeetalk-1.cc.gatech.edu
Wed Dec 14 07:44:53 EST 2011


Author: rcurtin
Date: 2011-12-14 07:44:53 -0500 (Wed, 14 Dec 2011)
New Revision: 10774

Added:
   mlpack/trunk/src/mlpack/core/util/
   mlpack/trunk/src/mlpack/core/util/CMakeLists.txt
   mlpack/trunk/src/mlpack/core/util/cli.cpp
   mlpack/trunk/src/mlpack/core/util/cli.hpp
   mlpack/trunk/src/mlpack/core/util/cli_deleter.cpp
   mlpack/trunk/src/mlpack/core/util/cli_deleter.hpp
   mlpack/trunk/src/mlpack/core/util/cli_impl.hpp
   mlpack/trunk/src/mlpack/core/util/log.cpp
   mlpack/trunk/src/mlpack/core/util/log.hpp
   mlpack/trunk/src/mlpack/core/util/nulloutstream.hpp
   mlpack/trunk/src/mlpack/core/util/option.cpp
   mlpack/trunk/src/mlpack/core/util/option.hpp
   mlpack/trunk/src/mlpack/core/util/option_impl.hpp
   mlpack/trunk/src/mlpack/core/util/prefixedoutstream.cpp
   mlpack/trunk/src/mlpack/core/util/prefixedoutstream.hpp
   mlpack/trunk/src/mlpack/core/util/prefixedoutstream_impl.hpp
   mlpack/trunk/src/mlpack/core/util/timers.cpp
   mlpack/trunk/src/mlpack/core/util/timers.hpp
Removed:
   mlpack/trunk/src/mlpack/core/io/
   mlpack/trunk/src/mlpack/core/util/CMakeLists.txt
   mlpack/trunk/src/mlpack/core/util/timers.cpp
   mlpack/trunk/src/mlpack/core/util/timers.hpp
   mlpack/trunk/src/mlpack/core/utilities/
Modified:
   mlpack/trunk/src/mlpack/core.hpp
   mlpack/trunk/src/mlpack/core/CMakeLists.txt
   mlpack/trunk/src/mlpack/core/data/load.hpp
   mlpack/trunk/src/mlpack/core/data/save.hpp
   mlpack/trunk/src/mlpack/core/math/math_misc.hpp
   mlpack/trunk/src/mlpack/core/tree/binary_space_tree_impl.hpp
   mlpack/trunk/src/mlpack/core/tree/periodichrectbound_impl.hpp
   mlpack/trunk/src/mlpack/core/util/save_restore_utility.hpp
   mlpack/trunk/src/mlpack/methods/gmm/gmm_main.cpp
   mlpack/trunk/src/mlpack/tests/save_restore_utility_test.cpp
Log:
Move io/* to utilities/* then utilities to util (shorter, simpler name) and
update all references thereto.


Modified: mlpack/trunk/src/mlpack/core/CMakeLists.txt
===================================================================
--- mlpack/trunk/src/mlpack/core/CMakeLists.txt	2011-12-14 12:41:57 UTC (rev 10773)
+++ mlpack/trunk/src/mlpack/core/CMakeLists.txt	2011-12-14 12:44:53 UTC (rev 10774)
@@ -2,13 +2,12 @@
 set(DIRS
   arma_extend
   data
-  io
   kernels
   math
   metrics
   optimizers
   tree
-  utilities
+  util
 )
 
 foreach(dir ${DIRS})

Modified: mlpack/trunk/src/mlpack/core/data/load.hpp
===================================================================
--- mlpack/trunk/src/mlpack/core/data/load.hpp	2011-12-14 12:41:57 UTC (rev 10773)
+++ mlpack/trunk/src/mlpack/core/data/load.hpp	2011-12-14 12:44:53 UTC (rev 10774)
@@ -9,7 +9,7 @@
 #ifndef __MLPACK_CORE_DATA_LOAD_HPP
 #define __MLPACK_CORE_DATA_LOAD_HPP
 
-#include <mlpack/core/io/log.hpp>
+#include <mlpack/core/util/log.hpp>
 #include <mlpack/core/arma_extend/arma_extend.hpp> // Includes Armadillo.
 #include <string>
 

Modified: mlpack/trunk/src/mlpack/core/data/save.hpp
===================================================================
--- mlpack/trunk/src/mlpack/core/data/save.hpp	2011-12-14 12:41:57 UTC (rev 10773)
+++ mlpack/trunk/src/mlpack/core/data/save.hpp	2011-12-14 12:44:53 UTC (rev 10774)
@@ -9,7 +9,7 @@
 #ifndef __MLPACK_CORE_DATA_SAVE_HPP
 #define __MLPACK_CORE_DATA_SAVE_HPP
 
-#include <mlpack/core/io/log.hpp>
+#include <mlpack/core/util/log.hpp>
 #include <mlpack/core/arma_extend/arma_extend.hpp> // Includes Armadillo.
 #include <string>
 

Modified: mlpack/trunk/src/mlpack/core/math/math_misc.hpp
===================================================================
--- mlpack/trunk/src/mlpack/core/math/math_misc.hpp	2011-12-14 12:41:57 UTC (rev 10773)
+++ mlpack/trunk/src/mlpack/core/math/math_misc.hpp	2011-12-14 12:44:53 UTC (rev 10774)
@@ -3,13 +3,10 @@
  *
  * Miscellaneous math routines.
  */
+#ifndef __MLPACK_CORE_MATH_MATH_MISC_HPP
+#define __MLPACK_CORE_MATH_MATH_MISC_HPP
 
-#ifndef __MLPACK_CORE_MATH_MATH_LIB_HPP
-#define __MLPACK_CORE_MATH_MATH_LIB_HPP
-
-#include "../io/cli.hpp"
-#include "../io/log.hpp"
-
+#include <stdlib.h>
 #include <math.h>
 #include <float.h>
 

Modified: mlpack/trunk/src/mlpack/core/tree/binary_space_tree_impl.hpp
===================================================================
--- mlpack/trunk/src/mlpack/core/tree/binary_space_tree_impl.hpp	2011-12-14 12:41:57 UTC (rev 10773)
+++ mlpack/trunk/src/mlpack/core/tree/binary_space_tree_impl.hpp	2011-12-14 12:44:53 UTC (rev 10774)
@@ -9,8 +9,8 @@
 // In case it wasn't included already for some reason.
 #include "binary_space_tree.hpp"
 
-#include <mlpack/core/io/cli.hpp>
-#include <mlpack/core/io/log.hpp>
+#include <mlpack/core/util/cli.hpp>
+#include <mlpack/core/util/log.hpp>
 
 namespace mlpack {
 namespace tree {

Modified: mlpack/trunk/src/mlpack/core/tree/periodichrectbound_impl.hpp
===================================================================
--- mlpack/trunk/src/mlpack/core/tree/periodichrectbound_impl.hpp	2011-12-14 12:41:57 UTC (rev 10773)
+++ mlpack/trunk/src/mlpack/core/tree/periodichrectbound_impl.hpp	2011-12-14 12:44:53 UTC (rev 10774)
@@ -13,7 +13,6 @@
 #include <math.h>
 
 #include "../math/math_misc.hpp"
-#include "../io/log.hpp"
 
 namespace mlpack {
 namespace bound {

Deleted: mlpack/trunk/src/mlpack/core/util/CMakeLists.txt
===================================================================
--- mlpack/trunk/src/mlpack/core/utilities/CMakeLists.txt	2011-12-13 07:23:09 UTC (rev 10737)
+++ mlpack/trunk/src/mlpack/core/util/CMakeLists.txt	2011-12-14 12:44:53 UTC (rev 10774)
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8)
-
-# Define the files we need to compile.
-# Anything not in this list will not be compiled into MLPACK.
-set(SOURCES
-    save_restore_utility.cpp
-    save_restore_utility.hpp
-    timers.hpp
-    timers.cpp
-)
-
-# add directory name to sources
-set(DIR_SRCS)
-foreach(file ${SOURCES})
-  set(DIR_SRCS ${DIR_SRCS} ${CMAKE_CURRENT_SOURCE_DIR}/${file})
-endforeach()
-# Append sources (with directory name) to list of all MLPACK sources (used at
-# the parent scope).
-set(MLPACK_SRCS ${MLPACK_SRCS} ${DIR_SRCS} PARENT_SCOPE)

Copied: mlpack/trunk/src/mlpack/core/util/CMakeLists.txt (from rev 10767, mlpack/trunk/src/mlpack/core/utilities/CMakeLists.txt)
===================================================================
--- mlpack/trunk/src/mlpack/core/util/CMakeLists.txt	                        (rev 0)
+++ mlpack/trunk/src/mlpack/core/util/CMakeLists.txt	2011-12-14 12:44:53 UTC (rev 10774)
@@ -0,0 +1,34 @@
+cmake_minimum_required(VERSION 2.8)
+
+# Define the files we need to compile.
+# Anything not in this list will not be compiled into MLPACK.
+set(SOURCES
+  cli.hpp
+  cli.cpp
+  cli_deleter.hpp
+  cli_deleter.cpp
+  cli_impl.hpp
+  log.hpp
+  log.cpp
+  nulloutstream.hpp
+  option.hpp
+  option.cpp
+  option_impl.hpp
+  prefixedoutstream.hpp
+  prefixedoutstream.cpp
+  prefixedoutstream_impl.hpp
+  save_restore_utility.hpp
+  save_restore_utility.cpp
+  save_restore_utility_impl.hpp
+  timers.hpp
+  timers.cpp
+)
+
+# add directory name to sources
+set(DIR_SRCS)
+foreach(file ${SOURCES})
+  set(DIR_SRCS ${DIR_SRCS} ${CMAKE_CURRENT_SOURCE_DIR}/${file})
+endforeach()
+# Append sources (with directory name) to list of all MLPACK sources (used at
+# the parent scope).
+set(MLPACK_SRCS ${MLPACK_SRCS} ${DIR_SRCS} PARENT_SCOPE)

Copied: mlpack/trunk/src/mlpack/core/util/cli.cpp (from rev 10768, mlpack/trunk/src/mlpack/core/io/cli.cpp)
===================================================================
--- mlpack/trunk/src/mlpack/core/util/cli.cpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/core/util/cli.cpp	2011-12-14 12:44:53 UTC (rev 10774)
@@ -0,0 +1,683 @@
+/**
+ * @file cli.cpp
+ * @author Matthew Amidon
+ *
+ * Implementation of the CLI module for parsing parameters.
+ */
+#include <list>
+#include <boost/program_options.hpp>
+#include <boost/any.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <iostream>
+#include <string>
+#include <execinfo.h>
+
+#ifndef _WIN32
+  #include <sys/time.h> // For Linux.
+#else
+  #include <winsock.h> // timeval on Windows.
+  #include <windows.h> // GetSystemTimeAsFileTime() on Windows.
+// gettimeofday() has no equivalent; we will need to write extra code for that.
+  #if defined(_MSC_VER) || defined(_MSC_EXTENSCLINS)
+    #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
+  #else
+    #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
+  #endif
+#endif // _WIN32
+
+#include "cli.hpp"
+#include "log.hpp"
+
+#include "option.hpp"
+
+using namespace mlpack;
+using namespace mlpack::io;
+
+CLI* CLI::singleton = NULL;
+
+/* For clarity, we will alias boost's namespace. */
+namespace po = boost::program_options;
+
+// Fake ProgramDoc in case none is supplied.
+static ProgramDoc empty_program_doc = ProgramDoc("", "");
+
+/* Constructors, Destructors, Copy */
+/* Make the constructor private, to preclude unauthorized instances */
+CLI::CLI() : desc("Allowed Options") , did_parse(false), doc(&empty_program_doc)
+{
+  return;
+}
+
+/**
+ * Initialize desc with a particular name.
+ *
+ * @param optionsName Name of the module, as far as boost is concerned.
+ */
+CLI::CLI(std::string& optionsName) :
+    desc(optionsName.c_str()), did_parse(false), doc(&empty_program_doc)
+{
+  return;
+}
+
+// Private copy constructor; don't want copies floating around.
+CLI::CLI(const CLI& other) : desc(other.desc),
+    did_parse(false), doc(&empty_program_doc)
+{
+  return;
+}
+
+CLI::~CLI()
+{
+  // Terminate the program timer.
+  Timer::Stop("total_time");
+
+  // Did the user ask for verbose output?  If so we need to print everything.
+  // But only if the user did not ask for help or info.
+  if (HasParam("verbose") && !HasParam("help") && !HasParam("info"))
+  {
+    Log::Info << std::endl << "Execution parameters:" << std::endl;
+    Print();
+
+    Log::Info << "Program timers:" << std::endl;
+    std::map<std::string, timeval>::iterator it;
+    for (it = timer.GetAllTimers().begin(); it != timer.GetAllTimers().end();
+        ++it)
+    {
+      std::string i = (*it).first;
+      Log::Info << "  " << i << ": ";
+      timer.PrintTimer((*it).first.c_str());
+    }
+  }
+
+  // Notify the user if we are debugging, but only if we actually parsed the
+  // options.  This way this output doesn't show up inexplicably for someone who
+  // may not have wanted it there (i.e. in Boost unit tests).
+  if (did_parse)
+    Log::Debug << "Compiled with debugging symbols." << std::endl;
+
+  return;
+}
+
+/* Methods */
+
+/**
+ * Adds a parameter to the hierarchy. Use char* and not std::string since the
+ * vast majority of use cases will be literal strings.
+ *
+ * @param identifier The name of the parameter.
+ * @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.
+ */
+void CLI::Add(const char* identifier,
+             const char* description,
+             const char* alias,
+             bool required)
+{
+  po::options_description& desc = CLI::GetSingleton().desc;
+
+  std::string tmp = TYPENAME(bool);
+  std::string path = identifier;
+  std::string stringAlias = alias;
+  std::string prog_opt_id = path; // Use boost's syntax for aliasing.
+
+  // Deal with a required alias.
+  if (stringAlias.length()) {
+    amap_t& amap = GetSingleton().aliasValues;
+    amap[stringAlias] = path;
+    prog_opt_id = path + "," + alias;
+  }
+
+  // Add the option to boost::program_options.
+  desc.add_options()(prog_opt_id.c_str(), description);
+
+  // Make sure the description, etc. ends up in gmap.
+  gmap_t& gmap = GetSingleton().globalValues;
+  ParamData data;
+  data.desc = description;
+  data.tname = "";
+  data.name = path;
+  data.isFlag = false;
+  data.wasPassed = false;
+
+  gmap[path] = data;
+
+  // If the option is required, add it to the required options list.
+  if (required)
+    GetSingleton().requiredOptions.push_front(path);
+
+  return;
+}
+
+/*
+ * @brief Adds a flag parameter to CLI.
+ */
+void CLI::AddFlag(const char* identifier,
+                 const char* description,
+                 const char* alias)
+{
+  po::options_description& desc = CLI::GetSingleton().desc;
+
+  std::string path = identifier;
+  std::string stringAlias = alias;
+  std::string prog_opt_id = path;
+
+  //Deal with a required alias
+  if (stringAlias.length()) {
+    amap_t& amap = GetSingleton().aliasValues;
+    amap[stringAlias] = path;
+    prog_opt_id = path + "," + alias;
+  }
+
+  // Add the option to boost::program_options.
+  desc.add_options()
+    (prog_opt_id.c_str(), po::value<bool>()->implicit_value(true), description);
+
+  // Add the proper metadata in gmap.
+  gmap_t& gmap = GetSingleton().globalValues;
+  ParamData data;
+  data.desc = description;
+  data.tname = TYPENAME(bool);
+  data.name = path;
+  data.isFlag = true;
+  data.wasPassed = false;
+
+  gmap[path] = data;
+}
+
+/**
+ * See if the specified flag was found while parsing.
+ *
+ * @param identifier The name of the parameter in question.
+ */
+bool CLI::HasParam(const char* identifier)
+{
+  po::variables_map vmap = GetSingleton().vmap;
+  gmap_t& gmap = GetSingleton().globalValues;
+  std::string key = identifier;
+
+  // Take any possible alias into account.
+  amap_t& amap = GetSingleton().aliasValues;
+  if (amap.count(key))
+    key = amap[key];
+
+  // Does the parameter exist at all?
+  int isInGmap = gmap.count(key);
+
+  // Check if the parameter is boolean; if it is, we just want to see if it was
+  // passed.
+  if(isInGmap)
+    return gmap[key].wasPassed;
+
+  // The parameter was not passed in; return false.
+  return false;
+}
+
+/**
+ * Grab the description of the specified node.
+ *
+ * @param identifier Name of the node in question.
+ * @return Description of the node in question.
+ */
+std::string CLI::GetDescription(const char* identifier)
+{
+  gmap_t& gmap = GetSingleton().globalValues;
+  std::string name = std::string(identifier);
+
+  //Take any possible alias into account
+  amap_t& amap = GetSingleton().aliasValues;
+  if (amap.count(name))
+    name = amap[name];
+
+
+  if(gmap.count(name))
+    return gmap[name].desc;
+  else
+    return "";
+
+}
+
+// Returns the sole instance of this class.
+CLI& CLI::GetSingleton()
+{
+  if (singleton == NULL)
+    singleton = new CLI();
+
+  return *singleton;
+}
+
+/**
+ * Parses the commandline for arguments.
+ *
+ * @param argc The number of arguments on the commandline.
+ * @param argv The array of arguments as strings
+ */
+void CLI::ParseCommandLine(int argc, char** line)
+{
+  Timer::Start("total_time");
+
+  po::variables_map& vmap = GetSingleton().vmap;
+  po::options_description& desc = GetSingleton().desc;
+
+  // Parse the command line, place the options & values into vmap
+  try
+  {
+    po::store(po::parse_command_line(argc, line, desc), vmap);
+  }
+  catch (std::exception& ex)
+  {
+    Log::Fatal << ex.what() << std::endl;
+  }
+
+  // Flush the buffer, make sure changes are propagated to vmap
+  po::notify(vmap);
+  UpdateGmap();
+  DefaultMessages();
+  RequiredOptions();
+}
+
+/**
+ * Parses a stream for arguments
+ *
+ * @param stream The stream to be parsed.
+ */
+void CLI::ParseStream(std::istream& stream)
+{
+  po::variables_map& vmap = GetSingleton().vmap;
+  po::options_description& desc = GetSingleton().desc;
+
+  // Parse the stream; place options & values into vmap.
+  try
+  {
+    po::store(po::parse_config_file(stream, desc), vmap);
+  }
+  catch (std::exception& ex)
+  {
+    Log::Fatal << ex.what() << std::endl;
+  }
+
+  // Flush the buffer; make sure changes are propagated to vmap.
+  po::notify(vmap);
+
+  UpdateGmap();
+  DefaultMessages();
+  RequiredOptions();
+
+  Timer::Start("total_time");
+}
+
+/**
+ * Parses the values given on the command line, overriding any default values.
+ */
+void CLI::UpdateGmap()
+{
+  gmap_t& gmap = GetSingleton().globalValues;
+  po::variables_map& vmap = GetSingleton().vmap;
+
+  // Iterate through vmap, and overwrite default values with anything found on
+  // command line.
+  po::variables_map::iterator i;
+  for (i = vmap.begin(); i != vmap.end(); i++)
+  {
+    ParamData param;
+    if (gmap.count(i->first)) // We need to preserve certain data
+      param = gmap[i->first];
+
+    param.value = vmap[i->first].value();
+    param.wasPassed = true;
+    gmap[i->first] = param;
+  }
+}
+
+/**
+ * Registers a ProgramDoc object, which contains documentation about the
+ * program.
+ *
+ * @param doc Pointer to the ProgramDoc object.
+ */
+void CLI::RegisterProgramDoc(ProgramDoc* doc)
+{
+  // Only register the doc if it is not the dummy object we created at the
+  // beginning of the file (as a default value in case this is never called).
+  if (doc != &empty_program_doc)
+    GetSingleton().doc = doc;
+}
+
+/**
+ * Destroy the CLI object.  This resets the pointer to the singleton, so in case
+ * someone tries to access it after destruction, a new one will be made (the
+ * program will not fail).
+ */
+void CLI::Destroy()
+{
+  if (singleton != NULL)
+  {
+    delete singleton;
+    singleton = NULL; // Reset pointer.
+  }
+}
+
+/**
+ * Parses the parameters for 'help' and 'info'
+ * If found, will print out the appropriate information
+ * and kill the program.
+ */
+void CLI::DefaultMessages()
+{
+  // Default help message
+  if (GetParam<bool>("help"))
+  {
+    Log::Info.ignoreInput = false;
+    PrintHelp();
+    exit(0); // The user doesn't want to run the program, he wants help.
+  }
+
+  if (HasParam("info"))
+  {
+    Log::Info.ignoreInput = false;
+    std::string str = GetParam<std::string>("info");
+
+    // The info node should always be there, but the user may not have specified
+    // anything.
+    if (str != "")
+    {
+      PrintHelp(str);
+      exit(0);
+    }
+
+    // Otherwise just print the generalized help.
+    PrintHelp();
+    exit(0);
+  }
+
+  if (GetParam<bool>("verbose"))
+  {
+    // Give [INFO ] output.
+    Log::Info.ignoreInput = false;
+  }
+
+  // Notify the user if we are debugging.  This is not done in the constructor
+  // because the output streams may not be set up yet.  We also don't want this
+  // message twice if the user just asked for help or information.
+  Log::Debug << "Compiled with debugging symbols." << std::endl;
+}
+
+/**
+ * Checks that all parameters specified as required have been specified on the
+ * command line.  If they havent, prints an error message and kills the program.
+ */
+void CLI::RequiredOptions()
+{
+  po::variables_map& vmap = GetSingleton().vmap;
+  std::list<std::string> rOpt = GetSingleton().requiredOptions;
+
+  // Now, warn the user if they missed any required options.
+  std::list<std::string>::iterator iter;
+  for (iter = rOpt.begin(); iter != rOpt.end(); iter++)
+  {
+    std::string str = *iter;
+    if (!vmap.count(str))
+    { // If a required option isn't there...
+      Log::Fatal << "Required option --" << str.c_str() << " is undefined."
+          << std::endl;
+    }
+  }
+}
+
+/* Prints out the current hierarchy. */
+void CLI::Print()
+{
+  gmap_t& gmap = GetSingleton().globalValues;
+  gmap_t::iterator iter;
+
+  // Print out all the values.
+  for (iter = gmap.begin(); iter != gmap.end(); iter++)
+  {
+    std::string key = iter->first;
+
+    Log::Info << "  " << key << ": ";
+
+    // Now, figure out what type it is, and print it.
+    // We can handle strings, ints, bools, floats, doubles.
+    ParamData data = iter->second;
+    if (data.tname == TYPENAME(std::string))
+    {
+      std::string value = GetParam<std::string>(key.c_str());
+      if(value == "")
+        Log::Info << "\"\"";
+      Log::Info << value;
+    }
+    else if (data.tname == TYPENAME(int))
+    {
+      int value = GetParam<int>(key.c_str());
+      Log::Info << value;
+    }
+    else if (data.tname == TYPENAME(bool))
+    {
+      bool value = HasParam(key.c_str());
+      Log::Info << (value ? "true" : "false");
+    }
+    else if (data.tname == TYPENAME(float))
+    {
+      float value = GetParam<float>(key.c_str());
+      Log::Info << value;
+    }
+    else if (data.tname == TYPENAME(double))
+    {
+      double value = GetParam<double>(key.c_str());
+      Log::Info << value;
+    }
+    else
+    {
+      // We don't know how to print this, or it's a timeval which is printed
+      // later.
+      Log::Info << "(unknown data type)";
+    }
+
+    Log::Info << std::endl;
+  }
+  Log::Info << std::endl;
+}
+
+
+/* Prints the descriptions of the current hierarchy. */
+void CLI::PrintHelp(std::string param)
+{
+  gmap_t& gmap = GetSingleton().globalValues;
+  amap_t& amap = GetSingleton().aliasValues;
+  gmap_t::iterator iter;
+  ProgramDoc docs = *GetSingleton().doc;
+
+  // If we pass a single param, alias it if necessary.
+  if (param != "" && amap.count(param))
+    param = amap[param];
+
+  // Do we only want to print out one value?
+  if (param != "" && gmap.count(param))
+  {
+    ParamData data = gmap[param];
+    std::string alias = AliasReverseLookup(param);
+    alias = alias.length() ? " (-" + alias + ")" : alias;
+
+    // Figure out the name of the type.
+    std::string type = "";
+    if (data.tname == TYPENAME(std::string))
+      type = " [string]";
+    else if (data.tname == TYPENAME(int))
+      type = " [int]";
+    else if (data.tname == TYPENAME(bool))
+      type = ""; // Nothing to pass for a flag.
+    else if (data.tname == TYPENAME(float))
+      type = " [float]";
+    else if (data.tname == TYPENAME(double))
+      type = " [double]";
+
+    // Now, print the descriptions.
+    std::string fullDesc = "  --" + param + alias + type + "  ";
+
+    if (fullDesc.length() <= 32) // It all fits on one line.
+      std::cout << fullDesc << std::string(32 - fullDesc.length(), ' ');
+    else // We need multiple lines.
+      std::cout << fullDesc << std::endl << std::string(32, ' ');
+
+    std::cout << HyphenateString(data.desc, 32) << std::endl;
+    return;
+  }
+  else if (param != "")
+  {
+    // User passed a single variable, but it doesn't exist.
+    std::cerr << "Parameter --" << param << " does not exist." << std::endl;
+    exit(1); // Nothing left to do.
+  }
+
+  // Print out the descriptions.
+  if(docs.programName != "")
+  {
+    std::cout << docs.programName << std::endl << std::endl;
+    std::cout << "  " << HyphenateString(docs.documentation, 2) << std::endl
+        << std::endl;
+  }
+  else
+    std::cout << "[undocumented program]" << std::endl << std::endl;
+
+  for (size_t pass = 0; pass < 2; ++pass)
+  {
+    if (pass == 0)
+      std::cout << "Required options:" << std::endl << std::endl;
+    else
+      std::cout << "Options: " << std::endl << std::endl;
+
+    // Print out the descriptions of everything else.
+    for (iter = gmap.begin(); iter != gmap.end(); iter++)
+    {
+      std::string key = iter->first;
+      ParamData data = iter->second;
+      std::string desc = data.desc;
+      std::string alias = AliasReverseLookup(key);
+      alias = alias.length() ? " (-" + alias + ")" : alias;
+
+      // Is the option required or not?
+      bool required = false;
+      std::list<std::string>::iterator iter;
+      std::list<std::string>& 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.
+
+      if (pass == 1) // Append default value to description.
+      {
+        desc += "  Default value ";
+        std::stringstream tmp;
+
+        if (data.tname == TYPENAME(std::string))
+          tmp << "'" << boost::any_cast<std::string>(data.value) << "'.";
+        else if (data.tname == TYPENAME(int))
+          tmp << boost::any_cast<int>(data.value) << '.';
+        else if (data.tname == TYPENAME(bool))
+          desc = data.desc; // No extra output for that.
+        else if (data.tname == TYPENAME(float))
+          tmp << boost::any_cast<float>(data.value) << '.';
+        else if (data.tname == TYPENAME(double))
+          tmp << boost::any_cast<double>(data.value) << '.';
+
+        desc += tmp.str();
+      }
+
+      // Figure out the name of the type.
+      std::string type = "";
+      if (data.tname == TYPENAME(std::string))
+        type = " [string]";
+      else if (data.tname == TYPENAME(int))
+        type = " [int]";
+      else if (data.tname == TYPENAME(bool))
+        type = ""; // Nothing to pass for a flag.
+      else if (data.tname == TYPENAME(float))
+        type = " [float]";
+      else if (data.tname == TYPENAME(double))
+        type = " [double]";
+
+      // Now, print the descriptions.
+      std::string fullDesc = "  --" + key + alias + type + "  ";
+
+      if (fullDesc.length() <= 32) // It all fits on one line.
+        std::cout << fullDesc << std::string(32 - fullDesc.length(), ' ');
+      else // We need multiple lines.
+        std::cout << fullDesc << std::endl << std::string(32, ' ');
+
+      std::cout << HyphenateString(desc, 32) << std::endl;
+    }
+
+  std::cout << std::endl;
+
+  }
+}
+
+/**
+ * Hyphenate a string or split it onto multiple 80-character lines, with some
+ * amount of padding on each line.  This is used for option output.
+ *
+ * @param str String to hyphenate (splits are on ' ').
+ * @param padding Amount of padding on the left for each new line.
+ */
+std::string CLI::HyphenateString(std::string str, int padding)
+{
+  size_t margin = 80 - padding;
+  if (str.length() < margin)
+    return str;
+  std::string out("");
+  unsigned int pos = 0;
+  // First try to look as far as possible.
+  while (pos < str.length() - 1)
+  {
+    size_t splitpos;
+    // Check that we don't have a newline first.
+    splitpos = str.find('\n', pos);
+    if (splitpos == std::string::npos || splitpos > (pos + margin))
+    {
+      // We did not find a newline.
+      if (str.length() - pos < margin)
+      {
+        splitpos = str.length(); // The rest fits on one line.
+      }
+      else
+      {
+        splitpos = str.rfind(' ', margin + pos); // Find nearest space.
+        if (splitpos <= pos || splitpos == std::string::npos) // Not found.
+          splitpos = pos + margin;
+      }
+    }
+    out += str.substr(pos, (splitpos - pos));
+    if (splitpos < str.length())
+    {
+      out += '\n';
+      out += std::string(padding, ' ');
+    }
+
+    pos = splitpos;
+    if (str[pos] == ' ' || str[pos] == '\n')
+      pos++;
+  }
+  return out;
+}
+
+std::string CLI::AliasReverseLookup(std::string value)
+{
+  amap_t& amap = GetSingleton().aliasValues;
+  amap_t::iterator iter;
+  for (iter = amap.begin(); iter != amap.end(); iter++)
+    if (iter->second == value) // Found our match.
+      return iter->first;
+
+  return ""; // Nothing found.
+}
+
+// Add help parameter.
+PARAM_FLAG("help", "Default help info.", "h");
+PARAM_STRING("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.", "");

Copied: mlpack/trunk/src/mlpack/core/util/cli.hpp (from rev 10767, mlpack/trunk/src/mlpack/core/io/cli.hpp)
===================================================================
--- mlpack/trunk/src/mlpack/core/util/cli.hpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/core/util/cli.hpp	2011-12-14 12:44:53 UTC (rev 10774)
@@ -0,0 +1,780 @@
+/**
+ * @file cli.hpp
+ * @author Matthew Amidon
+ *
+ * This file implements the CLI subsystem which is intended to replace FX.
+ * This can be used more or less regardless of context.  In the future,
+ * it might be expanded to include file I/O.
+ */
+#ifndef __MLPACK_CORE_IO_CLI_HPP
+#define __MLPACK_CORE_IO_CLI_HPP
+
+#include <list>
+#include <iostream>
+#include <map>
+#include <string>
+
+#include <boost/any.hpp>
+#include <boost/program_options.hpp>
+
+#include "timers.hpp"
+#include "cli_deleter.hpp" // To make sure we can delete the singleton.
+
+/**
+ * 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.
+ */
+#define PROGRAM_INFO(NAME, DESC) static mlpack::io::ProgramDoc \
+    io_programdoc_dummy_object = mlpack::io::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
+ *
+ * @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
+ * http://mlpack.org/ticket/74 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.
+ * @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
+ * http://mlpack.org/ticket/74 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.
+ * @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
+ * http://mlpack.org/ticket/74 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.
+ * @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
+ * http://mlpack.org/ticket/74 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.
+ * @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
+ * http://mlpack.org/ticket/74 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.
+ * @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
+ * http://mlpack.org/ticket/74 for more information.
+ */
+#define PARAM_VECTOR(T, ID, DESC, ALIAS) \
+    PARAM(std::vector<T>, ID, DESC, ALIAS, std::vector<T>(), 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.
+ *
+ * @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
+ * http://mlpack.org/ticket/74 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.
+ *
+ * @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
+ * http://mlpack.org/ticket/74 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.
+ *
+ * @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
+ * http://mlpack.org/ticket/74 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.
+ *
+ * @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
+ * http://mlpack.org/ticket/74 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.
+ *
+ * @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
+ * http://mlpack.org/ticket/74 for more information.
+ */
+#define PARAM_VECTOR_REQ(T, ID, DESC, ALIAS) PARAM(std::vector<T>, ID, DESC, \
+    ALIAS, std::vector<T>(), 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.
+ * @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::io::Option<T> \
+      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::io::Option<bool>\
+  JOIN(__io_option_flag_object_, __COUNTER__) (ID, DESC, ALIAS);
+  /** @endcond */
+
+  /**
+   * Define a module.
+   *
+   * @param ID Name of the module.
+   * @param DESC Description of the module (1-2 sentences).
+   */
+  #define PARAM_MODULE(ID, DESC) static mlpack::io::Option<int> \
+      JOIN(io_option_module_dummy_object_, __COUNTER__) (true, 0, ID, DESC, \
+      NULL);
+#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::io::Option<T> \
+      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::io::Option<bool>\
+      JOIN(__io_option_flag_object_, __LINE__) (ID, DESC, ALIAS);
+  /** @endcond */
+
+  /**
+   * Define a module.
+   *
+   * @param ID Name of the module.
+   * @param DESC Description of the module (1-2 sentences).
+   */
+  #define PARAM_MODULE(ID, DESC) static mlpack::io::Option<int> \
+      JOIN(JOIN(io_option_dummy_object_, __LINE__), mod) (true, 0, ID, DESC, \
+      NULL);
+
+#endif
+
+/**
+ * The TYPENAME macro is used internally to convert a type into a string.
+ */
+#define TYPENAME(x) (std::string(typeid(x).name()))
+
+namespace po = boost::program_options;
+
+namespace mlpack {
+
+namespace io {
+
+// Externally defined in option.hpp, this class holds information about the
+// program being run.
+class ProgramDoc;
+
+}; // namespace io
+
+/**
+ * Aids in the extensibility of OptionsHierarchy by focusing the potential
+ * changes into one structure.
+ */
+struct ParamData
+{
+  //! Name of this parameter.
+  std::string name;
+  //! Description of this parameter, if any.
+  std::string desc;
+  //! Type information of this parameter.
+  std::string tname;
+  //! The actual value of this parameter.
+  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
+  bool isFlag;
+};
+
+/**
+ * @brief Parses the command line for parameters and holds user-specified
+ *     parameters.
+ *
+ * The CLI class is a subsystem by which parameters for machine learning methods
+ * can be specified and accessed.  In conjunction with the macros PARAM_DOUBLE,
+ * PARAM_INT, PARAM_STRING, PARAM_FLAG, and others, this class aims to make user
+ * configurability of MLPACK methods very easy.
+ *
+ * @section addparam Adding parameters to a program
+ *
+ * @code
+ * $ ./executable --foo/bar=5
+ * @endcode
+ *
+ * @note The = is optional; a space can also be used.
+ *
+ * A parameter is specified by using one of the following macros (this is not a
+ * complete list; see core/io/cli.hpp):
+ *
+ *  - PARAM_FLAG(ID, DESC, ALIAS)
+ *  - PARAM_DOUBLE(ID, DESC, ALIAS, DEF)
+ *  - PARAM_INT(ID, DESC, ALIAS, DEF)
+ *  - PARAM_STRING(ID, DESC, ALIAS, DEF)
+ *
+ * @param ID Name of the parameter.
+ * @param DESC Short description of the parameter (one/two sentences).
+ * @param ALIAS An alias for the parameter.
+ * @param DEF Default value of the parameter.
+ *
+ * The flag (boolean) type automatically defaults to false; it is specified
+ * merely as a flag on the command line (no '=true' is required).
+ *
+ * Here is an example of a few parameters being defined; this is for the L-BFGS
+ * optimizer (mlpack::optimizers::L_BFGS):
+ *
+ * @code
+ * PARAM_MODULE("lbfgs", "Options for the L-BFGS optimizer, which uses a "
+ *    "back-tracing line search to determine the step size to take.");
+ *
+ * PARAM_DOUBLE("armijo_constant", "Controls the accuracy of the line search "
+ *    "routine for determining the Armijo condition.", "lbfgs", 1e-4);
+ * PARAM_DOUBLE("min_step", "The minimum step of the line search.", "lbfgs",
+ *    1e-20);
+ * PARAM_DOUBLE("max_step", "The maximum step of the line search.", "lbfgs",
+ *    1e20);
+ * PARAM_INT("max_line_search_trials", "The maximum number of trials for the "
+ *    "line search.", "lbfgs", 50);
+ * PARAM_DOUBLE("wolfe", "Parameter for detecting the Wolfe condition.",
+ *    "lbfgs", 0.9);
+ * PARAM_DOUBLE("min_gradient_norm", "Minimum gradient norm required to "
+ *  "continue the optimization.", "lbfgs", 1e-10);
+ * @endcode
+ *
+ * More documentation is available on the PARAM_*() macros in the documentation
+ * for core/io/cli.hpp.
+ *
+ * @section programinfo Documenting the program itself
+ *
+ * In addition to allowing documentation for each individual parameter and
+ * module, the PROGRAM_INFO() macro provides support for documenting the program
+ * itself.  There should only be one instance of the PROGRAM_INFO() macro.
+ * Below is an example:
+ *
+ * @code
+ * PROGRAM_INFO("Maximum Variance Unfolding", "This program performs maximum "
+ *    "variance unfolding on the given dataset, writing a lower-dimensional "
+ *    "unfolded dataset to the given output file.", "mvu");
+ * @endcode
+ *
+ * The last parameter, the default module (DEF_MOD), is discussed in detail in
+ * the PROGRAM_INFO() documentation.
+ *
+ * @section parsecli Parsing the command line with CLI
+ *
+ * To have CLI parse the command line at the beginning of code execution, only a
+ * call to ParseCommandLine() is necessary:
+ *
+ * @code
+ * int main(int argc, char** argv) {
+ *   CLI::ParseCommandLine(argc, argv);
+ *
+ *   ...
+ * }
+ * @endcode
+ *
+ * CLI provides --help and --info options which give nicely formatted
+ * documentation of each option; the documentation is generated from the DESC
+ * arguments in the PARAM_*() macros.
+ *
+ * @section getparam Getting/setting parameters with CLI
+ *
+ * When the parameters have been defined, the next important thing is how to
+ * access and modify them.  For this, the HasParam() and GetParam() methods are
+ * used.  For instance, the option "neighbor_search/k" could be
+ * modified like this (it could also be merely accessed with the same call as an
+ * r-value).
+ *
+ * @code
+ * CLI::GetParam<index_t>("neighbor_search/k") = 50;
+ * @endcode
+ *
+ * @note
+ * Care is needed when defining options.  Because the PARAM_*() macros expand to
+ * a global object definition (of type mlpack::io::Option) whose constructor
+ * adds the parameter to the hierarchy, the parameters defined in any included
+ * file will be added to the program--and the documentation for those options
+ * will appear when --help is given. For this reason, mlpack/core.h does not
+ * include more than the core components necessary to write MLPACK code.  Care
+ * is required so that only the files which are absolutely necessary are
+ * included, so as to avoid cluttering the documentation with irrelevant
+ * options.
+ *
+ * @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
+ * http://mlpack.org/ticket/74 for more information.
+ */
+class CLI
+{
+ public:
+  /**
+   * Adds a parameter to the hierarchy; use the PARAM_*() macros instead of this
+   * (i.e. PARAM_INT()). Uses char* and not std::string since the vast majority
+   * of use cases will be literal strings.
+   *
+   * @param identifier The name of the parameter.
+   * @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.
+   */
+  static void Add(const char* identifier,
+                  const char* description,
+                  const char* alias = "",
+                  bool required = false);
+
+  /**
+   * Adds a parameter to the hierarchy; use the PARAM_*() macros instead of this
+   * (i.e. PARAM_INT()). Uses char* and not std::string since the vast majority
+   * of use cases will be literal strings.  If the argument requires a
+   * parameter, you must specify a type.
+   *
+   * @param identifier The name of the parameter.
+   * @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.
+   */
+  template<class T>
+  static void Add(const char* identifier,
+                  const char* description,
+                  const char* alias = "",
+                  bool required = false);
+
+  /**
+   * Adds a flag parameter to the hierarchy; use PARAM_FLAG() instead of this.
+   *
+   * @param identifier The name of the paramater.
+   * @param description Short string description of the parameter.
+   * @param alias An alias for the parameter, defaults to "" which is no alias.
+   */
+  static void AddFlag(const char* identifier,
+                      const char* description,
+                      const char* alias = "");
+
+  /**
+   * See if the specified flag was found while parsing.
+   *
+   * @param identifier The name of the parameter in question.
+   */
+  static bool HasParam(const char* identifier);
+
+
+  /**
+   * Parses the parameters for 'help' and 'info'.
+   * If found, will print out the appropriate information and kill the program.
+   */
+  static void DefaultMessages();
+
+  /**
+   * Grab the value of type T found while parsing.  You can set the value using
+   * this reference safely.
+   *
+   * @param identifier The name of the parameter in question.
+   */
+  template<typename T>
+  static T& GetParam(const char* identifier);
+
+  /**
+   * Get the description of the specified node.
+   *
+   * @param identifier Name of the node in question.
+   * @return Description of the node in question.
+   */
+  static std::string GetDescription(const char* identifier);
+
+  /**
+   * Searches for unqualified paramters; when one is found, the default module
+   * is prepended onto it (if necessary).
+   *
+   * @param argc The number of parameters.
+   * @param argv 2D array of the parameter strings.
+   * @return Valid modified strings.
+   */
+  static std::vector<std::string> InsertDefaultModule(int argc, char** argv);
+
+  /**
+   * Parses the commandline for arguments.
+   *
+   * @param argc The number of arguments on the commandline.
+   * @param argv The array of arguments as strings.
+   */
+  static void ParseCommandLine(int argc, char** argv);
+
+  /**
+   * Parses a stream for arguments.
+   *
+   * @param stream The stream to be parsed.
+   */
+  static void ParseStream(std::istream& stream);
+
+  /**
+   * Print out the current hierarchy.
+   */
+  static void Print();
+
+  /**
+   * Print out the help info of the hierarchy.
+   */
+  static void PrintHelp(std::string param="");
+
+  /**
+   * Checks that all required parameters have been specified on the command
+   * line.  If any have not been specified, an error message is printed and the
+   * program is terminated.
+   */
+  static void RequiredOptions();
+
+  /**
+   * Cleans up input pathnames, rendering strings such as /foo/bar
+   * and foo/bar/ equivalent inputs.
+   *
+   * @param str Input string.
+   * @return Sanitized string.
+   */
+  static std::string SanitizeString(const char* str);
+
+  /**
+   * Hyphenate a string or split it onto multiple 80-character lines, with some
+   * amount of padding on each line.  This is ued for option output.
+   *
+   * @param str String to hyphenate (splits are on ' ').
+   * @param padding Amount of padding on the left for each new line.
+   */
+  static std::string HyphenateString(std::string str, int padding);
+
+  /**
+   * Parses the values given on the command line, overriding any default values.
+   */
+  static void UpdateGmap();
+
+  /**
+   * Registers a ProgramDoc object, which contains documentation about the
+   * program.  If this method has been called before (that is, if two
+   * ProgramDocs are instantiated in the program), a fatal error will occur.
+   *
+   * @param doc Pointer to the ProgramDoc object.
+   */
+  static void RegisterProgramDoc(io::ProgramDoc* doc);
+
+  /**
+   * Destroy the CLI object.  This resets the pointer to the singleton, so in
+   * case someone tries to access it after destruction, a new one will be made
+   * (the program will not fail).
+   */
+  static void Destroy();
+
+  /**
+   * Destructor.
+   */
+  ~CLI();
+
+ private:
+  //! The documentation and names of options.
+  po::options_description desc;
+
+  //! Values of the options given by user.
+  po::variables_map vmap;
+
+  //! Pathnames of required options.
+  std::list<std::string> requiredOptions;
+
+  //! Map of global values.
+  typedef std::map<std::string, ParamData> gmap_t;
+  gmap_t globalValues;
+
+  //! Map for aliases, from alias to actual name.
+  typedef std::map<std::string, std::string> amap_t;
+  amap_t aliasValues;
+
+  //! The singleton itself.
+  static CLI* singleton;
+
+  //! True, if CLI was used to parse command line options.
+  bool did_parse;
+
+  //! Holds the timer objects.
+  Timers timer;
+
+  //! So that Timer::Start() and Timer::Stop() can access the timer variable.
+  friend class Timer;
+
+ public:
+  //! Pointer to the ProgramDoc object.
+  io::ProgramDoc *doc;
+
+ private:
+
+  /**
+   * Returns an alias, if given the name of the original.
+   *
+   * @param value The value in a key:value pair where the key
+   * is an alias.
+   * @return The alias associated with value.
+   */
+  static std::string AliasReverseLookup(std::string value);
+
+  /**
+   * Retrieve the singleton.
+   *
+   * Not exposed to the outside, so as to spare users some ungainly
+   * x.GetSingleton().foo() syntax.
+   *
+   * In this case, the singleton is used to store data for the static methods,
+   * as there is no point in defining static methods only to have users call
+   * private instance methods
+   *
+   * @return The singleton instance for use in the static methods.
+   */
+  static CLI& GetSingleton();
+
+#ifdef _WIN32
+  /**
+   * Converts a FILETIME structure to an equivalent timeval structure.
+   * Only necessary on windows platforms.
+   * @param tv Valid timeval structure.
+   */
+  void FileTimeToTimeVal(timeval* tv);
+#endif
+
+  /**
+   * Make the constructor private, to preclude unauthorized instances.
+   */
+  CLI();
+
+  /**
+   * Initialize desc with a particular name.
+   *
+   * @param optionsName Name of the module, as far as boost is concerned.
+   */
+  CLI(std::string& optionsName);
+
+  //! Private copy constructor; we don't want copies floating around.
+  CLI(const CLI& other);
+};
+
+}; // namespace mlpack
+
+// Include the actual definitions of templated methods
+#include "cli_impl.hpp"
+
+#endif

Copied: mlpack/trunk/src/mlpack/core/util/cli_deleter.cpp (from rev 10737, mlpack/trunk/src/mlpack/core/io/cli_deleter.cpp)
===================================================================
--- mlpack/trunk/src/mlpack/core/util/cli_deleter.cpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/core/util/cli_deleter.cpp	2011-12-14 12:44:53 UTC (rev 10774)
@@ -0,0 +1,32 @@
+/**
+ * @file io_deleter.cc
+ * @author Ryan Curtin
+ *
+ * Extremely simple class whose only job is to delete the existing CLI object at
+ * the end of execution.  This is meant to allow the user to avoid typing
+ * 'CLI::Destroy()' at the end of their program.  The file also defines a static
+ * CLIDeleter class, which will be initialized at the beginning of the program
+ * and deleted at the end.  The destructor destroys the CLI singleton.
+ */
+#include "cli_deleter.hpp"
+#include "cli.hpp"
+
+using namespace mlpack;
+using namespace mlpack::io;
+
+/***
+ * Empty constructor that does nothing.
+ */
+CLIDeleter::CLIDeleter()
+{
+  /* nothing to do */
+}
+
+/***
+ * This destructor deletes the CLI singleton.
+ */
+CLIDeleter::~CLIDeleter()
+{
+  // Delete the singleton!
+  CLI::Destroy();
+}

Copied: mlpack/trunk/src/mlpack/core/util/cli_deleter.hpp (from rev 10737, mlpack/trunk/src/mlpack/core/io/cli_deleter.hpp)
===================================================================
--- mlpack/trunk/src/mlpack/core/util/cli_deleter.hpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/core/util/cli_deleter.hpp	2011-12-14 12:44:53 UTC (rev 10774)
@@ -0,0 +1,33 @@
+/**
+ * @file cli_deleter.hpp
+ * @author Ryan Curtin
+ *
+ * Definition of the CLIDeleter() class.
+ */
+#ifndef __MLPACK_CORE_IO_CLI_DELETER_HPP
+#define __MLPACK_CORE_IO_CLI_DELETER_HPP
+
+namespace mlpack {
+namespace io {
+
+/**
+ * Extremely simple class whose only job is to delete the existing CLI object at
+ * the end of execution.  This is meant to allow the user to avoid typing
+ * 'CLI::Destroy()' at the end of their program.  The file also defines a static
+ * CLIDeleter class, which will be initialized at the beginning of the program
+ * and deleted at the end.  The destructor destroys the CLI singleton.
+ */
+class CLIDeleter
+{
+ public:
+  CLIDeleter();
+  ~CLIDeleter();
+};
+
+//! Declare the deleter.
+static CLIDeleter cli_deleter;
+
+}; // namespace io
+}; // namespace mlpack
+
+#endif

Copied: mlpack/trunk/src/mlpack/core/util/cli_impl.hpp (from rev 10767, mlpack/trunk/src/mlpack/core/io/cli_impl.hpp)
===================================================================
--- mlpack/trunk/src/mlpack/core/util/cli_impl.hpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/core/util/cli_impl.hpp	2011-12-14 12:44:53 UTC (rev 10774)
@@ -0,0 +1,118 @@
+/**
+ * @file cli_impl.hpp
+ * @author Matthew Amidon
+ *
+ * Implementation of templated functions of the CLI class.
+ */
+#ifndef __MLPACK_CORE_IO_CLI_HPP
+#error "Do not include this file directly."
+#endif
+
+#ifndef __MLPACK_CORE_IO_CLI_IMPL_HPP
+#define __MLPACK_CORE_IO_CLI_IMPL_HPP
+
+// Include option.hpp here because it requires CLI but is also templated.
+#include "option.hpp"
+
+namespace mlpack {
+
+/**
+ * @brief Adds a parameter to CLI, making it accessibile via GetParam &
+ *     CheckValue.
+ *
+ * @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.
+ */
+template<typename T>
+void CLI::Add(const char* identifier,
+             const char* description,
+             const char* alias,
+             bool required)
+{
+
+  po::options_description& desc = CLI::GetSingleton().desc;
+  std::string path = identifier;
+  std::string stringAlias = alias;
+  std::string prog_opt_id = path;
+
+  // Add the alias, if necessary
+  if (stringAlias.length()) {
+    amap_t& amap = GetSingleton().aliasValues;
+    amap[stringAlias] = path;
+    prog_opt_id = path + "," + alias;
+  }
+
+  // Add the option to boost program_options.
+  desc.add_options()
+    (prog_opt_id.c_str(), po::value<T>(),  description);
+
+  // Make sure the appropriate metadata is inserted into gmap.
+  gmap_t& gmap = GetSingleton().globalValues;
+
+  ParamData data;
+  T tmp = T();
+
+  data.desc = description;
+  data.name = path;
+  data.tname = TYPENAME(T);
+  data.value = boost::any(tmp);
+  data.wasPassed = false;
+  gmap[path] = data;
+
+  // If the option is required, add it to the required options list.
+  if (required)
+    GetSingleton().requiredOptions.push_front(path);
+}
+
+
+/**
+ * @brief Returns the value of the specified parameter.
+ *   If the parameter is unspecified, an undefined but
+ *   more or less valid value is returned.
+ *
+ * @tparam T The type of the parameter.
+ * @param identifier The full pathname of the parameter.
+ *
+ * @return The value of the parameter.  Use CLI::CheckValue to determine if it's
+ *     valid.
+ */
+template<typename T>
+T& CLI::GetParam(const char* identifier)
+{
+  // Used to ensure we have a valid value.
+  T tmp = T();
+
+  // Used to index into the globalValues map.
+  std::string key = std::string(identifier);
+  gmap_t& gmap = GetSingleton().globalValues;
+
+  //  Now check if we have an alias.
+  amap_t& amap = GetSingleton().aliasValues;
+  if (amap.count(key))
+    key = amap[key];
+
+  //What if we don't actually have any value?
+  if (!gmap.count(key))
+  {
+    gmap[key] = ParamData();
+    gmap[key].value = boost::any(tmp);
+    *boost::any_cast<T>(&gmap[key].value) = tmp;
+  }
+
+  //What if we have meta-data, but no data?
+  boost::any val = gmap[key].value;
+  if(val.empty())
+    gmap[key].value = boost::any(tmp);
+
+
+  return *boost::any_cast<T>(&gmap[key].value);
+}
+
+}; // namespace mlpack
+
+#endif

Copied: mlpack/trunk/src/mlpack/core/util/log.cpp (from rev 10737, mlpack/trunk/src/mlpack/core/io/log.cpp)
===================================================================
--- mlpack/trunk/src/mlpack/core/util/log.cpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/core/util/log.cpp	2011-12-14 12:44:53 UTC (rev 10774)
@@ -0,0 +1,116 @@
+/**
+ * @file log.cpp
+ * @author Matthew Amidon
+ *
+ * Implementation of the Log class.
+ */
+#include <cxxabi.h>
+#include <execinfo.h>
+
+#include "log.hpp"
+
+// Color code escape sequences.
+#define BASH_RED "\033[0;31m"
+#define BASH_GREEN "\033[0;32m"
+#define BASH_YELLOW "\033[0;33m"
+#define BASH_CYAN "\033[0;36m"
+#define BASH_CLEAR "\033[0m"
+
+using namespace mlpack;
+using namespace mlpack::io;
+
+// Only output debugging output if in debug mode.
+#ifdef DEBUG
+PrefixedOutStream Log::Debug = PrefixedOutStream(std::cout,
+    BASH_CYAN "[DEBUG] " BASH_CLEAR);
+#else
+NullOutStream Log::Debug = NullOutStream();
+#endif
+
+PrefixedOutStream Log::Info = PrefixedOutStream(std::cout,
+    BASH_GREEN "[INFO ] " BASH_CLEAR, true /* unless --verbose */, false);
+PrefixedOutStream Log::Warn = PrefixedOutStream(std::cout,
+    BASH_YELLOW "[WARN ] " BASH_CLEAR, false, false);
+PrefixedOutStream Log::Fatal = PrefixedOutStream(std::cerr,
+    BASH_RED "[FATAL] " BASH_CLEAR, false, true /* fatal */);
+
+std::ostream& Log::cout = std::cout;
+
+// Only do anything for Assert() if in debugging mode.
+#ifdef DEBUG
+void Log::Assert(bool condition, const char* message)
+{
+  if(!condition)
+  {
+    void* array[25];
+    size_t size = backtrace (array, sizeof(array)/sizeof(void*));
+    char** messages = backtrace_symbols(array, size);
+
+    // skip first stack frame (points here)
+    for (size_t i = 1; i < size && messages != NULL; ++i)
+    {
+      char *mangled_name = 0, *offset_begin = 0, *offset_end = 0;
+
+      // find parantheses and +address offset surrounding mangled name
+      for (char *p = messages[i]; *p; ++p)
+      {
+        if (*p == '(')
+        {
+          mangled_name = p;
+        }
+        else if (*p == '+')
+        {
+          offset_begin = p;
+        }
+        else if (*p == ')')
+        {
+          offset_end = p;
+          break;
+        }
+      }
+
+      // if the line could be processed, attempt to demangle the symbol
+      if (mangled_name && offset_begin && offset_end &&
+          mangled_name < offset_begin)
+      {
+        *mangled_name++ = '\0';
+        *offset_begin++ = '\0';
+        *offset_end++ = '\0';
+
+        int status;
+        char* real_name = abi::__cxa_demangle(mangled_name, 0, 0, &status);
+
+        // if demangling is successful, output the demangled function name
+        if (status == 0)
+        {
+          Log::Debug << "[bt]: (" << i << ") " << messages[i] << " : "
+                    << real_name << "+" << offset_begin << offset_end
+                    << std::endl;
+
+        }
+        // otherwise, output the mangled function name
+        else
+        {
+          Log::Debug << "[bt]: (" << i << ") " << messages[i] << " : "
+                    << mangled_name << "+" << offset_begin << offset_end
+                    << std::endl;
+        }
+        free(real_name);
+      }
+      // otherwise, print the whole line
+      else
+      {
+          Log::Debug << "[bt]: (" << i << ") " << messages[i] << std::endl;
+      }
+    }
+    Log::Debug << message << std::endl;
+    free(messages);
+
+    //backtrace_symbols_fd (array, size, 2);
+    exit(1);
+  }
+}
+#else
+void Log::Assert(bool condition, const char* message)
+{ }
+#endif

Copied: mlpack/trunk/src/mlpack/core/util/log.hpp (from rev 10737, mlpack/trunk/src/mlpack/core/io/log.hpp)
===================================================================
--- mlpack/trunk/src/mlpack/core/util/log.hpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/core/util/log.hpp	2011-12-14 12:44:53 UTC (rev 10774)
@@ -0,0 +1,84 @@
+/**
+ * @file log.hpp
+ * @author Matthew Amidon
+ *
+ * Definition of the Log class.
+ */
+#ifndef __MLPACK_CORE_IO_LOG_HPP
+#define __MLPACK_CORE_IO_LOG_HPP
+
+#include "prefixedoutstream.hpp"
+#include "nulloutstream.hpp"
+
+namespace mlpack {
+
+/**
+ * Provides a convenient way to give formatted output.
+ *
+ * The Log class has four members which can be used in the same way ostreams can
+ * be used:
+ *
+ *  - Log::Debug
+ *  - Log::Info
+ *  - Log::Warn
+ *  - Log::Fatal
+ *
+ * Each of these will prefix a tag to the output (for easy filtering), and the
+ * fatal output will terminate the program when a newline is encountered.  An
+ * example is given below.
+ *
+ * @code
+ * Log::Info << "Checking a condition." << std::endl;
+ * if (!someCondition())
+ *   Log::Warn << "someCondition() is not satisfied!" << std::endl;
+ * Log::Info << "Checking an important condition." << std::endl;
+ * if (!someImportantCondition()) {
+ *   Log::Fatal << "someImportantCondition() is not satisfied! Terminating.";
+ *   Log::Fatal << std::endl;
+ * }
+ * @endcode
+ *
+ * Any messages sent to Log::Debug will not be shown when compiling in non-debug
+ * mode.  Messages to Log::Info will only be shown when the --verbose flag is
+ * given to the program (or rather, the CLI class).
+ *
+ * @see PrefixedOutStream, NullOutStream, CLI
+ */
+class Log
+{
+ public:
+  /**
+   * Checks if the specified condition is true.
+   * If not, halts program execution and prints a custom error message.
+   * Does nothing in non-debug mode.
+   */
+  static void Assert(bool condition, const char* message = "Assert Failed.");
+
+
+  // We only use PrefixedOutStream if the program is compiled with debug
+  // symbols.
+#ifdef DEBUG
+  //! Prints debug output with the appropriate tag: [DEBUG].
+  static io::PrefixedOutStream Debug;
+#else
+  //! Dumps debug output into the bit nether regions.
+  static io::NullOutStream Debug;
+#endif
+
+  //! Prints informational messages if --verbose is specified, prefixed with
+  //! [INFO ].
+  static io::PrefixedOutStream Info;
+
+  //! Prints warning messages prefixed with [WARN ].
+  static io::PrefixedOutStream Warn;
+
+  //! Prints fatal messages prefixed with [FATAL], then terminates the program.
+  static io::PrefixedOutStream Fatal;
+
+  //! Reference to cout, if necessary.
+  static std::ostream& cout;
+};
+
+}; //namespace mlpack
+
+#endif

Copied: mlpack/trunk/src/mlpack/core/util/nulloutstream.hpp (from rev 10737, mlpack/trunk/src/mlpack/core/io/nulloutstream.hpp)
===================================================================
--- mlpack/trunk/src/mlpack/core/util/nulloutstream.hpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/core/util/nulloutstream.hpp	2011-12-14 12:44:53 UTC (rev 10774)
@@ -0,0 +1,80 @@
+/**
+ * @file nulloutstream.hpp
+ * @author Ryan Curtin
+ * @author Matthew Amidon
+ *
+ * Definition of the NullOutStream class.
+ */
+#ifndef __MLPACK_CORE_IO_NULLOUTSTREAM_HPP
+#define __MLPACK_CORE_IO_NULLOUTSTREAM_HPP
+
+#include <iostream>
+#include <streambuf>
+#include <string>
+
+namespace mlpack {
+namespace io {
+
+/**
+ * Used for Log::Debug when not compiled with debugging symbols.  This class
+ * does nothing and should be optimized out entirely by the compiler.
+ */
+class NullOutStream {
+ public:
+  /**
+   * Does nothing.
+   */
+  NullOutStream() { }
+
+  /**
+   * Does nothing.
+   */
+  NullOutStream(const NullOutStream& other) { }
+
+  //! Does nothing.
+  NullOutStream& operator<<(bool val) { return *this; }
+  //! Does nothing.
+  NullOutStream& operator<<(short val) { return *this; }
+  //! Does nothing.
+  NullOutStream& operator<<(unsigned short val) { return *this; }
+  //! Does nothing.
+  NullOutStream& operator<<(int val) { return *this; }
+  //! Does nothing.
+  NullOutStream& operator<<(unsigned int val) { return *this; }
+  //! Does nothing.
+  NullOutStream& operator<<(long val) { return *this; }
+  //! Does nothing.
+  NullOutStream& operator<<(unsigned long val) { return *this; }
+  //! Does nothing.
+  NullOutStream& operator<<(float val) { return *this; }
+  //! Does nothing.
+  NullOutStream& operator<<(double val) { return *this; }
+  //! Does nothing.
+  NullOutStream& operator<<(long double val) { return *this; }
+  //! Does nothing.
+  NullOutStream& operator<<(void* val) { return *this; }
+  //! Does nothing.
+  NullOutStream& operator<<(const char* str) { return *this; }
+  //! Does nothing.
+  NullOutStream& operator<<(std::string& str) { return *this; }
+  //! Does nothing.
+  NullOutStream& operator<<(std::streambuf* sb) { return *this; }
+  //! Does nothing.
+  NullOutStream& operator<<(std::ostream& (*pf) (std::ostream&))
+  { return *this; }
+  //! Does nothing.
+  NullOutStream& operator<<(std::ios& (*pf) (std::ios&)) { return *this; }
+  //! Does nothing.
+  NullOutStream& operator<<(std::ios_base& (*pf) (std::ios_base&))
+  { return *this; }
+
+  //! Does nothing.
+  template<typename T>
+  NullOutStream& operator<<(T s)
+  { return *this; }
+};
+
+} // namespace io
+} // namespace mlpack
+
+#endif

Copied: mlpack/trunk/src/mlpack/core/util/option.cpp (from rev 10737, mlpack/trunk/src/mlpack/core/io/option.cpp)
===================================================================
--- mlpack/trunk/src/mlpack/core/util/option.cpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/core/util/option.cpp	2011-12-14 12:44:53 UTC (rev 10774)
@@ -0,0 +1,34 @@
+/**
+ * @file option.cpp
+ * @author Ryan Curtin
+ *
+ * Implementation of the ProgramDoc class.  The class registers itself with CLI
+ * when constructed.
+ */
+#include "cli.hpp"
+#include "option.hpp"
+
+#include <string>
+
+using namespace mlpack;
+using namespace mlpack::io;
+using namespace std;
+
+/**
+ * Construct a ProgramDoc object.  When constructed, it will register itself
+ * with CLI.  A fatal error will be thrown if more than one is constructed.
+ *
+ * @param programName Short string representing the name of the program.
+ * @param documentation Long string containing documentation on how to use the
+ *    program and what it is.  No newline characters are necessary; this is
+ *    taken care of by CLI later.
+ * @param defaultModule Name of the default module.
+ */
+ProgramDoc::ProgramDoc(const std::string programName,
+                       const std::string documentation) :
+    programName(programName),
+    documentation(documentation)
+{
+  // Register this with CLI.
+  CLI::RegisterProgramDoc(this);
+}

Copied: mlpack/trunk/src/mlpack/core/util/option.hpp (from rev 10737, mlpack/trunk/src/mlpack/core/io/option.hpp)
===================================================================
--- mlpack/trunk/src/mlpack/core/util/option.hpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/core/util/option.hpp	2011-12-14 12:44:53 UTC (rev 10774)
@@ -0,0 +1,102 @@
+/**
+ * @file option.hpp
+ * @author Matthew Amidon
+ *
+ * Definition of the Option class, which is used to define parameters which are
+ * used by CLI.  The ProgramDoc class also resides here.
+ */
+#ifndef __MLPACK_CORE_IO_OPTION_HPP
+#define __MLPACK_CORE_IO_OPTION_HPP
+
+#include <string>
+
+#include "cli.hpp"
+
+namespace mlpack {
+namespace io {
+
+/**
+ * A static object whose constructor registers a parameter with the CLI class.
+ * This should not be used outside of CLI itself, and you should use the
+ * PARAM_FLAG(), PARAM_DOUBLE(), PARAM_INT(), PARAM_STRING(), or other similar
+ * macros to declare these objects instead of declaring them directly.
+ *
+ * @see core/io/cli.hpp, mlpack::CLI
+ */
+template<typename N>
+class Option
+{
+ public:
+  /**
+   * Construct an Option object.  When constructed, it will register
+   * itself with CLI.
+   *
+   * @param ignoreTemplate Whether or not the template type matters for this
+   *     option.  Essentially differs options with no value (flags) from those
+   *     that do, and thus require a type.
+   * @param defaultValue Default value this parameter will be initialized to.
+   * @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 required Whether or not the option is required at runtime.
+   */
+  Option(bool ignoreTemplate,
+         N defaultValue,
+         const char* identifier,
+         const char* description,
+         const char* parent = NULL,
+         bool required = false);
+
+  /**
+   * Constructs an Option object.  When constructed, it will register a flag
+   * with CLI.
+   *
+   * @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).
+   */
+  Option(const char* identifier,
+         const char* description,
+         const char* parent = NULL);
+};
+
+/**
+ * A static object whose constructor registers program documentation with the
+ * CLI class.  This should not be used outside of CLI itself, and you should use
+ * the PROGRAM_INFO() macro to declare these objects.  Only one ProgramDoc
+ * object should ever exist.
+ *
+ * @see core/io/cli.hpp, mlpack::CLI
+ */
+class ProgramDoc
+{
+ public:
+  /**
+   * Construct a ProgramDoc object.  When constructed, it will register itself
+   * with CLI.
+   *
+   * @param programName Short string representing the name of the program.
+   * @param documentation Long string containing documentation on how to use the
+   *     program and what it is.  No newline characters are necessary; this is
+   *     taken care of by CLI later.
+   */
+  ProgramDoc(const std::string programName,
+             const std::string documentation);
+
+  //! The name of the program.
+  std::string programName;
+  //! Documentation for what the program does.
+  std::string documentation;
+};
+
+}; // namespace io
+}; // namespace mlpack
+
+// For implementations of templated functions
+#include "option_impl.hpp"
+
+#endif

Copied: mlpack/trunk/src/mlpack/core/util/option_impl.hpp (from rev 10737, mlpack/trunk/src/mlpack/core/io/option_impl.hpp)
===================================================================
--- mlpack/trunk/src/mlpack/core/util/option_impl.hpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/core/util/option_impl.hpp	2011-12-14 12:44:53 UTC (rev 10774)
@@ -0,0 +1,63 @@
+/**
+ * @file option_impl.hpp
+ * @author Matthew Amidon
+ *
+ * Implementation of template functions for the Option class.
+ */
+#ifndef __MLPACK_CORE_IO_OPTION_IMPL_HPP
+#define __MLPACK_CORE_IO_OPTION_IMPL_HPP
+
+// Just in case it has not been included.
+#include "option.hpp"
+
+namespace mlpack {
+namespace io {
+
+/**
+ * Registers a parameter with CLI.
+ */
+template<typename N>
+Option<N>::Option(bool ignoreTemplate,
+                N defaultValue,
+                const char* identifier,
+                const char* description,
+                const char* alias,
+                bool required)
+{
+  if (ignoreTemplate)
+  {
+    if(alias == NULL)
+      alias = "";
+
+    CLI::Add(identifier, description, alias, required);
+  }
+  else
+  {
+    if(alias == NULL)
+      alias = "";
+
+    CLI::Add<N>(identifier, description, alias, required);
+
+    CLI::GetParam<N>(identifier) = defaultValue;
+  }
+}
+
+
+/**
+ * Registers a flag parameter with CLI.
+ */
+template<typename N>
+Option<N>::Option(const char* identifier,
+                  const char* description,
+                  const char* alias)
+{
+  if(alias == NULL)
+    alias = "";
+
+  CLI::AddFlag(identifier, description, alias);
+}
+
+}; // namespace io
+}; // namespace mlpack
+
+#endif

Copied: mlpack/trunk/src/mlpack/core/util/prefixedoutstream.cpp (from rev 10737, mlpack/trunk/src/mlpack/core/io/prefixedoutstream.cpp)
===================================================================
--- mlpack/trunk/src/mlpack/core/util/prefixedoutstream.cpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/core/util/prefixedoutstream.cpp	2011-12-14 12:44:53 UTC (rev 10774)
@@ -0,0 +1,127 @@
+/**
+ * @file prefixedoutstream.cpp
+ * @author Ryan Curtin
+ * @author Matthew Amidon
+ *
+ * Implementation of PrefixedOutStream methods.
+ */
+#include <string>
+#include <iostream>
+#include <streambuf>
+#include <string.h>
+#include <stdlib.h>
+
+#include "prefixedoutstream.hpp"
+
+using namespace mlpack::io;
+
+/**
+ * These are all necessary because gcc's template mechanism does not seem smart
+ * enough to figure out what I want to pass into operator<< without these.  That
+ * may not be the actual case, but it works when these is here.
+ */
+
+PrefixedOutStream& PrefixedOutStream::operator<<(bool val)
+{
+  BaseLogic<bool>(val);
+  return *this;
+}
+
+PrefixedOutStream& PrefixedOutStream::operator<<(short val)
+{
+  BaseLogic<short>(val);
+  return *this;
+}
+
+PrefixedOutStream& PrefixedOutStream::operator<<(unsigned short val)
+{
+ BaseLogic<unsigned short>(val);
+  return *this;
+}
+
+PrefixedOutStream& PrefixedOutStream::operator<<(int val)
+{
+  BaseLogic<int>(val);
+  return *this;
+}
+
+PrefixedOutStream& PrefixedOutStream::operator<<(unsigned int val)
+{
+  BaseLogic<unsigned int>(val);
+  return *this;
+}
+
+PrefixedOutStream& PrefixedOutStream::operator<<(long val)
+{
+  BaseLogic<long>(val);
+  return *this;
+}
+
+PrefixedOutStream& PrefixedOutStream::operator<<(unsigned long val)
+{
+  BaseLogic<unsigned long>(val);
+  return *this;
+}
+
+PrefixedOutStream& PrefixedOutStream::operator<<(float val)
+{
+  BaseLogic<float>(val);
+  return *this;
+}
+
+PrefixedOutStream& PrefixedOutStream::operator<<(double val)
+{
+  BaseLogic<double>(val);
+  return *this;
+}
+
+PrefixedOutStream& PrefixedOutStream::operator<<(long double val)
+{
+  BaseLogic<long double>(val);
+  return *this;
+}
+
+PrefixedOutStream& PrefixedOutStream::operator<<(void* val)
+{
+  BaseLogic<void*>(val);
+  return *this;
+}
+
+PrefixedOutStream& PrefixedOutStream::operator<<(const char* str)
+{
+  BaseLogic<const char*>(str);
+  return *this;
+}
+
+
+PrefixedOutStream& PrefixedOutStream::operator<<(std::string& str)
+{
+  BaseLogic<std::string&>(str);
+  return *this;
+}
+
+PrefixedOutStream& PrefixedOutStream::operator<<(std::streambuf* sb)
+{
+  BaseLogic<std::streambuf*>(sb);
+  return *this;
+}
+
+PrefixedOutStream& PrefixedOutStream::operator<<(
+    std::ostream& (*pf)(std::ostream&))
+{
+  BaseLogic<std::ostream& (*)(std::ostream&)>(pf);
+  return *this;
+}
+
+PrefixedOutStream& PrefixedOutStream::operator<<(std::ios& (*pf)(std::ios&))
+{
+  BaseLogic<std::ios& (*)(std::ios&)>(pf);
+  return *this;
+}
+
+PrefixedOutStream& PrefixedOutStream::operator<<(
+    std::ios_base& (*pf) (std::ios_base&))
+{
+  BaseLogic<std::ios_base& (*)(std::ios_base&)>(pf);
+  return *this;
+}

Copied: mlpack/trunk/src/mlpack/core/util/prefixedoutstream.hpp (from rev 10737, mlpack/trunk/src/mlpack/core/io/prefixedoutstream.hpp)
===================================================================
--- mlpack/trunk/src/mlpack/core/util/prefixedoutstream.hpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/core/util/prefixedoutstream.hpp	2011-12-14 12:44:53 UTC (rev 10774)
@@ -0,0 +1,147 @@
+/**
+ * @file prefixedoutstream.hpp
+ * @author Ryan Curtin
+ * @author Matthew Amidon
+ *
+ * Declaration of the PrefixedOutStream class.
+ */
+#ifndef __MLPACK_CORE_IO_PREFIXEDOUTSTREAM_HPP
+#define __MLPACK_CORE_IO_PREFIXEDOUTSTREAM_HPP
+
+#include <iostream>
+#include <iomanip>
+#include <string>
+#include <streambuf>
+
+#include <boost/lexical_cast.hpp>
+
+namespace mlpack {
+namespace io {
+
+/**
+ * Allows us to output to an ostream with a prefix at the beginning of each
+ * line, in the same way we would output to cout or cerr.  The prefix is
+ * specified in the constructor (as well as the destination ostream).  A newline
+ * must be passed to the stream, and then the prefix will be prepended to the
+ * next line.  For example,
+ *
+ * @code
+ * PrefixedOutStream outstr(std::cout, "[TEST] ");
+ * outstr << "Hello world I like " << 7.5;
+ * outstr << "...Continue" << std::endl;
+ * outstr << "After the CR\n" << std::endl;
+ * @endcode
+ *
+ * would give, on std::cout,
+ *
+ * @code
+ * [TEST] Hello world I like 7.5...Continue
+ * [TEST] After the CR
+ * [TEST]
+ * @endcode
+ *
+ * These objects are used for the mlpack::Log levels (DEBUG, INFO, WARN, and
+ * FATAL).
+ */
+class PrefixedOutStream
+{
+ public:
+  /**
+   * Set up the PrefixedOutStream.
+   *
+   * @param destination ostream which receives output from this object.
+   * @param prefix The prefix to prepend to each line.
+   */
+  PrefixedOutStream(std::ostream& destination,
+                    const char* prefix,
+                    bool ignoreInput = false,
+                    bool fatal = false) :
+      destination(destination),
+      ignoreInput(ignoreInput),
+      prefix(prefix),
+      // We want the first call to operator<< to prefix the prefix so we set
+      // carriageReturned to true.
+      carriageReturned(true),
+      fatal(fatal)
+    { /* nothing to do */ }
+
+  //! Write a bool to the stream.
+  PrefixedOutStream& operator<<(bool val);
+  //! Write a short to the stream.
+  PrefixedOutStream& operator<<(short val);
+  //! Write an unsigned short to the stream.
+  PrefixedOutStream& operator<<(unsigned short val);
+  //! Write an int to the stream.
+  PrefixedOutStream& operator<<(int val);
+  //! Write an unsigned int to the stream.
+  PrefixedOutStream& operator<<(unsigned int val);
+  //! Write a long to the stream.
+  PrefixedOutStream& operator<<(long val);
+  //! Write an unsigned long to the stream.
+  PrefixedOutStream& operator<<(unsigned long val);
+  //! Write a float to the stream.
+  PrefixedOutStream& operator<<(float val);
+  //! Write a double to the stream.
+  PrefixedOutStream& operator<<(double val);
+  //! Write a long double to the stream.
+  PrefixedOutStream& operator<<(long double val);
+  //! Write a void pointer to the stream.
+  PrefixedOutStream& operator<<(void* val);
+  //! Write a character array to the stream.
+  PrefixedOutStream& operator<<(const char* str);
+  //! Write a string to the stream.
+  PrefixedOutStream& operator<<(std::string& str);
+  //! Write a streambuf to the stream.
+  PrefixedOutStream& operator<<(std::streambuf* sb);
+  //! Write an ostream manipulator function to the stream.
+  PrefixedOutStream& operator<<(std::ostream& (*pf)(std::ostream&));
+  //! Write an ios manipulator function to the stream.
+  PrefixedOutStream& operator<<(std::ios& (*pf)(std::ios&));
+  //! Write an ios_base manipulator function to the stream.
+  PrefixedOutStream& operator<<(std::ios_base& (*pf)(std::ios_base&));
+
+  //! Write anything else to the stream.
+  template<typename T>
+  PrefixedOutStream& operator<<(T s);
+
+  //! The output stream that all data is to be sent too; example: std::cout.
+  std::ostream& destination;
+
+  //! Discards input, prints nothing if true.
+  bool ignoreInput;
+
+ private:
+  /**
+   * @brief Conducts the base logic required in all the operator << overloads.
+   *   Mostly just a good idea to reduce copy-pasta.
+   *
+   * @tparam T The type of the data to output.
+   * @param val The The data to be output.
+   */
+  template<typename T>
+  void BaseLogic(T val);
+
+  /**
+   * Output the prefix, but only if we need to and if we are allowed to.
+   */
+  inline void PrefixIfNeeded();
+
+  //! Contains the prefix we must prepend to each line.
+  std::string prefix;
+
+  //! If true, the previous call to operator<< encountered a CR, and a prefix
+  //! will be necessary.
+  bool carriageReturned;
+
+  //! If true, the application will terminate with an error code when a CR is
+  //! encountered.
+  bool fatal;
+};
+
+// Template definitions
+#include "prefixedoutstream_impl.hpp"
+
+} // namespace io
+} // namespace mlpack
+
+#endif

Copied: mlpack/trunk/src/mlpack/core/util/prefixedoutstream_impl.hpp (from rev 10737, mlpack/trunk/src/mlpack/core/io/prefixedoutstream_impl.hpp)
===================================================================
--- mlpack/trunk/src/mlpack/core/util/prefixedoutstream_impl.hpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/core/util/prefixedoutstream_impl.hpp	2011-12-14 12:44:53 UTC (rev 10774)
@@ -0,0 +1,107 @@
+/**
+ * @file prefixedoutstream.hpp
+ * @author Ryan Curtin
+ * @author Matthew Amidon
+ *
+ * Implementation of templated PrefixedOutStream member functions.
+ */
+#ifndef __MLPACK_CORE_IO_PREFIXEDOUTSTREAM_IMPL_HPP
+#define __MLPACK_CORE_IO_PREFIXEDOUTSTREAM_IMPL_HPP
+
+// Just in case it hasn't been included.
+#include "prefixedoutstream.hpp"
+
+template<typename T>
+PrefixedOutStream& PrefixedOutStream::operator<<(T s)
+{
+  BaseLogic<T>(s);
+
+  return *this;
+}
+
+template<typename T>
+void PrefixedOutStream::BaseLogic(T val)
+{
+  // We will use this to track whether or not we need to terminate at the end of
+  // this call (only for streams which terminate after a newline).
+  bool newlined = false;
+
+  // If we need to, output the prefix.
+  PrefixIfNeeded();
+
+  // Now we try to output the T (whatever it is).
+  try
+  {
+    std::string line = boost::lexical_cast<std::string>(val);
+
+    // If the length of the casted thing was 0, it may have been a stream
+    // manipulator, so send it directly to the stream and don't ask questions.
+    if (line.length() == 0)
+    {
+      // The prefix cannot be necessary at this point.
+      if (!ignoreInput) // Only if the user wants it.
+        destination << val;
+
+      return;
+    }
+
+    // Now, we need to check for newlines in this line.  If we find one, output
+    // up until the newline, then output the newline and the prefix and continue
+    // looking.
+    size_t nl;
+    size_t pos = 0;
+    while ((nl = line.find('\n', pos)) != std::string::npos)
+    {
+      PrefixIfNeeded();
+
+      // Only output if the user wants it.
+      if (!ignoreInput)
+      {
+        destination << line.substr(pos, nl - pos);
+        destination << std::endl;
+        newlined = true;
+      }
+
+      carriageReturned = true; // Regardless of whether or not we display it.
+
+      pos = nl + 1;
+    }
+
+    if (pos != line.length()) // We need to display the rest.
+    {
+      PrefixIfNeeded();
+      if (!ignoreInput)
+        destination << line.substr(pos);
+    }
+  }
+  catch (boost::bad_lexical_cast &e)
+  {
+    // Warn the user that there was a failure.
+    PrefixIfNeeded();
+    if (!ignoreInput)
+    {
+      destination << "Failed lexical_cast<std::string>(T) for output; output"
+          " not shown." << std::endl;
+      newlined = true;
+    }
+  }
+
+  // If we displayed a newline and we need to terminate afterwards, do that.
+  if (fatal && newlined)
+    exit(1);
+}
+
+// This is an inline function (that is why it is here and not in .cc).
+void PrefixedOutStream::PrefixIfNeeded()
+{
+  // If we need to, output a prefix.
+  if (carriageReturned)
+  {
+    if (!ignoreInput) // But only if we are allowed to.
+      destination << prefix;
+
+    carriageReturned = false; // Denote that the prefix has been displayed.
+  }
+}
+
+#endif // MLPACK_CLI_PREFIXEDOUTSTREAM_IMPL_H

Modified: mlpack/trunk/src/mlpack/core/util/save_restore_utility.hpp
===================================================================
--- mlpack/trunk/src/mlpack/core/utilities/save_restore_utility.hpp	2011-12-13 07:23:09 UTC (rev 10737)
+++ mlpack/trunk/src/mlpack/core/util/save_restore_utility.hpp	2011-12-14 12:44:53 UTC (rev 10774)
@@ -32,62 +32,76 @@
    * parameters contains a list of names and parameters in string form.
    */
   std::map<std::string, std::string> parameters;
+
   /**
    * RecurseOnNodes performs a depth first search of the XML tree.
    */
   void RecurseOnNodes(xmlNode* n);
+
  public:
   SaveRestoreUtility() {}
   ~SaveRestoreUtility() { parameters.clear(); }
+
   /**
    * ReadFile reads an XML tree from a file.
    */
   bool ReadFile(std::string filename);
+
   /**
    * WriteFile writes the XML tree to a file.
    */
   bool WriteFile(std::string filename);
+
   /**
    * LoadParameter loads a parameter from the parameters map.
    */
   template<typename T>
   T& LoadParameter(T& t, std::string name);
+
   /**
    * LoadParameter loads a parameter from the parameters map.
    */
   template<typename T>
   std::vector<T>& LoadParameter(std::vector<T>& v, std::string name);
+
   /**
    * LoadParameter loads a character from the parameters map.
    */
   char LoadParameter(char c, std::string name);
+
   /**
    * LoadParameter loads a string from the parameters map.
    */
   std::string LoadParameter(std::string str, std::string name);
+
   /**
    * LoadParameter loads an arma::mat from the parameters map.
    */
   arma::mat& LoadParameter(arma::mat& matrix, std::string name);
+
   /**
    * SaveParameter saves a parameter to the parameters map.
    */
   template<typename T>
   void SaveParameter(T& t, std::string name);
+
   /**
    * SaveParameter saves a parameter to the parameters map.
    */
   template<typename T>
   void SaveParameter(std::vector<T>& v, std::string name);
+
   /**
    * SaveParameter saves a character to the parameters map.
    */
   void SaveParameter(char c, std::string name);
+
   /**
    * SaveParameter saves an arma::mat to the parameters map.
    */
   void SaveParameter(arma::mat& mat, std::string name);
 };
+
 } /* namespace utilities */
 } /* namespace mlpack */
 

Deleted: mlpack/trunk/src/mlpack/core/util/timers.cpp
===================================================================
--- mlpack/trunk/src/mlpack/core/utilities/timers.cpp	2011-12-13 07:23:09 UTC (rev 10737)
+++ mlpack/trunk/src/mlpack/core/util/timers.cpp	2011-12-14 12:44:53 UTC (rev 10774)
@@ -1,134 +0,0 @@
-/**
- * @file timers.cpp
- * @author Matthew Amidon
- *
- * Implementation of timers.
- */
-#include "timers.hpp"
-#include "../io/cli.hpp"
-#include "../io/log.hpp"
-
-#include <map>
-#include <string>
-
-using namespace mlpack;
-
-std::map<std::string, timeval> Timers::timers;
-
-std::map<std::string, timeval> Timers::GetAllTimers()
-{
-  return timers;
-}
-
-timeval Timers::GetTimer(const char* timerName)
-{
-  std::string name(timerName);
-  return timers[name];
-}
-
-void Timers::PrintTimer(const char* timerName)
-{
-  std::string name=timerName;
-  timeval& t = timers[name];
-  Log::Info << t.tv_sec << "." << std::setw(6) << std::setfill('0')
-      << t.tv_usec << "s";
-
-  // Also output convenient day/hr/min/sec.
-  int days = t.tv_sec / 86400; // Integer division rounds down.
-  int hours = (t.tv_sec % 86400) / 3600;
-  int minutes = (t.tv_sec % 3600) / 60;
-  int seconds = (t.tv_sec % 60);
-  // No output if it didn't even take a minute.
-  if (!(days == 0 && hours == 0 && minutes == 0))
-  {
-    bool output = false; // Denotes if we have output anything yet.
-    Log::Info << " (";
-
-    // Only output units if they have nonzero values (yes, a bit tedious).
-    if (days > 0)
-    {
-      Log::Info << days << " days";
-      output = true;
-    }
-
-    if (hours > 0)
-    {
-      if (output)
-        Log::Info << ", ";
-      Log::Info << hours << " hrs";
-      output = true;
-    }
-
-    if (minutes > 0)
-    {
-      if (output)
-        Log::Info << ", ";
-      Log::Info << minutes << " mins";
-      output = true;
-    }
-
-    if (seconds > 0)
-    {
-      if (output)
-        Log::Info << ",";
-      Log::Info << seconds << "." << std::setw(1) << (t.tv_usec / 100000) <<
-          "secs";
-      output = true;
-    }
-
-    Log::Info << ")";
-  }
-
-  Log::Info << std::endl;
-}
-
-void Timers::StartTimer(const char* timerName)
-{
-  // Convert the name to std::string.
-  std::string name(timerName);
-  timeval tmp;
-
-  tmp.tv_sec = 0;
-  tmp.tv_usec = 0;
-
-#ifndef _WIN32
-  gettimeofday(&tmp, NULL);
-#else
-  FileTimeToTimeVal(&tmp);
-#endif
-  timers[name] = tmp;
-}
-
-void Timers::StopTimer(const char* timerName)
-{
-  std::string name(timerName);
-  timeval delta, b, a = timers[name];
-
-#ifndef _WIN32
-  gettimeofday(&b, NULL);
-#else
-  FileTimeToTimeVal(&b);
-#endif
-  // Calculate the delta time.
-  timersub(&b, &a, &delta);
-  timers[name] = delta;
-}
-
-#ifdef _WIN32
-void Timers::FileTimeToTimeVal(timeval* tv)
-{
-  FILETIME ftime;
-  uint64_t ptime = 0;
-  // Acquire the file time.
-  GetSystemTimeAsFileTime(&ftime);
-  // Now convert FILETIME to timeval.
-  ptime |= ftime.dwHighDateTime;
-  ptime = ptime << 32;
-  ptime |= ftime.dwLowDateTime;
-  ptime /= 10;
-  ptime -= DELTA_EPOC_IN_MICROSECONDS;
-
-  tv.tv_sec = (long) (ptime / 1000000UL);
-  tv.tv_usec = (long) (ptime % 1000000UL);
-}
-#endif // _WIN32

Copied: mlpack/trunk/src/mlpack/core/util/timers.cpp (from rev 10767, mlpack/trunk/src/mlpack/core/io/timers.cpp)
===================================================================
--- mlpack/trunk/src/mlpack/core/util/timers.cpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/core/util/timers.cpp	2011-12-14 12:44:53 UTC (rev 10774)
@@ -0,0 +1,153 @@
+/**
+ * @file timers.cpp
+ * @author Matthew Amidon
+ *
+ * Implementation of timers.
+ */
+#include "timers.hpp"
+#include "cli.hpp"
+#include "log.hpp"
+
+#include <map>
+#include <string>
+
+using namespace mlpack;
+
+/**
+ * Start the given timer.
+ */
+void Timer::Start(const std::string name)
+{
+  CLI::GetSingleton().timer.StartTimer(name);
+}
+
+/**
+ * Stop the given timer.
+ */
+void Timer::Stop(const std::string name)
+{
+  CLI::GetSingleton().timer.StopTimer(name);
+}
+
+/**
+ * Get the given timer.
+ */
+timeval Timer::Get(const std::string name)
+{
+  return CLI::GetSingleton().timer.GetTimer(name);
+}
+
+std::map<std::string, timeval>& Timers::GetAllTimers()
+{
+  return timers;
+}
+
+timeval Timers::GetTimer(const std::string timerName)
+{
+  std::string name(timerName);
+  return timers[name];
+}
+
+void Timers::PrintTimer(const std::string timerName)
+{
+  timeval& t = timers[timerName];
+  Log::Info << t.tv_sec << "." << std::setw(6) << std::setfill('0')
+      << t.tv_usec << "s";
+
+  // Also output convenient day/hr/min/sec.
+  int days = t.tv_sec / 86400; // Integer division rounds down.
+  int hours = (t.tv_sec % 86400) / 3600;
+  int minutes = (t.tv_sec % 3600) / 60;
+  int seconds = (t.tv_sec % 60);
+  // No output if it didn't even take a minute.
+  if (!(days == 0 && hours == 0 && minutes == 0))
+  {
+    bool output = false; // Denotes if we have output anything yet.
+    Log::Info << " (";
+
+    // Only output units if they have nonzero values (yes, a bit tedious).
+    if (days > 0)
+    {
+      Log::Info << days << " days";
+      output = true;
+    }
+
+    if (hours > 0)
+    {
+      if (output)
+        Log::Info << ", ";
+      Log::Info << hours << " hrs";
+      output = true;
+    }
+
+    if (minutes > 0)
+    {
+      if (output)
+        Log::Info << ", ";
+      Log::Info << minutes << " mins";
+      output = true;
+    }
+
+    if (seconds > 0)
+    {
+      if (output)
+        Log::Info << ",";
+      Log::Info << seconds << "." << std::setw(1) << (t.tv_usec / 100000) <<
+          "secs";
+      output = true;
+    }
+
+    Log::Info << ")";
+  }
+
+  Log::Info << std::endl;
+}
+
+void Timers::StartTimer(const std::string timerName)
+{
+  timeval tmp;
+
+  tmp.tv_sec = 0;
+  tmp.tv_usec = 0;
+
+#ifndef _WIN32
+  gettimeofday(&tmp, NULL);
+#else
+  FileTimeToTimeVal(&tmp);
+#endif
+  timers[timerName] = tmp;
+}
+
+void Timers::StopTimer(const std::string timerName)
+{
+  timeval delta, b, a = timers[timerName];
+
+#ifndef _WIN32
+  gettimeofday(&b, NULL);
+#else
+  FileTimeToTimeVal(&b);
+#endif
+  // Calculate the delta time.
+  timersub(&b, &a, &delta);
+  timers[timerName] = delta;
+}
+
+#ifdef _WIN32
+void Timers::FileTimeToTimeVal(timeval* tv)
+{
+  FILETIME ftime;
+  uint64_t ptime = 0;
+  // Acquire the file time.
+  GetSystemTimeAsFileTime(&ftime);
+  // Now convert FILETIME to timeval.
+  ptime |= ftime.dwHighDateTime;
+  ptime = ptime << 32;
+  ptime |= ftime.dwLowDateTime;
+  ptime /= 10;
+  ptime -= DELTA_EPOC_IN_MICROSECONDS;
+
+  tv.tv_sec = (long) (ptime / 1000000UL);
+  tv.tv_usec = (long) (ptime % 1000000UL);
+}
+
+#endif // _WIN32

Deleted: mlpack/trunk/src/mlpack/core/util/timers.hpp
===================================================================
--- mlpack/trunk/src/mlpack/core/utilities/timers.hpp	2011-12-13 07:23:09 UTC (rev 10737)
+++ mlpack/trunk/src/mlpack/core/util/timers.hpp	2011-12-14 12:44:53 UTC (rev 10774)
@@ -1,79 +0,0 @@
-/**
- * @file timers.hpp
- * @author Matthew Amidon
- *
- * Timers for MLPACK.
- */
-#ifndef __MLPACK_CORE_UTILITIES_TIMERS_HPP
-#define __MLPACK_CORE_UTILITIES_TIMERS_HPP
-
-#include <map>
-#include <string>
-
-#ifndef _WIN32
-  #include <sys/time.h> //linux
-#else
-  #include <winsock.h> //timeval on windows
-  #include <windows.h> //GetSystemTimeAsFileTime on windows
-//gettimeofday has no equivalent will need to write extra code for that.
-  #if defined(_MSC_VER) || defined(_MSC_EXTENSCLINS)
-    #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
-  #else
-    #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
-  #endif
-#endif //_WIN32
-
-namespace mlpack {
-
-class Timers
-{
- public:
-  /**
-   * Returns a copy of all the timers used via this interface.
-   */
-  static std::map<std::string, timeval> GetAllTimers();
-
-  /**
-   * Returns a copy of the timer specified.
-   *
-   * @param timerName The name of the timer in question.
-   */
-  static timeval GetTimer(const char* timerName);
-
-  /**
-   * Prints the specified timer.  If it took longer than a minute to complete
-   * the timer will be displayed in days, hours, and minutes as well.
-   *
-   * @param timerName The name of the timer in question.
-   */
-  static void PrintTimer(const char* timerName);
-
-  /**
-   * Initializes a timer, available like a normal value specified on
-   * the command line.  Timers are of type timval
-   *
-   * @param timerName The name of the timer in question.
-   */
-  static void StartTimer(const char* timerName);
-
-  /**
-   * Halts the timer, and replaces it's value with
-   * the delta time from it's start
-   *
-   * @param timerName The name of the timer in question.
-   */
-  static void StopTimer(const char* timerName);
-
- private:
-  static std::map<std::string, timeval> timers;
-
-  void FileTimeToTimeVal(timeval* tv);
-
-  // Don't want any instances floating around.
-  Timers();
-  ~Timers();
-};
-
-}; // namespace mlpack
-
-#endif // __MLPACK_CORE_UTILITIES_TIMERS_HPP

Copied: mlpack/trunk/src/mlpack/core/util/timers.hpp (from rev 10767, mlpack/trunk/src/mlpack/core/io/timers.hpp)
===================================================================
--- mlpack/trunk/src/mlpack/core/util/timers.hpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/core/util/timers.hpp	2011-12-14 12:44:53 UTC (rev 10774)
@@ -0,0 +1,104 @@
+/**
+ * @file timers.hpp
+ * @author Matthew Amidon
+ *
+ * Timers for MLPACK.
+ */
+#ifndef __MLPACK_CORE_UTILITIES_TIMERS_HPP
+#define __MLPACK_CORE_UTILITIES_TIMERS_HPP
+
+#include <map>
+#include <string>
+
+#ifndef _WIN32
+  #include <sys/time.h> //linux
+#else
+  #include <winsock.h> //timeval on windows
+  #include <windows.h> //GetSystemTimeAsFileTime on windows
+//gettimeofday has no equivalent will need to write extra code for that.
+  #if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
+    #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
+  #else
+    #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
+  #endif
+#endif //_WIN32
+
+namespace mlpack {
+
+class Timers
+{
+ public:
+  //! Nothing to do for the constructor.
+  Timers() { }
+
+  /**
+   * Returns a copy of all the timers used via this interface.
+   */
+  std::map<std::string, timeval>& GetAllTimers();
+
+  /**
+   * Returns a copy of the timer specified.
+   *
+   * @param timerName The name of the timer in question.
+   */
+  timeval GetTimer(const std::string timerName);
+
+  /**
+   * Prints the specified timer.  If it took longer than a minute to complete
+   * the timer will be displayed in days, hours, and minutes as well.
+   *
+   * @param timerName The name of the timer in question.
+   */
+  void PrintTimer(const std::string timerName);
+
+  /**
+   * Initializes a timer, available like a normal value specified on
+   * the command line.  Timers are of type timval
+   *
+   * @param timerName The name of the timer in question.
+   */
+  void StartTimer(const std::string timerName);
+
+  /**
+   * Halts the timer, and replaces it's value with
+   * the delta time from it's start
+   *
+   * @param timerName The name of the timer in question.
+   */
+  void StopTimer(const std::string timerName);
+
+ private:
+  std::map<std::string, timeval> timers;
+
+  void FileTimeToTimeVal(timeval* tv);
+};
+
+// Static access methods.
+class Timer
+{
+ public:
+  /**
+   * Start the given timer.
+   *
+   * @param name Name of timer to be started.
+   */
+  static void Start(const std::string name);
+
+  /**
+   * Stop the given timer.
+   *
+   * @param name Name of timer to be stopped.
+   */
+  static void Stop(const std::string name);
+
+  /**
+   * Get the value of the given timer.
+   *
+   * @param name Name of timer to return value of.
+   */
+  static timeval Get(const std::string name);
+};
+
+}; // namespace mlpack
+
+#endif // __MLPACK_CORE_UTILITIES_TIMERS_HPP

Modified: mlpack/trunk/src/mlpack/core.hpp
===================================================================
--- mlpack/trunk/src/mlpack/core.hpp	2011-12-14 12:41:57 UTC (rev 10773)
+++ mlpack/trunk/src/mlpack/core.hpp	2011-12-14 12:44:53 UTC (rev 10774)
@@ -88,12 +88,12 @@
 
 // Now MLPACK-specific includes.
 #include <mlpack/core/arma_extend/arma_extend.hpp> // Includes Armadillo.
-#include <mlpack/core/io/log.hpp>
-#include <mlpack/core/io/cli.hpp>
+#include <mlpack/core/util/log.hpp>
+#include <mlpack/core/util/cli.hpp>
 #include <mlpack/core/data/load.hpp>
 #include <mlpack/core/data/save.hpp>
 #include <mlpack/core/math/math_misc.hpp>
 #include <mlpack/core/math/range.hpp>
-#include <mlpack/core/utilities/save_restore_utility.hpp>
+#include <mlpack/core/util/save_restore_utility.hpp>
 
 #endif

Modified: mlpack/trunk/src/mlpack/methods/gmm/gmm_main.cpp
===================================================================
--- mlpack/trunk/src/mlpack/methods/gmm/gmm_main.cpp	2011-12-14 12:41:57 UTC (rev 10773)
+++ mlpack/trunk/src/mlpack/methods/gmm/gmm_main.cpp	2011-12-14 12:44:53 UTC (rev 10774)
@@ -13,6 +13,8 @@
 PARAM_STRING_REQ("data", "A file containing the data on which the model has to "
     "be fit.", "D");
 PARAM_INT("gaussians", "g", "G", 1);
+PARAM_STRING("output_file", "The file to write the trained GMM parameters into "
+    "(as XML).", "gmm.xml");
 
 using namespace mlpack;
 using namespace mlpack::gmm;
@@ -33,6 +35,8 @@
   Timer::Stop("em");
 
   ////// OUTPUT RESULTS //////
+  
+
   // We need a better solution for this.  So, currently, we do nothing.
   // XML is probably the right tool for the job.
 }

Modified: mlpack/trunk/src/mlpack/tests/save_restore_utility_test.cpp
===================================================================
--- mlpack/trunk/src/mlpack/tests/save_restore_utility_test.cpp	2011-12-14 12:41:57 UTC (rev 10773)
+++ mlpack/trunk/src/mlpack/tests/save_restore_utility_test.cpp	2011-12-14 12:44:53 UTC (rev 10774)
@@ -4,7 +4,7 @@
  *
  * Here we have tests for the SaveRestoreModel class.
  */
-#include <mlpack/core/utilities/save_restore_utility.hpp>
+#include <mlpack/core/util/save_restore_utility.hpp>
 
 #include <boost/test/unit_test.hpp>
 




More information about the mlpack-svn mailing list