summaryrefslogtreecommitdiff
path: root/match/match.c
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2008-11-06 23:01:41 +0100
committerHenrik Rydberg <rydberg@euromail.se>2008-11-06 23:01:41 +0100
commitd44b4794c679141a08fd802475bb542ecf5b7c51 (patch)
tree74251970cfbcc58d0252366be6e5e668149b8a48 /match/match.c
parent63de72d8d810e3692c96c7385b497bb4d68ef54a (diff)
ok, fast (but not fastest) matcher in place, no check output...
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'match/match.c')
-rw-r--r--match/match.c326
1 files changed, 326 insertions, 0 deletions
diff --git a/match/match.c b/match/match.c
new file mode 100644
index 0000000..604faaf
--- /dev/null
+++ b/match/match.c
@@ -0,0 +1,326 @@
1#include "match.h"
2#include <string.h>
3#include <stdio.h>
4
5/**
6 * MATLAB implementation of the hungarian algorithm (2008)
7 *
8 * modified by Henrik Rydberg (2008)
9 */
10
11const float BIG_VALUE = 1e20;
12
13typedef unsigned short col_t;
14
15#define GETBIT2(m, row, col) ((m[col]>>row)&1U)
16#define SETBIT2(m, row, col) (m[col]|=(1U<<row))
17#define CLEARBIT2(m, row, col) (m[col]&=~(1U<<row))
18
19#define GETBIT(m, x) ((m>>x)&1U)
20#define SETBIT(m, x) (m|=(1U<<x))
21#define CLEARBIT(m, x) (m&=~(1U<<x))
22
23/********************************************************/
24
25static void buildixvector(int *ix, col_t *mstar, int nrows, int ncols)
26{
27 int row, col;
28 for (row = 0; row < nrows; row++) {
29 for (col = 0; col < ncols; col++) {
30 if (GETBIT2(mstar, row, col)) {
31 ix[row] = col;
32 break;
33 }
34 }
35 }
36}
37
38
39/********************************************************/
40
41static void step2a(int *ix, float *mdist, col_t *mstar, col_t *nmstar, col_t *mprime, col_t ccol, col_t crow, int nrows, int ncols, int dmin);
42static void step2b(int *ix, float *mdist, col_t *mstar, col_t *nmstar, col_t *mprime, col_t ccol, col_t crow, int nrows, int ncols, int dmin);
43static void step3 (int *ix, float *mdist, col_t *mstar, col_t *nmstar, col_t *mprime, col_t ccol, col_t crow, int nrows, int ncols, int dmin);
44static void step4 (int *ix, float *mdist, col_t *mstar, col_t *nmstar, col_t *mprime, col_t ccol, col_t crow, int nrows, int ncols, int dmin, int row, int col);
45static void step5 (int *ix, float *mdist, col_t *mstar, col_t *nmstar, col_t *mprime, col_t ccol, col_t crow, int nrows, int ncols, int dmin);
46
47static void ixoptimal(int *ix, float *mdist, int nrows, int ncols)
48{
49 float *mdistTemp, *mdistEnd, *columnEnd, value, minValue;
50 int nelem, dmin, row, col;
51 col_t ccol,crow, mstar[DIM_FINGER],mprime[DIM_FINGER],nmstar[DIM_FINGER];
52
53 ccol = crow = 0;
54 memset(mstar, 0, sizeof(mstar));
55 memset(mprime, 0, sizeof(mprime));
56 memset(nmstar, 0, sizeof(nmstar));
57
58
59 /* initialization */
60 for(row=0; row<nrows; row++)
61 ix[row] = -1;
62
63 nelem = nrows * ncols;
64 mdistEnd = mdist + nelem;
65
66 /* preliminary steps */
67 if(nrows <= ncols) {
68 dmin = nrows;
69
70 for(row=0; row<nrows; row++) {
71 /* find the smallest element in the row */
72 mdistTemp = mdist + row;
73 minValue = *mdistTemp;
74 mdistTemp += nrows;
75 while(mdistTemp < mdistEnd) {
76 value = *mdistTemp;
77 if(value < minValue)
78 minValue = value;
79 mdistTemp += nrows;
80 }
81
82 /* subtract the smallest element from each element of the row */
83 mdistTemp = mdist + row;
84 while(mdistTemp < mdistEnd) {
85 *mdistTemp -= minValue;
86 mdistTemp += nrows;
87 }
88 }
89
90 /* Steps 1 and 2a */
91 for(row=0; row<nrows; row++)
92 for(col=0; col<ncols; col++)
93 if(mdist[row + nrows*col] == 0)
94 if(!GETBIT(ccol, col)) {
95 SETBIT2(mstar, row, col);
96 SETBIT(ccol, col);
97 break;
98 }
99 }
100 else /* if(nrows > ncols) */
101 {
102 dmin = ncols;
103
104 for(col=0; col<ncols; col++)
105 {
106 /* find the smallest element in the column */
107 mdistTemp = mdist + nrows*col;
108 columnEnd = mdistTemp + nrows;
109
110 minValue = *mdistTemp++;
111 while(mdistTemp < columnEnd)
112 {
113 value = *mdistTemp++;
114 if(value < minValue)
115 minValue = value;
116 }
117
118 /* subtract the smallest element from each element of the column */
119 mdistTemp = mdist + nrows*col;
120 while(mdistTemp < columnEnd)
121 *mdistTemp++ -= minValue;
122 }
123
124 /* Steps 1 and 2a */
125 for(col=0; col<ncols; col++)
126 for(row=0; row<nrows; row++)
127 if(mdist[row + nrows*col] == 0)
128 if(!GETBIT(crow, row))
129 {
130 SETBIT2(mstar, row, col);
131 SETBIT(ccol, col);
132 SETBIT(crow, row);
133 break;
134 }
135 for(row=0; row<nrows; row++)
136 CLEARBIT(crow, row);
137
138 }
139
140 /* move to step 2b */
141 step2b(ix, mdist, mstar, nmstar, mprime, ccol, crow, nrows, ncols, dmin);
142}
143
144/********************************************************/
145static void step2a(int *ix, float *mdist, col_t *mstar, col_t *nmstar, col_t *mprime, col_t ccol, col_t crow, int nrows, int ncols, int dmin)
146{
147 int col, row;
148
149 /* cover every column containing a starred zero */
150 for(col=0; col<ncols; col++) {
151 for(row=col;row<nrows;row++) {
152 if(GETBIT2(mstar, row, col)) {
153 SETBIT(ccol, col);
154 break;
155 }
156 }
157 }
158
159 /* move to step 3 */
160 step2b(ix, mdist, mstar, nmstar, mprime, ccol, crow, nrows, ncols, dmin);
161}
162
163/********************************************************/
164static void step2b(int *ix, float *mdist, col_t *mstar, col_t *nmstar, col_t *mprime, col_t ccol, col_t crow, int nrows, int ncols, int dmin)
165{
166 int col, ncc;
167
168 /* count covered columns */
169 ncc = 0;
170 for(col=0; col<ncols; col++)
171 if(GETBIT(ccol, col))
172 ncc++;
173
174 if(ncc == dmin)
175 {
176 /* algorithm finished */
177 buildixvector(ix, mstar, nrows, ncols);
178 }
179 else
180 {
181 /* move to step 3 */
182 step3(ix, mdist, mstar, nmstar, mprime, ccol, crow, nrows, ncols, dmin);
183 }
184
185}
186
187/********************************************************/
188static void step3(int *ix, float *mdist, col_t *mstar, col_t *nmstar, col_t *mprime, col_t ccol, col_t crow, int nrows, int ncols, int dmin)
189{
190 bool zerosFound;
191 int row, col, cstar;
192
193 zerosFound = 1;
194 while(zerosFound)
195 {
196 zerosFound = 0;
197 for(col=0; col<ncols; col++)
198 if(!GETBIT(ccol,col))
199 for(row=0; row<nrows; row++)
200 if((!GETBIT(crow,row)) && (mdist[row + nrows*col] == 0))
201 {
202 /* prime zero */
203 SETBIT2(mprime, row, col);
204
205 /* find starred zero in current row */
206 for(cstar=0; cstar<ncols; cstar++)
207 if(GETBIT2(mstar, row, cstar))
208 break;
209
210 if(cstar == ncols) /* no starred zero found */
211 {
212 /* move to step 4 */
213 step4(ix, mdist, mstar, nmstar, mprime, ccol, crow, nrows, ncols, dmin, row, col);
214 return;
215 }
216 else
217 {
218 SETBIT(crow, row);
219 CLEARBIT(ccol,cstar);
220 zerosFound = 1;
221 break;
222 }
223 }
224 }
225
226 /* move to step 5 */
227 step5(ix, mdist, mstar, nmstar, mprime, ccol, crow, nrows, ncols, dmin);
228}
229
230/********************************************************/
231static void step4(int *ix, float *mdist, col_t *mstar, col_t *nmstar, col_t *mprime, col_t ccol, col_t crow, int nrows, int ncols, int dmin, int row, int col)
232{
233 int n, rstar, cstar, primeRow, primeCol;
234 int nelem = nrows*ncols;
235
236 /* generate temporary copy of mstar */
237 for(n=0; n<nelem; n++)
238 nmstar[n] = mstar[n];
239
240 /* star current zero */
241 SETBIT2(nmstar, row, col);
242
243 /* find starred zero in current column */
244 cstar = col;
245 for(rstar=0; rstar<nrows; rstar++)
246 if(GETBIT2(mstar, rstar, cstar))
247 break;
248
249 while(rstar<nrows)
250 {
251 /* unstar the starred zero */
252 CLEARBIT2(nmstar, rstar, cstar);
253
254 /* find primed zero in current row */
255 primeRow = rstar;
256 for(primeCol=0; primeCol<ncols; primeCol++)
257 if(GETBIT2(mprime, primeRow, primeCol))
258 break;
259
260 /* star the primed zero */
261 SETBIT2(nmstar, primeRow, primeCol);
262
263 /* find starred zero in current column */
264 cstar = primeCol;
265 for(rstar=0; rstar<nrows; rstar++)
266 if(GETBIT2(mstar, rstar, cstar))
267 break;
268 }
269
270 /* use temporary copy as new mstar */
271 /* delete all primes, uncover all rows */
272 for(n=0; n<nelem; n++)
273 {
274 mprime[n] = 0;
275 mstar[n] = nmstar[n];
276 }
277 for(n=0; n<nrows; n++)
278 CLEARBIT(crow, n);
279
280 /* move to step 2a */
281 step2a(ix, mdist, mstar, nmstar, mprime, ccol, crow, nrows, ncols, dmin);
282}
283
284/********************************************************/
285static void step5(int *ix, float *mdist, col_t *mstar, col_t *nmstar, col_t *mprime, col_t ccol, col_t crow, int nrows, int ncols, int dmin)
286{
287 float h, value;
288 int row, col;
289
290 /* find smallest uncovered element h */
291 h = BIG_VALUE;
292 for(row=0; row<nrows; row++)
293 if(!GETBIT(crow, row))
294 for(col=0; col<ncols; col++)
295 if(!GETBIT(ccol,col))
296 {
297 value = mdist[row + nrows*col];
298 if(value < h)
299 h = value;
300 }
301
302 /* add h to each covered row */
303 for(row=0; row<nrows; row++)
304 if(GETBIT(crow, row))
305 for(col=0; col<ncols; col++)
306 mdist[row + nrows*col] += h;
307
308 /* subtract h from each uncovered column */
309 for(col=0; col<ncols; col++)
310 if(!GETBIT(ccol,col))
311 for(row=0; row<nrows; row++)
312 mdist[row + nrows*col] -= h;
313
314 /* move to step 3 */
315 step3(ix, mdist, mstar, nmstar, mprime, ccol, crow, nrows, ncols, dmin);
316}
317
318////////////////////////////////////////////////////////
319
320void match_fingers(int ix[DIM_FINGER], float A[DIM2_FINGER], int nrow, int ncol)
321{
322 ixoptimal(ix, A, nrow, ncol);
323}
324
325////////////////////////////////////////////////////////
326