hikmeans.c
Go to the documentation of this file.
00001 
00007 /*
00008 Copyright (C) 2007-12 Andrea Vedaldi and Brian Fulkerson.
00009 All rights reserved.
00010 
00011 This file is part of the VLFeat library and is made available under
00012 the terms of the BSD license (see the COPYING file).
00013 */
00014 
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039 #include <math.h>
00040 
00041 #include "hikmeans.h"
00042 
00055 vl_uint8*
00056 vl_hikm_copy_subset (vl_uint8 const * data,
00057                      vl_uint32 *ids,
00058                      vl_size N, vl_size M,
00059                      vl_uint32 id, vl_size *N2)
00060 {
00061   vl_uindex i ;
00062   vl_size count = 0;
00063 
00064   /* count how many data points with this label there are */
00065   for (i = 0 ; i < N ; i++) {
00066     if (ids[i] == id) {
00067       count ++ ;
00068     }
00069   }
00070   *N2 = count ;
00071 
00072   /* copy each datum to the buffer */
00073   {
00074     vl_uint8 *new_data = vl_malloc (sizeof(*new_data) * M * count);
00075     count = 0;
00076     for (i = 0 ; i < N ; i ++) {
00077       if (ids[i] == id) {
00078         memcpy(new_data + count * M,
00079                data + i * M,
00080                sizeof(*new_data) * M);
00081         count ++ ;
00082       }
00083     }
00084     *N2 = count ;
00085     return new_data ;
00086   }
00087 }
00088 
00103 static VlHIKMNode *
00104 xmeans (VlHIKMTree *tree,
00105         vl_uint8 const *data,
00106         vl_size N, vl_size K, vl_size height)
00107 {
00108   VlHIKMNode *node = vl_malloc (sizeof(*node)) ;
00109   vl_uint32 *ids = vl_malloc (sizeof(*ids) * N) ;
00110 
00111   node->filter = vl_ikm_new (tree -> method) ;
00112   node->children = (height == 1) ? 0 : vl_malloc (sizeof(*node->children) * K) ;
00113 
00114   vl_ikm_set_max_niters (node->filter, tree->max_niters) ;
00115   vl_ikm_set_verbosity  (node->filter, tree->verb - 1  ) ;
00116   vl_ikm_init_rand_data (node->filter, data, tree->M, N, K) ;
00117   vl_ikm_train (node->filter, data, N) ;
00118   vl_ikm_push (node->filter, ids, data, N) ;
00119 
00120   /* recursively process each child */
00121   if (height > 1) {
00122     vl_uindex k ;
00123     for (k = 0 ; k < K ; ++k) {
00124       vl_size partition_N ;
00125       vl_size partition_K ;
00126       vl_uint8 *partition ;
00127 
00128       partition = vl_hikm_copy_subset
00129         (data, ids, N, tree->M, (vl_uint32)k, &partition_N) ;
00130 
00131       partition_K = VL_MIN (K, partition_N) ;
00132 
00133       node->children [k] = xmeans
00134         (tree, partition, partition_N, partition_K, height - 1) ;
00135 
00136       vl_free (partition) ;
00137 
00138       if (tree->verb > (signed)tree->depth - (signed)height) {
00139         VL_PRINTF("hikmeans: branch at depth %d: %6.1f %% completed\n",
00140                   tree->depth - height,
00141                   (double) (k+1) / K * 100) ;
00142       }
00143     }
00144   }
00145 
00146   vl_free (ids) ;
00147   return node ;
00148 }
00149 
00159 static void
00160 xdelete (VlHIKMNode *node)
00161 {
00162   if(node) {
00163     vl_uindex k ;
00164     if (node->children) {
00165       for(k = 0 ; k < vl_ikm_get_K (node->filter) ; ++k)
00166         xdelete (node->children[k]) ;
00167       vl_free (node->children) ;
00168     }
00169     if (node->filter) {
00170       vl_ikm_delete (node->filter) ;
00171     }
00172     vl_free(node);
00173   }
00174 }
00175 
00182 VlHIKMTree *
00183 vl_hikm_new (int method)
00184 {
00185   VlHIKMTree *f = vl_calloc (sizeof(VlHIKMTree), 1) ;
00186   f->max_niters = 200 ;
00187   f->method = method ;
00188   return f ;
00189 }
00190 
00196 void
00197 vl_hikm_delete (VlHIKMTree *f)
00198 {
00199   if (f) {
00200     xdelete (f->root) ;
00201     vl_free (f) ;
00202   }
00203 }
00204 
00216 void
00217 vl_hikm_init (VlHIKMTree *f, vl_size M, vl_size K, vl_size depth)
00218 {
00219   assert(depth > 0) ;
00220   assert(M > 0) ;
00221   assert(K > 0) ;
00222 
00223   xdelete (f -> root) ;
00224   f->root = 0;
00225   f->M = M ;
00226   f->K = K ;
00227   f->depth = depth ;
00228 }
00229 
00237 void
00238 vl_hikm_train (VlHIKMTree *f, vl_uint8 const *data, vl_size N)
00239 {
00240   f->root= xmeans (f, data, N, VL_MIN(f->K, N), f->depth) ;
00241 }
00242 
00256 void
00257 vl_hikm_push (VlHIKMTree *f, vl_uint32 *asgn, vl_uint8 const *data, vl_size N)
00258 {
00259   vl_uindex i, d ;
00260   vl_size M = vl_hikm_get_ndims (f) ;
00261   vl_size depth = vl_hikm_get_depth (f) ;
00262 
00263   /* for each datum */
00264   for(i = 0 ; i < N ; i++) {
00265     VlHIKMNode *node = f->root ;
00266     d = 0 ;
00267     while (node) {
00268       vl_uint32 best ;
00269       vl_ikm_push (node->filter,
00270                    &best,
00271                    data + i * M, 1) ;
00272       asgn[i * depth + d] = best ;
00273       ++ d ;
00274       if (!node->children) break ;
00275       node = node->children [best] ;
00276     }
00277   }
00278 }
00279 
00280 /* ---------------------------------------------------------------- */
00281 /*                                              Setters and getters */
00282 /* ---------------------------------------------------------------- */
00283 
00289 vl_size
00290 vl_hikm_get_ndims (VlHIKMTree const* f)
00291 {
00292   return f->M ;
00293 }
00294 
00300 vl_size
00301 vl_hikm_get_K (VlHIKMTree const *f)
00302 {
00303   return f->K ;
00304 }
00305 
00311 vl_size
00312 vl_hikm_get_depth (VlHIKMTree const *f)
00313 {
00314   return f->depth ;
00315 }
00316 
00317 
00323 int
00324 vl_hikm_get_verbosity (VlHIKMTree const *f)
00325 {
00326   return f->verb ;
00327 }
00328 
00334 vl_size
00335 vl_hikm_get_max_niters (VlHIKMTree const *f)
00336 {
00337   return f-> max_niters ;
00338 }
00339 
00345 VlHIKMNode const *
00346 vl_hikm_get_root (VlHIKMTree const *f)
00347 {
00348   return f->root ;
00349 }
00350 
00356 void
00357 vl_hikm_set_verbosity (VlHIKMTree *f, int verb)
00358 {
00359   f->verb = verb ;
00360 }
00361 
00367 void
00368 vl_hikm_set_max_niters (VlHIKMTree *f, int max_niters)
00369 {
00370   f->max_niters = max_niters ;
00371 }


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