vl_alldist.c
Go to the documentation of this file.
00001 
00006 /*
00007 Copyright (C) 2007-12 Andrea Vedaldi and Brian Fulkerson.
00008 All rights reserved.
00009 
00010 This file is part of the VLFeat library and is made available under
00011 the terms of the BSD license (see the COPYING file).
00012 */
00013 
00014 #include "mexutils.h"
00015 #include <vl/mathop.h>
00016 
00017 enum {
00018   opt_LINF,
00019   opt_L2,
00020   opt_L1,
00021   opt_L0,
00022   opt_CHI2,
00023   opt_HELL,
00024   opt_JS,
00025 
00026   opt_KL2,
00027   opt_KL1,
00028   opt_KCHI2,
00029   opt_KHELL,
00030   opt_KJS
00031 } ;
00032 
00033 vlmxOption  options [] = {
00034 {"linf",         0,   opt_LINF          },
00035 {"l2",           0,   opt_L2            },
00036 {"l1",           0,   opt_L1            },
00037 {"l0",           0,   opt_L0            },
00038 {"chi2",         0,   opt_CHI2          },
00039 {"hell",         0,   opt_HELL          },
00040 {"js",           0,   opt_JS            },
00041 
00042 {"kl2",          0,   opt_KL2           },
00043 {"kl1",          0,   opt_KL1           },
00044 {"kchi2",        0,   opt_KCHI2         },
00045 {"khell",        0,   opt_KHELL         },
00046 {"kjs",          0,   opt_KJS           },
00047 
00048 {0,              0,   0                 }
00049 } ;
00050 
00051 /* driver */
00052 void
00053 mexFunction(int nout, mxArray *out[],
00054             int nin, const mxArray *in[])
00055 {
00056 
00057   typedef int  unsigned data_t ;
00058 
00059   vl_bool autoComparison = VL_TRUE ;
00060   VlVectorComparisonType comparisonType = VlDistanceL2 ;
00061 
00062   enum {IN_X = 0, IN_Y} ;
00063   enum {OUT_D = 0} ;
00064   mwSize numDataX = 0 ;
00065   mwSize numDataY = 0 ;
00066   mwSize dimension ;
00067   mxClassID classId ;
00068 
00069   /* for option parsing */
00070   int opt ;
00071   int next ;
00072   mxArray const *optarg ;
00073 
00074   VL_USE_MATLAB_ENV ;
00075 
00076   if (nout > 1) {
00077     vlmxError(vlmxErrTooManyOutputArguments, NULL) ;
00078   }
00079   if (nin < 1) {
00080     vlmxError(vlmxErrNotEnoughInputArguments, NULL) ;
00081   }
00082   if (! (vlmxIsMatrix (in[IN_X],-1,-1) && vlmxIsReal(in[IN_X]))) {
00083     vlmxError(vlmxErrInvalidArgument, "X must be a real matrix.") ;
00084   }
00085   next = 1 ;
00086   classId = mxGetClassID(in[IN_X]) ;
00087   dimension = mxGetM(in[IN_X]) ;
00088   numDataX = mxGetN(in[IN_X]) ;
00089 
00090   if (nin > 1 && vlmxIsMatrix (in[IN_Y],-1,-1) && vlmxIsReal(in[IN_Y])) {
00091     next = 2 ;
00092     autoComparison = VL_FALSE ;
00093     numDataY = mxGetN(in[IN_Y]) ;
00094     if (mxGetClassID(in[IN_Y]) != classId) {
00095       vlmxError(vlmxErrInvalidArgument, "X and Y must have the same class.") ;
00096     }
00097     if (dimension != mxGetM(in[IN_Y])) {
00098       vlmxError(vlmxErrInvalidArgument, "X and Y must have the same number of rows.") ;
00099     }
00100   }
00101 
00102   if (classId != mxSINGLE_CLASS && classId != mxDOUBLE_CLASS) {
00103     vlmxError(vlmxErrInvalidArgument,
00104              "X must be either of class SINGLE or DOUBLE.");
00105   }
00106 
00107   while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
00108     switch (opt) {
00109       case opt_L2    : comparisonType = VlDistanceL2 ; break ;
00110       case opt_L1    : comparisonType = VlDistanceL1 ; break ;
00111       case opt_CHI2  : comparisonType = VlDistanceChi2 ; break ;
00112       case opt_HELL  : comparisonType = VlDistanceHellinger ; break ;
00113       case opt_JS    : comparisonType = VlDistanceJS ; break ;
00114       case opt_KL2   : comparisonType = VlKernelL2 ; break ;
00115       case opt_KL1   : comparisonType = VlKernelL1 ; break ;
00116       case opt_KCHI2 : comparisonType = VlKernelChi2 ; break ;
00117       case opt_KHELL : comparisonType = VlKernelHellinger ; break ;
00118       case opt_KJS   : comparisonType = VlKernelJS ; break ;
00119       default:
00120         abort() ;
00121     }
00122   }
00123 
00124   /* allocate output */
00125   {
00126     mwSize dims [2] ;
00127     dims[0] = numDataX ;
00128     dims[1] = autoComparison ? numDataX : numDataY ;
00129     out[OUT_D] = mxCreateNumericArray (2, dims, classId, mxREAL) ;
00130   }
00131 
00132   /* If either numDataX or numDataY are null, their data pointers are
00133      null as well. This may confuse
00134      vl_eval_vector_comparison_on_all_pairs_*, so we intercept this as
00135      a special case. The same is true if dimension is null.
00136   */
00137 
00138   if (numDataX == 0 || (! autoComparison && numDataY == 0)) {
00139     return ;
00140   }
00141   if (dimension == 0) {
00142     return ;
00143   }
00144 
00145   /* make calculation */
00146   switch (classId) {
00147   case mxSINGLE_CLASS:
00148     {
00149       VlFloatVectorComparisonFunction f = vl_get_vector_comparison_function_f (comparisonType) ;
00150       if (autoComparison) {
00151         vl_eval_vector_comparison_on_all_pairs_f ((float*)mxGetData(out[OUT_D]),
00152                                                   dimension,
00153                                                   (float*)mxGetData(in[IN_X]), numDataX,
00154                                                   0, 0,
00155                                                   f) ;
00156       } else {
00157         vl_eval_vector_comparison_on_all_pairs_f ((float*)mxGetData(out[OUT_D]),
00158                                                   dimension,
00159                                                   (float*)mxGetData(in[IN_X]), numDataX,
00160                                                   (float*)mxGetData(in[IN_Y]), numDataY,
00161                                                   f) ;
00162       }
00163     }
00164     break ;
00165 
00166     case mxDOUBLE_CLASS:
00167     {
00168       VlDoubleVectorComparisonFunction f = vl_get_vector_comparison_function_d (comparisonType) ;
00169       if (autoComparison) {
00170         vl_eval_vector_comparison_on_all_pairs_d ((double*)mxGetData(out[OUT_D]),
00171                                                   dimension,
00172                                                   (double*)mxGetData(in[IN_X]), numDataX,
00173                                                   0, 0,
00174                                                   f) ;
00175       } else {
00176         vl_eval_vector_comparison_on_all_pairs_d ((double*)mxGetData(out[OUT_D]),
00177                                                   dimension,
00178                                                   (double*)mxGetData(in[IN_X]), numDataX,
00179                                                   (double*)mxGetData(in[IN_Y]), numDataY,
00180                                                   f) ;
00181       }
00182     }
00183     break ;
00184 
00185   default:
00186     abort() ;
00187   }
00188 }


libvlfeat
Author(s): Andrea Vedaldi
autogenerated on Thu Jun 6 2019 20:25:51