Ejemplo n.º 1
0
void
mexFunction(int nout, mxArray *out[],
            int nin, const mxArray *in[])
{
  enum {IN_DATA, IN_LABELS, IN_LAMBDA, IN_END} ;
  enum {OUT_MODEL = 0} ;

  int            verbose = 0 ;
  int            opt ;
  int            next = IN_END ;
  mxArray const *optarg ;

  double biasMultiplier = 0 ;
  double lambda ;
  void * data ;
  void * preconditioner = NULL ;
  vl_size preconditionerDimension = 0 ;
  mxClassID dataClass ;
  vl_type dataType ;
  vl_size numSamples ;
  vl_size dimension ;
  vl_size numIterations = 0 ;
  vl_uindex startingIteration = 1 ;
  vl_uint32 * permutation  = NULL ;
  vl_size permutationSize = 0 ;

  VL_USE_MATLAB_ENV ;

  /* -----------------------------------------------------------------
   *                                               Check the arguments
   * -------------------------------------------------------------- */

  if (nin < 3) {
    vlmxError(vlmxErrInvalidArgument,
              "At least three arguments are required.") ;
  } else if (nout > 2) {
    vlmxError(vlmxErrInvalidArgument,
              "Too many output arguments.");
  }

  dataClass = mxGetClassID(IN(DATA)) ;

  if (! vlmxIsMatrix (IN(DATA), -1, -1) ||
      ! vlmxIsReal (IN(DATA))) {
    vlmxError(vlmxErrInvalidArgument,
              "DATA must be a real matrix.") ;
  }

  data = mxGetData (IN(DATA)) ;
  dimension = mxGetM(IN(DATA)) ;
  numSamples = mxGetN(IN(DATA)) ;

  switch (dataClass) {
  case mxSINGLE_CLASS : dataType = VL_TYPE_FLOAT ; break ;
  case mxDOUBLE_CLASS : dataType = VL_TYPE_DOUBLE ; break ;
  default:
    vlmxError(vlmxErrInvalidArgument,
              "DATA must be either SINGLE or DOUBLE.") ;
  }

  if (mxGetClassID(IN(LABELS)) != mxINT8_CLASS) {
    vlmxError(vlmxErrInvalidArgument, "LABELS must be INT8.") ;
  }
  if (! vlmxIsVector(IN(LABELS), numSamples)) {
    vlmxError(vlmxErrInvalidArgument, "LABELS is not a vector of dimension compatible with DATA.") ;
  }

  if (! vlmxIsPlainScalar(IN(LAMBDA))) {
    vlmxError(vlmxErrInvalidArgument, "LAMBDA is not a plain scalar.") ;
  }
  lambda = *mxGetPr(IN(LAMBDA)) ;

  while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
    switch (opt) {
      case opt_bias_multiplier :
        if (!vlmxIsPlainScalar(optarg)) {
          vlmxError(vlmxErrInvalidArgument, "BIASMULTIPLIER is not a plain scalar.") ;
        }
        biasMultiplier = *mxGetPr(optarg) ;
        break ;

      case opt_num_iterations :
        if (!vlmxIsPlainScalar(optarg)) {
          vlmxError(vlmxErrInvalidArgument, "NUMITERATIONS is not a plain scalar.") ;
        }
        if (*mxGetPr(optarg) < 0) {
          vlmxError(vlmxErrInvalidArgument, "NUMITERATIONS is negative.") ;
        }
        numIterations = (vl_size) *mxGetPr(optarg) ;
        break ;

      case opt_starting_iteration :
        if (!vlmxIsPlainScalar(optarg)) {
          vlmxError(vlmxErrInvalidArgument, "STARTINGITERATION is not a plain scalar.") ;
        }
        if (*mxGetPr(optarg) < 1) {
          vlmxError(vlmxErrInvalidArgument, "STARTINGITERATION is smaller than 1.") ;
        }
        startingIteration = (vl_size) *mxGetPr(optarg) ;
        break ;

      case opt_starting_model :
        if (!vlmxIsVector(optarg, -1) ||
            mxIsComplex(optarg) ||
            !mxIsNumeric(optarg)) {
          vlmxError(vlmxErrInvalidArgument, "STARTINGMODEL is not a real vector.") ;
        }
        OUT(MODEL) = mxDuplicateArray(optarg) ;
        break ;

      case opt_permutation :
        if (!vlmxIsVector(optarg, -1) ||
            mxIsComplex(optarg) ||
            mxGetClassID(optarg) != mxUINT32_CLASS) {
          vlmxError(vlmxErrInvalidArgument, "PERMUTATION is not a UINT32 vector.") ;
        }
        permutationSize = mxGetNumberOfElements(optarg) ;
        permutation = mxMalloc(sizeof(vl_uint32) * permutationSize) ;
        {
          /* adjust indexing */
          vl_uint32 const * matlabPermutation = mxGetData(optarg) ;
          vl_uindex k ;
          for (k = 0 ; k < permutationSize ; ++k) {
            permutation[k] = matlabPermutation[k] - 1 ;
            if (permutation[k] >= numSamples) {
              vlmxError(vlmxErrInconsistentData,
                        "Permutation indexes out of bounds: PERMUTATION(%d) = %d > %d = number of data samples.",
                        k + 1, permutation[k] + 1, numSamples) ;
            }
          }
        }
        break ;

      case opt_preconditioner :
        if (!vlmxIsVector(optarg, -1) ||
            mxIsComplex(optarg) ||
            !mxIsNumeric(optarg)) {
          vlmxError(vlmxErrInvalidArgument, "PRECONDITIONER is not a real vector.") ;
        }
        if (mxGetClassID(optarg) != dataClass) {
          vlmxError(vlmxErrInvalidArgument, "PRECODNITIONER storage class does not match the data.") ;
        }
        preconditioner = mxGetData(optarg) ;
        preconditionerDimension = mxGetNumberOfElements(optarg) ;
        break ;

      case opt_verbose :
        ++ verbose ;
        break ;
    }
  }

  if (preconditioner && preconditionerDimension != (dimension + (biasMultiplier > 0))) {
    vlmxError(vlmxErrInvalidArgument, "PRECONDITIONER has incompatible dimension.") ;
  }

  if (numIterations == 0) {
    numIterations = (vl_size) 10 / (lambda + 1) ;
  }

  if (! OUT(MODEL)) {
    OUT(MODEL) = mxCreateNumericMatrix(dimension + (biasMultiplier > 0),
                                       1,
                                       dataClass, mxREAL) ;
  } else {
    if (mxGetClassID(OUT(MODEL)) != dataClass) {
      vlmxError(vlmxErrInvalidArgument, "STARTINGMODEL is not of the same class of DATA.") ;
    }
    if (mxGetNumberOfElements(OUT(MODEL)) != dimension + (biasMultiplier > 0)) {
      vlmxError(vlmxErrInvalidArgument, "STARTINGMODEL has incompatible dimension.") ;
    }
  }

  if (verbose) {
    mexPrintf("vl_pegasos: Lambda = %g\n", lambda) ;
    mexPrintf("vl_pegasos: BiasMultiplier = %g\n", biasMultiplier) ;
    mexPrintf("vl_pegasos: NumIterations = %d\n", numIterations) ;
    mexPrintf("vl_pegasos: permutation size = %d\n", permutationSize) ;
    mexPrintf("vl_pegasos: using preconditioner = %s\n", VL_YESNO(preconditioner)) ;
  }

  switch (dataType) {
    case VL_TYPE_FLOAT :
      vl_pegasos_train_binary_svm_f((float *)mxGetData(OUT(MODEL)),
                                    (float const *)mxGetPr(IN(DATA)), dimension, numSamples,
                                    (vl_int8 const *)mxGetData(IN(LABELS)),
                                    lambda,
                                    biasMultiplier,
                                    startingIteration,
                                    numIterations,
                                    NULL,
                                    permutation,
                                    permutationSize,
                                    (float const*)preconditioner) ;
      break ;
    case VL_TYPE_DOUBLE:
      vl_pegasos_train_binary_svm_d((double *)mxGetData(OUT(MODEL)),
                                    (double const *)mxGetData(IN(DATA)), dimension, numSamples,
                                    (vl_int8 const *)mxGetData(IN(LABELS)),
                                    lambda,
                                    biasMultiplier,
                                    startingIteration,
                                    numIterations,
                                    NULL,
                                    permutation,
                                    permutationSize,
                                    (double const *)preconditioner) ;
      break ;
  }

  if (permutation) vl_free(permutation) ;

}
Ejemplo n.º 2
0
void
mexFunction(int nout, mxArray *out[],
            int nin, const mxArray *in[])
{
  enum {IN_FOREST = 0, IN_DATA, IN_QUERY, IN_END} ;
  enum {OUT_INDEX = 0, OUT_DISTANCE} ;

  int            verbose = 0 ;
  int            opt ;
  int            next = IN_END ;
  mxArray const *optarg ;

  VlKDForest * forest ;
  mxArray const * forest_array = in[IN_FOREST] ;
  mxArray const * data_array = in[IN_DATA] ;
  mxArray const * query_array = in[IN_QUERY] ;
  mxArray * index_array ;
  mxArray * distance_array ;
  void * query ;
  vl_uint32 * index ;
  void * distance ;
  vl_size numNeighbors = 1 ;
  vl_size numQueries ;
  vl_uindex qi, ni;
  unsigned int numComparisons = 0 ;
  unsigned int maxNumComparisons = 0 ;
  VlKDForestNeighbor * neighbors ;
  mxClassID dataClass ;

  VL_USE_MATLAB_ENV ;

  /* -----------------------------------------------------------------
   *                                               Check the arguments
   * -------------------------------------------------------------- */

  if (nin < 3) {
    vlmxError(vlmxErrNotEnoughInputArguments, NULL) ;
  }
  if (nout > 2) {
    vlmxError(vlmxErrTooManyOutputArguments, NULL) ;
  }

  forest = new_kdforest_from_array (forest_array, data_array) ;

  dataClass = mxGetClassID (data_array) ;
  if (mxGetClassID (query_array) != dataClass) {
    vlmxError(vlmxErrInvalidArgument,
             "QUERY must have the same storage class as DATA.") ;
  }
  if (! vlmxIsReal (query_array)) {
    vlmxError(vlmxErrInvalidArgument,
             "QUERY must be real.") ;
  }
  if (! vlmxIsMatrix (query_array, forest->dimension, -1)) {
    vlmxError(vlmxErrInvalidArgument,
             "QUERY must be a matrix with TREE.NUMDIMENSIONS rows.") ;
  }

  while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
    switch (opt) {
      case opt_num_neighs :
        if (! vlmxIsScalar(optarg) ||
            (numNeighbors = mxGetScalar(optarg)) < 1) {
          vlmxError(vlmxErrInvalidArgument,
                   "NUMNEIGHBORS must be a scalar not smaller than one.") ;
        }
        break;

      case opt_max_num_comparisons :
        if (! vlmxIsScalar(optarg)) {
          vlmxError(vlmxErrInvalidArgument,
                   "MAXNUMCOMPARISONS must be a scalar.") ;
        }
        maxNumComparisons = mxGetScalar(optarg) ;
        break;

      case opt_verbose :
        ++ verbose ;
        break ;
    }
  }

  vl_kdforest_set_max_num_comparisons (forest, maxNumComparisons) ;

  neighbors = vl_malloc (sizeof(VlKDForestNeighbor) * numNeighbors) ;

  query = mxGetData (query_array) ;
  numQueries = mxGetN (query_array) ;

  out[OUT_INDEX] = index_array = mxCreateNumericMatrix
    (numNeighbors, numQueries, mxUINT32_CLASS, mxREAL) ;

  out[OUT_DISTANCE] = distance_array = mxCreateNumericMatrix
    (numNeighbors, numQueries, dataClass, mxREAL) ;

  index = mxGetData (index_array) ;
  distance = mxGetData (distance_array) ;

  if (verbose) {
    VL_PRINTF ("vl_kdforestquery: number of queries: %d\n", numQueries) ;
    VL_PRINTF ("vl_kdforestquery: number of neighbors per query: %d\n", numNeighbors) ;
    VL_PRINTF ("vl_kdforestquery: max num of comparisons per query: %d\n",
               vl_kdforest_get_max_num_comparisons (forest)) ;
  }

  for (qi = 0 ; qi < numQueries ; ++ qi) {
    numComparisons += vl_kdforest_query (forest, neighbors, numNeighbors,
                                         query) ;
    switch (dataClass) {
      case mxSINGLE_CLASS:
      {
        float * distance_ = (float*) distance ;
        for (ni = 0 ; ni < numNeighbors ; ++ni) {
          *index++     = neighbors[ni].index + 1 ;
          *distance_++ = neighbors[ni].distance ;
        }
        query = (float*)query + vl_kdforest_get_data_dimension (forest) ;
        distance = distance_ ;
        break ;
      }
      case mxDOUBLE_CLASS:
      {
        double * distance_ = (double*) distance ;
        for (ni = 0 ; ni < numNeighbors ; ++ni) {
          *index++     = neighbors[ni].index + 1 ;
          *distance_++ = neighbors[ni].distance ;
        }
        query = (double*)query + vl_kdforest_get_data_dimension (forest)  ;
        distance = distance_ ;
        break ;
      }
      default:
        abort() ;
    }
  }

  if (verbose) {
    VL_PRINTF ("vl_kdforestquery: number of comparisons per query: %.3f\n",
               ((double) numComparisons) / numQueries) ;
    VL_PRINTF ("vl_kdforestquery: number of comparisons per neighbor: %.3f\n",
               ((double) numComparisons) / (numQueries * numNeighbors)) ;
  }

  vl_kdforest_delete (forest) ;
  vl_free (neighbors) ;
}
Ejemplo n.º 3
0
void
mexFunction(int nout, mxArray *out[],
            int nin, const mxArray *in[])
{
  enum {IN_DATA = 0, IN_END} ;
  enum {OUT_TREE = 0} ;

  int            verbose = 0 ;
  int            opt ;
  int            next = IN_END ;
  mxArray const *optarg ;

  VlKDForest * forest ;
  void * data ;
  vl_size numData ;
  vl_size dimension ;
  mxClassID dataClass ;
  vl_type dataType ;
  int thresholdingMethod = VL_KDTREE_MEDIAN ;
  vl_size numTrees = 1 ;

  VL_USE_MATLAB_ENV ;

  /* -----------------------------------------------------------------
   *                                               Check the arguments
   * -------------------------------------------------------------- */

  if (nin < 1) {
    vlmxError(vlmxErrInvalidArgument,
             "At least one argument required") ;
  } else if (nout > 2) {
    vlmxError(vlmxErrInvalidArgument,
             "Too many output arguments");
  }

  dataClass = mxGetClassID(IN(DATA)) ;

  if (! vlmxIsMatrix (IN(DATA), -1, -1) ||
      ! vlmxIsReal (IN(DATA))) {
    vlmxError(vlmxErrInvalidArgument,
             "DATA must be a real matrix ") ;
  }

  switch (dataClass) {
    case mxSINGLE_CLASS : dataType = VL_TYPE_FLOAT ; break ;
    case mxDOUBLE_CLASS : dataType = VL_TYPE_DOUBLE ; break ;
    default:
      vlmxError(vlmxErrInvalidArgument,
               "DATA must be either SINGLE or DOUBLE") ;
  }

  while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
    char buffer [1024] ;
    switch (opt) {
      case opt_threshold_method :
        mxGetString (optarg, buffer, sizeof(buffer)/sizeof(buffer[0])) ;
        if (! vlmxIsString(optarg, -1)) {
          vlmxError(vlmxErrInvalidOption,
                   "THRESHOLDMETHOD must be a string") ;
        }
        if (vl_string_casei_cmp(buffer, "median") == 0) {
          thresholdingMethod = VL_KDTREE_MEDIAN ;
        } else if (vl_string_casei_cmp(buffer, "mean") == 0) {
          thresholdingMethod = VL_KDTREE_MEAN ;
        } else {
          vlmxError(vlmxErrInvalidOption,
                   "Unknown thresholding method %s", buffer) ;
        }
        break ;

      case opt_num_trees :
        if (! vlmxIsScalar(optarg) ||
            (numTrees = mxGetScalar(optarg)) < 1) {
          vlmxError(vlmxErrInvalidOption,
                   "NUMTREES must be not smaller than one") ;
        }
        break ;

      case opt_verbose :
        ++ verbose ;
        break ;
    }
  }

  data = mxGetData (IN(DATA)) ;
  numData = mxGetN (IN(DATA)) ;
  dimension = mxGetM (IN(DATA)) ;

  forest = vl_kdforest_new (dataType, dimension, numTrees) ;
  vl_kdforest_set_thresholding_method (forest, thresholdingMethod) ;

  if (verbose) {
    char const * str = 0 ;
    mexPrintf("vl_kdforestbuild: data %s [%d x %d]\n",
              vl_get_type_name (dataType), dimension, numData) ;
    switch (vl_kdforest_get_thresholding_method(forest)) {
      case VL_KDTREE_MEAN : str = "mean" ; break ;
      case VL_KDTREE_MEDIAN : str = "median" ; break ;
      default: abort() ;
    }
    mexPrintf("vl_kdforestbuild: threshold selection method: %s\n", str) ;
    mexPrintf("vl_kdforestbuild: number of trees: %d\n",
              vl_kdforest_get_num_trees(forest)) ;
  }

  /* -----------------------------------------------------------------
   *                                                            Do job
   * -------------------------------------------------------------- */

  vl_kdforest_build (forest, numData, data) ;

  if (verbose) {
    vl_uindex ti ;
    for (ti = 0 ; ti < vl_kdforest_get_num_trees(forest) ; ++ ti) {
      mexPrintf("vl_kdforestbuild: tree %d: depth %d, num nodes %d\n",
                ti,
                vl_kdforest_get_depth_of_tree(forest, ti),
                vl_kdforest_get_num_nodes_of_tree(forest, ti)) ;
    }
  }

  out[OUT_TREE] = new_array_from_kdforest (forest) ;
  vl_kdforest_delete (forest) ;
}
Ejemplo n.º 4
0
void
mexFunction(int nout, mxArray *out[],
            int nin, const mxArray *in[])
{
  enum {IN_DATA, IN_LABELS, IN_LAMBDA, IN_END} ;
  enum {OUT_MODEL = 0, OUT_BIAS, OUT_INFO} ;

  int verbose = 0 ;
  int opt ;
  int next = IN_END ;
  mxArray const *optarg ;

  mxArray *inputModel = NULL;
  VlSvmPegasos* svm = NULL ;

  vl_bool freeModel = VL_TRUE ;
  vl_size dataDimension ;

  vl_uint32* matlabPermutation ;

  void * data ;
  mxClassID dataClass ;
  vl_type dataType ;
  vl_size numSamples ;

  vl_uint32 * permutation  = NULL ;
  vl_size permutationSize = 0 ;

  DiagnosticsDispatcher* disp ;
  VlSvmDatasetInnerProduct innerProduct = NULL ;
  VlSvmDatasetAccumulator accumulator = NULL ;

  /* maps */
  VlSvmDatasetFeatureMap mapFunc  = NULL ;

  /* Homkermap */
  VlHomogeneousKernelType kernelType = VlHomogeneousKernelChi2 ;
  VlHomogeneousKernelMapWindowType windowType = VlHomogeneousKernelMapWindowRectangular ;
  double gamma = 1.0 ;
  int n = 0 ;
  double period = -1 ;

  VlSvmDataset* dataset ;

  vl_bool homkermap = VL_FALSE ;
  void * map = NULL ;

  VL_USE_MATLAB_ENV ;

  disp = (DiagnosticsDispatcher*) vl_malloc(sizeof(DiagnosticsDispatcher)) ;
  disp->diagnosticsHandle = NULL ;
  disp->callerRef = NULL ;
  disp->verbose = 0 ;

  /* -----------------------------------------------------------------
   *                                               Check the arguments
   * -------------------------------------------------------------- */

  if (nin < 3) {
    vlmxError(vlmxErrInvalidArgument,
              "At least three arguments are required.") ;
  } else if (nout > 3) {
    vlmxError(vlmxErrInvalidArgument,
              "Too many output arguments.");
  }

  dataClass = mxGetClassID(IN(DATA)) ;

  if (! vlmxIsMatrix (IN(DATA), -1, -1) ||
      ! vlmxIsReal (IN(DATA))) {
    vlmxError(vlmxErrInvalidArgument,
              "DATA must be a real matrix.") ;
  }

  data = mxGetData (IN(DATA)) ;
  dataDimension = mxGetM(IN(DATA)) ;
  numSamples = mxGetN(IN(DATA)) ;

  /* Get order of the HOMKERMAP, if used. */
  while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
    if  (opt == opt_homkermap) {
      homkermap = VL_TRUE ;
      if (! vlmxIsPlainScalar(optarg)) {
        vlmxError(vlmxErrInvalidArgument, "N is not a scalar.") ;
      }
      n = *mxGetPr(optarg) ;
      if (n < 0) {
        vlmxError(vlmxErrInvalidArgument, "N is negative.") ;
      }
    }
  }

  next = IN_END ;

  if (! vlmxIsVector(IN(LABELS), numSamples)) {
    vlmxError(vlmxErrInvalidArgument, "LABELS is not a vector of dimension compatible with DATA.") ;
  }


  switch (dataClass) {
  case mxSINGLE_CLASS : dataType = VL_TYPE_FLOAT ; break ;
  case mxDOUBLE_CLASS : dataType = VL_TYPE_DOUBLE ; break ;
  default:
    vlmxError(vlmxErrInvalidArgument,
              "DATA must be either SINGLE or DOUBLE.") ;
  }

  if (mxGetClassID(IN(LABELS)) != mxINT8_CLASS) {
    vlmxError(vlmxErrInvalidArgument, "LABELS must be INT8.") ;
  }


  if (! vlmxIsPlainScalar(IN(LAMBDA))) {
    vlmxError(vlmxErrInvalidArgument, "LAMBDA is not a plain scalar.") ;
  }

  svm = vl_svmpegasos_new ((2*n + 1)*dataDimension,*mxGetPr(IN(LAMBDA))) ;

  while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
    switch (opt) {
    case opt_bias_multiplier :
      if (!vlmxIsPlainScalar(optarg)) {
        vlmxError(vlmxErrInvalidArgument, "BIASMULTIPLIER is not a plain scalar.") ;
      }
      vl_svmpegasos_set_bias_multiplier(svm, *mxGetPr(optarg)) ;
      break ;

    case opt_max_iterations :
      if (!vlmxIsPlainScalar(optarg)) {
        vlmxError(vlmxErrInvalidArgument, "MAXITERATIONS is not a plain scalar.") ;
      }
      if (*mxGetPr(optarg) < 0) {
        vlmxError(vlmxErrInvalidArgument, "MAXITERATIONS is negative.") ;
      }
      vl_svmpegasos_set_maxiterations(svm, (vl_size) *mxGetPr(optarg)) ;
      break ;

    case opt_epsilon :
      if (!vlmxIsPlainScalar(optarg)) {
        vlmxError(vlmxErrInvalidArgument, "EPSILON is not a plain scalar.") ;
      }
      if (*mxGetPr(optarg) < 0) {
        vlmxError(vlmxErrInvalidArgument, "EPSILON is negative.") ;
      }
      vl_svmpegasos_set_epsilon(svm, (double) *mxGetPr(optarg)) ;
      break ;

    case opt_starting_iteration :
      if (!vlmxIsPlainScalar(optarg)) {
        vlmxError(vlmxErrInvalidArgument, "STARTINGITERATION is not a plain scalar.") ;
      }
      if (*mxGetPr(optarg) < 1) {
        vlmxError(vlmxErrInvalidArgument, "STARTINGITERATION is smaller than 1.") ;
      }
      vl_svmpegasos_set_iterations(svm, (vl_size) *mxGetPr(optarg) - 1) ;
      break ;

    case opt_starting_model :
      if (!vlmxIsVector(optarg, -1) ||
          mxIsComplex(optarg) ||
          mxGetClassID(optarg) != mxDOUBLE_CLASS) {
        vlmxError(vlmxErrInvalidArgument, "STARTINGMODEL is not a real vector.") ;
      }
      inputModel = mxDuplicateArray(optarg) ;
      vl_svmpegasos_set_model(svm,(double*) mxGetData(inputModel)) ;
      freeModel = VL_FALSE ;
      break ;

    case opt_starting_bias :
      if (!vlmxIsPlainScalar(optarg)) {
        vlmxError(vlmxErrInvalidArgument, "STARTINGBIAS is not a plain scalar.") ;
      }
      vl_svmpegasos_set_bias(svm, (double) *mxGetPr(optarg)) ;
      break ;

    case opt_permutation :
      if (!vlmxIsVector(optarg, -1) ||
          mxIsComplex(optarg) ||
          mxGetClassID(optarg) != mxUINT32_CLASS) {
        vlmxError(vlmxErrInvalidArgument, "PERMUTATION is not a UINT32 vector.") ;
      }
      permutationSize = mxGetNumberOfElements(optarg) ;
      permutation = mxMalloc(sizeof(vl_uint32) * permutationSize) ;
      matlabPermutation = mxGetData(optarg) ;
      {
        /* adjust indexing */
        vl_uindex k ;
        for (k = 0 ; k < permutationSize ; ++k) {
          permutation[k] = matlabPermutation[k] - 1 ;
          if (permutation[k] >= numSamples) {
            vlmxError(vlmxErrInconsistentData,
                      "Permutation indexes out of bounds: PERMUTATION(%d) = %d > %d = number of data samples.",
                      k + 1, permutation[k] + 1, numSamples) ;
          }
        }
      }
      vl_svmpegasos_set_permutation(svm,permutation,permutationSize) ;
      break ;

    case opt_bias_learningrate :
      if (!vlmxIsPlainScalar(optarg)) {
        vlmxError(vlmxErrInvalidArgument, "BIASLEARNINGRATE is not a plain scalar.") ;
      }
      if (mxGetClassID(optarg) != mxDOUBLE_CLASS) {
        vlmxError(vlmxErrInvalidArgument, "BIASLEARNINGRATE must be double.") ;
      }
      vl_svmpegasos_set_bias_learningrate(svm, (double)*mxGetPr(optarg)) ;
      break ;
    case opt_diagnostic :

      if( !mxIsClass( optarg , "function_handle")) {
        mexErrMsgTxt("DIAGNOSTICSFUNCTION must be  a function handle.");
      }
      disp->diagnosticsHandle = (mxArray*)(optarg) ;
      break ;

    case opt_diagnostic_caller_ref :
      disp->callerRef = (mxArray*)(optarg) ;
      break ;

    case opt_energy_freq :
      if (!vlmxIsPlainScalar(optarg)) {
        vlmxError(vlmxErrInvalidArgument, "ENERGYFREQ is not a plain scalar.") ;
      }
      vl_svmpegasos_set_energy_frequency (svm, (vl_size)*mxGetPr(optarg)) ;
      break ;

    case opt_verbose :
      ++ verbose ;
      disp->verbose = 1 ;
      break ;

    case opt_KINTERS:
    case opt_KL1:
      kernelType = VlHomogeneousKernelIntersection ;
      break ;

    case opt_KCHI2:
      kernelType = VlHomogeneousKernelChi2 ;
      break ;

    case opt_KJS:
      kernelType = VlHomogeneousKernelJS ;
      break ;

    case opt_period:
      if (! vlmxIsPlainScalar(optarg)){
        vlmxError(vlmxErrInvalidArgument, "PERIOD is not a scalar.") ;
      }
      period = *mxGetPr(optarg) ;
      if (period <= 0) {
        vlmxError(vlmxErrInvalidArgument, "PERIOD is not positive.") ;
      }
      break ;

    case opt_gamma:
      if (! vlmxIsPlainScalar(optarg)){
        vlmxError(vlmxErrInvalidArgument, "GAMMA is not a scalar.") ;
      }
      gamma = *mxGetPr(optarg) ;
      if (gamma <= 0) {
        vlmxError(vlmxErrInvalidArgument, "GAMMA is not positive.") ;
      }
      break ;

    case opt_window:
      if (! vlmxIsString(optarg,-1)){
        vlmxError(vlmxErrInvalidArgument, "WINDOW is not a string.") ;
      } else {
        char buffer [1024] ;
        mxGetString(optarg, buffer, sizeof(buffer) / sizeof(char)) ;
        if (vl_string_casei_cmp("uniform", buffer) == 0) {
          windowType = VlHomogeneousKernelMapWindowUniform ;
        } else if (vl_string_casei_cmp("rectangular", buffer) == 0) {
          windowType = VlHomogeneousKernelMapWindowRectangular ;
        } else {
          vlmxError(vlmxErrInvalidArgument, "WINDOW=%s is not recognized.", buffer) ;
        }
      }
      break ;
    }
  }

  if (verbose) {
    mexPrintf("vl_pegasos: Lambda = %g\n", svm->lambda) ;
    mexPrintf("vl_pegasos: BiasMultiplier = %g\n", svm->biasMultiplier) ;
    mexPrintf("vl_pegasos: MaxIterations = %d\n", svm->maxIterations) ;
    mexPrintf("vl_pegasos: permutation size = %d\n", permutationSize) ;
  }

  switch (dataType) {
  case VL_TYPE_FLOAT :
    innerProduct = (VlSvmDatasetInnerProduct)&vl_svmdataset_innerproduct_f ;
    accumulator = (VlSvmDatasetAccumulator)&vl_svmdataset_accumulator_f ;
    break ;
  case VL_TYPE_DOUBLE:
    innerProduct = (VlSvmDatasetInnerProduct)&vl_svmdataset_innerproduct_d ;
    accumulator = (VlSvmDatasetAccumulator)&vl_svmdataset_accumulator_d ;
    break ;
  }

  dataset = vl_svmdataset_new(data,dataDimension) ;
  if (homkermap) {
    map = vl_homogeneouskernelmap_new (kernelType, gamma, n, period, windowType) ;
    mapFunc = (VlSvmDatasetFeatureMap)&vl_homogeneouskernelmap_evaluate_d ;
    vl_svmdataset_set_map(dataset,map,mapFunc,2*n + 1) ;
  }

  /* -----------------------------------------------------------------
   *                                                            Do job
   * -------------------------------------------------------------- */
  if (disp->diagnosticsHandle) {
    vl_svmpegasos_set_diagnostic (svm, (VlSvmDiagnostics)&diagnosticDispatcher, disp) ;
  }

  vl_svmpegasos_train (svm,dataset, numSamples,innerProduct, accumulator,
                       (vl_int8 const *)mxGetData(IN(LABELS))) ;

  /* -----------------------------------------------------------------
   *                                                            Output
   * -------------------------------------------------------------- */

  if (nout >= 1) {
    double * tempBuffer ;
    mwSize dims[2] ;
    dims[0] = svm->dimension ;
    dims[1] = 1 ;
    out[OUT_MODEL] = mxCreateNumericArray(2, dims,
                                          mxDOUBLE_CLASS, mxREAL) ;
    tempBuffer  = (double*) mxGetData(out[OUT_MODEL]) ;
    memcpy(tempBuffer,svm->model,svm->dimension * sizeof(double)) ;
  }

  if (nout >= 2) {
    double * tempBuffer ;
    mwSize dims[2] ;
    dims[0] = 1 ;
    dims[1] = 1 ;

    out[OUT_BIAS] = mxCreateNumericArray(2, dims,
                                         mxDOUBLE_CLASS, mxREAL) ;
    tempBuffer = (double*) mxGetData(out[OUT_BIAS]) ;
    *tempBuffer = svm->bias ;
  }

  if (nout == 3) {
    out[OUT_INFO] = createInfoStruct(svm) ;
  }

  if (homkermap) {
    vl_homogeneouskernelmap_delete(map);
  }
  vl_svmdataset_delete(dataset) ;
  vl_svmpegasos_delete(svm,freeModel) ;
  vl_free(disp) ;
}
Ejemplo n.º 5
0
/* driver */
void
mexFunction(int nout, mxArray *out[],
            int nin, const mxArray *in[])
{

  typedef int  unsigned data_t ;

  vl_bool autoComparison = VL_TRUE ;
  VlVectorComparisonType comparisonType = VlDistanceL2 ;

  enum {IN_X = 0, IN_Y} ;
  enum {OUT_D = 0} ;
  mwSize numDataX = 0 ;
  mwSize numDataY = 0 ;
  mwSize dimension ;
  mxClassID classId ;

  /* for option parsing */
  int opt ;
  int next ;
  mxArray const *optarg ;

  VL_USE_MATLAB_ENV ;

  if (nout > 1) {
    vlmxError(vlmxErrTooManyOutputArguments, NULL) ;
  }
  if (nin < 1) {
    vlmxError(vlmxErrNotEnoughInputArguments, NULL) ;
  }
  if (! (vlmxIsMatrix (in[IN_X],-1,-1) && vlmxIsReal(in[IN_X]))) {
    vlmxError(vlmxErrInvalidArgument, "X must be a real matrix.") ;
  }
  next = 1 ;
  classId = mxGetClassID(in[IN_X]) ;
  dimension = mxGetM(in[IN_X]) ;
  numDataX = mxGetN(in[IN_X]) ;

  if (nin > 1 && vlmxIsMatrix (in[IN_Y],-1,-1) && vlmxIsReal(in[IN_Y])) {
    next = 2 ;
    autoComparison = VL_FALSE ;
    numDataY = mxGetN(in[IN_Y]) ;
    if (mxGetClassID(in[IN_Y]) != classId) {
      vlmxError(vlmxErrInvalidArgument, "X and Y must have the same class.") ;
    }
    if (dimension != mxGetM(in[IN_Y])) {
      vlmxError(vlmxErrInvalidArgument, "X and Y must have the same number of rows.") ;
    }
  }

  if (classId != mxSINGLE_CLASS && classId != mxDOUBLE_CLASS) {
    vlmxError(vlmxErrInvalidArgument,
             "X must be either of class SINGLE or DOUBLE.");
  }

  while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
    switch (opt) {
      case opt_L2    : comparisonType = VlDistanceL2 ; break ;
      case opt_L1    : comparisonType = VlDistanceL1 ; break ;
      case opt_CHI2  : comparisonType = VlDistanceChi2 ; break ;
      case opt_HELL  : comparisonType = VlDistanceHellinger ; break ;
      case opt_JS    : comparisonType = VlDistanceJS ; break ;
      case opt_KL2   : comparisonType = VlKernelL2 ; break ;
      case opt_KL1   : comparisonType = VlKernelL1 ; break ;
      case opt_KCHI2 : comparisonType = VlKernelChi2 ; break ;
      case opt_KHELL : comparisonType = VlKernelHellinger ; break ;
      case opt_KJS   : comparisonType = VlKernelJS ; break ;
      default:
        abort() ;
    }
  }

  /* allocate output */
  {
    mwSize dims [2] ;
    dims[0] = numDataX ;
    dims[1] = autoComparison ? numDataX : numDataY ;
    out[OUT_D] = mxCreateNumericArray (2, dims, classId, mxREAL) ;
  }

  /* If either numDataX or numDataY are null, their data pointers are
     null as well. This may confuse
     vl_eval_vector_comparison_on_all_pairs_*, so we intercept this as
     a special case. The same is true if dimension is null.
  */

  if (numDataX == 0 || (! autoComparison && numDataY == 0)) {
    return ;
  }
  if (dimension == 0) {
    return ;
  }

  /* make calculation */
  switch (classId) {
  case mxSINGLE_CLASS:
    {
      VlFloatVectorComparisonFunction f = vl_get_vector_comparison_function_f (comparisonType) ;
      if (autoComparison) {
        vl_eval_vector_comparison_on_all_pairs_f ((float*)mxGetData(out[OUT_D]),
                                                  dimension,
                                                  (float*)mxGetData(in[IN_X]), numDataX,
                                                  0, 0,
                                                  f) ;
      } else {
        vl_eval_vector_comparison_on_all_pairs_f ((float*)mxGetData(out[OUT_D]),
                                                  dimension,
                                                  (float*)mxGetData(in[IN_X]), numDataX,
                                                  (float*)mxGetData(in[IN_Y]), numDataY,
                                                  f) ;
      }
    }
    break ;

    case mxDOUBLE_CLASS:
    {
      VlDoubleVectorComparisonFunction f = vl_get_vector_comparison_function_d (comparisonType) ;
      if (autoComparison) {
        vl_eval_vector_comparison_on_all_pairs_d ((double*)mxGetData(out[OUT_D]),
                                                  dimension,
                                                  (double*)mxGetData(in[IN_X]), numDataX,
                                                  0, 0,
                                                  f) ;
      } else {
        vl_eval_vector_comparison_on_all_pairs_d ((double*)mxGetData(out[OUT_D]),
                                                  dimension,
                                                  (double*)mxGetData(in[IN_X]), numDataX,
                                                  (double*)mxGetData(in[IN_Y]), numDataY,
                                                  f) ;
      }
    }
    break ;

  default:
    abort() ;
  }
}
Ejemplo n.º 6
0
void
mexFunction(int nout, mxArray *out[],
            int nin, const mxArray *in[])
{
  float * image ;
  vl_size width, height ;
  vl_size cellSize = 16 ;
  enum {IN_I = 0, IN_CELLSIZE} ;
  enum {OUT_FEATURES = 0} ;

  /* -----------------------------------------------------------------
   *                                               Check the arguments
   * -------------------------------------------------------------- */

  if (nin > 2) {
    vlmxError(vlmxErrTooManyInputArguments, NULL) ;
  }
  if (nin < 2) {
    vlmxError(vlmxErrNotEnoughInputArguments, NULL) ;
  }
  if (nout > 1) {
    vlmxError(vlmxErrTooManyOutputArguments, NULL) ;
  }

  if (! mxIsNumeric(IN(I)) ||
      ! vlmxIsReal(IN(I)) ||
      ! vlmxIsMatrix(IN(I), -1, -1)) {
    vlmxError(vlmxErrInvalidArgument,
              "I is not a numeric matrix.") ;
  }

  if (mxGetClassID(IN(I)) != mxSINGLE_CLASS) {
    vlmxError(vlmxErrInvalidArgument,
              "I is not of class SINGLE.") ;
  }

  if (! vlmxIsPlainScalar(IN(CELLSIZE))) {
    vlmxError(vlmxErrInvalidArgument,
              "CELLSIZE is not a plain scalar.") ;
  }

  if (mxGetScalar(IN(CELLSIZE)) < 1.0) {
    vlmxError(vlmxErrInvalidArgument,
              "CELLSIZE is less than 1.") ;
  }

  cellSize = (vl_size) mxGetScalar(IN(CELLSIZE)) ;
  image = mxGetData(IN(I)) ;
  width = mxGetN(IN(I)) ;
  height = mxGetM(IN(I)) ;

  /* do job */
  {
    /* recall that MATLAB images are transposed */
    mwSize dimensions [3] ;

    /* get LBP object */
    VlLbp * lbp = vl_lbp_new (VlLbpUniform, VL_TRUE) ;
    if (lbp == NULL) {
      vlmxError(vlmxErrAlloc, NULL) ;
    }

    /* get output buffer */
    dimensions[0] = height / cellSize ;
    dimensions[1] = width / cellSize ;
    dimensions[2] = vl_lbp_get_dimension(lbp) ;

    OUT(FEATURES) = mxCreateNumericArray(3, dimensions, mxSINGLE_CLASS, mxREAL) ;

    vl_lbp_process(lbp, mxGetData(OUT(FEATURES)), image, height, width, cellSize) ;
    vl_lbp_delete(lbp) ;
  }
}
Ejemplo n.º 7
0
void
mexFunction(int nout, mxArray *out[],
            int nin, const mxArray *in[])
{
  enum {IN_FOREST = 0, IN_DATA, IN_QUERY, IN_END} ;
  enum {OUT_INDEX = 0, OUT_DISTANCE} ;

  int verbose = 0 ;
  int opt ;
  int next = IN_END ;
  mxArray const *optarg ;

  VlKDForest * forest ;
  mxArray const * forest_array = in[IN_FOREST] ;
  mxArray const * data_array = in[IN_DATA] ;
  mxArray const * query_array = in[IN_QUERY] ;
  void * query ;
  vl_uint32 * index ;
  void * distance ;
  vl_size numNeighbors = 1 ;
  vl_size numQueries ;
  unsigned int numComparisons = 0 ;
  unsigned int maxNumComparisons = 0 ;
  mxClassID dataClass ;
  vl_index i ;

  VL_USE_MATLAB_ENV ;

  /* -----------------------------------------------------------------
   *                                               Check the arguments
   * -------------------------------------------------------------- */

  if (nin < 3) {
    vlmxError(vlmxErrNotEnoughInputArguments, NULL) ;
  }
  if (nout > 2) {
    vlmxError(vlmxErrTooManyOutputArguments, NULL) ;
  }

  forest = new_kdforest_from_array (forest_array, data_array) ;

  dataClass = mxGetClassID (data_array) ;
  if (mxGetClassID (query_array) != dataClass) {
    vlmxError(vlmxErrInvalidArgument,
              "QUERY must have the same storage class as DATA.") ;
  }
  if (! vlmxIsReal (query_array)) {
    vlmxError(vlmxErrInvalidArgument,
              "QUERY must be real.") ;
  }
  if (! vlmxIsMatrix (query_array, forest->dimension, -1)) {
    vlmxError(vlmxErrInvalidArgument,
              "QUERY must be a matrix with TREE.NUMDIMENSIONS rows.") ;
  }

  while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
    switch (opt) {
      case opt_num_neighs :
        if (! vlmxIsScalar(optarg) ||
            (numNeighbors = mxGetScalar(optarg)) < 1) {
          vlmxError(vlmxErrInvalidArgument,
                    "NUMNEIGHBORS must be a scalar not smaller than one.") ;
        }
        break;

      case opt_max_num_comparisons :
        if (! vlmxIsScalar(optarg)) {
          vlmxError(vlmxErrInvalidArgument,
                    "MAXNUMCOMPARISONS must be a scalar.") ;
        }
        maxNumComparisons = mxGetScalar(optarg) ;
        break;

      case opt_verbose :
        ++ verbose ;
        break ;
    }
  }

  vl_kdforest_set_max_num_comparisons (forest, maxNumComparisons) ;

  query = mxGetData (query_array) ;
  numQueries = mxGetN (query_array) ;

  out[OUT_INDEX] = mxCreateNumericMatrix (numNeighbors, numQueries, mxUINT32_CLASS, mxREAL) ;
  out[OUT_DISTANCE] = mxCreateNumericMatrix (numNeighbors, numQueries, dataClass, mxREAL) ;

  index = mxGetData (out[OUT_INDEX]) ;
  distance = mxGetData (out[OUT_DISTANCE]) ;

  if (verbose) {
    VL_PRINTF ("vl_kdforestquery: number of queries: %d\n", numQueries) ;
    VL_PRINTF ("vl_kdforestquery: number of neighbors per query: %d\n", numNeighbors) ;
    VL_PRINTF ("vl_kdforestquery: max num of comparisons per query: %d\n",
               vl_kdforest_get_max_num_comparisons (forest)) ;
  }

  numComparisons = vl_kdforest_query_with_array (forest, index, numNeighbors, numQueries, distance, query) ;
  
  vl_kdforest_delete(forest) ;
  
  /* adjust for MATLAB indexing */
  for (i = 0 ; i < (signed) (numNeighbors * numQueries) ; ++i) { index[i] ++ ; }

  if (verbose) {
    VL_PRINTF ("vl_kdforestquery: number of comparisons per query: %.3f\n",
               ((double) numComparisons) / numQueries) ;
    VL_PRINTF ("vl_kdforestquery: number of comparisons per neighbor: %.3f\n",
               ((double) numComparisons) / (numQueries * numNeighbors)) ;
  }
}