// file: $isip/class/stat/SupportVectorModel/svm_07.cc
// version: $Id: svm_07.cc 8764 2002-10-26 19:45:56Z jelinek $
//

// isip include files
//
#include "SupportVectorModel.h"

// method: setMode
//
// arguments:
//  MODE arg: (input) mode to set
//
// return: a boolean value indicating status
//
// this method sets the computation mode and sets the initialization flag.
//
boolean SupportVectorModel::setMode(MODE arg_a) {

  // mode: PRECOMPUTE and prior mode is NONE
  //  we must initialize
  //
  if ((arg_a == PRECOMPUTE) && (mode_d == NONE)) {
    mode_d = PRECOMPUTE;
    is_valid_d = false;
  }

  // mode: PRECOMPUTE and prior mode is PRECOMPUTE
  //  or NONE and prior mode is NONE
  //  leave the state unchanged. we still might need to initialize
  //  if is_valid_d was false.
  //  note: it does not have to work in all cases
  //

  // mode: NONE and prior mode is PRECOMPUTE
  // 
  else if ((arg_a == NONE) && (mode_d == PRECOMPUTE)) {
    mode_d = arg_a;
  }

  // exit gracefully
  //
  return true;
}

// method: init
//
// arguments: none
//
// return: a boolean value indicating status
//
// this method checks the initial status
//
boolean SupportVectorModel::init() {

  // if we are not in the precompute mode, we don't need to do anything.
  //
  if (mode_d != PRECOMPUTE) {
    is_valid_d = true;
    return true;
  }

  // if the data are valid, we also don't need to do anything.
  // note: it does not have to work in all cases
  //
  else if (is_valid_d) {
    return true;
  }

  // check the arguments
  //
  long len_sv = support_vectors_d.length();
  long len_alphas = alphas_d.length();

  if ((len_sv != len_alphas) || (len_sv <= 0)) {
    is_valid_d = false;
    return false;
  }
       
  // exit gracefully
  //
  return (is_valid_d = true);
}


// method: setNumSupportVectors
//
// arguments:
//  long num: (input) number of support vectors
//  ALGORITHM algo: (input) single or multiple kernel algorithm
//
// return: a boolean value indicating status
//
// this method sets the number of support vectors
//
boolean SupportVectorModel::setNumSupportVectors(long num_a,
						 ALGORITHM algo_a) {

  support_vectors_d.setLength(num_a);
  alphas_d.setLength(num_a);

  // initialize all weight to have the same value
  //
  float equal_weight = 1.0 / num_a;
  for (long i = 0; i < num_a; i++) {
    alphas_d(i) = equal_weight;
  }
  
  // set the number of kernels depending on algorithm
  //
  if (algo_a == SINGLE_KERNEL) {
    
    // for SINGLE_KERNEL algorithm set up only one kernel
    //
    kernels_d.setLength(1);
    kernels_d(0).setAlgorithm(Kernel::RBF);
  }

  // for MULTI_KERNEL algorithm set up all the kernels
  //
  else if (algo_a == MULTIPLE_KERNEL) {
    
    // initialize all kernels to be RBF
    //
    kernels_d.setLength(num_a);
    for (long i = 0; i < num_a; i++) {
      kernels_d(i).setAlgorithm(Kernel::RBF);
    }
  }
  else {
    return Error::handle(name(), L"setNumSupportVectors",
			 Error::NOT_IMPLEM, __FILE__, __LINE__);
  }
  
  // exit gracefully
  //
  return true;
}

