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
25namespace Gudhi {
26namespace persistence_matrix {
27
28// TODO: factorize/inherit/compose with Base_matrix?
39template <class Master_matrix>
40class 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 = typename Master_matrix::Dimension;
52 using Field_operators = typename Master_matrix::Field_operators;
53 using Field_element = typename Master_matrix::Element;
54 using Column = typename Master_matrix::Column;
55 using Boundary = typename Master_matrix::Boundary;
56 using Row = typename Master_matrix::Row;
58 using Entry_constructor = typename Master_matrix::Entry_constructor;
59 using Column_settings = typename Master_matrix::Column_settings;
68 Boundary_matrix(Column_settings* colSettings);
91 template <class Boundary_range = Boundary>
92 Boundary_matrix(const std::vector<Boundary_range>& orderedBoundaries,
93 Column_settings* colSettings);
101 Boundary_matrix(unsigned int numberOfColumns, Column_settings* colSettings);
111 Boundary_matrix(const Boundary_matrix& matrixToCopy,
112 Column_settings* colSettings = nullptr);
118 Boundary_matrix(Boundary_matrix&& other) noexcept;
119
143 template <class Boundary_range = Boundary>
144 Index insert_boundary(const Boundary_range& boundary,
145 Dimension dim = Master_matrix::template get_null_value<Dimension>());
164 template <class Boundary_range = Boundary>
165 Index insert_boundary(ID_index cellIndex, const Boundary_range& boundary,
166 Dimension dim = Master_matrix::template get_null_value<Dimension>());
178 Column& get_column(Index columnIndex);
191 Row& get_row(Index rowIndex);
214 void erase_empty_row(Index rowIndex);
215
222
229 Dimension get_column_dimension(Index columnIndex) const;
230
241 void add_to(Index sourceColumnIndex, Index targetColumnIndex);
254 void multiply_target_and_add_to(Index sourceColumnIndex,
255 const Field_element& coefficient,
256 Index targetColumnIndex);
269 void multiply_source_and_add_to(const Field_element& coefficient,
270 Index sourceColumnIndex,
271 Index targetColumnIndex);
272
282 void zero_entry(Index columnIndex, Index rowIndex);
291 void zero_column(Index columnIndex);
300 bool is_zero_entry(Index columnIndex, Index rowIndex) const;
308 bool is_zero_column(Index columnIndex);
309
316 Index get_pivot(Index columnIndex);
317
324 void reset(Column_settings* colSettings) {
325 matrix_.clear();
326 nextInsertIndex_ = 0;
327 colSettings_ = colSettings;
328 }
329
337 friend void swap(Boundary_matrix& matrix1, Boundary_matrix& matrix2) {
338 swap(static_cast<typename Master_matrix::Matrix_dimension_option&>(matrix1),
339 static_cast<typename Master_matrix::Matrix_dimension_option&>(matrix2));
340 swap(static_cast<typename Master_matrix::template Base_swap_option<Boundary_matrix<Master_matrix> >&>(matrix1),
341 static_cast<typename Master_matrix::template Base_swap_option<Boundary_matrix<Master_matrix> >&>(matrix2));
342 swap(static_cast<typename Master_matrix::Base_pairing_option&>(matrix1),
343 static_cast<typename Master_matrix::Base_pairing_option&>(matrix2));
344 matrix1.matrix_.swap(matrix2.matrix_);
345 std::swap(matrix1.nextInsertIndex_, matrix2.nextInsertIndex_);
346 std::swap(matrix1.colSettings_, matrix2.colSettings_);
347
348 if constexpr (Master_matrix::Option_list::has_row_access) {
349 swap(static_cast<typename Master_matrix::Matrix_row_access_option&>(matrix1),
350 static_cast<typename Master_matrix::Matrix_row_access_option&>(matrix2));
351 }
352 }
353
354 void print(); // for debug
355
356 private:
357 using Dim_opt = typename Master_matrix::Matrix_dimension_option;
358 using Swap_opt = typename Master_matrix::template Base_swap_option<Boundary_matrix<Master_matrix> >;
359 using Pair_opt = typename Master_matrix::Base_pairing_option;
360 using RA_opt = typename Master_matrix::Matrix_row_access_option;
361 using Column_container = typename Master_matrix::Column_container;
362
363 friend Swap_opt;
364 friend Pair_opt;
365
366 Column_container matrix_;
367 Index nextInsertIndex_;
368 Column_settings* colSettings_;
370 static constexpr bool activeDimOption =
371 Master_matrix::Option_list::has_matrix_maximal_dimension_access || Master_matrix::maxDimensionIsNeeded;
372 static constexpr bool activeSwapOption =
373 Master_matrix::Option_list::has_column_and_row_swaps || Master_matrix::Option_list::has_vine_update;
374 static constexpr bool activePairingOption = Master_matrix::Option_list::has_column_pairings &&
375 !Master_matrix::Option_list::has_vine_update &&
376 !Master_matrix::Option_list::can_retrieve_representative_cycles;
377
378 void _orderRowsIfNecessary();
379 const Column& _get_column(Index columnIndex) const;
380 Column& _get_column(Index columnIndex);
381 Index _get_real_row_index(Index rowIndex) const;
382 template <class Container>
383 void _container_insert(const Container& column, Index pos, Dimension dim);
384 void _container_insert(const Column& column, [[maybe_unused]] Index pos = 0);
385};
386
387template <class Master_matrix>
389 : Dim_opt(Master_matrix::template get_null_value<Dimension>()),
390 Swap_opt(),
391 Pair_opt(),
392 RA_opt(),
393 nextInsertIndex_(0),
394 colSettings_(colSettings)
395{}
396
397template <class Master_matrix>
398template <class Boundary_range>
399inline Boundary_matrix<Master_matrix>::Boundary_matrix(const std::vector<Boundary_range>& orderedBoundaries,
400 Column_settings* colSettings)
401 : Dim_opt(Master_matrix::template get_null_value<Dimension>()),
402 Swap_opt(orderedBoundaries.size()),
403 Pair_opt(),
404 RA_opt(orderedBoundaries.size()),
405 nextInsertIndex_(orderedBoundaries.size()),
406 colSettings_(colSettings)
407{
408 matrix_.reserve(orderedBoundaries.size());
409
410 for (Index i = 0; i < orderedBoundaries.size(); i++) {
411 _container_insert(orderedBoundaries[i], i, orderedBoundaries[i].size() == 0 ? 0 : orderedBoundaries[i].size() - 1);
412 }
413}
414
415template <class Master_matrix>
416inline Boundary_matrix<Master_matrix>::Boundary_matrix(unsigned int numberOfColumns,
417 Column_settings* colSettings)
418 : Dim_opt(Master_matrix::template get_null_value<Dimension>()),
419 Swap_opt(numberOfColumns),
420 Pair_opt(),
421 RA_opt(numberOfColumns),
422 matrix_(!Master_matrix::Option_list::has_map_column_container && Master_matrix::Option_list::has_row_access
423 ? 0
424 : numberOfColumns),
425 nextInsertIndex_(0),
426 colSettings_(colSettings)
427{
428 if constexpr (!Master_matrix::Option_list::has_map_column_container && Master_matrix::Option_list::has_row_access)
429 matrix_.reserve(numberOfColumns);
430}
431
432template <class Master_matrix>
434 Column_settings* colSettings)
435 : Dim_opt(static_cast<const Dim_opt&>(matrixToCopy)),
436 Swap_opt(static_cast<const Swap_opt&>(matrixToCopy)),
437 Pair_opt(static_cast<const Pair_opt&>(matrixToCopy)),
438 RA_opt(static_cast<const RA_opt&>(matrixToCopy)),
439 nextInsertIndex_(matrixToCopy.nextInsertIndex_),
440 colSettings_(colSettings == nullptr ? matrixToCopy.colSettings_ : colSettings)
441{
442 matrix_.reserve(matrixToCopy.matrix_.size());
443 for (const auto& cont : matrixToCopy.matrix_){
444 if constexpr (Master_matrix::Option_list::has_map_column_container){
445 _container_insert(cont.second, cont.first);
446 } else {
447 _container_insert(cont);
448 }
449 }
450}
451
452template <class Master_matrix>
454 : Dim_opt(std::move(static_cast<Dim_opt&>(other))),
455 Swap_opt(std::move(static_cast<Swap_opt&>(other))),
456 Pair_opt(std::move(static_cast<Pair_opt&>(other))),
457 RA_opt(std::move(static_cast<RA_opt&>(other))),
458 matrix_(std::move(other.matrix_)),
459 nextInsertIndex_(std::exchange(other.nextInsertIndex_, 0)),
460 colSettings_(std::exchange(other.colSettings_, nullptr))
461{}
462
463template <class Master_matrix>
464template <class Boundary_range>
466 const Boundary_range& boundary, Dimension dim)
467{
468 return insert_boundary(nextInsertIndex_, boundary, dim);
469}
470
471template <class Master_matrix>
472template <class Boundary_range>
474 ID_index cellIndex, const Boundary_range& boundary, Dimension dim)
475{
476 if (dim == Master_matrix::template get_null_value<Dimension>()) dim = boundary.size() == 0 ? 0 : boundary.size() - 1;
477
478 _orderRowsIfNecessary();
479
480 //updates container sizes
481 if constexpr (Master_matrix::Option_list::has_row_access && !Master_matrix::Option_list::has_removable_rows) {
482 if (boundary.size() != 0){
483 ID_index pivot;
484 if constexpr (Master_matrix::Option_list::is_z2) {
485 pivot = *std::prev(boundary.end());
486 } else {
487 pivot = std::prev(boundary.end())->first;
488 }
489 //row container
490 if (RA_opt::rows_->size() <= pivot) RA_opt::rows_->resize(pivot + 1);
491 }
492 }
493
494 //row swap map containers
495 if constexpr (Master_matrix::Option_list::has_map_column_container) {
496 if constexpr (activeSwapOption) {
497 Swap_opt::indexToRow_.emplace(cellIndex, cellIndex);
498 Swap_opt::rowToIndex_.emplace(cellIndex, cellIndex);
499 }
500 } else {
501 if constexpr (activeSwapOption) {
502 for (Index i = Swap_opt::indexToRow_.size(); i <= cellIndex; ++i) {
503 Swap_opt::indexToRow_.push_back(i);
504 Swap_opt::rowToIndex_.push_back(i);
505 }
506 }
507 }
508
509 //maps for possible shifting between column content and position indices used for birth events
510 if constexpr (activePairingOption){
511 if (cellIndex != nextInsertIndex_){
512 Pair_opt::idToPosition_.emplace(cellIndex, nextInsertIndex_);
513 if constexpr (Master_matrix::Option_list::has_removable_columns){
514 Pair_opt::PIDM::map_.emplace(nextInsertIndex_, cellIndex);
515 }
516 }
517 }
518
519 _container_insert(boundary, nextInsertIndex_, dim);
520
521 return nextInsertIndex_++;
522}
523
524template <class Master_matrix>
526{
527 _orderRowsIfNecessary();
528
529 return _get_column(columnIndex);
530}
531
532template <class Master_matrix>
534{
535 static_assert(Master_matrix::Option_list::has_row_access, "'get_row' is not implemented for the chosen options.");
536
537 _orderRowsIfNecessary();
538
539 return RA_opt::get_row(rowIndex);
540}
541
542template <class Master_matrix>
544{
545 static_assert(Master_matrix::Option_list::has_removable_columns,
546 "'remove_last' is not implemented for the chosen options.");
547
548 if (nextInsertIndex_ == 0) return Master_matrix::template get_null_value<Index>(); // empty matrix
549 --nextInsertIndex_;
550
551 //updates dimension max
552 if constexpr (activeDimOption) {
553 Dim_opt::update_down(matrix_.at(nextInsertIndex_).get_dimension());
554 }
555
556 //computes pivot and removes column from matrix_
557 ID_index pivot;
558 if constexpr (Master_matrix::Option_list::has_map_column_container) {
559 auto it = matrix_.find(nextInsertIndex_);
560 pivot = it->second.get_pivot();
561 if constexpr (activeSwapOption) {
562 // if the removed column is positive, the pivot won't change value
563 if (Swap_opt::rowSwapped_ && pivot != Master_matrix::template get_null_value<ID_index>()) {
564 Swap_opt::_orderRows();
565 pivot = it->second.get_pivot();
566 }
567 }
568 matrix_.erase(it);
569 } else {
570 pivot = matrix_[nextInsertIndex_].get_pivot();
571 if constexpr (activeSwapOption) {
572 // if the removed column is positive, the pivot won't change value
573 if (Swap_opt::rowSwapped_ && pivot != Master_matrix::template get_null_value<ID_index>()) {
574 Swap_opt::_orderRows();
575 pivot = matrix_[nextInsertIndex_].get_pivot();
576 }
577 }
578 if constexpr (Master_matrix::Option_list::has_row_access) {
579 GUDHI_CHECK(nextInsertIndex_ == matrix_.size() - 1,
580 std::logic_error("Boundary_matrix::remove_last - Indexation problem."));
581 matrix_.pop_back();
582 } else {
583 matrix_[nextInsertIndex_].clear();
584 }
585 }
586
587 erase_empty_row(nextInsertIndex_); // maximal, so empty
588
589 //updates barcode
590 if constexpr (activePairingOption) {
591 Pair_opt::_remove_last(nextInsertIndex_);
592 }
593
594 return pivot;
595}
596
597template <class Master_matrix>
599{
600 //computes real row index and erases it if necessary from the row swap map containers
601 ID_index rowID = rowIndex;
602 if constexpr (activeSwapOption) {
603 if constexpr (Master_matrix::Option_list::has_map_column_container) {
604 auto it = Swap_opt::indexToRow_.find(rowIndex);
605 rowID = it->second;
606 Swap_opt::rowToIndex_.erase(rowID);
607 Swap_opt::indexToRow_.erase(it);
608 } else {
609 rowID = Swap_opt::indexToRow_[rowIndex];
610 }
611 }
612
613 if constexpr (Master_matrix::Option_list::has_row_access && Master_matrix::Option_list::has_removable_rows) {
614 RA_opt::erase_empty_row(rowID);
615 }
616}
617
618template <class Master_matrix>
620{
621 if constexpr (Master_matrix::Option_list::has_map_column_container) {
622 return matrix_.size();
623 } else {
624 return nextInsertIndex_; // matrix could have been resized much bigger while insert
625 }
626}
627
628template <class Master_matrix>
630 Index columnIndex) const
631{
632 return _get_column(columnIndex).get_dimension();
633}
634
635template <class Master_matrix>
636inline void Boundary_matrix<Master_matrix>::add_to(Index sourceColumnIndex, Index targetColumnIndex)
637{
638 _get_column(targetColumnIndex) += _get_column(sourceColumnIndex);
639}
640
641template <class Master_matrix>
643 const Field_element& coefficient,
644 Index targetColumnIndex)
645{
646 _get_column(targetColumnIndex).multiply_target_and_add(coefficient, _get_column(sourceColumnIndex));
647}
648
649template <class Master_matrix>
651 Index sourceColumnIndex,
652 Index targetColumnIndex)
653{
654 _get_column(targetColumnIndex).multiply_source_and_add(_get_column(sourceColumnIndex), coefficient);
655}
656
657template <class Master_matrix>
659{
660 _get_column(columnIndex).clear(_get_real_row_index(rowIndex));
661}
662
663template <class Master_matrix>
665{
666 _get_column(columnIndex).clear();
667}
668
669template <class Master_matrix>
670inline bool Boundary_matrix<Master_matrix>::is_zero_entry(Index columnIndex, Index rowIndex) const
671{
672 return !(_get_column(columnIndex).is_non_zero(_get_real_row_index(rowIndex)));
673}
674
675template <class Master_matrix>
677{
678 return _get_column(columnIndex).is_empty();
679}
680
681template <class Master_matrix>
683{
684 _orderRowsIfNecessary();
685
686 return _get_column(columnIndex).get_pivot();
687}
688
689template <class Master_matrix>
691{
692 Dim_opt::operator=(other);
693 Swap_opt::operator=(other);
694 Pair_opt::operator=(other);
695 RA_opt::operator=(other);
696
697 matrix_.clear();
698 nextInsertIndex_ = other.nextInsertIndex_;
699 colSettings_ = other.colSettings_;
700
701 matrix_.reserve(other.matrix_.size());
702 for (const auto& cont : other.matrix_){
703 if constexpr (Master_matrix::Option_list::has_map_column_container){
704 _container_insert(cont.second, cont.first);
705 } else {
706 _container_insert(cont);
707 }
708 }
709
710 return *this;
711}
712
713template <class Master_matrix>
715{
716 if constexpr (activeSwapOption) {
717 if (Swap_opt::rowSwapped_) Swap_opt::_orderRows();
718 }
719 std::cout << "Boundary_matrix:\n";
720 for (Index i = 0; i < nextInsertIndex_; ++i) {
721 Column& col = matrix_[i];
722 for (auto e : col.get_content(nextInsertIndex_)) {
723 if (e == 0u)
724 std::cout << "- ";
725 else
726 std::cout << e << " ";
727 }
728 std::cout << "\n";
729 }
730 std::cout << "\n";
731 if constexpr (Master_matrix::Option_list::has_row_access) {
732 std::cout << "Row Matrix:\n";
733 for (ID_index i = 0; i < nextInsertIndex_; ++i) {
734 const auto& row = (*RA_opt::rows_)[i];
735 for (const typename Column::Entry& entry : row) {
736 std::cout << entry.get_column_index() << " ";
737 }
738 std::cout << "(" << i << ")\n";
739 }
740 std::cout << "\n";
741 }
742}
743
744template <class Master_matrix>
745inline void Boundary_matrix<Master_matrix>::_orderRowsIfNecessary()
746{
747 if constexpr (activeSwapOption) {
748 if (Swap_opt::rowSwapped_) Swap_opt::_orderRows();
749 }
750}
751
752template <class Master_matrix>
753inline const typename Boundary_matrix<Master_matrix>::Column& Boundary_matrix<Master_matrix>::_get_column(
754 Index columnIndex) const
755{
756 if constexpr (Master_matrix::Option_list::has_map_column_container) {
757 return matrix_.at(columnIndex);
758 } else {
759 return matrix_[columnIndex];
760 }
761}
762
763template <class Master_matrix>
764inline typename Boundary_matrix<Master_matrix>::Column& Boundary_matrix<Master_matrix>::_get_column(
765 Index columnIndex)
766{
767 if constexpr (Master_matrix::Option_list::has_map_column_container) {
768 return matrix_.at(columnIndex);
769 } else {
770 return matrix_[columnIndex];
771 }
772}
773
774template <class Master_matrix>
775inline typename Boundary_matrix<Master_matrix>::Index Boundary_matrix<Master_matrix>::_get_real_row_index(
776 Index rowIndex) const
777{
778 if constexpr (Master_matrix::Option_list::has_column_and_row_swaps || Master_matrix::Option_list::has_vine_update) {
779 if constexpr (Master_matrix::Option_list::has_map_column_container) {
780 return Swap_opt::indexToRow_.at(rowIndex);
781 } else {
782 return Swap_opt::indexToRow_[rowIndex];
783 }
784 } else {
785 return rowIndex;
786 }
787}
788
789template <class Master_matrix>
790template <class Container>
791inline void Boundary_matrix<Master_matrix>::_container_insert(const Container& column,
792 Index pos,
793 Dimension dim)
794{
795 if constexpr (Master_matrix::Option_list::has_map_column_container) {
796 if constexpr (Master_matrix::Option_list::has_row_access) {
797 matrix_.try_emplace(pos, Column(pos, column, dim, RA_opt::rows_, colSettings_));
798 } else {
799 matrix_.try_emplace(pos, Column(column, dim, colSettings_));
800 }
801 } else {
802 if constexpr (Master_matrix::Option_list::has_row_access) {
803 matrix_.emplace_back(pos, column, dim, RA_opt::rows_, colSettings_);
804 } else {
805 if (matrix_.size() <= pos) {
806 matrix_.emplace_back(column, dim, colSettings_);
807 } else {
808 matrix_[pos] = Column(column, dim, colSettings_);
809 }
810 }
811 }
812 if constexpr (activeDimOption) {
813 Dim_opt::update_up(dim);
814 }
815}
816
817template <class Master_matrix>
818inline void Boundary_matrix<Master_matrix>::_container_insert(const Column& column, [[maybe_unused]] Index pos)
819{
820 if constexpr (Master_matrix::Option_list::has_map_column_container) {
821 if constexpr (Master_matrix::Option_list::has_row_access) {
822 matrix_.try_emplace(pos, Column(column, column.get_column_index(), RA_opt::rows_, colSettings_));
823 } else {
824 matrix_.try_emplace(pos, Column(column, colSettings_));
825 }
826 } else {
827 if constexpr (Master_matrix::Option_list::has_row_access) {
828 matrix_.emplace_back(column, column.get_column_index(), RA_opt::rows_, colSettings_);
829 } else {
830 matrix_.emplace_back(column, colSettings_);
831 }
832 }
833}
834
835} // namespace persistence_matrix
836} // namespace Gudhi
837
838#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::Dimension Dimension
Definition: Boundary_matrix.h:48
typename Master_matrix::Entry_constructor Entry_constructor
Definition: Boundary_matrix.h:58
typename Master_matrix::Element Field_element
Definition: Boundary_matrix.h:53
void erase_empty_row(Index rowIndex)
If PersistenceMatrixOptions::has_row_access and PersistenceMatrixOptions::has_removable_rows are true...
Definition: Boundary_matrix.h:598
typename Master_matrix::Column_settings Column_settings
Definition: Boundary_matrix.h:60
typename Master_matrix::Index Index
Definition: Boundary_matrix.h:46
Dimension get_column_dimension(Index columnIndex) const
Returns the dimension of the given column.
Definition: Boundary_matrix.h:629
void zero_entry(Index columnIndex, Index rowIndex)
Zeroes the entry at the given coordinates.
Definition: Boundary_matrix.h:658
Index remove_last()
Only available if PersistenceMatrixOptions::has_removable_columns is true. Removes the last cell in t...
Definition: Boundary_matrix.h:543
bool is_zero_column(Index columnIndex)
Indicates if the column at given index has value zero.
Definition: Boundary_matrix.h:676
friend void swap(Boundary_matrix &matrix1, Boundary_matrix &matrix2)
Swap operator.
Definition: Boundary_matrix.h:337
void zero_column(Index columnIndex)
Zeroes the column at the given index.
Definition: Boundary_matrix.h:664
Index get_number_of_columns() const
Returns the current number of columns in the matrix.
Definition: Boundary_matrix.h:619
bool is_zero_entry(Index columnIndex, Index rowIndex) const
Indicates if the entry at given coordinates has value zero.
Definition: Boundary_matrix.h:670
typename Master_matrix::Boundary Boundary
Definition: Boundary_matrix.h:55
void reset(Column_settings *colSettings)
Resets the matrix to an empty matrix.
Definition: Boundary_matrix.h:324
typename Master_matrix::Row Row
Definition: Boundary_matrix.h:57
Index get_pivot(Index columnIndex)
Returns the pivot of the given column.
Definition: Boundary_matrix.h:682
Column & get_column(Index columnIndex)
Returns the column at the given MatIdx index. The type of the column depends on the chosen options,...
Definition: Boundary_matrix.h:525
Index insert_boundary(const Boundary_range &boundary, Dimension dim=Master_matrix::template get_null_value< Dimension >())
Inserts at the end of the matrix a new ordered column corresponding to the given boundary....
Definition: Boundary_matrix.h:465
typename Master_matrix::Column Column
Definition: Boundary_matrix.h:54
void add_to(Index sourceColumnIndex, Index targetColumnIndex)
Adds column at sourceColumnIndex onto the column at targetColumnIndex in the matrix.
Definition: Boundary_matrix.h:636
typename Master_matrix::ID_index ID_index
Definition: Boundary_matrix.h:47
Boundary_matrix(Column_settings *colSettings)
Constructs an empty matrix.
Definition: Boundary_matrix.h:388
void multiply_source_and_add_to(const Field_element &coefficient, Index sourceColumnIndex, Index targetColumnIndex)
Multiplies the source column with the coefficient before adding it to the target column....
Definition: Boundary_matrix.h:650
void multiply_target_and_add_to(Index sourceColumnIndex, const Field_element &coefficient, Index targetColumnIndex)
Multiplies the target column with the coefficient and then adds the source column to it....
Definition: Boundary_matrix.h:642
Row & get_row(Index rowIndex)
Only available if PersistenceMatrixOptions::has_row_access is true. Returns the row at the given row ...
Definition: Boundary_matrix.h:533
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:690
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14