00001
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 #include <string.h>
00031 #include <math.h>
00032
00033 #include "hikmeans.h"
00034
00049 vl_uint8*
00050 vl_hikm_copy_subset (vl_uint8 const * data,
00051 vl_uint * ids,
00052 int N, int M,
00053 vl_uint id, int *N2)
00054 {
00055 int i ;
00056 int count = 0;
00057
00058
00059 for (i = 0 ; i < N ; i++)
00060 if (ids[i] == id)
00061 count ++ ;
00062 *N2 = count ;
00063
00064
00065 {
00066 vl_uint8 * new_data = vl_malloc (sizeof(vl_uint8) * M * count);
00067 count = 0;
00068 for (i = 0 ; i < N ; i ++)
00069 if (ids[i] == id)
00070 {
00071 memcpy(new_data + count * M,
00072 data + i * M,
00073 sizeof(vl_uint8) * M);
00074 count ++ ;
00075 }
00076 *N2 = count ;
00077 return new_data ;
00078 }
00079 }
00080
00095 static VlHIKMNode *
00096 xmeans (VlHIKMTree *tree,
00097 vl_uint8 const *data,
00098 int N, int K, int height)
00099 {
00100 VlHIKMNode *node = vl_malloc (sizeof(VlHIKMNode)) ;
00101 vl_uint *ids = vl_malloc (sizeof(vl_uint) * N) ;
00102
00103 node-> filter = vl_ikm_new (tree -> method) ;
00104 node-> children = (height == 1) ? 0 : vl_malloc (sizeof(VlHIKMNode*) * K) ;
00105
00106 vl_ikm_set_max_niters (node->filter, tree->max_niters) ;
00107 vl_ikm_set_verbosity (node->filter, tree->verb - 1 ) ;
00108 vl_ikm_init_rand_data (node->filter, data, tree->M, N, K) ;
00109 vl_ikm_train (node->filter, data, N) ;
00110 vl_ikm_push (node->filter, ids, data, N) ;
00111
00112
00113 if (height > 1) {
00114 int k ;
00115 for (k = 0 ; k < K ; k ++) {
00116 int partition_N ;
00117 int partition_K ;
00118 vl_uint8 *partition ;
00119
00120 partition = vl_hikm_copy_subset
00121 (data, ids, N, tree->M, k, &partition_N) ;
00122
00123 partition_K = VL_MIN (K, partition_N) ;
00124
00125 node->children [k] = xmeans
00126 (tree, partition, partition_N, partition_K, height - 1) ;
00127
00128 vl_free (partition) ;
00129
00130 if (tree->verb > tree->depth - height) {
00131 VL_PRINTF("hikmeans: branch at depth %d: %6.1f %% completed\n",
00132 tree->depth - height,
00133 (double) (k+1) / K * 100) ;
00134 }
00135 }
00136 }
00137
00138 vl_free (ids) ;
00139 return node ;
00140 }
00141
00151 static void
00152 xdelete (VlHIKMNode *node)
00153 {
00154 if(node) {
00155 int k ;
00156 if (node->children) {
00157 for(k = 0 ; k < vl_ikm_get_K (node->filter) ; ++k)
00158 xdelete (node->children[k]) ;
00159 vl_free (node->children) ;
00160 }
00161 if (node->filter)
00162 vl_ikm_delete (node->filter) ;
00163 vl_free(node);
00164 }
00165 }
00166
00173 VL_EXPORT
00174 VlHIKMTree *
00175 vl_hikm_new (int method)
00176 {
00177 VlHIKMTree *f = vl_malloc (sizeof(VlHIKMTree)) ;
00178 f -> M = 0 ;
00179 f -> K = 0 ;
00180 f -> max_niters = 200 ;
00181 f -> method = method ;
00182 f -> verb = 0 ;
00183 f -> depth = 0 ;
00184 f -> root = 0 ;
00185 return f ;
00186 }
00187
00193 VL_EXPORT
00194 void
00195 vl_hikm_delete (VlHIKMTree *f)
00196 {
00197 if (f) {
00198 xdelete (f -> root) ;
00199 vl_free (f) ;
00200 }
00201 }
00202
00216 VL_EXPORT
00217 void
00218 vl_hikm_init (VlHIKMTree *f, int M, int K, int depth)
00219 {
00220 assert(depth > 0) ;
00221 assert(M > 0) ;
00222 assert(K > 0) ;
00223
00224 xdelete (f -> root) ;
00225 f -> root = 0;
00226
00227 f -> M = M ;
00228 f -> K = K ;
00229 f -> depth = depth ;
00230 }
00231
00239 VL_EXPORT
00240 void
00241 vl_hikm_train (VlHIKMTree *f, vl_uint8 const *data, int N)
00242 {
00243 f -> root = xmeans (f, data, N, VL_MIN(f->K, N), f->depth) ;
00244 }
00245
00260 VL_EXPORT
00261 void
00262 vl_hikm_push (VlHIKMTree *f, vl_uint *asgn, vl_uint8 const *data, int N)
00263 {
00264 int i, d,
00265 M = vl_hikm_get_ndims (f),
00266 depth = vl_hikm_get_depth (f) ;
00267
00268
00269 for(i = 0 ; i < N ; i++) {
00270 VlHIKMNode *node = f->root ;
00271 d = 0 ;
00272 while (node) {
00273
00274
00275
00276
00277
00278
00279
00280
00281 vl_uint best ;
00282 vl_ikm_push (node->filter, &best, data + i * M, 1) ;
00283
00284 asgn [i*depth + d] = best ;
00285 ++ d ;
00286
00287 if (!node->children) break ;
00288 node = node->children [best] ;
00289 }
00290 }
00291 }