00001
00007
00008
00009
00010
00011
00012
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
00065 for (i = 0 ; i < N ; i++) {
00066 if (ids[i] == id) {
00067 count ++ ;
00068 }
00069 }
00070 *N2 = count ;
00071
00072
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
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
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
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 }