You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
138 lines
3.4 KiB
138 lines
3.4 KiB
/** @file ikmeans_lloyd.tc
|
|
** @brief Integer K-Means - LLoyd Algorithm - Definition
|
|
** @author Brian Fulkerson
|
|
** @author Andrea Vedaldi
|
|
**/
|
|
|
|
/*
|
|
Copyright (C) 2007-12 Andrea Vedaldi and Brian Fulkerson.
|
|
All rights reserved.
|
|
|
|
This file is part of the VLFeat library and is made available under
|
|
the terms of the BSD license (see the COPYING file).
|
|
*/
|
|
|
|
/** @internal
|
|
** @brief Helper function to initialize a filter for Lloyd algorithm
|
|
**
|
|
** @param f filter.
|
|
**/
|
|
|
|
static void
|
|
vl_ikm_init_lloyd (VlIKMFilt * f VL_UNUSED)
|
|
{ }
|
|
|
|
/** @internal
|
|
** @brief LLoyd algorithm
|
|
** @param f IKM quantizer.
|
|
** @param data Training data.
|
|
** @param N Number of traning data.
|
|
** @return error code.
|
|
**/
|
|
|
|
static int
|
|
vl_ikm_train_lloyd (VlIKMFilt* f, vl_uint8 const* data, vl_size N)
|
|
{
|
|
int err = 0 ;
|
|
vl_uindex iter, i, j, k ;
|
|
vl_uint32 *asgn = vl_malloc (sizeof(vl_uint32) * N) ;
|
|
vl_uint32 *counts = vl_malloc (sizeof(vl_uint32) * N) ;
|
|
|
|
for (iter = 0 ; 1 ; ++ iter) {
|
|
vl_bool done = 1 ;
|
|
|
|
/* ---------------------------------------------------------------
|
|
* Calc. assignments
|
|
* ------------------------------------------------------------ */
|
|
|
|
for (j = 0 ; j < N ; ++j) {
|
|
vl_ikmacc_t best_dist = 0 ;
|
|
vl_index best = -1 ;
|
|
|
|
for (k = 0; k < f->K ; ++k) {
|
|
vl_ikmacc_t dist = 0 ;
|
|
|
|
/* compute distance with this center */
|
|
for (i = 0; i < f->M ; ++i) {
|
|
vl_ikmacc_t delta =
|
|
data [j * f->M + i] - f->centers [k * f->M + i] ;
|
|
dist += delta * delta ;
|
|
}
|
|
|
|
/* compare with current best */
|
|
if (best == -1 || dist < best_dist) {
|
|
best = k ;
|
|
best_dist = dist ;
|
|
}
|
|
}
|
|
if (asgn [j] != best) {
|
|
asgn [j] = (vl_uint32) best ;
|
|
done = 0 ;
|
|
}
|
|
}
|
|
|
|
/* stopping condition */
|
|
if (done || iter == f->max_niters) break ;
|
|
|
|
/* ---------------------------------------------------------------
|
|
* Calc. centers
|
|
* ------------------------------------------------------------ */
|
|
|
|
/* re-compute centers */
|
|
memset (f->centers, 0, sizeof(*f->centers) * f->M * f->K);
|
|
memset (counts, 0, sizeof(*counts) * f->K);
|
|
for (j = 0; j < N; ++j) {
|
|
vl_uindex this_center = asgn [j] ;
|
|
++ counts [this_center] ;
|
|
for (i = 0; i < f->M ; ++i) {
|
|
f->centers [this_center * f->M + i] += data[j * f->M + i] ;
|
|
}
|
|
}
|
|
|
|
for (k = 0; k < f->K; ++k) {
|
|
vl_index n = counts [k];
|
|
if (n > 0xffffff) {
|
|
err = 1 ;
|
|
}
|
|
if (n > 0) {
|
|
for (i = 0; i < f->M; ++i) {
|
|
f->centers [k * f->M + i] /= n;
|
|
}
|
|
} else {
|
|
/*
|
|
If no data are assigned to the center, it is not changed
|
|
with respect to the previous iteration, so we do not do anything.
|
|
*/
|
|
}
|
|
}
|
|
}
|
|
|
|
vl_free (counts) ;
|
|
vl_free (asgn) ;
|
|
return err ;
|
|
}
|
|
|
|
|
|
/** @internal
|
|
** @brief LLoyd algorithm
|
|
** @param f IKM quantizer.
|
|
** @param asgn Assignments (out).
|
|
** @param data Data to quantize.
|
|
** @param N Number of data.
|
|
**/
|
|
|
|
static void
|
|
vl_ikm_push_lloyd (VlIKMFilt *f, vl_uint32 *asgn, vl_uint8 const *data, vl_size N)
|
|
{
|
|
vl_uindex j ;
|
|
for(j = 0 ; j < N ; ++j) {
|
|
asgn[j] = vl_ikm_push_one (f->centers, data + j * f->M, f->M, f->K);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Local Variables: *
|
|
* mode: C *
|
|
* End: *
|
|
*/
|