157#if BOOST_VERSION >= 108100
158 using Birth_dictionary = boost::unordered_flat_map<Index, Index>;
161 using Birth_dictionary = std::unordered_map<Index, Index>;
186 struct Birth_ordering {
190 Birth_ordering() : birthToPos_(), maxBirthPos_(0), minBirthPos_(-1) {}
199 void add_birth_forward(
Index arrowNumber) {
200 birthToPos_.emplace_hint(birthToPos_.end(), arrowNumber, maxBirthPos_);
210 void add_birth_backward(
Index arrowNumber) {
211 birthToPos_.emplace_hint(birthToPos_.end(), arrowNumber, minBirthPos_);
222 void remove_birth(
Index birth) { birthToPos_.erase(birth); }
230 bool birth_order(
Index k1,
Index k2)
const {
return birthToPos_.at(k1) < birthToPos_.at(k2); }
238 bool reverse_birth_order(
Index k1,
Index k2)
const {
return birthToPos_.at(k1) > birthToPos_.at(k2); }
241 Birth_dictionary birthToPos_;
265 unsigned int preallocationSize = 0)
268 [this](Matrix_index columnIndex1, Matrix_index columnIndex2) -> bool {
269 if (matrix_.get_column(columnIndex1).is_paired()) {
270 return matrix_.get_pivot(columnIndex1) < matrix_.get_pivot(columnIndex2);
272 return birthOrdering_.birth_order(births_.at(columnIndex1), births_.at(columnIndex2));
274 [
this](Matrix_index columnIndex1, Matrix_index columnIndex2) ->
bool {
return false; }),
276 stream_interval_(std::move(stream_interval)) {}
288 template <
class BoundaryRange = std::initializer_list<Index> >
291 _process_forward_arrow(boundary, dimension);
303 _process_backward_arrow(arrowNumber);
323 template <
typename F>
325 for (
auto& p : births_) {
326 auto& col = matrix_.get_column(p.first);
327 stream_infinite_interval(col.get_dimension(), p.second);
340 template <
class BoundaryRange>
341 void _process_forward_arrow(
const BoundaryRange& boundary, Dimension dim) {
342 std::vector<Matrix_index> chainsInF = matrix_.insert_boundary(numArrow_, boundary, dim);
344 if (!chainsInF.empty()) {
345 _apply_surjective_reflection_diamond(dim, chainsInF);
347 birthOrdering_.add_birth_forward(numArrow_);
348 births_[matrix_.get_column_with_pivot(numArrow_)] = numArrow_;
363 void _apply_surjective_reflection_diamond(Dimension dim,
const std::vector<Matrix_index>& chainsInF) {
366 auto chainFp = chainsInF[0];
374 auto cmp_birth = [
this](Index k1, Index k2) ->
bool {
375 return birthOrdering_.reverse_birth_order(k1, k2);
380 std::set<Index,
decltype(cmp_birth)> availableBirth(cmp_birth);
382 for (
auto& chainF : chainsInF) {
383 availableBirth.insert(births_.at(chainF));
386 auto maxbIt = availableBirth.begin();
388 availableBirth.erase(maxbIt);
390 auto lastModifiedChainIt = chainsInF.rbegin();
393 for (
auto chainFIt = chainsInF.rbegin();
394 *chainFIt != chainFp; ++chainFIt)
396 auto birthIt = availableBirth.find(births_.at(*chainFIt));
397 if (birthIt == availableBirth.end())
413 for (
auto chainPassedIt = lastModifiedChainIt; chainPassedIt != chainFIt; ++chainPassedIt) {
415 matrix_.add_to(*chainPassedIt, *chainFIt);
417 lastModifiedChainIt = chainFIt;
419 auto maxAvailBirthIt = availableBirth.begin();
420 Index maxAvailBirth = *maxAvailBirthIt;
422 births_.at(*chainFIt) = maxAvailBirth;
423 availableBirth.erase(maxAvailBirthIt);
425 availableBirth.erase(birthIt);
429 birthOrdering_.remove_birth(maxb);
430 births_.erase(chainFp);
433 stream_interval_(dim - 1, maxb, numArrow_);
441 void _process_backward_arrow(Index cellID) {
443 Matrix_index currCol = matrix_.get_column_with_pivot(cellID);
446 std::vector<Matrix_index> modifiedColumns;
447 const auto& row = matrix_.get_row(cellID);
448 modifiedColumns.reserve(row.size());
449 std::transform(row.begin(), row.end(), std::back_inserter(modifiedColumns),
450 [](
const auto& cell) { return cell.get_column_index(); });
452 std::stable_sort(modifiedColumns.begin(), modifiedColumns.end(), [
this](Matrix_index i1, Matrix_index i2) {
453 return matrix_.get_pivot(i1) < matrix_.get_pivot(i2);
457 for (
auto otherColIt = std::next(modifiedColumns.begin()); otherColIt != modifiedColumns.end(); ++otherColIt) {
458 currCol = matrix_.vine_swap_with_z_eq_1_case(currCol, *otherColIt);
462 auto& col = matrix_.get_column(currCol);
463 if (!col.is_paired()) {
464 auto it = births_.find(currCol);
465 stream_interval_(col.get_dimension(), it->second, numArrow_);
466 birthOrdering_.remove_birth(it->second);
470 birthOrdering_.add_birth_backward(numArrow_);
471 births_[col.get_paired_chain_index()] = numArrow_;
475 matrix_.remove_maximal_cell(cellID, {});
480 Birth_dictionary births_;
481 Birth_ordering birthOrdering_;
483 std::function<void(Dimension, Index, Index)> stream_interval_;