18#ifndef PM_SET_COLUMN_H 
   19#define PM_SET_COLUMN_H 
   27#include <boost/iterator/indirect_iterator.hpp> 
   33namespace persistence_matrix {
 
   46template <
class Master_matrix>
 
   52  using Master = Master_matrix;
 
   53  using Index = 
typename Master_matrix::Index;
 
   54  using ID_index = 
typename Master_matrix::ID_index;
 
   55  using Dimension = 
typename Master_matrix::Dimension;
 
   56  using Field_element = 
typename Master_matrix::Element;
 
   57  using Entry = 
typename Master_matrix::Matrix_entry;
 
   58  using Column_settings = 
typename Master_matrix::Column_settings;
 
   61  using Field_operators = 
typename Master_matrix::Field_operators;
 
   63  struct EntryPointerComp {
 
   64    bool operator()(
const Entry* c1, 
const Entry* c2)
 const { 
return *c1 < *c2; }
 
   67  using Column_support = std::set<Entry*, EntryPointerComp>;
 
   68  using Entry_constructor = 
typename Master_matrix::Entry_constructor;
 
   71  using iterator = boost::indirect_iterator<typename Column_support::iterator>;
 
   72  using const_iterator = boost::indirect_iterator<typename Column_support::const_iterator>;
 
   73  using reverse_iterator = boost::indirect_iterator<typename Column_support::reverse_iterator>;
 
   74  using const_reverse_iterator = boost::indirect_iterator<typename Column_support::const_reverse_iterator>;
 
   76  Set_column(Column_settings* colSettings = 
nullptr);
 
   77  template <
class Container = 
typename Master_matrix::Boundary>
 
   78  Set_column(
const Container& nonZeroRowIndices, Column_settings* colSettings);
 
   79  template <
class Container = 
typename Master_matrix::Boundary, 
class Row_container>
 
   81             const Container& nonZeroRowIndices,
 
   82             Row_container* rowContainer,
 
   83             Column_settings* colSettings);
 
   84  template <
class Container = 
typename Master_matrix::Boundary>
 
   85  Set_column(
const Container& nonZeroChainRowIndices, Dimension dimension, Column_settings* colSettings);
 
   86  template <
class Container = 
typename Master_matrix::Boundary, 
class Row_container>
 
   88             const Container& nonZeroChainRowIndices,
 
   90             Row_container* rowContainer,
 
   91             Column_settings* colSettings);
 
   93  template <
class Row_container>
 
   96             Row_container* rowContainer,
 
   97             Column_settings* colSettings = 
nullptr);
 
  101  std::vector<Field_element> get_content(
int columnLength = -1) 
const;
 
  102  bool is_non_zero(ID_index rowIndex) 
const;
 
  103  bool is_empty() 
const;
 
  104  std::size_t size() 
const;
 
  106  template <
class Row_index_map>
 
  107  void reorder(
const Row_index_map& valueMap,
 
  108               [[maybe_unused]] Index columnIndex = Master_matrix::template get_null_value<Index>());
 
  110  void clear(ID_index rowIndex);
 
  112  ID_index get_pivot() 
const;
 
  113  Field_element get_pivot_value() 
const;
 
  115  iterator begin() 
noexcept;
 
  116  const_iterator begin() 
const noexcept;
 
  117  iterator end() 
noexcept;
 
  118  const_iterator end() 
const noexcept;
 
  119  reverse_iterator rbegin() 
noexcept;
 
  120  const_reverse_iterator rbegin() 
const noexcept;
 
  121  reverse_iterator rend() 
noexcept;
 
  122  const_reverse_iterator rend() 
const noexcept;
 
  124  template <
class Entry_range>
 
  125  Set_column& operator+=(
const Entry_range& column);
 
  131  template <
class Entry_range>
 
  132  Set_column& multiply_target_and_add(
const Field_element& val, 
const Entry_range& column);
 
  135  template <
class Entry_range>
 
  136  Set_column& multiply_source_and_add(
const Entry_range& column, 
const Field_element& val);
 
  139  void push_back(
const Entry& entry);
 
  142    if (&c1 == &c2) 
return true;
 
  144    auto it1 = c1.column_.begin();
 
  145    auto it2 = c2.column_.begin();
 
  146    if (c1.column_.size() != c2.column_.size()) 
return false;
 
  147    while (it1 != c1.column_.end() && it2 != c2.column_.end()) {
 
  148      if constexpr (Master_matrix::Option_list::is_z2) {
 
  149        if ((*it1)->get_row_index() != (*it2)->get_row_index()) 
return false;
 
  151        if ((*it1)->get_row_index() != (*it2)->get_row_index() || (*it1)->get_element() != (*it2)->get_element())
 
  161    if (&c1 == &c2) 
return false;
 
  163    auto it1 = c1.column_.begin();
 
  164    auto it2 = c2.column_.begin();
 
  165    while (it1 != c1.column_.end() && it2 != c2.column_.end()) {
 
  166      if ((*it1)->get_row_index() != (*it2)->get_row_index()) 
return (*it1)->get_row_index() < (*it2)->get_row_index();
 
  167      if constexpr (!Master_matrix::Option_list::is_z2) {
 
  168        if ((*it1)->get_element() != (*it2)->get_element()) 
return (*it1)->get_element() < (*it2)->get_element();
 
  173    return it2 != c2.column_.end();
 
  186    col1.column_.swap(col2.column_);
 
  187    std::swap(col1.operators_, col2.operators_);
 
  188    std::swap(col1.entryPool_, col2.entryPool_);
 
  196  Column_support column_;
 
  197  Field_operators* operators_;
 
  198  Entry_constructor* entryPool_;
 
  200  template <
class Column, 
class Entry_iterator, 
typename F1, 
typename F2, 
typename F3, 
typename F4>
 
  201  friend void _generic_merge_entry_to_column(Column& targetColumn,
 
  202                                             Entry_iterator& itSource,
 
  203                                             typename Column::Column_support::iterator& itTarget,
 
  208                                             bool& pivotIsZeroed);
 
  209  template <
class Column, 
class Entry_range, 
typename F1, 
typename F2, 
typename F3, 
typename F4, 
typename F5>
 
  210  friend bool _generic_add_to_column(
const Entry_range& source,
 
  211                                     Column& targetColumn,
 
  217  template <
class Column, 
class Entry_range>
 
  218  friend bool _add_to_column(
const Entry_range& source, Column& targetColumn);
 
  219  template <
class Column, 
class Entry_range>
 
  220  friend bool _multiply_target_and_add_to_column(
const typename Column::Field_element& val,
 
  221                                                 const Entry_range& source,
 
  222                                                 Column& targetColumn);
 
  223  template <
class Column, 
class Entry_range>
 
  224  friend bool _multiply_source_and_add_to_column(
const typename Column::Field_element& val,
 
  225                                                 const Entry_range& source,
 
  226                                                 Column& targetColumn);
 
  228  void _delete_entry(
typename Column_support::iterator& it);
 
  229  Entry* _insert_entry(
const Field_element& value,
 
  231                       const typename Column_support::iterator& position);
 
  232  void _insert_entry(ID_index rowIndex, 
const typename Column_support::iterator& position);
 
  233  template <
class Entry_range>
 
  234  bool _add(
const Entry_range& column);
 
  235  template <
class Entry_range>
 
  236  bool _multiply_target_and_add(
const Field_element& val, 
const Entry_range& column);
 
  237  template <
class Entry_range>
 
  238  bool _multiply_source_and_add(
const Entry_range& column, 
const Field_element& val);
 
  241template <
class Master_matrix>
 
  247      entryPool_(colSettings == nullptr ? nullptr : &(colSettings->entryConstructor))
 
  249  if (operators_ == 
nullptr && entryPool_ == 
nullptr)
 
  251  if constexpr (!Master_matrix::Option_list::is_z2) {
 
  252    operators_ = &(colSettings->operators);
 
  256template <
class Master_matrix>
 
  257template <
class Container>
 
  258inline Set_column<Master_matrix>::Set_column(
const Container& nonZeroRowIndices, Column_settings* colSettings)
 
  260      Dim_opt(nonZeroRowIndices.size() == 0 ? 0 : nonZeroRowIndices.size() - 1),
 
  263      entryPool_(&(colSettings->entryConstructor))
 
  265  static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
 
  266                "Constructor not available for chain columns, please specify the dimension of the chain.");
 
  268  if constexpr (Master_matrix::Option_list::is_z2) {
 
  269    for (ID_index 
id : nonZeroRowIndices) {
 
  270      _insert_entry(
id, column_.end());
 
  273    operators_ = &(colSettings->operators);
 
  274    for (
const auto& p : nonZeroRowIndices) {
 
  275      _insert_entry(operators_->get_value(p.second), p.first, column_.end());
 
  280template <
class Master_matrix>
 
  281template <
class Container, 
class Row_container>
 
  282inline Set_column<Master_matrix>::Set_column(Index columnIndex,
 
  283                                             const Container& nonZeroRowIndices,
 
  284                                             Row_container* rowContainer,
 
  285                                             Column_settings* colSettings)
 
  286    : RA_opt(columnIndex, rowContainer),
 
  287      Dim_opt(nonZeroRowIndices.size() == 0 ? 0 : nonZeroRowIndices.size() - 1),
 
  289        if constexpr (Master_matrix::Option_list::is_z2) {
 
  290          return nonZeroRowIndices.begin() == nonZeroRowIndices.end()
 
  291                     ? Master_matrix::template get_null_value<ID_index>()
 
  292                     : *
std::prev(nonZeroRowIndices.end());
 
  294          return nonZeroRowIndices.begin() == nonZeroRowIndices.end()
 
  295                     ? Master_matrix::template get_null_value<ID_index>()
 
  296                     : 
std::prev(nonZeroRowIndices.end())->first;
 
  300      entryPool_(&(colSettings->entryConstructor))
 
  302  static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
 
  303                "Constructor not available for chain columns, please specify the dimension of the chain.");
 
  305  if constexpr (Master_matrix::Option_list::is_z2) {
 
  306    for (ID_index 
id : nonZeroRowIndices) {
 
  307      _insert_entry(
id, column_.end());
 
  310    operators_ = &(colSettings->operators);
 
  311    for (
const auto& p : nonZeroRowIndices) {
 
  312      _insert_entry(operators_->get_value(p.second), p.first, column_.end());
 
  317template <
class Master_matrix>
 
  318template <
class Container>
 
  319inline Set_column<Master_matrix>::Set_column(
const Container& nonZeroRowIndices,
 
  321                                             Column_settings* colSettings)
 
  325        if constexpr (Master_matrix::Option_list::is_z2) {
 
  326          return nonZeroRowIndices.begin() == nonZeroRowIndices.end()
 
  327                     ? Master_matrix::template get_null_value<ID_index>()
 
  328                     : *
std::prev(nonZeroRowIndices.end());
 
  330          return nonZeroRowIndices.begin() == nonZeroRowIndices.end()
 
  331                     ? Master_matrix::template get_null_value<ID_index>()
 
  332                     : 
std::prev(nonZeroRowIndices.end())->first;
 
  336      entryPool_(&(colSettings->entryConstructor))
 
  338  if constexpr (Master_matrix::Option_list::is_z2) {
 
  339    for (ID_index 
id : nonZeroRowIndices) {
 
  340      _insert_entry(
id, column_.end());
 
  343    operators_ = &(colSettings->operators);
 
  344    for (
const auto& p : nonZeroRowIndices) {
 
  345      _insert_entry(operators_->get_value(p.second), p.first, column_.end());
 
  350template <
class Master_matrix>
 
  351template <
class Container, 
class Row_container>
 
  352inline Set_column<Master_matrix>::Set_column(Index columnIndex,
 
  353                                             const Container& nonZeroRowIndices,
 
  355                                             Row_container* rowContainer,
 
  356                                             Column_settings* colSettings)
 
  357    : RA_opt(columnIndex, rowContainer),
 
  360        if constexpr (Master_matrix::Option_list::is_z2) {
 
  361          return nonZeroRowIndices.begin() == nonZeroRowIndices.end()
 
  362                     ? Master_matrix::template get_null_value<ID_index>()
 
  363                     : *
std::prev(nonZeroRowIndices.end());
 
  365          return nonZeroRowIndices.begin() == nonZeroRowIndices.end()
 
  366                     ? Master_matrix::template get_null_value<ID_index>()
 
  367                     : 
std::prev(nonZeroRowIndices.end())->first;
 
  371      entryPool_(&(colSettings->entryConstructor))
 
  373  if constexpr (Master_matrix::Option_list::is_z2) {
 
  374    for (ID_index 
id : nonZeroRowIndices) {
 
  375      _insert_entry(
id, column_.end());
 
  378    operators_ = &(colSettings->operators);
 
  379    for (
const auto& p : nonZeroRowIndices) {
 
  380      _insert_entry(operators_->get_value(p.second), p.first, column_.end());
 
  385template <
class Master_matrix>
 
  386inline Set_column<Master_matrix>::Set_column(
const Set_column& column, Column_settings* colSettings)
 
  388      Dim_opt(static_cast<const Dim_opt&>(column)),
 
  389      Chain_opt(static_cast<const Chain_opt&>(column)),
 
  390      operators_(colSettings == nullptr ? column.operators_ : nullptr),
 
  391      entryPool_(colSettings == nullptr ? column.entryPool_ : &(colSettings->entryConstructor))
 
  393  static_assert(!Master_matrix::Option_list::has_row_access,
 
  394                "Simple copy constructor not available when row access option enabled. Please specify the new column " 
  395                "index and the row container.");
 
  397  if constexpr (!Master_matrix::Option_list::is_z2) {
 
  398    if (colSettings != 
nullptr) operators_ = &(colSettings->operators);
 
  401  for (
const Entry* entry : column.column_) {
 
  402    if constexpr (Master_matrix::Option_list::is_z2) {
 
  403      _insert_entry(entry->get_row_index(), column_.end());
 
  405      _insert_entry(entry->get_element(), entry->get_row_index(), column_.end());
 
  410template <
class Master_matrix>
 
  411template <
class Row_container>
 
  412inline Set_column<Master_matrix>::Set_column(
const Set_column& column,
 
  414                                             Row_container* rowContainer,
 
  415                                             Column_settings* colSettings)
 
  416    : RA_opt(columnIndex, rowContainer),
 
  417      Dim_opt(static_cast<const Dim_opt&>(column)),
 
  418      Chain_opt(static_cast<const Chain_opt&>(column)),
 
  419      operators_(colSettings == nullptr ? column.operators_ : nullptr),
 
  420      entryPool_(colSettings == nullptr ? column.entryPool_ : &(colSettings->entryConstructor))
 
  422  if constexpr (!Master_matrix::Option_list::is_z2) {
 
  423    if (colSettings != 
nullptr) operators_ = &(colSettings->operators);
 
  426  for (
const Entry* entry : column.column_) {
 
  427    if constexpr (Master_matrix::Option_list::is_z2) {
 
  428      _insert_entry(entry->get_row_index(), column_.end());
 
  430      _insert_entry(entry->get_element(), entry->get_row_index(), column_.end());
 
  435template <
class Master_matrix>
 
  436inline Set_column<Master_matrix>::Set_column(Set_column&& column) noexcept
 
  437    : RA_opt(std::move(
static_cast<RA_opt&
>(column))),
 
  438      Dim_opt(std::move(
static_cast<Dim_opt&
>(column))),
 
  439      Chain_opt(std::move(
static_cast<Chain_opt&
>(column))),
 
  440      column_(std::move(column.column_)),
 
  441      operators_(std::exchange(column.operators_, 
nullptr)),
 
  442      entryPool_(std::exchange(column.entryPool_, 
nullptr))
 
  445template <
class Master_matrix>
 
  446inline Set_column<Master_matrix>::~Set_column()
 
  448  for (
auto* entry : column_) {
 
  449    if constexpr (Master_matrix::Option_list::has_row_access) RA_opt::unlink(entry);
 
  450    entryPool_->destroy(entry);
 
  454template <
class Master_matrix>
 
  455inline std::vector<typename Set_column<Master_matrix>::Field_element> Set_column<Master_matrix>::get_content(
 
  456    int columnLength)
 const 
  458  if (columnLength < 0 && column_.size() > 0)
 
  459    columnLength = (*column_.rbegin())->get_row_index() + 1;
 
  460  else if (columnLength < 0)
 
  461    return std::vector<Field_element>();
 
  463  std::vector<Field_element> container(columnLength, 0);
 
  464  for (
auto it = column_.begin(); it != column_.end() && (*it)->get_row_index() < 
static_cast<ID_index
>(columnLength);
 
  466    if constexpr (Master_matrix::Option_list::is_z2) {
 
  467      container[(*it)->get_row_index()] = 1;
 
  469      container[(*it)->get_row_index()] = (*it)->get_element();
 
  475template <
class Master_matrix>
 
  476inline bool Set_column<Master_matrix>::is_non_zero(ID_index rowIndex)
 const 
  478  Entry entry(rowIndex);
 
  479  return column_.find(&entry) != column_.end();
 
  482template <
class Master_matrix>
 
  483inline bool Set_column<Master_matrix>::is_empty()
 const 
  485  return column_.empty();
 
  488template <
class Master_matrix>
 
  489inline std::size_t Set_column<Master_matrix>::size()
 const 
  491  return column_.size();
 
  494template <
class Master_matrix>
 
  495template <
class Row_index_map>
 
  496inline void Set_column<Master_matrix>::reorder(
const Row_index_map& valueMap, [[maybe_unused]] Index columnIndex)
 
  498  static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
 
  499                "Method not available for chain columns.");
 
  501  Column_support newSet;
 
  503  for (Entry* entry : column_) {
 
  504    if constexpr (Master_matrix::Option_list::has_row_access) {
 
  505      RA_opt::unlink(entry);
 
  506      if (columnIndex != Master_matrix::template get_null_value<Index>()) entry->set_column_index(columnIndex);
 
  508    entry->set_row_index(valueMap.at(entry->get_row_index()));
 
  509    newSet.insert(entry);
 
  510    if constexpr (Master_matrix::Option_list::has_row_access &&
 
  511                  Master_matrix::Option_list::has_intrusive_rows)  
 
  512      RA_opt::insert_entry(entry->get_row_index(), entry);
 
  516  if constexpr (Master_matrix::Option_list::has_row_access && !Master_matrix::Option_list::has_intrusive_rows) {  
 
  517    for (Entry* entry : newSet) {
 
  518      RA_opt::insert_entry(entry->get_row_index(), entry);
 
  522  column_.swap(newSet);
 
  525template <
class Master_matrix>
 
  526inline void Set_column<Master_matrix>::clear()
 
  528  static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
 
  529                "Method not available for chain columns as a base element should not be empty.");
 
  531  for (
auto* entry : column_) {
 
  532    if constexpr (Master_matrix::Option_list::has_row_access) RA_opt::unlink(entry);
 
  533    entryPool_->destroy(entry);
 
  539template <
class Master_matrix>
 
  540inline void Set_column<Master_matrix>::clear(ID_index rowIndex)
 
  542  static_assert(!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type,
 
  543                "Method not available for chain columns.");
 
  545  auto entry = entryPool_->construct(rowIndex);
 
  546  auto it = column_.find(entry);
 
  547  if (it != column_.end()) {
 
  550  entryPool_->destroy(entry);
 
  553template <
class Master_matrix>
 
  554inline typename Set_column<Master_matrix>::ID_index Set_column<Master_matrix>::get_pivot()
 const 
  556  static_assert(Master_matrix::isNonBasic,
 
  557                "Method not available for base columns.");  
 
  559  if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
 
  560    if (column_.empty()) 
return Master_matrix::template get_null_value<ID_index>();
 
  561    return (*column_.rbegin())->get_row_index();
 
  563    return Chain_opt::get_pivot();
 
  567template <
class Master_matrix>
 
  568inline typename Set_column<Master_matrix>::Field_element Set_column<Master_matrix>::get_pivot_value()
 const 
  570  static_assert(Master_matrix::isNonBasic,
 
  571                "Method not available for base columns.");  
 
  573  if constexpr (Master_matrix::Option_list::is_z2) {
 
  576    if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
 
  577      if (column_.empty()) 
return 0;
 
  578      return (*column_.rbegin())->get_element();
 
  580      if (Chain_opt::get_pivot() == Master_matrix::template get_null_value<ID_index>()) 
return Field_element();
 
  581      for (
const Entry* entry : column_) {
 
  582        if (entry->get_row_index() == Chain_opt::get_pivot()) 
return entry->get_element();
 
  584      return Field_element();  
 
  589template <
class Master_matrix>
 
  590inline typename Set_column<Master_matrix>::iterator Set_column<Master_matrix>::begin() noexcept
 
  592  return column_.begin();
 
  595template <
class Master_matrix>
 
  596inline typename Set_column<Master_matrix>::const_iterator Set_column<Master_matrix>::begin() const noexcept
 
  598  return column_.begin();
 
  601template <
class Master_matrix>
 
  602inline typename Set_column<Master_matrix>::iterator Set_column<Master_matrix>::end() noexcept
 
  604  return column_.end();
 
  607template <
class Master_matrix>
 
  608inline typename Set_column<Master_matrix>::const_iterator Set_column<Master_matrix>::end() const noexcept
 
  610  return column_.end();
 
  613template <
class Master_matrix>
 
  614inline typename Set_column<Master_matrix>::reverse_iterator Set_column<Master_matrix>::rbegin() noexcept
 
  616  return column_.rbegin();
 
  619template <
class Master_matrix>
 
  620inline typename Set_column<Master_matrix>::const_reverse_iterator Set_column<Master_matrix>::rbegin() const noexcept
 
  622  return column_.rbegin();
 
  625template <
class Master_matrix>
 
  626inline typename Set_column<Master_matrix>::reverse_iterator Set_column<Master_matrix>::rend() noexcept
 
  628  return column_.rend();
 
  631template <
class Master_matrix>
 
  632inline typename Set_column<Master_matrix>::const_reverse_iterator Set_column<Master_matrix>::rend() const noexcept
 
  634  return column_.rend();
 
  637template <
class Master_matrix>
 
  638template <
class Entry_range>
 
  639inline Set_column<Master_matrix>& Set_column<Master_matrix>::operator+=(
const Entry_range& column)
 
  641  static_assert((!Master_matrix::isNonBasic || std::is_same_v<Entry_range, Set_column>),
 
  642                "For boundary columns, the range has to be a column of same type to help ensure the validity of the " 
  644  static_assert((!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type),
 
  645                "For chain columns, the given column cannot be constant.");
 
  652template <
class Master_matrix>
 
  653inline Set_column<Master_matrix>& Set_column<Master_matrix>::operator+=(Set_column& column)
 
  655  if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
 
  658      Chain_opt::swap_pivots(column);
 
  659      Dim_opt::swap_dimension(column);
 
  668template <
class Master_matrix>
 
  669inline Set_column<Master_matrix>& Set_column<Master_matrix>::operator*=(
unsigned int v)
 
  671  if constexpr (Master_matrix::Option_list::is_z2) {
 
  673      if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
 
  674        throw std::invalid_argument(
"A chain column should not be multiplied by 0.");
 
  680    Field_element val = operators_->get_value(v);
 
  682    if (val == Field_operators::get_additive_identity()) {
 
  683      if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
 
  684        throw std::invalid_argument(
"A chain column should not be multiplied by 0.");
 
  691    if (val == Field_operators::get_multiplicative_identity()) 
return *
this;
 
  693    for (Entry* entry : column_) {
 
  694      operators_->multiply_inplace(entry->get_element(), val);
 
  695      if constexpr (Master_matrix::Option_list::has_row_access) RA_opt::update_entry(*entry);
 
  702template <
class Master_matrix>
 
  703template <
class Entry_range>
 
  704inline Set_column<Master_matrix>& Set_column<Master_matrix>::multiply_target_and_add(
const Field_element& val,
 
  705                                                                                     const Entry_range& column)
 
  707  static_assert((!Master_matrix::isNonBasic || std::is_same_v<Entry_range, Set_column>),
 
  708                "For boundary columns, the range has to be a column of same type to help ensure the validity of the " 
  710  static_assert((!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type),
 
  711                "For chain columns, the given column cannot be constant.");
 
  713  if constexpr (Master_matrix::Option_list::is_z2) {
 
  721    _multiply_target_and_add(val, column);
 
  727template <
class Master_matrix>
 
  728inline Set_column<Master_matrix>& Set_column<Master_matrix>::multiply_target_and_add(
const Field_element& val,
 
  731  if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
 
  733    if constexpr (Master_matrix::Option_list::is_z2) {
 
  736          Chain_opt::swap_pivots(column);
 
  737          Dim_opt::swap_dimension(column);
 
  740        throw std::invalid_argument(
"A chain column should not be multiplied by 0.");
 
  743      if (_multiply_target_and_add(val, column)) {
 
  744        Chain_opt::swap_pivots(column);
 
  745        Dim_opt::swap_dimension(column);
 
  749    if constexpr (Master_matrix::Option_list::is_z2) {
 
  757      _multiply_target_and_add(val, column);
 
  764template <
class Master_matrix>
 
  765template <
class Entry_range>
 
  766inline Set_column<Master_matrix>& Set_column<Master_matrix>::multiply_source_and_add(
const Entry_range& column,
 
  767                                                                                     const Field_element& val)
 
  769  static_assert((!Master_matrix::isNonBasic || std::is_same_v<Entry_range, Set_column>),
 
  770                "For boundary columns, the range has to be a column of same type to help ensure the validity of the " 
  772  static_assert((!Master_matrix::isNonBasic || Master_matrix::Option_list::is_of_boundary_type),
 
  773                "For chain columns, the given column cannot be constant.");
 
  775  if constexpr (Master_matrix::Option_list::is_z2) {
 
  780    _multiply_source_and_add(column, val);
 
  786template <
class Master_matrix>
 
  787inline Set_column<Master_matrix>& Set_column<Master_matrix>::multiply_source_and_add(Set_column& column,
 
  788                                                                                     const Field_element& val)
 
  790  if constexpr (Master_matrix::isNonBasic && !Master_matrix::Option_list::is_of_boundary_type) {
 
  792    if constexpr (Master_matrix::Option_list::is_z2) {
 
  795          Chain_opt::swap_pivots(column);
 
  796          Dim_opt::swap_dimension(column);
 
  800      if (_multiply_source_and_add(column, val)) {
 
  801        Chain_opt::swap_pivots(column);
 
  802        Dim_opt::swap_dimension(column);
 
  806    if constexpr (Master_matrix::Option_list::is_z2) {
 
  811      _multiply_source_and_add(column, val);
 
  818template <
class Master_matrix>
 
  819inline void Set_column<Master_matrix>::push_back(
const Entry& entry)
 
  821  static_assert(Master_matrix::Option_list::is_of_boundary_type, 
"`push_back` is not available for Chain matrices.");
 
  823  GUDHI_CHECK(entry.get_row_index() > get_pivot(), 
"The new row index has to be higher than the current pivot.");
 
  825  if constexpr (Master_matrix::Option_list::is_z2) {
 
  826    _insert_entry(entry.get_row_index(), column_.end());
 
  828    _insert_entry(entry.get_element(), entry.get_row_index(), column_.end());
 
  832template <
class Master_matrix>
 
  833inline Set_column<Master_matrix>& Set_column<Master_matrix>::operator=(
const Set_column& other)
 
  835  static_assert(!Master_matrix::Option_list::has_row_access, 
"= assignment not enabled with row access option.");
 
  837  Dim_opt::operator=(other);
 
  838  Chain_opt::operator=(other);
 
  840  for (
auto* entry : column_) {
 
  841    if constexpr (Master_matrix::Option_list::has_row_access) RA_opt::unlink(entry);
 
  842    entryPool_->destroy(entry);
 
  846  entryPool_ = other.entryPool_;
 
  847  operators_ = other.operators_;
 
  849  for (
const Entry* entry : other.column_) {
 
  850    if constexpr (Master_matrix::Option_list::is_z2) {
 
  851      _insert_entry(entry->get_row_index(), column_.end());
 
  853      _insert_entry(entry->get_element(), entry->get_row_index(), column_.end());
 
  860template <
class Master_matrix>
 
  861inline void Set_column<Master_matrix>::_delete_entry(
typename Column_support::iterator& it)
 
  863  if constexpr (Master_matrix::Option_list::has_row_access) RA_opt::unlink(*it);
 
  864  entryPool_->destroy(*it);
 
  865  it = column_.erase(it);
 
  868template <
class Master_matrix>
 
  869inline typename Set_column<Master_matrix>::Entry* Set_column<Master_matrix>::_insert_entry(
 
  870    const Field_element& value,
 
  872    const typename Column_support::iterator& position)
 
  874  if constexpr (Master_matrix::Option_list::has_row_access) {
 
  875    Entry* newEntry = entryPool_->construct(RA_opt::columnIndex_, rowIndex);
 
  876    newEntry->set_element(value);
 
  877    column_.insert(position, newEntry);
 
  878    RA_opt::insert_entry(rowIndex, newEntry);
 
  881    Entry* newEntry = entryPool_->construct(rowIndex);
 
  882    newEntry->set_element(value);
 
  883    column_.insert(position, newEntry);
 
  888template <
class Master_matrix>
 
  889inline void Set_column<Master_matrix>::_insert_entry(ID_index rowIndex,
 
  890                                                     const typename Column_support::iterator& position)
 
  892  if constexpr (Master_matrix::Option_list::has_row_access) {
 
  893    Entry* newEntry = entryPool_->construct(RA_opt::columnIndex_, rowIndex);
 
  894    column_.insert(position, newEntry);
 
  895    RA_opt::insert_entry(rowIndex, newEntry);
 
  897    Entry* newEntry = entryPool_->construct(rowIndex);
 
  898    column_.insert(position, newEntry);
 
  902template <
class Master_matrix>
 
  903template <
class Entry_range>
 
  904inline bool Set_column<Master_matrix>::_add(
const Entry_range& column)
 
  906  return _add_to_column(column, *
this);
 
  909template <
class Master_matrix>
 
  910template <
class Entry_range>
 
  911inline bool Set_column<Master_matrix>::_multiply_target_and_add(
const Field_element& val, 
const Entry_range& column)
 
  913  return _multiply_target_and_add_to_column(val, column, *
this);
 
  916template <
class Master_matrix>
 
  917template <
class Entry_range>
 
  918inline bool Set_column<Master_matrix>::_multiply_source_and_add(
const Entry_range& column, 
const Field_element& val)
 
  920  return _multiply_source_and_add_to_column(val, column, *
this);
 
  934template <
class Master_matrix>
 
  935struct std::hash<
Gudhi::persistence_matrix::Set_column<Master_matrix> > {
 
  937    return Gudhi::persistence_matrix::hash_column(column);
 
Column class following the PersistenceMatrixColumn concept.
Definition: set_column.h:50
 
Contains helper methods for column addition and column hasher.
 
Contains different versions of Gudhi::persistence_matrix::Entry factories.
 
Chain_column_extra_properties Chain_column_option
If PersistenceMatrixOptions::is_of_boundary_type is false, and, PersistenceMatrixOptions::has_column_...
Definition: PersistenceMatrixColumn.h:45
 
Row_access Row_access_option
If PersistenceMatrixOptions::has_row_access is true, then Row_access. Otherwise Dummy_row_access....
Definition: PersistenceMatrixColumn.h:28
 
Column_dimension_holder Column_dimension_option
If PersistenceMatrixOptions::has_column_pairings or PersistenceMatrixOptions::has_vine_update or Pers...
Definition: PersistenceMatrixColumn.h:36
 
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14