00001
00006
00007
00008
00009
00010
00011
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
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
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
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
00133
00134
00135
00136
00137
00138 if (numDataX == 0 || (! autoComparison && numDataY == 0)) {
00139 return ;
00140 }
00141 if (dimension == 0) {
00142 return ;
00143 }
00144
00145
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 }