// file: $isip/util/speech/isip_svm_learn/isip_svm_learn.cc
//
// isip include files
//
#include "isip_svm_learn.h"

// isip_svm_learn: computes the distance of the feature from the hyperplain
//
int main(int argc, const char** argv) {

  // setup the command line
  //
  Sdb sdb;
  CommandLine cmdl(sdb);
  cmdl.setUsage(
#include "usage_message.text"
                );
  cmdl.setHelp(
#include "help_message.text"
               );

  cmdl.setIdent("$Revision: 10625 $",
		"$Name: $",
		"$Date: 2006-08-24 11:05:28 -0500 (Thu, 24 Aug 2006) $");
  
  // add a command line option for the parameters file
  //
  Filename params_file;
  cmdl.addOptionParam(params_file, OPTION_PARAMS_FILE, (Filename)EMPTY);
  
  // add a command line option for the positive example list
  //
  Filename pos_example_list;
  cmdl.addOptionParam(pos_example_list, OPTION_POS_EXAMPLE_LIST, (Filename)EMPTY);

  // add a command line option for the negative example list
  //
  Filename neg_example_list;
  cmdl.addOptionParam(neg_example_list, OPTION_NEG_EXAMPLE_LIST, (Filename)EMPTY);    
  
  // add a command line option for the penalty
  //
  Float penalty;
  cmdl.addOptionParam(penalty, OPTION_PENALTY, SupportVectorMachine::DEF_PENALTY);

  // add a command line option for the tolerance
  //
  Float tolerance;
  cmdl.addOptionParam(tolerance, OPTION_TOLERANCE, SupportVectorMachine::DEF_TOLERANCE);

  // add a command line option for the epsilon
  //
  Float epsilon;
  cmdl.addOptionParam(epsilon, OPTION_EPSILON, SupportVectorMachine::DEF_EPSILON);

  // add a command line option for the gamma
  //
  Float gamma;
  cmdl.addOptionParam(gamma, OPTION_RBF_GAMMA, SupportVectorMachine::DEF_RBF_GAMMA);

  // add a command line option for the kappa
  //
  Float kappa;
  cmdl.addOptionParam(kappa, OPTION_SIGMOID_KAPPA, SupportVectorMachine::DEF_SIGMOID_KAPPA);

  // add a command line option for the delta
  //
  Float delta;
  cmdl.addOptionParam(delta, OPTION_SIGMOID_DELTA, SupportVectorMachine::DEF_SIGMOID_DELTA);

  // add a command line option for the degree
  //
  Float degree;
  cmdl.addOptionParam(degree, OPTION_POLYNOMIAL_DEGREE, SupportVectorMachine::DEF_POLYNOMIAL_DEGREE);
  
  // add a command line option for the debug level
  //
  DebugLevel debug_level;
  cmdl.addOptionParam(debug_level, OPTION_DEBUG_LEVEL,
		      DEBUG_LEVEL_DEFAULT);

  // add a command line option for the log verbosity level
  //
  DebugLevel verbosity;
  cmdl.addOptionParam(verbosity, OPTION_VERBOSITY_LEVEL,
		      VERBOSITY_LEVEL_DEFAULT);

  // add a command line option for the log file
  //
  Filename log_file;
  cmdl.addOptionParam(log_file, OPTION_LOG_FILE, (Filename)LOG_FILE_DEFAULT);
  
  // parse the command line
  //
  if (!cmdl.parse(argc, argv)) {
    cmdl.printUsage();
  };

  // open the log file
  //
  if (log_file.ne(L"-")) {
    Console::open(log_file);
    Console::setLineWrap(File::NO_WRAP);
  }

  // print the command line
  //
  if (verbosity >= Integral::BRIEF) {
    cmdl.printCommandLine();
    cmdl.printVersion();
  }

  // check the parameter file argument
  //
  if(params_file.eq((Filename)EMPTY)) {
    cmdl.printUsage();
  };

  // check the positive examples list
  //
  if(pos_example_list.eq((Filename)EMPTY)) {
    cmdl.printUsage();
  };

  // check the negative examples list
  //
  if(neg_example_list.eq((Filename)EMPTY)) {
    cmdl.printUsage();
  };    

  // declare local variables
  //
  String output;
  SupportVectorMachine svm;
  
  // open the positive examples file
  //  
  Sof pos_sof;
  if (!pos_sof.open(pos_example_list, File::READ_ONLY)) {
    output.assign(L"\ncannot open file: ");
    output.concat(pos_example_list);
    output.concat(L", bailing out...");
    Console::put(output);
    Integral::exit();
  }

  // read the list of positive examples
  //
  Sdb pos_sdb;
  if (!pos_sdb.read(pos_sof, (long)0)) {
    output.assign(L"\ncannot read file: ");
    output.concat(pos_example_list);
    output.concat(L", bailing out...");
    Console::put(output);
    Integral::exit();
  }
  
  // open the negative examples file
  //  
  Sof neg_sof;
  if (!neg_sof.open(neg_example_list, File::READ_ONLY)) {
    output.assign(L"\ncannot open file: ");
    output.concat(neg_example_list);
    output.concat(L", bailing out...");
    Console::put(output);
    Integral::exit();
  }

  // read the list of positive examples
  //
  Sdb neg_sdb;
  if (!neg_sdb.read(neg_sof, (long)0)) {
    output.assign(L"\ncannot read file: ");
    output.concat(neg_example_list);
    output.concat(L", bailing out...");
    Console::put(output);
    Integral::exit();
  }

  // open the support vector parameter file
  //  
  if (verbosity >= Integral::BRIEF) {
    Console::increaseIndention();    
    output.assign(L"\nloading parameter file: ");
    output.concat(params_file);
    Console::put(output);
    Console::decreaseIndention();    
  }
  
  Sof param_sof;
  if (!param_sof.open(params_file, File::READ_ONLY)) {
    output.assign(L"\ncannot open file: ");
    output.concat(params_file);
    output.concat(L", bailing out...");
    Console::put(output);
    Integral::exit();
  }

  // read the support vector parameters
  //      
  if (!svm.read(param_sof, (long)0)) {
    output.assign(L"\nerror reading parameter file: ");
    output.concat(params_file);
    output.concat(L", bailing out...");
    Console::put(output);
    Integral::exit();    
  }

  // overide the support vector machine parameters
  //
  svm.setVerbosity(verbosity);
  svm.setPenalty(penalty);
  svm.setTolerance(tolerance);
  svm.setEpsilon(epsilon);
  svm.setGamma(gamma);
  svm.setKappa(kappa);
  svm.setDelta(delta);
  svm.setDegree(degree);
  
  // load the features from file
  //
  svm.loadFeatures(pos_sdb, neg_sdb);
    
  // start training
  //
  svm.train();
  
  // write the support vector model
  //
  svm.writeModel();
  
  // close the file descriptor(s)
  //
  pos_sof.close();
  neg_sof.close();  
  param_sof.close();
  
  // close the log file
  //
  if (log_file.ne(L"-")) {
    Console::close();
  }

  // exit gracefully
  //
  return Integral::exit();
}
