00001
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "mexutils.h"
00015 #include <vl/homkermap.h>
00016 #include <vl/mathop.h>
00017 #include <vl/stringop.h>
00018
00019 enum {
00020 opt_KCHI2,
00021 opt_KL1,
00022 opt_KJS,
00023 opt_KINTERS,
00024 opt_kernel,
00025 opt_gamma,
00026 opt_period,
00027 opt_window
00028 } ;
00029
00030 vlmxOption options [] = {
00031 {"kl1", 0, opt_KL1 },
00032 {"kchi2", 0, opt_KCHI2 },
00033 {"kjs", 0, opt_KJS },
00034 {"kinters", 0, opt_KINTERS },
00035 {"kernel", 1, opt_kernel },
00036 {"gamma", 1, opt_gamma },
00037 {"period", 1, opt_period },
00038 {"window", 1, opt_window },
00039 {0, 0, 0 }
00040 } ;
00041
00042
00043
00044
00045
00046 void
00047 mexFunction(int nout, mxArray *out[],
00048 int nin, const mxArray *in[])
00049 {
00050
00051 typedef int unsigned data_t ;
00052
00053 enum {IN_X = 0, IN_N, IN_END} ;
00054 enum {OUT_V = 0} ;
00055 VlHomogeneousKernelType kernelType = VlHomogeneousKernelChi2 ;
00056 VlHomogeneousKernelMapWindowType windowType = VlHomogeneousKernelMapWindowRectangular ;
00057 mwSize numDimensions ;
00058 mwSize const * dimensions ;
00059 mxClassID dataClassId ;
00060 double gamma = 1.0 ;
00061 int n ;
00062 double period = -1 ;
00063
00064
00065 int opt ;
00066 int next = IN_END ;
00067 mxArray const *optarg ;
00068
00069 VL_USE_MATLAB_ENV ;
00070
00071
00072
00073
00074
00075 if (nout > 1) {
00076 vlmxError(vlmxErrTooManyOutputArguments, NULL) ;
00077 }
00078 if (nin < IN_END) {
00079 vlmxError(vlmxErrNotEnoughInputArguments, NULL) ;
00080 }
00081
00082 dataClassId = mxGetClassID(IN(X)) ;
00083 if (dataClassId != mxDOUBLE_CLASS &&
00084 dataClassId != mxSINGLE_CLASS) {
00085 vlmxError(vlmxErrInvalidArgument, "X is neither DOUBLE nor SINGLE.") ;
00086 }
00087
00088 numDimensions = mxGetNumberOfDimensions(IN(X)) ;
00089 dimensions = mxGetDimensions(IN(X)) ;
00090
00091 if (! vlmxIsPlainScalar(IN(N))) {
00092 vlmxError(vlmxErrInvalidArgument, "N is not a scalar.") ;
00093 }
00094 n = *mxGetPr(IN(N)) ;
00095 if (n < 0) {
00096 vlmxError(vlmxErrInvalidArgument, "N is negative.") ;
00097 }
00098
00099 while ((opt = vlmxNextOption(in, nin, options, &next, &optarg)) >= 0) {
00100 switch (opt) {
00101 case opt_KINTERS:
00102 case opt_KL1:
00103 kernelType = VlHomogeneousKernelIntersection ;
00104 break ;
00105 case opt_KCHI2:
00106 kernelType = VlHomogeneousKernelChi2 ;
00107 break ;
00108 case opt_KJS:
00109 kernelType = VlHomogeneousKernelJS ;
00110 break ;
00111 case opt_kernel:
00112
00113
00114 next-- ;
00115 break ;
00116 case opt_period:
00117 if (! vlmxIsPlainScalar(optarg)){
00118 vlmxError(vlmxErrInvalidArgument, "PERIOD is not a scalar.") ;
00119 }
00120 period = *mxGetPr(optarg) ;
00121 if (period <= 0) {
00122 vlmxError(vlmxErrInvalidArgument, "PERIOD is not positive.") ;
00123 }
00124 break ;
00125 case opt_gamma:
00126 if (! vlmxIsPlainScalar(optarg)){
00127 vlmxError(vlmxErrInvalidArgument, "GAMMA is not a scalar.") ;
00128 }
00129 gamma = *mxGetPr(optarg) ;
00130 if (gamma <= 0) {
00131 vlmxError(vlmxErrInvalidArgument, "GAMMA is not positive.") ;
00132 }
00133 break ;
00134 case opt_window:
00135 if (! vlmxIsString(optarg,-1)){
00136 vlmxError(vlmxErrInvalidArgument, "WINDOW is not a string.") ;
00137 } else {
00138 char buffer [1024] ;
00139 mxGetString(optarg, buffer, sizeof(buffer) / sizeof(char)) ;
00140 if (vl_string_casei_cmp("uniform", buffer) == 0) {
00141 windowType = VlHomogeneousKernelMapWindowUniform ;
00142 } else if (vl_string_casei_cmp("rectangular", buffer) == 0) {
00143 windowType = VlHomogeneousKernelMapWindowRectangular ;
00144 } else {
00145 vlmxError(vlmxErrInvalidArgument, "WINDOW=%s is not recognized.", buffer) ;
00146 }
00147 }
00148 break ;
00149 default:
00150 abort() ;
00151 }
00152 }
00153
00154
00155
00156
00157
00158 {
00159 vl_uindex j ;
00160 vl_size numElements = mxGetNumberOfElements(IN(X)) ;
00161 VlHomogeneousKernelMap * map = vl_homogeneouskernelmap_new (kernelType, gamma, n, period, windowType) ;
00162 mwSize extDimensions [20] ;
00163 for (j = 0 ; j < numDimensions ; ++j) extDimensions[j] = dimensions[j] ;
00164 extDimensions[0] *= 2*n+1 ;
00165 OUT(V) = mxCreateNumericArray(numDimensions, extDimensions, dataClassId, mxREAL) ;
00166 switch (dataClassId) {
00167 case mxDOUBLE_CLASS :
00168 {
00169 double * X = mxGetData(IN(X)) ;
00170 double * V = mxGetData(OUT(V)) ;
00171 for (j = 0 ; j < numElements ; ++j) {
00172 vl_homogeneouskernelmap_evaluate_d(map, V, 1, *X++) ;
00173 V += 2*n+1 ;
00174 }
00175 break ;
00176 }
00177 case mxSINGLE_CLASS :
00178 {
00179 float * X = mxGetData(IN(X)) ;
00180 float * V = mxGetData(OUT(V)) ;
00181 for (j = 0 ; j < numElements ; ++j) {
00182 vl_homogeneouskernelmap_evaluate_f(map, V, 1, *X++) ;
00183 V += 2*n+1 ;
00184 }
00185 break ;
00186 }
00187 default:
00188 abort() ;
00189 }
00190 vl_homogeneouskernelmap_delete (map) ;
00191 }
00192 }