9  const std::vector<DiagramType> &intermediateDiagrams,
 
   10  const std::array<size_t, 2> &nInputs)
 const {
 
   14  const auto nDiags = intermediateDiagrams.size();
 
   17    this->
printMsg(
"Processing all critical pairs types");
 
   19    this->
printMsg(
"Processing only MIN-SAD pairs");
 
   21    this->
printMsg(
"Processing only SAD-SAD pairs");
 
   23    this->
printMsg(
"Processing only SAD-MAX pairs");
 
   26  std::vector<DiagramType> inputDiagramsMin(nDiags);
 
   27  std::vector<DiagramType> inputDiagramsSad(nDiags);
 
   28  std::vector<DiagramType> inputDiagramsMax(nDiags);
 
   30  std::vector<BidderDiagram> bidder_diagrams_min{};
 
   31  std::vector<BidderDiagram> bidder_diagrams_sad{};
 
   32  std::vector<BidderDiagram> bidder_diagrams_max{};
 
   33  std::vector<BidderDiagram> current_bidder_diagrams_min{};
 
   34  std::vector<BidderDiagram> current_bidder_diagrams_sad{};
 
   35  std::vector<BidderDiagram> current_bidder_diagrams_max{};
 
   38  std::vector<double> maxDiagPersistence(nDiags);
 
   41#ifdef TTK_ENABLE_OPENMP 
   42#pragma omp parallel for num_threads(threadNumber_) 
   44  for(
size_t i = 0; i < nDiags; i++) {
 
   45    for(
const auto &p : intermediateDiagrams[i]) {
 
   46      maxDiagPersistence[i] = std::max(p.persistence(), maxDiagPersistence[i]);
 
   48      if(p.persistence() > 0) {
 
   51          inputDiagramsMax[i].emplace_back(p);
 
   55            inputDiagramsMax[i].emplace_back(p);
 
   59            inputDiagramsMin[i].emplace_back(p);
 
   65            inputDiagramsSad[i].emplace_back(p);
 
   84      this->
printMsg(
"Using all diagram pairs");
 
   88                     + 
" most persistent pairs");
 
   91      std::stringstream pers{};
 
   92      pers << std::fixed << std::setprecision(2) << this->
MinPersistence;
 
   93      this->
printMsg(
"Using diagram pairs above a persistence threshold of " 
   99        + std::to_string(
static_cast<int>(100 * (1 - this->
MinPersistence)))
 
  100        + 
"% most persistent pairs of every diagram");
 
  105        + std::to_string(
static_cast<int>(100 * (1 - this->
MinPersistence)))
 
  106        + 
"% most persistent pairs of all diagrams");
 
  110  std::vector<std::vector<double>> distMat{};
 
  113                       bidder_diagrams_sad, bidder_diagrams_max);
 
  117        bidder_diagrams_min, current_bidder_diagrams_min, maxDiagPersistence);
 
  121        bidder_diagrams_sad, current_bidder_diagrams_sad, maxDiagPersistence);
 
  125        bidder_diagrams_max, current_bidder_diagrams_max, maxDiagPersistence);
 
  128                       current_bidder_diagrams_sad,
 
  129                       current_bidder_diagrams_max);
 
  132  this->
printMsg(
"Complete", 1.0, tm.getElapsedTime(), this->threadNumber_);
 
 
  173  const std::array<size_t, 2> &nInputs,
 
  174  std::vector<std::vector<double>> &distanceMatrix,
 
  175  const std::vector<BidderDiagram> &diags_min,
 
  176  const std::vector<BidderDiagram> &diags_sad,
 
  177  const std::vector<BidderDiagram> &diags_max)
 const {
 
  179  distanceMatrix.resize(nInputs[0]);
 
  181#ifdef TTK_ENABLE_OPENMP 
  182#pragma omp parallel for schedule(dynamic) num_threads(this->threadNumber_) 
  184  for(
size_t i = 0; i < nInputs[0]; ++i) {
 
  186    if(nInputs[1] == 0) {
 
  187      distanceMatrix[i].resize(nInputs[0]);
 
  189      distanceMatrix[i][i] = 0.0;
 
  191      distanceMatrix[i].resize(nInputs[1]);
 
  194    const auto getDist = [&](
const size_t a, 
const size_t b) -> 
double {
 
  197        auto &dimin = diags_min[a];
 
  198        auto &djmin = diags_min[b];
 
  202        auto &disad = diags_sad[a];
 
  203        auto &djsad = diags_sad[b];
 
  207        auto &dimax = diags_max[a];
 
  208        auto &djmax = diags_max[b];
 
  214    if(nInputs[1] == 0) {
 
  216      for(
size_t j = i + 1; j < nInputs[0]; ++j) {
 
  217        distanceMatrix[i][j] = getDist(i, j);
 
  221      for(
size_t j = 0; j < nInputs[1]; ++j) {
 
  222        distanceMatrix[i][j] = getDist(i, j + nInputs[0]);
 
  227  if(nInputs[1] == 0) {
 
  229    for(
size_t i = 0; i < nInputs[0]; ++i) {
 
  230      for(
size_t j = i + 1; j < nInputs[0]; ++j) {
 
  231        distanceMatrix[j][i] = distanceMatrix[i][j];
 
 
  262  const std::vector<BidderDiagram> &bidder_diags,
 
  263  std::vector<BidderDiagram> ¤t_bidder_diags,
 
  264  const std::vector<double> &maxDiagPersistence)
 const {
 
  266  current_bidder_diags.resize(bidder_diags.size());
 
  267  const auto nInputs = current_bidder_diags.size();
 
  268  const auto maxPersistence
 
  269    = *std::max_element(maxDiagPersistence.begin(), maxDiagPersistence.end());
 
  274    for(
size_t i = 0; i < nInputs; ++i) {
 
  275      for(
auto b : bidder_diags[i]) {
 
  279           && b.getPersistence() > this->MinPersistence)
 
  283           && b.getPersistence() > this->
MinPersistence * maxDiagPersistence[i])
 
  288          b.id_ = current_bidder_diags[i].size();
 
  289          b.setPositionInAuction(current_bidder_diags[i].size());
 
  290          current_bidder_diags[i].emplace_back(b);
 
  298  double new_min_persistence = 0.0;
 
  302  size_t max_diagram_size = 0;
 
  303  for(
const auto &diag : current_bidder_diags) {
 
  304    max_diagram_size = std::max(diag.size(), max_diagram_size);
 
  306  size_t const max_points_to_add = std::max(
 
  309  std::vector<std::vector<int>> candidates_to_be_added(nInputs);
 
  310  std::vector<std::vector<size_t>> idx(nInputs);
 
  312  for(
size_t i = 0; i < nInputs; i++) {
 
  313    double local_min_persistence = std::numeric_limits<double>::min();
 
  314    std::vector<double> persistences;
 
  315    for(
size_t j = 0; j < bidder_diags[i].size(); j++) {
 
  316      const auto &b = bidder_diags[i][j];
 
  317      double const persistence = b.getPersistence();
 
  318      if(persistence >= 0.0 && persistence <= prev_min_persistence) {
 
  319        candidates_to_be_added[i].emplace_back(j);
 
  320        idx[i].emplace_back(idx[i].size());
 
  321        persistences.emplace_back(persistence);
 
  324    const auto cmp = [&persistences](
const size_t a, 
const size_t b) {
 
  325      return ((persistences[a] > persistences[b])
 
  326              || ((persistences[a] == persistences[b]) && (a > b)));
 
  328    std::sort(idx[i].
begin(), idx[i].
end(), cmp);
 
  329    const auto size = candidates_to_be_added[i].size();
 
  330    if(size >= max_points_to_add) {
 
  331      double const last_persistence_added
 
  332        = persistences[idx[i][max_points_to_add - 1]];
 
  333      if(last_persistence_added > local_min_persistence) {
 
  334        local_min_persistence = last_persistence_added;
 
  338      new_min_persistence = local_min_persistence;
 
  340      if(local_min_persistence < new_min_persistence) {
 
  341        new_min_persistence = local_min_persistence;
 
  345    const auto s = candidates_to_be_added[i].size();
 
  346    for(
size_t j = 0; j < std::min(max_points_to_add, s); j++) {
 
  347      auto b = bidder_diags[i].at(candidates_to_be_added[i][idx[i][j]]);
 
  348      const double persistence = b.getPersistence();
 
  349      if(persistence >= new_min_persistence) {
 
  350        b.id_ = current_bidder_diags[i].size();
 
  351        b.setPositionInAuction(current_bidder_diags[i].size());
 
  352        current_bidder_diags[i].emplace_back(b);