Ejemplo n.º 1
0
ArgSplitter& ArgSplitter::putRawArgs(const char* argv) {
	strcpy(rawArgs_, argv);
	args_ = arg_split(argv);
	return *this;
} // putRawArgs
void
mexFunction (int nout, mxArray ** out, int nin, mxArray const ** in)
{
  SAMPLE sample;  /* training sample */
  LEARN_PARM learn_parm;
  KERNEL_PARM kernel_parm;
  STRUCT_LEARN_PARM struct_parm;
  STRUCTMODEL structmodel;
  int alg_type;

  enum {IN_ARGS=0, IN_SPARM} ;
  enum {OUT_W=0} ;

  /* SVM-light is not fully reentrant, so we need to run this patch first */
  init_qp_solver() ;
  verbosity = 0 ;
  kernel_cache_statistic = 0 ;

  if (nin != 2) {
    mexErrMsgTxt("Two arguments required") ;
  }

  /* Parse ARGS  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  char arg [1024 + 1] ;
  int argc ;
  char ** argv ;

  if (! uIsString(in[IN_ARGS], -1)) {
    mexErrMsgTxt("ARGS must be a string") ;
  }

  mxGetString(in[IN_ARGS], arg, sizeof(arg) / sizeof(char)) ;
  arg_split (arg, &argc, &argv) ;

  svm_struct_learn_api_init(argc+1, argv-1) ;

  read_input_parameters (argc+1,argv-1,
                         &verbosity, &struct_verbosity,
                         &struct_parm, &learn_parm,
                         &kernel_parm, &alg_type ) ;
  
  if (kernel_parm.kernel_type != LINEAR &&
      kernel_parm.kernel_type != CUSTOM) {
    mexErrMsgTxt ("Only LINEAR or CUSTOM kerneles are supported") ;
  }

  /* Parse SPARM ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  mxArray const * sparm_array = in [IN_SPARM] ;
  mxArray const * patterns_array ;
  mxArray const * labels_array ;
  mxArray const * kernelFn_array ;
  int numExamples, ei ;

  if (! sparm_array) {
    mexErrMsgTxt("SPARM must be a structure") ;
  }
  struct_parm.mex = sparm_array ;

  patterns_array = mxGetField(sparm_array, 0, "patterns") ;
  if (! patterns_array ||
      ! mxIsCell(patterns_array)) {
    mexErrMsgTxt("SPARM.PATTERNS must be a cell array") ;
  }

  numExamples = mxGetNumberOfElements(patterns_array) ;

  labels_array = mxGetField(sparm_array, 0, "labels") ;
  if (! labels_array ||
      ! mxIsCell(labels_array) ||
      ! mxGetNumberOfElements(labels_array) == numExamples) {
    mexErrMsgTxt("SPARM.LABELS must be a cell array "
                 "with the same number of elements of "
                 "SPARM.PATTERNS") ;
  }

  sample.n = numExamples ;
  sample.examples = (EXAMPLE *) my_malloc (sizeof(EXAMPLE) * numExamples) ;
  for (ei = 0 ; ei < numExamples ; ++ ei) {
    sample.examples[ei].x.mex = mxGetCell(patterns_array, ei) ;
    sample.examples[ei].y.mex = mxGetCell(labels_array,   ei) ;
    sample.examples[ei].y.isOwner = 0 ;
  }

  if (struct_verbosity >= 1) {
    mexPrintf("There are %d training examples\n", numExamples) ;
  }

  kernelFn_array = mxGetField(sparm_array, 0, "kernelFn") ;
  if (! kernelFn_array && kernel_parm.kernel_type == CUSTOM) {
    mexErrMsgTxt("SPARM.KERNELFN must be define for CUSTOM kernels") ;
  }
  if (kernelFn_array) {
    MexKernelInfo * info ;
    if (mxGetClassID(kernelFn_array) != mxFUNCTION_CLASS) {
      mexErrMsgTxt("SPARM.KERNELFN must be a valid function handle") ;
    }
    info = (MexKernelInfo*) kernel_parm.custom ;
    info -> structParm = sparm_array ;
    info -> kernelFn   = kernelFn_array ;
  }

  /* Learning  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  switch (alg_type) {
  case 0:
    svm_learn_struct(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,NSLACK_ALG) ;
    break ;
  case 1:
    svm_learn_struct(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,NSLACK_SHRINK_ALG);
    break ;
  case 2:
    svm_learn_struct_joint(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,ONESLACK_PRIMAL_ALG);
    break ;
  case 3:
    svm_learn_struct_joint(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,ONESLACK_DUAL_ALG);
    break ;
  case 4:
    svm_learn_struct_joint(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,ONESLACK_DUAL_CACHE_ALG);
    break  ;
  case 9:
    svm_learn_struct_joint_custom(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel);
    break ;
  default:
    mexErrMsgTxt("Unknown algorithm type") ;
  }

  /* Write output  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */

  /* Warning: The model contains references to the original data 'docs'.
     If you want to free the original data, and only keep the model, you
     have to make a deep copy of 'model'. */

  mxArray * model_array = newMxArrayEncapsulatingSmodel (&structmodel) ;
  out[OUT_W] = mxDuplicateArray (model_array) ;
  destroyMxArrayEncapsulatingSmodel (model_array) ;
  
  free_struct_sample (sample) ;
  free_struct_model (structmodel) ;
  svm_struct_learn_api_exit () ;
  free_qp_solver () ;
}