File: ChainComplex.h

package info (click to toggle)
polymake 4.14-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 35,888 kB
  • sloc: cpp: 168,933; perl: 43,407; javascript: 31,575; ansic: 3,007; java: 2,654; python: 632; sh: 268; xml: 117; makefile: 61
file content (147 lines) | stat: -rw-r--r-- 4,257 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/* Copyright (c) 1997-2024
   Ewgenij Gawrilow, Michael Joswig, and the polymake team
   Technische Universität Berlin, Germany
   https://polymake.org

   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
   Free Software Foundation; either version 2, or (at your option) any
   later version: http://www.gnu.org/licenses/gpl.txt.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
--------------------------------------------------------------------------------
*/

#pragma once

#include "polymake/Array.h"
#include "polymake/topaz/HomologyComplex.h"

namespace polymake { namespace topaz {

/** @class ChainComplex
    @brief A general chain complex represented by its differential matrices.
    @tparam MatrixType specifies the type of the differential matrices.
*/
template <typename MatrixType>
class ChainComplex
{
public:
  // The matrices is a map via multiplying them to a vector from the __left__.
  Array<MatrixType> bd_matrix;

  /// Create as empty.
  ChainComplex() : bd_matrix(){ }

  /**@brief Create from an Array of matrices.
   *
   * The matrices are interpreted as maps via multiplying them to a vector from the __left__.
   * @param sanity_check indicating whether to test if the input matrices' dimensions match
   *  and the maps satisfy the differential condition. default: 0
   */
  ChainComplex(const Array<MatrixType> & bd_in, bool check = false)
    :  bd_matrix(bd_in)
  {
    if(check) sanity_check();
  }

private:
  void sanity_check()
  {
    for (auto d = entire(bd_matrix); !d.at_end() && !std::next(d).at_end(); ++d){
      auto next = std::next(d);
      if (d->rows() != next->cols()) {
        throw std::runtime_error("ChainComplex - matrix dimensions incompatible");
      } else {
        const MatrixType prod = (*next) * (*d);
        if (prod.non_zero())
          throw std::runtime_error("ChainComplex - differential condition not satisfied");
      }
    }
  }

public:
  Int dim() const{ return bd_matrix.size(); }

  /**@brief Convert the boundary matrix into a compatible type.
   *
   * @param d the number of the desired matrix.
   * @tparam E The return type is either SparseMatrix<E> or Matrix<E>,
   *  depending on whether MatrixType is sparse or not.
   */
  template <typename E>
  std::conditional_t<MatrixType::is_sparse, SparseMatrix<E,typename MatrixType::sym_discr>, Matrix<E>>
  boundary_matrix(Int d) const
  {
    if (d < 0) d += dim()+1;
    if (d > dim()) return { 0, bd_matrix[dim()-1].rows() };
    if (d == 0) return { bd_matrix[0].cols(), 0 };
    return convert_to<E>(bd_matrix[d-1]);
  }

  /**Return the n-th boundary matrix.
   * @param n number of the desired matrix.
   */
  MatrixType boundary_matrix(Int d) const
  {
    return boundary_matrix<typename MatrixType::value_type>(d);
  }

  /// Compare two ChainComplexes.
  template<typename MatrixType2>
  bool operator==(const ChainComplex<MatrixType2> & other) const
  {
    return bd_matrix == other.bd_matrix;
  }

  template<typename MatrixType2>
  bool operator!=(const ChainComplex<MatrixType2> & other) const
  {
    return !operator==(other);
  }

   template <typename Output> friend
   Output& operator<< (GenericOutput<Output>& out, const ChainComplex<MatrixType>& me)
   {
      out.top() << me.bd_matrix;
      return out.top();
   }

};

} }

namespace pm {

template <typename MatrixType>
struct spec_object_traits< Serialized< polymake::topaz::ChainComplex<MatrixType> > > :
    spec_object_traits<is_composite> {

  typedef polymake::topaz::ChainComplex<MatrixType> masquerade_for;

  typedef Array<MatrixType> elements;

  template <typename Me, typename Visitor>
  static void visit_elements(Me& me, Visitor& v) //for data_load
  {
    v << me.bd_matrix;
  }

  template <typename Visitor>
  static void visit_elements(const pm::Serialized<masquerade_for>& me, Visitor& v) //for data_save
  {
    v << me.bd_matrix;
  }
};

}


// Local Variables:
// mode:C++
// c-basic-offset:3
// indent-tabs-mode:nil
// End: