vl_hikmeanspush.c
Go to the documentation of this file.
00001 
00008 /*
00009 Copyright (C) 2014 Andrea Vedaldi.
00010 Copyright (C) 2007-12 Andrea Vedaldi and Brian Fulkerson.
00011 All rights reserved.
00012 
00013 This file is part of the VLFeat library and is made available under
00014 the terms of the BSD license (see the COPYING file).
00015 */
00016 
00017 #include<mexutils.h>
00018 
00019 #include<stdio.h>
00020 #include<stdlib.h>
00021 #include<math.h>
00022 #include<string.h>
00023 #include<assert.h>
00024 
00025 #include <vl/hikmeans.h>
00026 #include <vl/generic.h>
00027 
00028 enum {
00029   opt_method,
00030   opt_verbose
00031 } ;
00032 
00033 vlmxOption  options [] = {
00034   {"Method",       1,   opt_method      },
00035   {"Verbose",      0,   opt_verbose     },
00036   {0,              0,   0               }
00037 } ;
00038 
00039 #define NFIELDS(field_names) (sizeof(field_names)/sizeof(*field_names))
00040 
00041 
00047 static VlHIKMNode *
00048 xcreate (VlHIKMTree *tree, mxArray const *mnode, int i)
00049 {
00050   mxArray const *mcenters, *msub ;
00051   VlHIKMNode *node ;
00052   mwSize M ;
00053   mwSize node_K ;
00054   vl_uindex k ;
00055 
00056   /* sanity checks */
00057   mcenters = mxGetField(mnode, i, "centers") ;
00058   msub     = mxGetField(mnode, i, "sub") ;
00059 
00060   if (!mcenters ||
00061       mxGetClassID (mcenters) != mxINT32_CLASS  ||
00062       !vlmxIsMatrix (mcenters, -1, -1)) {
00063     mexErrMsgTxt("A NODE.CENTERS is not a INT32 matrix.") ;
00064   }
00065 
00066   M = mxGetM (mcenters) ;
00067   node_K = mxGetN (mcenters) ;
00068 
00069   if (M == 0) {
00070     mexErrMsgTxt("A NODE.CENTERS has zero rows.") ;
00071   }
00072   if ((vl_size)node_K > tree->K) {
00073     mexErrMsgTxt("A NODE.CENTERS has more columns than overall clusters TREE.K.") ;
00074   }
00075   if (tree->M == 0) {
00076     tree->M = M ;
00077   } else if (M != tree->M) {
00078     mexErrMsgTxt("A NODE.CENTERS field has inconsistent dimensionality.") ;
00079   }
00080 
00081   node = mxMalloc (sizeof(VlHIKMNode)) ;
00082   node->filter = vl_ikm_new (tree->method) ;
00083   node->children = 0 ;
00084 
00085   vl_ikm_init (node->filter, mxGetData(mcenters), M, node_K) ;
00086 
00087   /* has any childer? */
00088   if (msub) {
00089 
00090     /* sanity checks */
00091     if (mxGetClassID (msub) != mxSTRUCT_CLASS) {
00092       mexErrMsgTxt("A NODE.SUB is not a MATLAB structure array.") ;
00093     }
00094     if (mxGetNumberOfElements (msub) != node_K) {
00095       mexErrMsgTxt("A NODE.SUB does not correspond to NODE.CENTERS.") ;
00096     }
00097 
00098     node->children = mxMalloc (sizeof(VlHIKMNode *) * node_K) ;
00099     for(k = 0 ; k < node_K ; ++ k) {
00100       node->children[k] = xcreate (tree, msub, k) ;
00101     }
00102   }
00103   return node ;
00104 }
00105 
00111 static VlHIKMTree*
00112 matlab_to_hikm (mxArray const *mtree, int method_type)
00113 {
00114   VlHIKMTree *tree ;
00115   mxArray *mK ;
00116   mxArray *mdepth ;
00117   vl_index K = 0 ;
00118   vl_index depth = 0 ;
00119 
00120   VL_USE_MATLAB_ENV ;
00121 
00122   if (mxGetClassID (mtree) != mxSTRUCT_CLASS) {
00123     mexErrMsgTxt("TREE must be a MATLAB structure.") ;
00124   }
00125 
00126   mK = mxGetField(mtree, 0, "K") ;
00127   mdepth = mxGetField(mtree, 0, "depth") ;
00128 
00129   if (!mK ||
00130       !vlmxIsPlainScalar(mK) ||
00131       (K = (int) *mxGetPr(mK)) < 1) {
00132     mexErrMsgTxt("TREE.K must be a DOUBLE not smaller than one.") ;
00133   }
00134 
00135   if (!mdepth                    ||
00136       !vlmxIsPlainScalar (mdepth)    ||
00137       (depth = (int) *mxGetPr (mdepth)) < 1) {
00138     mexErrMsgTxt("TREE.DEPTH must be a DOUBLE not smaller than one.") ;
00139   }
00140 
00141   tree = mxMalloc (sizeof(VlHIKMTree)) ;
00142   tree->depth = (vl_size)depth ;
00143   tree->K = (vl_size)K ;
00144   tree->M = 0 ; /* to be initialized later */
00145   tree->method = method_type ;
00146   tree->root = xcreate (tree, mtree, 0) ;
00147   return tree ;
00148 }
00149 
00150 /* ---------------------------------------------------------------- */
00153 void mexFunction (int nout, mxArray * out[],
00154                   int nin, const mxArray * in[])
00155 {
00156   enum {IN_TREE = 0, IN_DATA, IN_END} ;
00157   enum {OUT_ASGN = 0} ;
00158   vl_uint8 const *data;
00159 
00160   int opt ;
00161   int next = IN_END ;
00162   mxArray const  *optarg ;
00163 
00164   mwSize N = 0 ;
00165   int method_type = VL_IKM_LLOYD ;
00166   int verb = 0 ;
00167 
00168   /* -----------------------------------------------------------------
00169    *                                               Check the arguments
00170    * -------------------------------------------------------------- */
00171   if (nin < 2)
00172     mexErrMsgTxt ("At least two arguments required.");
00173   else if (nout > 1)
00174     mexErrMsgTxt ("Too many output arguments.");
00175 
00176   if (mxGetClassID (in[IN_DATA]) != mxUINT8_CLASS) {
00177     mexErrMsgTxt ("DATA must be of class UINT8");
00178   }
00179 
00180   N = mxGetN(in[IN_DATA]) ;
00181   data = (vl_uint8 *) mxGetPr (in[IN_DATA]);
00182 
00183   while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
00184     char buf [1024] ;
00185 
00186     switch (opt) {
00187 
00188     case opt_verbose :
00189       ++ verb ;
00190       break ;
00191 
00192     case opt_method :
00193       if (!vlmxIsString (optarg, -1)) {
00194         mexErrMsgTxt("'Method' must be a string.") ;
00195       }
00196       if (mxGetString (optarg, buf, sizeof(buf))) {
00197         mexErrMsgTxt("Option argument too long.") ;
00198       }
00199       if (strcmp("lloyd", buf) == 0) {
00200         method_type = VL_IKM_LLOYD ;
00201       } else if (strcmp("elkan", buf) == 0) {
00202         method_type = VL_IKM_ELKAN ;
00203       } else {
00204         mexErrMsgTxt("Unknown 'Method' type.") ;
00205       }
00206       break ;
00207 
00208     default :
00209       abort() ;
00210     }
00211   }
00212 
00213   /* -----------------------------------------------------------------
00214    *                                                        Do the job
00215    * -------------------------------------------------------------- */
00216 
00217   {
00218     VlHIKMTree *tree ;
00219     vl_uint32 *ids  ;
00220     vl_uindex j;
00221     vl_size depth ;
00222 
00223     tree = matlab_to_hikm (in[IN_TREE], method_type) ;
00224     depth = vl_hikm_get_depth (tree) ;
00225 
00226     if (verb) {
00227       mexPrintf("vl_hikmeanspush: ndims: %d K: %d depth: %d\n",
00228                 vl_hikm_get_ndims (tree),
00229                 vl_hikm_get_K (tree),
00230                 depth) ;
00231     }
00232 
00233     out[OUT_ASGN] = mxCreateNumericMatrix (depth, N, mxUINT32_CLASS, mxREAL) ;
00234     ids = mxGetData (out[OUT_ASGN]) ;
00235 
00236     vl_hikm_push (tree, ids, data, N) ;
00237     vl_hikm_delete (tree) ;
00238 
00239     for (j = 0 ; j < N * depth ; j++) ids[j] ++ ;
00240   }
00241 }


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