Skip to content

Commit 2366f3b

Browse files
committed
* c/nondominated.h (find_nondominated_3d_impl_sorted): Simplify assuming stable sort.
1 parent 4d8946d commit 2366f3b

1 file changed

Lines changed: 27 additions & 44 deletions

File tree

c/nondominated.h

Lines changed: 27 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -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
*/
333333
static __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

Comments
 (0)