annotate elbg.c @ 7351:1502ba3beb72 libavcodec

The codebook generator algorithm involves picking three different codebook centroids ("high utility", "low utility" and "closest to the low utility one"). This change avoid the corner case of choosing two times the same centroid.
author vitor
date Wed, 23 Jul 2008 03:54:31 +0000
parents f7cbb7733146
children c2318e551ff5
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
5095
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
1 /*
5219
661eff5542cb Add my last name to copyright headers
vitor
parents: 5122
diff changeset
2 * Copyright (C) 2007 Vitor Sessak <vitor1001@gmail.com>
5095
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
3 *
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
4 * This file is part of FFmpeg.
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
5 *
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
6 * FFmpeg is free software; you can redistribute it and/or
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
7 * modify it under the terms of the GNU Lesser General Public
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
8 * License as published by the Free Software Foundation; either
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
9 * version 2.1 of the License, or (at your option) any later version.
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
10 *
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
11 * FFmpeg is distributed in the hope that it will be useful,
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
14 * Lesser General Public License for more details.
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
15 *
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
16 * You should have received a copy of the GNU Lesser General Public
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
17 * License along with FFmpeg; if not, write to the Free Software
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
19 */
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
20
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
21 /**
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
22 * @file cbook_gen.c
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
23 * Codebook Generator using the ELBG algorithm
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
24 */
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
25
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
26 #include <string.h>
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
27
6763
f7cbb7733146 Use full path for #includes from another directory.
diego
parents: 5219
diff changeset
28 #include "libavutil/random.h"
5095
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
29 #include "elbg.h"
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
30 #include "avcodec.h"
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
31
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
32 #define DELTA_ERR_MAX 0.1 ///< Precision of the ELBG algorithm (as percentual error)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
33
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
34 /**
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
35 * In the ELBG jargon, a cell is the set of points that are closest to a
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
36 * codebook entry. Not to be confused with a RoQ Video cell. */
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
37 typedef struct cell_s {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
38 int index;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
39 struct cell_s *next;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
40 } cell;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
41
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
42 /**
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
43 * ELBG internal data
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
44 */
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
45 typedef struct{
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
46 int error;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
47 int dim;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
48 int numCB;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
49 int *codebook;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
50 cell **cells;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
51 int *utility;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
52 int *utility_inc;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
53 int *nearest_cb;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
54 int *points;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
55 AVRandomState *rand_state;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
56 } elbg_data;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
57
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
58 static inline int distance_limited(int *a, int *b, int dim, int limit)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
59 {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
60 int i, dist=0;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
61 for (i=0; i<dim; i++) {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
62 dist += (a[i] - b[i])*(a[i] - b[i]);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
63 if (dist > limit)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
64 return INT_MAX;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
65 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
66
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
67 return dist;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
68 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
69
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
70 static inline void vect_division(int *res, int *vect, int div, int dim)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
71 {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
72 int i;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
73 if (div > 1)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
74 for (i=0; i<dim; i++)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
75 res[i] = ROUNDED_DIV(vect[i],div);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
76 else if (res != vect)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
77 memcpy(res, vect, dim*sizeof(int));
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
78
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
79 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
80
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
81 static int eval_error_cell(elbg_data *elbg, int *centroid, cell *cells)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
82 {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
83 int error=0;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
84 for (; cells; cells=cells->next)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
85 error += distance_limited(centroid, elbg->points + cells->index*elbg->dim, elbg->dim, INT_MAX);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
86
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
87 return error;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
88 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
89
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
90 static int get_closest_codebook(elbg_data *elbg, int index)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
91 {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
92 int i, pick=0, diff, diff_min = INT_MAX;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
93 for (i=0; i<elbg->numCB; i++)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
94 if (i != index) {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
95 diff = distance_limited(elbg->codebook + i*elbg->dim, elbg->codebook + index*elbg->dim, elbg->dim, diff_min);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
96 if (diff < diff_min) {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
97 pick = i;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
98 diff_min = diff;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
99 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
100 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
101 return pick;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
102 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
103
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
104 static int get_high_utility_cell(elbg_data *elbg)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
105 {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
106 int i=0;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
107 /* Using linear search, do binary if it ever turns to be speed critical */
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
108 int r = av_random(elbg->rand_state)%elbg->utility_inc[elbg->numCB-1];
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
109 while (elbg->utility_inc[i] < r)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
110 i++;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
111 return i;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
112 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
113
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
114 /**
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
115 * Implementation of the simple LBG algorithm for just two codebooks
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
116 */
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
117 static int simple_lbg(int dim,
5122
753230e2dcf0 Cygwin compatibility workaround
benoit
parents: 5095
diff changeset
118 int *centroid[3],
5095
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
119 int newutility[3],
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
120 int *points,
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
121 cell *cells)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
122 {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
123 int i, idx;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
124 int numpoints[2] = {0,0};
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
125 int newcentroid[2][dim];
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
126 cell *tempcell;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
127
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
128 memset(newcentroid, 0, sizeof(newcentroid));
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
129
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
130 newutility[0] =
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
131 newutility[1] = 0;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
132
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
133 for (tempcell = cells; tempcell; tempcell=tempcell->next) {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
134 idx = distance_limited(centroid[0], points + tempcell->index*dim, dim, INT_MAX)>=
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
135 distance_limited(centroid[1], points + tempcell->index*dim, dim, INT_MAX);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
136 numpoints[idx]++;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
137 for (i=0; i<dim; i++)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
138 newcentroid[idx][i] += points[tempcell->index*dim + i];
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
139 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
140
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
141 vect_division(centroid[0], newcentroid[0], numpoints[0], dim);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
142 vect_division(centroid[1], newcentroid[1], numpoints[1], dim);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
143
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
144 for (tempcell = cells; tempcell; tempcell=tempcell->next) {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
145 int dist[2] = {distance_limited(centroid[0], points + tempcell->index*dim, dim, INT_MAX),
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
146 distance_limited(centroid[1], points + tempcell->index*dim, dim, INT_MAX)};
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
147 int idx = dist[0] > dist[1];
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
148 newutility[idx] += dist[idx];
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
149 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
150
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
151 return newutility[0] + newutility[1];
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
152 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
153
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
154 static void get_new_centroids(elbg_data *elbg, int huc, int *newcentroid_i,
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
155 int *newcentroid_p)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
156 {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
157 cell *tempcell;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
158 int min[elbg->dim];
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
159 int max[elbg->dim];
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
160 int i;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
161
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
162 for (i=0; i< elbg->dim; i++) {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
163 min[i]=INT_MAX;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
164 max[i]=0;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
165 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
166
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
167 for (tempcell = elbg->cells[huc]; tempcell; tempcell = tempcell->next)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
168 for(i=0; i<elbg->dim; i++) {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
169 min[i]=FFMIN(min[i], elbg->points[tempcell->index*elbg->dim + i]);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
170 max[i]=FFMAX(max[i], elbg->points[tempcell->index*elbg->dim + i]);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
171 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
172
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
173 for (i=0; i<elbg->dim; i++) {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
174 newcentroid_i[i] = min[i] + (max[i] - min[i])/3;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
175 newcentroid_p[i] = min[i] + (2*(max[i] - min[i]))/3;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
176 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
177 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
178
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
179 /**
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
180 * Add the points in the low utility cell to its closest cell. Split the high
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
181 * utility cell, putting the separed points in the (now empty) low utility
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
182 * cell.
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
183 *
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
184 * @param elbg Internal elbg data
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
185 * @param indexes {luc, huc, cluc}
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
186 * @param newcentroid A vector with the position of the new centroids
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
187 */
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
188 static void shift_codebook(elbg_data *elbg, int *indexes,
5122
753230e2dcf0 Cygwin compatibility workaround
benoit
parents: 5095
diff changeset
189 int *newcentroid[3])
5095
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
190 {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
191 cell *tempdata;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
192 cell **pp = &elbg->cells[indexes[2]];
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
193
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
194 while(*pp)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
195 pp= &(*pp)->next;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
196
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
197 *pp = elbg->cells[indexes[0]];
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
198
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
199 elbg->cells[indexes[0]] = NULL;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
200 tempdata = elbg->cells[indexes[1]];
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
201 elbg->cells[indexes[1]] = NULL;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
202
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
203 while(tempdata) {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
204 cell *tempcell2 = tempdata->next;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
205 int idx = distance_limited(elbg->points + tempdata->index*elbg->dim,
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
206 newcentroid[0], elbg->dim, INT_MAX) >
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
207 distance_limited(elbg->points + tempdata->index*elbg->dim,
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
208 newcentroid[1], elbg->dim, INT_MAX);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
209
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
210 tempdata->next = elbg->cells[indexes[idx]];
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
211 elbg->cells[indexes[idx]] = tempdata;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
212 tempdata = tempcell2;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
213 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
214 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
215
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
216 static void evaluate_utility_inc(elbg_data *elbg)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
217 {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
218 int i, inc=0;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
219
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
220 for (i=0; i < elbg->numCB; i++) {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
221 if (elbg->numCB*elbg->utility[i] > elbg->error)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
222 inc += elbg->utility[i];
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
223 elbg->utility_inc[i] = inc;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
224 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
225 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
226
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
227
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
228 static void update_utility_and_n_cb(elbg_data *elbg, int idx, int newutility)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
229 {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
230 cell *tempcell;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
231
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
232 elbg->utility[idx] = newutility;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
233 for (tempcell=elbg->cells[idx]; tempcell; tempcell=tempcell->next)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
234 elbg->nearest_cb[tempcell->index] = idx;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
235 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
236
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
237 /**
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
238 * Evaluate if a shift lower the error. If it does, call shift_codebooks
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
239 * and update elbg->error, elbg->utility and elbg->nearest_cb.
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
240 *
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
241 * @param elbg Internal elbg data
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
242 * @param indexes {luc (low utility cell, huc (high utility cell), cluc (closest cell to low utility cell)}
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
243 */
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
244 static void try_shift_candidate(elbg_data *elbg, int idx[3])
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
245 {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
246 int j, k, olderror=0, newerror, cont=0;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
247 int newutility[3];
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
248 int newcentroid[3][elbg->dim];
5122
753230e2dcf0 Cygwin compatibility workaround
benoit
parents: 5095
diff changeset
249 int *newcentroid_ptrs[3] = { newcentroid[0], newcentroid[1], newcentroid[2] };
5095
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
250 cell *tempcell;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
251
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
252 for (j=0; j<3; j++)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
253 olderror += elbg->utility[idx[j]];
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
254
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
255 memset(newcentroid[2], 0, elbg->dim*sizeof(int));
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
256
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
257 for (k=0; k<2; k++)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
258 for (tempcell=elbg->cells[idx[2*k]]; tempcell; tempcell=tempcell->next) {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
259 cont++;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
260 for (j=0; j<elbg->dim; j++)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
261 newcentroid[2][j] += elbg->points[tempcell->index*elbg->dim + j];
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
262 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
263
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
264 vect_division(newcentroid[2], newcentroid[2], cont, elbg->dim);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
265
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
266 get_new_centroids(elbg, idx[1], newcentroid[0], newcentroid[1]);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
267
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
268 newutility[2] = eval_error_cell(elbg, newcentroid[2], elbg->cells[idx[0]]);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
269 newutility[2] += eval_error_cell(elbg, newcentroid[2], elbg->cells[idx[2]]);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
270
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
271 newerror = newutility[2];
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
272
5122
753230e2dcf0 Cygwin compatibility workaround
benoit
parents: 5095
diff changeset
273 newerror += simple_lbg(elbg->dim, newcentroid_ptrs, newutility, elbg->points,
5095
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
274 elbg->cells[idx[1]]);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
275
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
276 if (olderror > newerror) {
5122
753230e2dcf0 Cygwin compatibility workaround
benoit
parents: 5095
diff changeset
277 shift_codebook(elbg, idx, newcentroid_ptrs);
5095
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
278
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
279 elbg->error += newerror - olderror;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
280
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
281 for (j=0; j<3; j++)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
282 update_utility_and_n_cb(elbg, idx[j], newutility[j]);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
283
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
284 evaluate_utility_inc(elbg);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
285 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
286 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
287
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
288 /**
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
289 * Implementation of the ELBG block
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
290 */
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
291 static void do_shiftings(elbg_data *elbg)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
292 {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
293 int idx[3];
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
294
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
295 evaluate_utility_inc(elbg);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
296
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
297 for (idx[0]=0; idx[0] < elbg->numCB; idx[0]++)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
298 if (elbg->numCB*elbg->utility[idx[0]] < elbg->error) {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
299 if (elbg->utility_inc[elbg->numCB-1] == 0)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
300 return;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
301
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
302 idx[2] = get_closest_codebook(elbg, idx[0]);
7351
1502ba3beb72 The codebook generator algorithm involves picking three
vitor
parents: 6763
diff changeset
303 do {
1502ba3beb72 The codebook generator algorithm involves picking three
vitor
parents: 6763
diff changeset
304 idx[1] = get_high_utility_cell(elbg);
1502ba3beb72 The codebook generator algorithm involves picking three
vitor
parents: 6763
diff changeset
305 } while (idx[1] == idx[0] || idx[1] == idx[2]);
5095
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
306
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
307 try_shift_candidate(elbg, idx);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
308 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
309 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
310
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
311 #define BIG_PRIME 433494437LL
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
312
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
313 void ff_init_elbg(int *points, int dim, int numpoints, int *codebook,
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
314 int numCB, int max_steps, int *closest_cb,
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
315 AVRandomState *rand_state)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
316 {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
317 int i, k;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
318
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
319 if (numpoints > 24*numCB) {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
320 /* ELBG is very costly for a big number of points. So if we have a lot
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
321 of them, get a good initial codebook to save on iterations */
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
322 int *temp_points = av_malloc(dim*(numpoints/8)*sizeof(int));
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
323 for (i=0; i<numpoints/8; i++) {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
324 k = (i*BIG_PRIME) % numpoints;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
325 memcpy(temp_points + i*dim, points + k*dim, dim*sizeof(int));
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
326 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
327
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
328 ff_init_elbg(temp_points, dim, numpoints/8, codebook, numCB, 2*max_steps, closest_cb, rand_state);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
329 ff_do_elbg(temp_points, dim, numpoints/8, codebook, numCB, 2*max_steps, closest_cb, rand_state);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
330
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
331 av_free(temp_points);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
332
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
333 } else // If not, initialize the codebook with random positions
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
334 for (i=0; i < numCB; i++)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
335 memcpy(codebook + i*dim, points + ((i*BIG_PRIME)%numpoints)*dim,
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
336 dim*sizeof(int));
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
337
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
338 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
339
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
340 void ff_do_elbg(int *points, int dim, int numpoints, int *codebook,
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
341 int numCB, int max_steps, int *closest_cb,
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
342 AVRandomState *rand_state)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
343 {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
344 int dist;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
345 elbg_data elbg_d;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
346 elbg_data *elbg = &elbg_d;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
347 int i, j, k, last_error, steps=0;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
348 int *dist_cb = av_malloc(numpoints*sizeof(int));
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
349 int *size_part = av_malloc(numCB*sizeof(int));
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
350 cell *list_buffer = av_malloc(numpoints*sizeof(cell));
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
351 cell *free_cells;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
352
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
353 elbg->error = INT_MAX;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
354 elbg->dim = dim;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
355 elbg->numCB = numCB;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
356 elbg->codebook = codebook;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
357 elbg->cells = av_malloc(numCB*sizeof(cell *));
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
358 elbg->utility = av_malloc(numCB*sizeof(int));
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
359 elbg->nearest_cb = closest_cb;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
360 elbg->points = points;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
361 elbg->utility_inc = av_malloc(numCB*sizeof(int));
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
362
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
363 elbg->rand_state = rand_state;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
364
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
365 do {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
366 free_cells = list_buffer;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
367 last_error = elbg->error;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
368 steps++;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
369 memset(elbg->utility, 0, numCB*sizeof(int));
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
370 memset(elbg->cells, 0, numCB*sizeof(cell *));
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
371
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
372 elbg->error = 0;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
373
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
374 /* This loop evaluate the actual Voronoi partition. It is the most
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
375 costly part of the algorithm. */
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
376 for (i=0; i < numpoints; i++) {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
377 dist_cb[i] = INT_MAX;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
378 for (k=0; k < elbg->numCB; k++) {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
379 dist = distance_limited(elbg->points + i*elbg->dim, elbg->codebook + k*elbg->dim, dim, dist_cb[i]);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
380 if (dist < dist_cb[i]) {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
381 dist_cb[i] = dist;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
382 elbg->nearest_cb[i] = k;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
383 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
384 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
385 elbg->error += dist_cb[i];
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
386 elbg->utility[elbg->nearest_cb[i]] += dist_cb[i];
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
387 free_cells->index = i;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
388 free_cells->next = elbg->cells[elbg->nearest_cb[i]];
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
389 elbg->cells[elbg->nearest_cb[i]] = free_cells;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
390 free_cells++;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
391 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
392
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
393 do_shiftings(elbg);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
394
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
395 memset(size_part, 0, numCB*sizeof(int));
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
396
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
397 memset(elbg->codebook, 0, elbg->numCB*dim*sizeof(int));
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
398
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
399 for (i=0; i < numpoints; i++) {
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
400 size_part[elbg->nearest_cb[i]]++;
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
401 for (j=0; j < elbg->dim; j++)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
402 elbg->codebook[elbg->nearest_cb[i]*elbg->dim + j] +=
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
403 elbg->points[i*elbg->dim + j];
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
404 }
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
405
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
406 for (i=0; i < elbg->numCB; i++)
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
407 vect_division(elbg->codebook + i*elbg->dim,
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
408 elbg->codebook + i*elbg->dim, size_part[i], elbg->dim);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
409
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
410 } while(((last_error - elbg->error) > DELTA_ERR_MAX*elbg->error) &&
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
411 (steps < max_steps));
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
412
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
413 av_free(dist_cb);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
414 av_free(size_part);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
415 av_free(elbg->utility);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
416 av_free(list_buffer);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
417 av_free(elbg->cells);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
418 av_free(elbg->utility_inc);
ed41cfae128d Codebook generator using the ELBG algorithm
benoit
parents:
diff changeset
419 }