@@ -331,7 +331,7 @@ find_nondominated_set_2d_(const double * restrict points, size_t size,
331331 When find_dominated, return as soon as it finds one dominated point.
332332*/
333333static __force_inline__ size_t
334- find_nondominated_3d_impl_sorted (const double * * rows , size_t size ,
334+ find_nondominated_3d_impl_sorted (const double * * restrict rows , size_t size ,
335335 const bool keep_weakly ,
336336 const bool find_dominated )
337337{
@@ -349,43 +349,42 @@ find_nondominated_3d_impl_sorted(const double ** rows, size_t size,
349349 avl_insert_after (& tree , node - 1 , node );
350350
351351 // In this context, size means "no dominated solution found".
352- size_t new_size = size , k = 0 ;
353- size_t last_dom_pos = size ;
354- const double * restrict pk = rows [0 ];
352+ size_t new_size = size ;
353+ size_t prev_dominated = false ;
354+ double pk0 = rows [ 0 ][ 0 ], pk1 = rows [0 ][ 1 ], pk2 = rows [ 0 ][ 2 ];
355355 for (size_t j = 1 ; j < size ; j ++ ) {
356356 const double * restrict pj = rows [j ];
357357 DEBUG2 (printf_point ("pj = [ " , pj , 3 , " ], " ));
358-
359- if (pk [ 0 ] > pj [ 0 ] || pk [ 1 ] > pj [ 1 ] ) {
358+ const double pj0 = pj [ 0 ], pj1 = pj [ 1 ], pj2 = pj [ 2 ];
359+ if (( pk0 > pj0 ) | ( pk1 > pj1 ) ) {
360360 // Check if pj is dominated by a point in the tree.
361- assert (pk [0 ] > pj [0 ] || pk [1 ] > pj [1 ]);
362361 avl_node_t * nodeaux ;
363362 int res = avl_search_closest (& tree , pj , & nodeaux );
364363 assert (res != 0 );
365364 if (res > 0 ) { // nodeaux goes before pj
366365 const double * restrict prev = nodeaux -> item ;
367366 DEBUG2 (printf_point ("res > 0: prev: " , prev , 3 , "\n" ));
368367 assert (prev [0 ] != sentinel [0 ]);
369- assert (prev [0 ] <= pj [ 0 ] );
370- if (prev [1 ] <= pj [ 1 ] )
368+ assert (prev [0 ] <= pj0 );
369+ if (prev [1 ] <= pj1 )
371370 goto j_is_dominated ;
372371 nodeaux = nodeaux -> next ;
373372 } else if (nodeaux -> prev ) { // nodeaux goes after pj, so move to the next one.
374373 const double * restrict prev = nodeaux -> prev -> item ;
375374 DEBUG2 (printf_point ("res < 0: prev: " , prev , 3 , "\n" ));
376375 assert (prev [0 ] != sentinel [0 ]);
377- assert (prev [0 ] <= pj [ 0 ] );
378- if (prev [1 ] <= pj [ 1 ] )
376+ assert (prev [0 ] <= pj0 );
377+ if (prev [1 ] <= pj1 )
379378 goto j_is_dominated ;
380379 }
381380
382381 // pj is NOT dominated by a point in the tree.
383382 const double * restrict point = nodeaux -> item ;
384- assert (pj [ 0 ] <= point [0 ]);
383+ assert (pj0 <= point [0 ]);
385384 // Delete everything in the tree that is dominated by pj.
386- while (pj [ 1 ] <= point [1 ]) {
385+ while (pj1 <= point [1 ]) {
387386 DEBUG2 (printf_point ("delete point: " , point , 3 , "\n" ));
388- assert (pj [ 0 ] <= point [0 ]);
387+ assert (pj0 <= point [0 ]);
389388 nodeaux = nodeaux -> next ;
390389 point = nodeaux -> item ;
391390 /* FIXME: A possible speed up is to delete without
@@ -399,37 +398,21 @@ find_nondominated_3d_impl_sorted(const double ** rows, size_t size,
399398 (++ node )-> item = pj ;
400399 avl_insert_before (& tree , nodeaux , node );
401400 // Fall-through to j_is_NOT_dominated.
402- } else {
403- // Handle duplicates and points that are dominated by the immediate
404- // previous one.
405- DEBUG2 (printf_point ("weakly dominated by pk: " , pk , 3 , "\n" ));
406- const bool k_not_equal_j = (pk [0 ] < pj [0 ]) | (pk [1 ] < pj [1 ]) | (pk [2 ] < pj [2 ]);
407-
408- if (likely (k_not_equal_j )) { // It is not a duplicate, so it is dominated.
409- goto j_is_dominated ;
410- } else if (keep_weakly ) {
411- // If pk was dominated, then this one is also dominated.
412- if (last_dom_pos == k )
413- goto j_is_dominated ;
414- // Fall-through to j_is_NOT_dominated.
415- } else { // Don't keep duplicates.
416- if (pk < pj ) // Only the first duplicated point is kept.
417- goto j_is_dominated ;
418-
419- if (find_dominated ) {
420- // In this context, it means "position of the first dominated solution found".
421- new_size = k ;
422- goto early_end ;
423- }
424- last_dom_pos = k ;
425- rows [k ] = NULL ;
426- new_size -- ;
427- // Fall-through to j_is_NOT_dominated.
428- }
401+ } // Handle duplicates and points that are dominated by the immediate previous one.
402+ else if (!keep_weakly // Don't keep duplicates.
403+ // or the previous was dominated, then this one is also dominated.
404+ || prev_dominated
405+ // or it is not a duplicate, so it is dominated.
406+ || pk0 != pj0 || pk1 != pj1 || pk2 != pj2 ) {
407+ // The sorting function must be stable so that we keep only the
408+ // first duplicated point.
409+ DEBUG2 (printf_point ("weakly dominated by pk: " ,
410+ (double [3 ]){pk0 , pk1 , pk2 }, 3 , "\n" ));
411+ goto j_is_dominated ;
429412 }
430413 // j_is_NOT_dominated
431- pk = pj ;
432- k = j ;
414+ pk0 = pj0 ; pk1 = pj1 ; pk2 = pj2 ;
415+ prev_dominated = false ;
433416 continue ;
434417
435418 j_is_dominated : // pj is dominated by a point in the tree or by pk.
@@ -438,7 +421,7 @@ find_nondominated_3d_impl_sorted(const double ** rows, size_t size,
438421 new_size = j ;
439422 goto early_end ;
440423 }
441- last_dom_pos = j ;
424+ prev_dominated = true ;
442425 rows [j ] = NULL ;
443426 new_size -- ;
444427 }
0 commit comments