boundary_matrix.h
Go to the documentation of this file.
1 /* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT.
2  * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details.
3  * Author(s): Hannah Schreiber
4  *
5  * Copyright (C) 2022-24 Inria
6  *
7  * Modification(s):
8  * - YYYY/MM Author: Description of the modification
9  */
10 
17 #ifndef PM_BOUNDARY_MATRIX_H
18 #define PM_BOUNDARY_MATRIX_H
19 
20 #include <cassert>
21 #include <iostream> //print() only
22 #include <vector>
23 #include <utility> //std::swap, std::move & std::exchange
24 
25 namespace Gudhi {
26 namespace persistence_matrix {
27 
28 // TODO: factorize/inheritate/compose with @ref basematrix "base matrix"?
39 template <class Master_matrix>
40 class Boundary_matrix : public Master_matrix::Matrix_dimension_option,
41  public Master_matrix::template Base_swap_option<Boundary_matrix<Master_matrix> >,
42  public Master_matrix::Base_pairing_option,
43  public Master_matrix::Matrix_row_access_option
44 {
45  public:
46  using index = typename Master_matrix::index;
47  using id_index = typename Master_matrix::id_index;
48  using dimension_type = typename Master_matrix::dimension_type;
52  using Field_operators = typename Master_matrix::Field_operators;
53  using Field_element_type = typename Master_matrix::element_type;
54  using Column_type = typename Master_matrix::Column_type;
55  using boundary_type = typename Master_matrix::boundary_type;
56  using Row_type = typename Master_matrix::Row_type;
58  using Cell_constructor = typename Master_matrix::Cell_constructor;
59  using Column_settings = typename Master_matrix::Column_settings;
68  Boundary_matrix(Column_settings* colSettings);
90  template <class Boundary_type = boundary_type>
91  Boundary_matrix(const std::vector<Boundary_type>& orderedBoundaries,
92  Column_settings* colSettings);
100  Boundary_matrix(unsigned int numberOfColumns, Column_settings* colSettings);
110  Boundary_matrix(const Boundary_matrix& matrixToCopy,
111  Column_settings* colSettings = nullptr);
117  Boundary_matrix(Boundary_matrix&& other) noexcept;
118 
141  template <class Boundary_type = boundary_type>
142  index insert_boundary(const Boundary_type& boundary, dimension_type dim = -1);
160  template <class Boundary_type = boundary_type>
161  index insert_boundary(id_index faceIndex, const Boundary_type& boundary, dimension_type dim = -1);
173  Column_type& get_column(index columnIndex);
186  Row_type& get_row(index rowIndex);
193  index remove_last();
209  void erase_empty_row(index rowIndex);
210 
217 
224  dimension_type get_column_dimension(index columnIndex) const;
225 
236  void add_to(index sourceColumnIndex, index targetColumnIndex);
249  void multiply_target_and_add_to(index sourceColumnIndex,
250  const Field_element_type& coefficient,
251  index targetColumnIndex);
264  void multiply_source_and_add_to(const Field_element_type& coefficient,
265  index sourceColumnIndex,
266  index targetColumnIndex);
267 
277  void zero_cell(index columnIndex, index rowIndex);
286  void zero_column(index columnIndex);
295  bool is_zero_cell(index columnIndex, index rowIndex) const;
303  bool is_zero_column(index columnIndex);
304 
311  index get_pivot(index columnIndex);
312 
319  void reset(Column_settings* colSettings) {
320  matrix_.clear();
321  nextInsertIndex_ = 0;
322  colSettings_ = colSettings;
323  }
324 
332  friend void swap(Boundary_matrix& matrix1, Boundary_matrix& matrix2) {
333  swap(static_cast<typename Master_matrix::Matrix_dimension_option&>(matrix1),
334  static_cast<typename Master_matrix::Matrix_dimension_option&>(matrix2));
335  swap(static_cast<typename Master_matrix::template Base_swap_option<Boundary_matrix<Master_matrix> >&>(matrix1),
336  static_cast<typename Master_matrix::template Base_swap_option<Boundary_matrix<Master_matrix> >&>(matrix2));
337  swap(static_cast<typename Master_matrix::Base_pairing_option&>(matrix1),
338  static_cast<typename Master_matrix::Base_pairing_option&>(matrix2));
339  matrix1.matrix_.swap(matrix2.matrix_);
340  std::swap(matrix1.nextInsertIndex_, matrix2.nextInsertIndex_);
341  std::swap(matrix1.colSettings_, matrix2.colSettings_);
342 
343  if constexpr (Master_matrix::Option_list::has_row_access) {
344  swap(static_cast<typename Master_matrix::Matrix_row_access_option&>(matrix1),
345  static_cast<typename Master_matrix::Matrix_row_access_option&>(matrix2));
346  }
347  }
348 
349  void print(); // for debug
350 
351  private:
352  using dim_opt = typename Master_matrix::Matrix_dimension_option;
353  using swap_opt = typename Master_matrix::template Base_swap_option<Boundary_matrix<Master_matrix> >;
354  using pair_opt = typename Master_matrix::Base_pairing_option;
355  using ra_opt = typename Master_matrix::Matrix_row_access_option;
356  using matrix_type = typename Master_matrix::column_container_type;
357 
358  friend swap_opt;
359  friend pair_opt;
360 
361  matrix_type matrix_;
362  index nextInsertIndex_;
363  Column_settings* colSettings_;
365  static constexpr bool activeDimOption =
366  Master_matrix::Option_list::has_matrix_maximal_dimension_access || Master_matrix::maxDimensionIsNeeded;
367  static constexpr bool activeSwapOption =
368  Master_matrix::Option_list::has_column_and_row_swaps || Master_matrix::Option_list::has_vine_update;
369  static constexpr bool activePairingOption = Master_matrix::Option_list::has_column_pairings &&
370  !Master_matrix::Option_list::has_vine_update &&
371  !Master_matrix::Option_list::can_retrieve_representative_cycles;
372 
373  void _orderRowsIfNecessary();
374  const Column_type& _get_column(index columnIndex) const;
375  Column_type& _get_column(index columnIndex);
376  index _get_real_row_index(index rowIndex) const;
377  template <class Container_type>
378  void _container_insert(const Container_type& column, index pos, dimension_type dim);
379  void _container_insert(const Column_type& column, [[maybe_unused]] index pos = 0);
380 };
381 
382 template <class Master_matrix>
384  : dim_opt(-1),
385  swap_opt(),
386  pair_opt(),
387  ra_opt(),
388  nextInsertIndex_(0),
389  colSettings_(colSettings)
390 {}
391 
392 template <class Master_matrix>
393 template <class Boundary_type>
394 inline Boundary_matrix<Master_matrix>::Boundary_matrix(const std::vector<Boundary_type>& orderedBoundaries,
395  Column_settings* colSettings)
396  : dim_opt(-1),
397  swap_opt(orderedBoundaries.size()),
398  pair_opt(),
399  ra_opt(orderedBoundaries.size()),
400  nextInsertIndex_(orderedBoundaries.size()),
401  colSettings_(colSettings)
402 {
403  matrix_.reserve(orderedBoundaries.size());
404 
405  for (index i = 0; i < orderedBoundaries.size(); i++) {
406  _container_insert(orderedBoundaries[i], i, orderedBoundaries[i].size() == 0 ? 0 : orderedBoundaries[i].size() - 1);
407  }
408 }
409 
410 template <class Master_matrix>
411 inline Boundary_matrix<Master_matrix>::Boundary_matrix(unsigned int numberOfColumns,
412  Column_settings* colSettings)
413  : dim_opt(-1),
414  swap_opt(numberOfColumns),
415  pair_opt(),
416  ra_opt(numberOfColumns),
417  matrix_(!Master_matrix::Option_list::has_map_column_container && Master_matrix::Option_list::has_row_access
418  ? 0
419  : numberOfColumns),
420  nextInsertIndex_(0),
421  colSettings_(colSettings)
422 {
423  if constexpr (!Master_matrix::Option_list::has_map_column_container && Master_matrix::Option_list::has_row_access)
424  matrix_.reserve(numberOfColumns);
425 }
426 
427 template <class Master_matrix>
429  Column_settings* colSettings)
430  : dim_opt(static_cast<const dim_opt&>(matrixToCopy)),
431  swap_opt(static_cast<const swap_opt&>(matrixToCopy)),
432  pair_opt(static_cast<const pair_opt&>(matrixToCopy)),
433  ra_opt(static_cast<const ra_opt&>(matrixToCopy)),
434  nextInsertIndex_(matrixToCopy.nextInsertIndex_),
435  colSettings_(colSettings == nullptr ? matrixToCopy.colSettings_ : colSettings)
436 {
437  matrix_.reserve(matrixToCopy.matrix_.size());
438  for (const auto& cont : matrixToCopy.matrix_){
439  if constexpr (Master_matrix::Option_list::has_map_column_container){
440  _container_insert(cont.second, cont.first);
441  } else {
442  _container_insert(cont);
443  }
444  }
445 }
446 
447 template <class Master_matrix>
449  : dim_opt(std::move(static_cast<dim_opt&>(other))),
450  swap_opt(std::move(static_cast<swap_opt&>(other))),
451  pair_opt(std::move(static_cast<pair_opt&>(other))),
452  ra_opt(std::move(static_cast<ra_opt&>(other))),
453  matrix_(std::move(other.matrix_)),
454  nextInsertIndex_(std::exchange(other.nextInsertIndex_, 0)),
455  colSettings_(std::exchange(other.colSettings_, nullptr))
456 {}
457 
458 template <class Master_matrix>
459 template <class Boundary_type>
461  const Boundary_type& boundary, dimension_type dim)
462 {
463  return insert_boundary(nextInsertIndex_, boundary, dim);
464 }
465 
466 template <class Master_matrix>
467 template <class Boundary_type>
469  id_index faceIndex, const Boundary_type& boundary, dimension_type dim)
470 {
471  if (dim == -1) dim = boundary.size() == 0 ? 0 : boundary.size() - 1;
472 
473  _orderRowsIfNecessary();
474 
475  //updates container sizes
476  if constexpr (Master_matrix::Option_list::has_row_access && !Master_matrix::Option_list::has_removable_rows) {
477  id_index pivot;
478  if constexpr (Master_matrix::Option_list::is_z2) {
479  pivot = *std::prev(boundary.end());
480  } else {
481  pivot = std::prev(boundary.end())->first;
482  }
483  //row container
484  if (ra_opt::rows_->size() <= pivot) ra_opt::rows_->resize(pivot + 1);
485  }
486 
487  //row swap map containers
488  if constexpr (Master_matrix::Option_list::has_map_column_container) {
489  if constexpr (activeSwapOption) {
490  swap_opt::indexToRow_.emplace(faceIndex, faceIndex);
491  swap_opt::rowToIndex_.emplace(faceIndex, faceIndex);
492  }
493  } else {
494  if constexpr (activeSwapOption) {
495  for (index i = swap_opt::indexToRow_.size(); i <= faceIndex; ++i) {
496  swap_opt::indexToRow_.push_back(i);
497  swap_opt::rowToIndex_.push_back(i);
498  }
499  }
500  }
501 
502  _container_insert(boundary, nextInsertIndex_, dim);
503 
504  return nextInsertIndex_++;
505 }
506 
507 template <class Master_matrix>
509  index columnIndex)
510 {
511  _orderRowsIfNecessary();
512 
513  return _get_column(columnIndex);
514 }
515 
516 template <class Master_matrix>
518 {
519  static_assert(Master_matrix::Option_list::has_row_access, "'get_row' is not implemented for the chosen options.");
520 
521  _orderRowsIfNecessary();
522 
523  return ra_opt::get_row(rowIndex);
524 }
525 
526 template <class Master_matrix>
528 {
529  static_assert(Master_matrix::Option_list::has_removable_columns,
530  "'remove_last' is not implemented for the chosen options.");
531 
532  if (nextInsertIndex_ == 0) return -1; // empty matrix
533  --nextInsertIndex_;
534 
535  //updates dimension max
536  if constexpr (activeDimOption) {
537  dim_opt::update_down(matrix_.at(nextInsertIndex_).get_dimension());
538  }
539 
540  //computes pivot and removes column from matrix_
541  id_index pivot;
542  if constexpr (Master_matrix::Option_list::has_map_column_container) {
543  auto it = matrix_.find(nextInsertIndex_);
544  pivot = it->second.get_pivot();
545  if constexpr (activeSwapOption) {
546  // if the removed column is positive, the pivot won't change value
547  if (swap_opt::rowSwapped_ && pivot != static_cast<id_index>(-1)) {
548  swap_opt::_orderRows();
549  pivot = it->second.get_pivot();
550  }
551  }
552  matrix_.erase(it);
553  } else {
554  pivot = matrix_[nextInsertIndex_].get_pivot();
555  if constexpr (activeSwapOption) {
556  // if the removed column is positive, the pivot won't change value
557  if (swap_opt::rowSwapped_ && pivot != static_cast<id_index>(-1)) {
558  swap_opt::_orderRows();
559  pivot = matrix_[nextInsertIndex_].get_pivot();
560  }
561  }
562  if constexpr (Master_matrix::Option_list::has_row_access) {
563  GUDHI_CHECK(nextInsertIndex_ == matrix_.size() - 1,
564  std::logic_error("Boundary_matrix::remove_last - Indexation problem."));
565  matrix_.pop_back();
566  } else {
567  matrix_[nextInsertIndex_].clear();
568  }
569  }
570 
571  erase_empty_row(nextInsertIndex_); // maximal, so empty
572 
573  //updates barcode
574  if constexpr (activePairingOption) {
575  pair_opt::_remove_last(nextInsertIndex_);
576  }
577 
578  return pivot;
579 }
580 
581 template <class Master_matrix>
583 {
584  //computes real row index and erases it if necessary from the row swap map containers
585  id_index rowID = rowIndex;
586  if constexpr (activeSwapOption) {
587  if constexpr (Master_matrix::Option_list::has_map_column_container) {
588  auto it = swap_opt::indexToRow_.find(rowIndex);
589  rowID = it->second;
590  swap_opt::rowToIndex_.erase(rowID);
591  swap_opt::indexToRow_.erase(it);
592  } else {
593  rowID = swap_opt::indexToRow_[rowIndex];
594  }
595  }
596 
597  if constexpr (Master_matrix::Option_list::has_row_access && Master_matrix::Option_list::has_removable_rows) {
598  ra_opt::erase_empty_row(rowID);
599  }
600 }
601 
602 template <class Master_matrix>
604 {
605  if constexpr (Master_matrix::Option_list::has_map_column_container) {
606  return matrix_.size();
607  } else {
608  return nextInsertIndex_; // matrix could have been resized much bigger while insert
609  }
610 }
611 
612 template <class Master_matrix>
614  index columnIndex) const
615 {
616  return _get_column(columnIndex).get_dimension();
617 }
618 
619 template <class Master_matrix>
620 inline void Boundary_matrix<Master_matrix>::add_to(index sourceColumnIndex, index targetColumnIndex)
621 {
622  _get_column(targetColumnIndex) += _get_column(sourceColumnIndex);
623 }
624 
625 template <class Master_matrix>
627  const Field_element_type& coefficient,
628  index targetColumnIndex)
629 {
630  _get_column(targetColumnIndex).multiply_target_and_add(coefficient, _get_column(sourceColumnIndex));
631 }
632 
633 template <class Master_matrix>
635  index sourceColumnIndex,
636  index targetColumnIndex)
637 {
638  _get_column(targetColumnIndex).multiply_source_and_add(_get_column(sourceColumnIndex), coefficient);
639 }
640 
641 template <class Master_matrix>
642 inline void Boundary_matrix<Master_matrix>::zero_cell(index columnIndex, index rowIndex)
643 {
644  _get_column(columnIndex).clear(_get_real_row_index(rowIndex));
645 }
646 
647 template <class Master_matrix>
649 {
650  _get_column(columnIndex).clear();
651 }
652 
653 template <class Master_matrix>
654 inline bool Boundary_matrix<Master_matrix>::is_zero_cell(index columnIndex, index rowIndex) const
655 {
656  return !(_get_column(columnIndex).is_non_zero(_get_real_row_index(rowIndex)));
657 }
658 
659 template <class Master_matrix>
661 {
662  return _get_column(columnIndex).is_empty();
663 }
664 
665 template <class Master_matrix>
667 {
668  _orderRowsIfNecessary();
669 
670  return _get_column(columnIndex).get_pivot();
671 }
672 
673 template <class Master_matrix>
675 {
676  dim_opt::operator=(other);
677  swap_opt::operator=(other);
678  pair_opt::operator=(other);
679  ra_opt::operator=(other);
680 
681  matrix_.clear();
682  nextInsertIndex_ = other.nextInsertIndex_;
683  colSettings_ = other.colSettings_;
684 
685  matrix_.reserve(other.matrix_.size());
686  for (const auto& cont : other.matrix_){
687  if constexpr (Master_matrix::Option_list::has_map_column_container){
688  _container_insert(cont.second, cont.first);
689  } else {
690  _container_insert(cont);
691  }
692  }
693 
694  return *this;
695 }
696 
697 template <class Master_matrix>
699 {
700  if constexpr (activeSwapOption) {
701  if (swap_opt::rowSwapped_) swap_opt::_orderRows();
702  }
703  std::cout << "Boundary_matrix:\n";
704  for (index i = 0; i < nextInsertIndex_; ++i) {
705  Column_type& col = matrix_[i];
706  for (auto e : col.get_content(nextInsertIndex_)) {
707  if (e == 0u)
708  std::cout << "- ";
709  else
710  std::cout << e << " ";
711  }
712  std::cout << "\n";
713  }
714  std::cout << "\n";
715  if constexpr (Master_matrix::Option_list::has_row_access) {
716  std::cout << "Row Matrix:\n";
717  for (id_index i = 0; i < nextInsertIndex_; ++i) {
718  const auto& row = ra_opt::rows_[i];
719  for (const auto& cell : row) {
720  std::cout << cell.get_column_index() << " ";
721  }
722  std::cout << "(" << i << ")\n";
723  }
724  std::cout << "\n";
725  }
726 }
727 
728 template <class Master_matrix>
729 inline void Boundary_matrix<Master_matrix>::_orderRowsIfNecessary()
730 {
731  if constexpr (activeSwapOption) {
732  if (swap_opt::rowSwapped_) swap_opt::_orderRows();
733  }
734 }
735 
736 template <class Master_matrix>
737 inline const typename Boundary_matrix<Master_matrix>::Column_type& Boundary_matrix<Master_matrix>::_get_column(
738  index columnIndex) const
739 {
740  if constexpr (Master_matrix::Option_list::has_map_column_container) {
741  return matrix_.at(columnIndex);
742  } else {
743  return matrix_[columnIndex];
744  }
745 }
746 
747 template <class Master_matrix>
748 inline typename Boundary_matrix<Master_matrix>::Column_type& Boundary_matrix<Master_matrix>::_get_column(
749  index columnIndex)
750 {
751  if constexpr (Master_matrix::Option_list::has_map_column_container) {
752  return matrix_.at(columnIndex);
753  } else {
754  return matrix_[columnIndex];
755  }
756 }
757 
758 template <class Master_matrix>
759 inline typename Boundary_matrix<Master_matrix>::index Boundary_matrix<Master_matrix>::_get_real_row_index(
760  index rowIndex) const
761 {
762  if constexpr (Master_matrix::Option_list::has_column_and_row_swaps || Master_matrix::Option_list::has_vine_update) {
763  if constexpr (Master_matrix::Option_list::has_map_column_container) {
764  return swap_opt::indexToRow_.at(rowIndex);
765  } else {
766  return swap_opt::indexToRow_[rowIndex];
767  }
768  } else {
769  return rowIndex;
770  }
771 }
772 
773 template <class Master_matrix>
774 template <class Container_type>
775 inline void Boundary_matrix<Master_matrix>::_container_insert(const Container_type& column,
776  index pos,
777  dimension_type dim)
778 {
779  if constexpr (Master_matrix::Option_list::has_map_column_container) {
780  if constexpr (Master_matrix::Option_list::has_row_access) {
781  matrix_.try_emplace(pos, Column_type(pos, column, dim, ra_opt::rows_, colSettings_));
782  } else {
783  matrix_.try_emplace(pos, Column_type(column, dim, colSettings_));
784  }
785  } else {
786  if constexpr (Master_matrix::Option_list::has_row_access) {
787  matrix_.emplace_back(pos, column, dim, ra_opt::rows_, colSettings_);
788  } else {
789  if (matrix_.size() <= pos) {
790  matrix_.emplace_back(column, dim, colSettings_);
791  } else {
792  matrix_[pos] = Column_type(column, dim, colSettings_);
793  }
794  }
795  }
796  if constexpr (activeDimOption) {
797  dim_opt::update_up(dim);
798  }
799 }
800 
801 template <class Master_matrix>
802 inline void Boundary_matrix<Master_matrix>::_container_insert(const Column_type& column, [[maybe_unused]] index pos)
803 {
804  if constexpr (Master_matrix::Option_list::has_map_column_container) {
805  if constexpr (Master_matrix::Option_list::has_row_access) {
806  matrix_.try_emplace(pos, Column_type(column, column.get_column_index(), ra_opt::rows_, colSettings_));
807  } else {
808  matrix_.try_emplace(pos, Column_type(column, colSettings_));
809  }
810  } else {
811  if constexpr (Master_matrix::Option_list::has_row_access) {
812  matrix_.emplace_back(column, column.get_column_index(), ra_opt::rows_, colSettings_);
813  } else {
814  matrix_.emplace_back(column, colSettings_);
815  }
816  }
817 }
818 
819 } // namespace persistence_matrix
820 } // namespace Gudhi
821 
822 #endif // PM_BOUNDARY_MATRIX_H
Matrix structure to store the ordered boundary matrix of a filtered complex in order to compute its ...
Definition: boundary_matrix.h:44
typename Master_matrix::Cell_constructor Cell_constructor
Definition: boundary_matrix.h:58
dimension_type get_column_dimension(index columnIndex) const
Returns the dimension of the given column.
Definition: boundary_matrix.h:613
void multiply_source_and_add_to(const Field_element_type &coefficient, index sourceColumnIndex, index targetColumnIndex)
Multiplies the source column with the coefficiant before adding it to the target column....
Definition: boundary_matrix.h:634
typename Master_matrix::Column_settings Column_settings
Definition: boundary_matrix.h:60
bool is_zero_cell(index columnIndex, index rowIndex) const
Indicates if the cell at given coordinates has value zero.
Definition: boundary_matrix.h:654
void zero_column(index columnIndex)
Zeroes the column at the given index.
Definition: boundary_matrix.h:648
void multiply_target_and_add_to(index sourceColumnIndex, const Field_element_type &coefficient, index targetColumnIndex)
Multiplies the target column with the coefficiant and then adds the source column to it....
Definition: boundary_matrix.h:626
void erase_empty_row(index rowIndex)
If PersistenceMatrixOptions::has_row_access and PersistenceMatrixOptions::has_removable_rows are true...
Definition: boundary_matrix.h:582
bool is_zero_column(index columnIndex)
Indicates if the column at given index has value zero.
Definition: boundary_matrix.h:660
friend void swap(Boundary_matrix &matrix1, Boundary_matrix &matrix2)
Swap operator.
Definition: boundary_matrix.h:332
typename Master_matrix::Column_type Column_type
Definition: boundary_matrix.h:54
Row_type & get_row(index rowIndex)
Only available if PersistenceMatrixOptions::has_row_access is true. Returns the row at the given row ...
Definition: boundary_matrix.h:517
void add_to(index sourceColumnIndex, index targetColumnIndex)
Adds column at sourceColumnIndex onto the column at targetColumnIndex in the matrix.
Definition: boundary_matrix.h:620
typename Master_matrix::element_type Field_element_type
Definition: boundary_matrix.h:53
index get_pivot(index columnIndex)
Returns the pivot of the given column.
Definition: boundary_matrix.h:666
typename Master_matrix::dimension_type dimension_type
Definition: boundary_matrix.h:48
void reset(Column_settings *colSettings)
Resets the matrix to an empty matrix.
Definition: boundary_matrix.h:319
typename Master_matrix::boundary_type boundary_type
Definition: boundary_matrix.h:55
typename Master_matrix::index index
Definition: boundary_matrix.h:46
void zero_cell(index columnIndex, index rowIndex)
Zeroes the cell at the given coordinates.
Definition: boundary_matrix.h:642
typename Master_matrix::id_index id_index
Definition: boundary_matrix.h:47
index insert_boundary(const Boundary_type &boundary, dimension_type dim=-1)
Inserts at the end of the matrix a new ordered column corresponding to the given boundary....
Definition: boundary_matrix.h:460
Column_type & get_column(index columnIndex)
Returns the column at the given MatIdx index. The type of the column depends on the choosen options,...
Definition: boundary_matrix.h:508
Boundary_matrix(Column_settings *colSettings)
Constructs an empty matrix.
Definition: boundary_matrix.h:383
typename Master_matrix::Row_type Row_type
Definition: boundary_matrix.h:57
index get_number_of_columns() const
Returns the current number of columns in the matrix.
Definition: boundary_matrix.h:603
typename Master_matrix::Field_operators Field_operators
Field operators class. Necessary only if PersistenceMatrixOptions::is_z2 is false.
Definition: boundary_matrix.h:52
Boundary_matrix & operator=(const Boundary_matrix &other)
Assign operator.
Definition: boundary_matrix.h:674
index remove_last()
Only available if PersistenceMatrixOptions::has_removable_columns is true. Removes the last face in t...
Definition: boundary_matrix.h:527
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14