1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
43 Partially based on Yossi Rubner code:
44 =========================================================================
49 An implementation of the Earth Movers Distance.
50 Based of the solution for the Transportation problem as described in
51 "Introduction to Mathematical Programming" by F. S. Hillier and
52 G. J. Lieberman, McGraw-Hill, 1990.
54 Copyright (C) 1998 Yossi Rubner
55 Computer Science Department, Stanford University
56 E-Mail: rubner@cs.stanford.edu URL: http://vision.stanford.edu/~rubner
57 ==========================================================================
61 #define MAX_ITERATIONS 500
62 #define CV_EMD_INF ((float)1e20)
63 #define CV_EMD_EPS ((float)1e-5)
65 /* CvNode1D is used for lists, representing 1D sparse array */
66 typedef struct CvNode1D
69 struct CvNode1D *next;
73 /* CvNode2D is used for lists, representing 2D sparse matrix */
74 typedef struct CvNode2D
77 struct CvNode2D *next[2]; /* next row & next column */
83 typedef struct CvEMDState
102 /* find_loop buffers */
111 float weight, max_cost;
116 /* static function declaration */
117 static CvStatus icvInitEMD( const float *signature1, int size1,
118 const float *signature2, int size2,
119 int dims, CvDistanceFunction dist_func, void *user_param,
120 const float* cost, int cost_step,
121 CvEMDState * state, float *lower_bound,
122 char *local_buffer, int local_buffer_size );
124 static CvStatus icvFindBasicVariables( float **cost, char **is_x,
125 CvNode1D * u, CvNode1D * v, int ssize, int dsize );
127 static float icvIsOptimal( float **cost, char **is_x,
128 CvNode1D * u, CvNode1D * v,
129 int ssize, int dsize, CvNode2D * enter_x );
131 static void icvRussel( CvEMDState * state );
134 static CvStatus icvNewSolution( CvEMDState * state );
135 static int icvFindLoop( CvEMDState * state );
137 static void icvAddBasicVariable( CvEMDState * state,
138 int min_i, int min_j,
139 CvNode1D * prev_u_min_i,
140 CvNode1D * prev_v_min_j,
143 static float icvDistL2( const float *x, const float *y, void *user_param );
144 static float icvDistL1( const float *x, const float *y, void *user_param );
145 static float icvDistC( const float *x, const float *y, void *user_param );
147 /* The main function */
149 cvCalcEMD2( const CvArr* signature_arr1,
150 const CvArr* signature_arr2,
152 CvDistanceFunction dist_func,
153 const CvArr* cost_matrix,
158 char local_buffer[16384];
159 char *local_buffer_ptr = (char *)cvAlignPtr(local_buffer,16);
163 CV_FUNCNAME( "cvCalcEMD2" );
165 memset( &state, 0, sizeof(state));
169 double total_cost = 0;
170 CvStatus result = CV_NO_ERR;
171 float eps, min_delta;
173 CvMat sign_stub1, *signature1 = (CvMat*)signature_arr1;
174 CvMat sign_stub2, *signature2 = (CvMat*)signature_arr2;
175 CvMat cost_stub, *cost = &cost_stub;
176 CvMat flow_stub, *flow = (CvMat*)flow_matrix;
177 int dims, size1, size2;
179 CV_CALL( signature1 = cvGetMat( signature1, &sign_stub1 ));
180 CV_CALL( signature2 = cvGetMat( signature2, &sign_stub2 ));
182 if( signature1->cols != signature2->cols )
183 CV_ERROR( CV_StsUnmatchedSizes, "The arrays must have equal number of columns (which is number of dimensions but 1)" );
185 dims = signature1->cols - 1;
186 size1 = signature1->rows;
187 size2 = signature2->rows;
189 if( !CV_ARE_TYPES_EQ( signature1, signature2 ))
190 CV_ERROR( CV_StsUnmatchedFormats, "The array must have equal types" );
192 if( CV_MAT_TYPE( signature1->type ) != CV_32FC1 )
193 CV_ERROR( CV_StsUnsupportedFormat, "The signatures must be 32fC1" );
197 CV_CALL( flow = cvGetMat( flow, &flow_stub ));
199 if( flow->rows != size1 || flow->cols != size2 )
200 CV_ERROR( CV_StsUnmatchedSizes,
201 "The flow matrix size does not match to the signatures' sizes" );
203 if( CV_MAT_TYPE( flow->type ) != CV_32FC1 )
204 CV_ERROR( CV_StsUnsupportedFormat, "The flow matrix must be 32fC1" );
215 CV_ERROR( CV_StsBadArg,
216 "Only one of cost matrix or distance function should be non-NULL in case of user-defined distance" );
219 CV_ERROR( CV_StsBadArg,
220 "The lower boundary can not be calculated if the cost matrix is used" );
222 CV_CALL( cost = cvGetMat( cost_matrix, &cost_stub ));
223 if( cost->rows != size1 || cost->cols != size2 )
224 CV_ERROR( CV_StsUnmatchedSizes,
225 "The cost matrix size does not match to the signatures' sizes" );
227 if( CV_MAT_TYPE( cost->type ) != CV_32FC1 )
228 CV_ERROR( CV_StsUnsupportedFormat, "The cost matrix must be 32fC1" );
230 else if( !dist_func )
231 CV_ERROR( CV_StsNullPtr, "In case of user-defined distance Distance function is undefined" );
236 CV_ERROR( CV_StsBadSize,
237 "Number of dimensions can be 0 only if a user-defined metric is used" );
238 user_param = (void *) (size_t)dims;
242 dist_func = icvDistL1;
245 dist_func = icvDistL2;
248 dist_func = icvDistC;
251 CV_ERROR( CV_StsBadFlag, "Bad or unsupported metric type" );
255 IPPI_CALL( result = icvInitEMD( signature1->data.fl, size1,
256 signature2->data.fl, size2,
257 dims, dist_func, user_param,
258 cost->data.fl, cost->step,
259 &state, lower_bound, local_buffer_ptr,
260 sizeof( local_buffer ) - 16 ));
262 if( result > 0 && lower_bound )
268 eps = CV_EMD_EPS * state.max_cost;
270 /* if ssize = 1 or dsize = 1 then we are done, else ... */
271 if( state.ssize > 1 && state.dsize > 1 )
275 for( itr = 1; itr < MAX_ITERATIONS; itr++ )
277 /* find basic variables */
278 result = icvFindBasicVariables( state.cost, state.is_x,
279 state.u, state.v, state.ssize, state.dsize );
283 /* check for optimality */
284 min_delta = icvIsOptimal( state.cost, state.is_x,
286 state.ssize, state.dsize, state.enter_x );
288 if( min_delta == CV_EMD_INF )
290 CV_ERROR( CV_StsNoConv, "" );
293 /* if no negative deltamin, we found the optimal solution */
294 if( min_delta >= -eps )
297 /* improve solution */
298 IPPI_CALL( icvNewSolution( &state ));
302 /* compute the total flow */
303 for( xp = state._x; xp < state.end_x; xp++ )
308 int ci = state.idx1[i];
309 int cj = state.idx2[j];
311 if( xp != state.enter_x && ci >= 0 && cj >= 0 )
313 total_cost += (double)val * state.cost[i][j];
315 ((float*)(flow->data.ptr + flow->step*ci))[cj] = val;
319 emd = (float) (total_cost / state.weight);
323 if( state.buffer && state.buffer != local_buffer_ptr )
324 cvFree( &state.buffer );
330 /************************************************************************************\
331 * initialize structure, allocate buffers and generate initial golution *
332 \************************************************************************************/
334 icvInitEMD( const float* signature1, int size1,
335 const float* signature2, int size2,
336 int dims, CvDistanceFunction dist_func, void* user_param,
337 const float* cost, int cost_step,
338 CvEMDState* state, float* lower_bound,
339 char* local_buffer, int local_buffer_size )
341 float s_sum = 0, d_sum = 0, diff;
343 int ssize = 0, dsize = 0;
347 char *buffer, *buffer_end;
349 memset( state, 0, sizeof( *state ));
350 assert( cost_step % sizeof(float) == 0 );
351 cost_step /= sizeof(float);
353 /* calculate buffer size */
354 buffer_size = (size1+1) * (size2+1) * (sizeof( float ) + /* cost */
355 sizeof( char ) + /* is_x */
356 sizeof( float )) + /* delta matrix */
357 (size1 + size2 + 2) * (sizeof( CvNode2D ) + /* _x */
358 sizeof( CvNode2D * ) + /* cols_x & rows_x */
359 sizeof( CvNode1D ) + /* u & v */
360 sizeof( float ) + /* s & d */
361 sizeof( int ) + sizeof(CvNode2D*)) + /* idx1 & idx2 */
362 (size1+1) * (sizeof( float * ) + sizeof( char * ) + /* rows pointers for */
363 sizeof( float * )) + 256; /* cost, is_x and delta */
365 if( buffer_size < (int) (dims * 2 * sizeof( float )))
367 buffer_size = dims * 2 * sizeof( float );
370 /* allocate buffers */
371 if( local_buffer != 0 && local_buffer_size >= buffer_size )
373 buffer = local_buffer;
377 buffer = (char*)cvAlloc( buffer_size );
379 return CV_OUTOFMEM_ERR;
382 state->buffer = buffer;
383 buffer_end = buffer + buffer_size;
385 state->idx1 = (int*) buffer;
386 buffer += (size1 + 1) * sizeof( int );
388 state->idx2 = (int*) buffer;
389 buffer += (size2 + 1) * sizeof( int );
391 state->s = (float *) buffer;
392 buffer += (size1 + 1) * sizeof( float );
394 state->d = (float *) buffer;
395 buffer += (size2 + 1) * sizeof( float );
397 /* sum up the supply and demand */
398 for( i = 0; i < size1; i++ )
400 float weight = signature1[i * (dims + 1)];
405 state->s[ssize] = weight;
406 state->idx1[ssize++] = i;
409 else if( weight < 0 )
410 return CV_BADRANGE_ERR;
413 for( i = 0; i < size2; i++ )
415 float weight = signature2[i * (dims + 1)];
420 state->d[dsize] = weight;
421 state->idx2[dsize++] = i;
423 else if( weight < 0 )
424 return CV_BADRANGE_ERR;
427 if( ssize == 0 || dsize == 0 )
428 return CV_BADRANGE_ERR;
430 /* if supply different than the demand, add a zero-cost dummy cluster */
431 diff = s_sum - d_sum;
432 if( fabs( diff ) >= CV_EMD_EPS * s_sum )
437 state->s[ssize] = -diff;
438 state->idx1[ssize++] = -1;
442 state->d[dsize] = diff;
443 state->idx2[dsize++] = -1;
447 state->ssize = ssize;
448 state->dsize = dsize;
449 state->weight = s_sum > d_sum ? s_sum : d_sum;
451 if( lower_bound && equal_sums ) /* check lower bound */
453 int sz1 = size1 * (dims + 1), sz2 = size2 * (dims + 1);
456 float* xs = (float *) buffer;
457 float* xd = xs + dims;
459 memset( xs, 0, dims*sizeof(xs[0]));
460 memset( xd, 0, dims*sizeof(xd[0]));
462 for( j = 0; j < sz1; j += dims + 1 )
464 float weight = signature1[j];
465 for( i = 0; i < dims; i++ )
466 xs[i] += signature1[j + i + 1] * weight;
469 for( j = 0; j < sz2; j += dims + 1 )
471 float weight = signature2[j];
472 for( i = 0; i < dims; i++ )
473 xd[i] += signature2[j + i + 1] * weight;
476 lb = dist_func( xs, xd, user_param ) / state->weight;
477 i = *lower_bound <= lb;
480 return ( CvStatus ) 1;
483 /* assign pointers */
484 state->is_used = (char *) buffer;
485 /* init delta matrix */
486 state->delta = (float **) buffer;
487 buffer += ssize * sizeof( float * );
489 for( i = 0; i < ssize; i++ )
491 state->delta[i] = (float *) buffer;
492 buffer += dsize * sizeof( float );
495 state->loop = (CvNode2D **) buffer;
496 buffer += (ssize + dsize + 1) * sizeof(CvNode2D*);
498 state->_x = state->end_x = (CvNode2D *) buffer;
499 buffer += (ssize + dsize) * sizeof( CvNode2D );
501 /* init cost matrix */
502 state->cost = (float **) buffer;
503 buffer += ssize * sizeof( float * );
505 /* compute the distance matrix */
506 for( i = 0; i < ssize; i++ )
508 int ci = state->idx1[i];
510 state->cost[i] = (float *) buffer;
511 buffer += dsize * sizeof( float );
515 for( j = 0; j < dsize; j++ )
517 int cj = state->idx2[j];
519 state->cost[i][j] = 0;
525 val = dist_func( signature1 + ci * (dims + 1) + 1,
526 signature2 + cj * (dims + 1) + 1,
532 val = cost[cost_step*ci + cj];
534 state->cost[i][j] = val;
542 for( j = 0; j < dsize; j++ )
543 state->cost[i][j] = 0;
547 state->max_cost = max_cost;
549 memset( buffer, 0, buffer_end - buffer );
551 state->rows_x = (CvNode2D **) buffer;
552 buffer += ssize * sizeof( CvNode2D * );
554 state->cols_x = (CvNode2D **) buffer;
555 buffer += dsize * sizeof( CvNode2D * );
557 state->u = (CvNode1D *) buffer;
558 buffer += ssize * sizeof( CvNode1D );
560 state->v = (CvNode1D *) buffer;
561 buffer += dsize * sizeof( CvNode1D );
563 /* init is_x matrix */
564 state->is_x = (char **) buffer;
565 buffer += ssize * sizeof( char * );
567 for( i = 0; i < ssize; i++ )
569 state->is_x[i] = buffer;
573 assert( buffer <= buffer_end );
577 state->enter_x = (state->end_x)++;
582 /****************************************************************************************\
583 * icvFindBasicVariables *
584 \****************************************************************************************/
586 icvFindBasicVariables( float **cost, char **is_x,
587 CvNode1D * u, CvNode1D * v, int ssize, int dsize )
590 int u_cfound, v_cfound;
591 CvNode1D u0_head, u1_head, *cur_u, *prev_u;
592 CvNode1D v0_head, v1_head, *cur_v, *prev_v;
594 /* initialize the rows list (u) and the columns list (v) */
596 for( i = 0; i < ssize; i++ )
598 u[i].next = u + i + 1;
600 u[ssize - 1].next = 0;
603 v0_head.next = ssize > 1 ? v + 1 : 0;
604 for( i = 1; i < dsize; i++ )
606 v[i].next = v + i + 1;
608 v[dsize - 1].next = 0;
611 /* there are ssize+dsize variables but only ssize+dsize-1 independent equations,
615 v1_head.next->next = 0;
617 /* loop until all variables are found */
618 u_cfound = v_cfound = 0;
619 while( u_cfound < ssize || v_cfound < dsize )
622 if( v_cfound < dsize )
624 /* loop over all marked columns */
627 for( found |= (cur_v = v1_head.next) != 0; cur_v != 0; cur_v = cur_v->next )
629 float cur_v_val = cur_v->val;
631 j = (int)(cur_v - v);
632 /* find the variables in column j */
634 for( cur_u = u0_head.next; cur_u != 0; )
636 i = (int)(cur_u - u);
640 cur_u->val = cost[i][j] - cur_v_val;
641 /* ...and add it to the marked list */
642 prev_u->next = cur_u->next;
643 cur_u->next = u1_head.next;
644 u1_head.next = cur_u;
645 cur_u = prev_u->next;
653 prev_v->next = cur_v->next;
658 if( u_cfound < ssize )
660 /* loop over all marked rows */
662 for( found |= (cur_u = u1_head.next) != 0; cur_u != 0; cur_u = cur_u->next )
664 float cur_u_val = cur_u->val;
668 i = (int)(cur_u - u);
671 /* find the variables in rows i */
673 for( cur_v = v0_head.next; cur_v != 0; )
675 j = (int)(cur_v - v);
679 cur_v->val = _cost[j] - cur_u_val;
680 /* ...and add it to the marked list */
681 prev_v->next = cur_v->next;
682 cur_v->next = v1_head.next;
683 v1_head.next = cur_v;
684 cur_v = prev_v->next;
692 prev_u->next = cur_u->next;
699 return CV_NOTDEFINED_ERR;
707 /****************************************************************************************\
709 \****************************************************************************************/
711 icvIsOptimal( float **cost, char **is_x,
712 CvNode1D * u, CvNode1D * v, int ssize, int dsize, CvNode2D * enter_x )
714 float delta, min_delta = CV_EMD_INF;
715 int i, j, min_i = 0, min_j = 0;
717 /* find the minimal cij-ui-vj over all i,j */
718 for( i = 0; i < ssize; i++ )
720 float u_val = u[i].val;
721 float *_cost = cost[i];
722 char *_is_x = is_x[i];
724 for( j = 0; j < dsize; j++ )
728 delta = _cost[j] - u_val - v[j].val;
729 if( min_delta > delta )
745 /****************************************************************************************\
747 \****************************************************************************************/
749 icvNewSolution( CvEMDState * state )
752 float min_val = CV_EMD_INF;
754 CvNode2D head, *cur_x, *next_x, *leave_x = 0;
755 CvNode2D *enter_x = state->enter_x;
756 CvNode2D **loop = state->loop;
758 /* enter the new basic variable */
761 state->is_x[i][j] = 1;
762 enter_x->next[0] = state->rows_x[i];
763 enter_x->next[1] = state->cols_x[j];
765 state->rows_x[i] = enter_x;
766 state->cols_x[j] = enter_x;
768 /* find a chain reaction */
769 steps = icvFindLoop( state );
772 return CV_NOTDEFINED_ERR;
774 /* find the largest value in the loop */
775 for( i = 1; i < steps; i += 2 )
777 float temp = loop[i]->val;
786 /* update the loop */
787 for( i = 0; i < steps; i += 2 )
789 float temp0 = loop[i]->val + min_val;
790 float temp1 = loop[i + 1]->val - min_val;
792 loop[i]->val = temp0;
793 loop[i + 1]->val = temp1;
796 /* remove the leaving basic variable */
799 state->is_x[i][j] = 0;
801 head.next[0] = state->rows_x[i];
803 while( (next_x = cur_x->next[0]) != leave_x )
808 cur_x->next[0] = next_x->next[0];
809 state->rows_x[i] = head.next[0];
811 head.next[1] = state->cols_x[j];
813 while( (next_x = cur_x->next[1]) != leave_x )
818 cur_x->next[1] = next_x->next[1];
819 state->cols_x[j] = head.next[1];
821 /* set enter_x to be the new empty slot */
822 state->enter_x = leave_x;
829 /****************************************************************************************\
831 \****************************************************************************************/
833 icvFindLoop( CvEMDState * state )
837 CvNode2D **loop = state->loop;
838 CvNode2D *enter_x = state->enter_x, *_x = state->_x;
839 char *is_used = state->is_used;
841 memset( is_used, 0, state->ssize + state->dsize );
843 new_x = loop[0] = enter_x;
844 is_used[enter_x - _x] = 1;
849 if( (steps & 1) == 1 )
851 /* find an unused x in the row */
852 new_x = state->rows_x[new_x->i];
853 while( new_x != 0 && is_used[new_x - _x] )
854 new_x = new_x->next[0];
858 /* find an unused x in the column, or the entering x */
859 new_x = state->cols_x[new_x->j];
860 while( new_x != 0 && is_used[new_x - _x] && new_x != enter_x )
861 new_x = new_x->next[1];
862 if( new_x == enter_x )
866 if( new_x != 0 ) /* found the next x */
868 /* add x to the loop */
869 loop[steps++] = new_x;
870 is_used[new_x - _x] = 1;
872 else /* didn't find the next x */
878 new_x = loop[steps - 1];
881 new_x = new_x->next[i];
883 while( new_x != 0 && is_used[new_x - _x] );
887 is_used[loop[--steps] - _x] = 0;
890 while( new_x == 0 && steps > 0 );
892 is_used[loop[steps - 1] - _x] = 0;
893 loop[steps - 1] = new_x;
894 is_used[new_x - _x] = 1;
904 /****************************************************************************************\
906 \****************************************************************************************/
908 icvRussel( CvEMDState * state )
910 int i, j, min_i = -1, min_j = -1;
911 float min_delta, diff;
912 CvNode1D u_head, *cur_u, *prev_u;
913 CvNode1D v_head, *cur_v, *prev_v;
914 CvNode1D *prev_u_min_i = 0, *prev_v_min_j = 0, *remember;
915 CvNode1D *u = state->u, *v = state->v;
916 int ssize = state->ssize, dsize = state->dsize;
917 float eps = CV_EMD_EPS * state->max_cost;
918 float **cost = state->cost;
919 float **delta = state->delta;
921 /* initialize the rows list (ur), and the columns list (vr) */
923 for( i = 0; i < ssize; i++ )
925 u[i].next = u + i + 1;
927 u[ssize - 1].next = 0;
930 for( i = 0; i < dsize; i++ )
932 v[i].val = -CV_EMD_INF;
933 v[i].next = v + i + 1;
935 v[dsize - 1].next = 0;
937 /* find the maximum row and column values (ur[i] and vr[j]) */
938 for( i = 0; i < ssize; i++ )
940 float u_val = -CV_EMD_INF;
941 float *cost_row = cost[i];
943 for( j = 0; j < dsize; j++ )
945 float temp = cost_row[j];
949 if( v[j].val < temp )
955 /* compute the delta matrix */
956 for( i = 0; i < ssize; i++ )
958 float u_val = u[i].val;
959 float *delta_row = delta[i];
960 float *cost_row = cost[i];
962 for( j = 0; j < dsize; j++ )
964 delta_row[j] = cost_row[j] - u_val - v[j].val;
968 /* find the basic variables */
971 /* find the smallest delta[i][j] */
973 min_delta = CV_EMD_INF;
975 for( cur_u = u_head.next; cur_u != 0; cur_u = cur_u->next )
977 i = (int)(cur_u - u);
978 float *delta_row = delta[i];
981 for( cur_v = v_head.next; cur_v != 0; cur_v = cur_v->next )
983 j = (int)(cur_v - v);
984 if( min_delta > delta_row[j] )
986 min_delta = delta_row[j];
989 prev_u_min_i = prev_u;
990 prev_v_min_j = prev_v;
1000 /* add x[min_i][min_j] to the basis, and adjust supplies and cost */
1001 remember = prev_u_min_i->next;
1002 icvAddBasicVariable( state, min_i, min_j, prev_u_min_i, prev_v_min_j, &u_head );
1004 /* update the necessary delta[][] */
1005 if( remember == prev_u_min_i->next ) /* line min_i was deleted */
1007 for( cur_v = v_head.next; cur_v != 0; cur_v = cur_v->next )
1009 j = (int)(cur_v - v);
1010 if( cur_v->val == cost[min_i][j] ) /* column j needs updating */
1012 float max_val = -CV_EMD_INF;
1014 /* find the new maximum value in the column */
1015 for( cur_u = u_head.next; cur_u != 0; cur_u = cur_u->next )
1017 float temp = cost[cur_u - u][j];
1019 if( max_val < temp )
1023 /* if needed, adjust the relevant delta[*][j] */
1024 diff = max_val - cur_v->val;
1025 cur_v->val = max_val;
1026 if( fabs( diff ) < eps )
1028 for( cur_u = u_head.next; cur_u != 0; cur_u = cur_u->next )
1029 delta[cur_u - u][j] += diff;
1034 else /* column min_j was deleted */
1036 for( cur_u = u_head.next; cur_u != 0; cur_u = cur_u->next )
1038 i = (int)(cur_u - u);
1039 if( cur_u->val == cost[i][min_j] ) /* row i needs updating */
1041 float max_val = -CV_EMD_INF;
1043 /* find the new maximum value in the row */
1044 for( cur_v = v_head.next; cur_v != 0; cur_v = cur_v->next )
1046 float temp = cost[i][cur_v - v];
1048 if( max_val < temp )
1052 /* if needed, adjust the relevant delta[i][*] */
1053 diff = max_val - cur_u->val;
1054 cur_u->val = max_val;
1056 if( fabs( diff ) < eps )
1058 for( cur_v = v_head.next; cur_v != 0; cur_v = cur_v->next )
1059 delta[i][cur_v - v] += diff;
1065 while( u_head.next != 0 || v_head.next != 0 );
1070 /****************************************************************************************\
1071 * icvAddBasicVariable *
1072 \****************************************************************************************/
1074 icvAddBasicVariable( CvEMDState * state,
1075 int min_i, int min_j,
1076 CvNode1D * prev_u_min_i, CvNode1D * prev_v_min_j, CvNode1D * u_head )
1079 CvNode2D *end_x = state->end_x;
1081 if( state->s[min_i] < state->d[min_j] + state->weight * CV_EMD_EPS )
1082 { /* supply exhausted */
1083 temp = state->s[min_i];
1084 state->s[min_i] = 0;
1085 state->d[min_j] -= temp;
1087 else /* demand exhausted */
1089 temp = state->d[min_j];
1090 state->d[min_j] = 0;
1091 state->s[min_i] -= temp;
1094 /* x(min_i,min_j) is a basic variable */
1095 state->is_x[min_i][min_j] = 1;
1100 end_x->next[0] = state->rows_x[min_i];
1101 end_x->next[1] = state->cols_x[min_j];
1102 state->rows_x[min_i] = end_x;
1103 state->cols_x[min_j] = end_x;
1104 state->end_x = end_x + 1;
1106 /* delete supply row only if the empty, and if not last row */
1107 if( state->s[min_i] == 0 && u_head->next->next != 0 )
1108 prev_u_min_i->next = prev_u_min_i->next->next; /* remove row from list */
1110 prev_v_min_j->next = prev_v_min_j->next->next; /* remove column from list */
1114 /****************************************************************************************\
1115 * standard metrics *
1116 \****************************************************************************************/
1118 icvDistL1( const float *x, const float *y, void *user_param )
1120 int i, dims = (int)(size_t)user_param;
1123 for( i = 0; i < dims; i++ )
1125 double t = x[i] - y[i];
1133 icvDistL2( const float *x, const float *y, void *user_param )
1135 int i, dims = (int)(size_t)user_param;
1138 for( i = 0; i < dims; i++ )
1140 double t = x[i] - y[i];
1144 return cvSqrt( (float)s );
1148 icvDistC( const float *x, const float *y, void *user_param )
1150 int i, dims = (int)(size_t)user_param;
1153 for( i = 0; i < dims; i++ )
1155 double t = fabs( x[i] - y[i] );