00001
00007
00008
00009
00010
00011
00012
00013
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <string.h>
00038 #include <math.h>
00039
00040 #include "hikmeans.h"
00041
00056 vl_uint8*
00057 vl_hikm_copy_subset (vl_uint8 const * data,
00058 vl_uint * ids,
00059 int N, int M,
00060 vl_uint id, int *N2)
00061 {
00062 int i ;
00063 int count = 0;
00064
00065
00066 for (i = 0 ; i < N ; i++)
00067 if (ids[i] == id)
00068 count ++ ;
00069 *N2 = count ;
00070
00071
00072 {
00073 vl_uint8 * new_data = vl_malloc (sizeof(vl_uint8) * M * count);
00074 count = 0;
00075 for (i = 0 ; i < N ; i ++)
00076 if (ids[i] == id)
00077 {
00078 memcpy(new_data + count * M,
00079 data + i * M,
00080 sizeof(vl_uint8) * M);
00081 count ++ ;
00082 }
00083 *N2 = count ;
00084 return new_data ;
00085 }
00086 }
00087
00102 static VlHIKMNode *
00103 xmeans (VlHIKMTree *tree,
00104 vl_uint8 const *data,
00105 int N, int K, int height)
00106 {
00107 VlHIKMNode *node = vl_malloc (sizeof(VlHIKMNode)) ;
00108 vl_uint *ids = vl_malloc (sizeof(vl_uint) * N) ;
00109
00110 node-> filter = vl_ikm_new (tree -> method) ;
00111 node-> children = (height == 1) ? 0 : vl_malloc (sizeof(VlHIKMNode*) * K) ;
00112
00113 vl_ikm_set_max_niters (node->filter, tree->max_niters) ;
00114 vl_ikm_set_verbosity (node->filter, tree->verb - 1 ) ;
00115 vl_ikm_init_rand_data (node->filter, data, tree->M, N, K) ;
00116 vl_ikm_train (node->filter, data, N) ;
00117 vl_ikm_push (node->filter, ids, data, N) ;
00118
00119
00120 if (height > 1) {
00121 int k ;
00122 for (k = 0 ; k < K ; k ++) {
00123 int partition_N ;
00124 int partition_K ;
00125 vl_uint8 *partition ;
00126
00127 partition = vl_hikm_copy_subset
00128 (data, ids, N, tree->M, k, &partition_N) ;
00129
00130 partition_K = VL_MIN (K, partition_N) ;
00131
00132 node->children [k] = xmeans
00133 (tree, partition, partition_N, partition_K, height - 1) ;
00134
00135 vl_free (partition) ;
00136
00137 if (tree->verb > tree->depth - height) {
00138 VL_PRINTF("hikmeans: branch at depth %d: %6.1f %% completed\n",
00139 tree->depth - height,
00140 (double) (k+1) / K * 100) ;
00141 }
00142 }
00143 }
00144
00145 vl_free (ids) ;
00146 return node ;
00147 }
00148
00158 static void
00159 xdelete (VlHIKMNode *node)
00160 {
00161 if(node) {
00162 int k ;
00163 if (node->children) {
00164 for(k = 0 ; k < vl_ikm_get_K (node->filter) ; ++k)
00165 xdelete (node->children[k]) ;
00166 vl_free (node->children) ;
00167 }
00168 if (node->filter)
00169 vl_ikm_delete (node->filter) ;
00170 vl_free(node);
00171 }
00172 }
00173
00180 VL_EXPORT
00181 VlHIKMTree *
00182 vl_hikm_new (int method)
00183 {
00184 VlHIKMTree *f = vl_malloc (sizeof(VlHIKMTree)) ;
00185 f -> M = 0 ;
00186 f -> K = 0 ;
00187 f -> max_niters = 200 ;
00188 f -> method = method ;
00189 f -> verb = 0 ;
00190 f -> depth = 0 ;
00191 f -> root = 0 ;
00192 return f ;
00193 }
00194
00200 VL_EXPORT
00201 void
00202 vl_hikm_delete (VlHIKMTree *f)
00203 {
00204 if (f) {
00205 xdelete (f -> root) ;
00206 vl_free (f) ;
00207 }
00208 }
00209
00223 VL_EXPORT
00224 void
00225 vl_hikm_init (VlHIKMTree *f, int M, int K, int depth)
00226 {
00227 assert(depth > 0) ;
00228 assert(M > 0) ;
00229 assert(K > 0) ;
00230
00231 xdelete (f -> root) ;
00232 f -> root = 0;
00233
00234 f -> M = M ;
00235 f -> K = K ;
00236 f -> depth = depth ;
00237 }
00238
00246 VL_EXPORT
00247 void
00248 vl_hikm_train (VlHIKMTree *f, vl_uint8 const *data, int N)
00249 {
00250 f -> root = xmeans (f, data, N, VL_MIN(f->K, N), f->depth) ;
00251 }
00252
00267 VL_EXPORT
00268 void
00269 vl_hikm_push (VlHIKMTree *f, vl_uint *asgn, vl_uint8 const *data, int N)
00270 {
00271 int i, d,
00272 M = vl_hikm_get_ndims (f),
00273 depth = vl_hikm_get_depth (f) ;
00274
00275
00276 for(i = 0 ; i < N ; i++) {
00277 VlHIKMNode *node = f->root ;
00278 d = 0 ;
00279 while (node) {
00280
00281
00282
00283
00284
00285
00286
00287
00288 vl_uint best ;
00289 vl_ikm_push (node->filter, &best, data + i * M, 1) ;
00290
00291 asgn [i*depth + d] = best ;
00292 ++ d ;
00293
00294 if (!node->children) break ;
00295 node = node->children [best] ;
00296 }
00297 }
00298 }