This file is indexed.

/usr/include/polymake/topaz/next/Filtration.h is in libpolymake-dev-common 3.2r2-3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
#ifndef POLYMAKE_TOPAZ_FILTRATION_H
#define POLYMAKE_TOPAZ_FILTRATION_H

#include "polymake/Array.h"
#include "polymake/Matrix.h"
#include "polymake/Set.h"
#include "polymake/SparseVector.h"
#include "polymake/graph/Lattice.h"
#include "polymake/graph/Decoration.h"
#include "polymake/internal/matrix_methods.h"

namespace polymake { namespace topaz {

    //dimension and index are needed to find the corresponding boundary via the given matrices.
    struct Cell{
        int deg,dim,idx;
        Cell(){
            deg=dim=idx=0;
        }

        Cell(int deg_in, int dim_in, int idx_in){
            deg = deg_in;
            dim = dim_in;
            idx = idx_in;
        }

        bool operator!= (const Cell & other) const{
            return deg!=other.deg || dim!=other.dim || idx!=other.idx;
       }

        //for testing.
        friend std::ostream & operator<<(std::ostream & os, const Cell & c){
            os << "(" << c.deg << "," << c.dim << "," << c.idx << ")";
            return os;
        }

    };

    template<typename MatrixType>
        class Filtration{
            typedef typename MatrixType::value_type Coeff;
            typedef typename MatrixType::persistent_nonsymmetric_type MatNS;

            public:
            Array<Cell> C; //after object initialization, this array is always sorted as required by the persistent homology algorithm.
            Array<MatrixType> bd_matrix; //boundary matrices by dimension. idx of the cells corresponds to the row in the corresponding matrix
            Array<Array<int> > ind; //keep track of indices to implement proper bd function

            Filtration() : C(), bd_matrix(), ind(){ }

            Filtration(Array<Cell> & C_in, const Array<MatrixType> & bd_in, bool sorted=false) : C(C_in), bd_matrix(bd_in), ind(bd_in.size()){
                if(sorted) update_indices();
                else sort();
            }

            Filtration(const graph::Lattice<graph::lattice::BasicDecoration> & HD, Array<int> degs) : C(HD.nodes()-2), //-2 for empty set and dummy
            bd_matrix(HD.rank()) {

                int dim = HD.rank()-1;

                const auto vertex_set = HD.nodes_of_rank(1); // nodes of dim 0
                int n_bd = vertex_set.size(); //number of vertices
                bd_matrix[0] = ones_matrix<Coeff>(n_bd,1);
                Map<int,int> reindex_map; // map index in hasse diagram to index in boundary matrix.
                int count_index = 0;
                for(int i : vertex_set) {
                    C[i-1] = Cell(degs[i-1],0,count_index);
                    reindex_map[i] = count_index;
                    ++count_index;
                }

                //compute boundary matrices for d>0:
                for(int d=1; d<dim; d++){
                   const auto d_set = HD.nodes_of_rank(d+1);
                   int n = d_set.size();//number of d-simplices
                   MatrixType bd(n,n_bd);
                   n_bd = n;
                   Map<int,int> new_reindex_map;

                   ///////////////////////
                   int r = 0; //row index
                   for(int f : d_set){ //iterate d-simplices
                      auto face = HD.face(f);
                      new_reindex_map[f] = r; //fill in index map for next iteration
                      C[f-1] = Cell(degs[f-1],d,r);//put indices into cell array

                      for(int sf : HD.in_adjacent_nodes(f)){ //iterate d-1-simplices
                         auto subface = HD.face(sf);
                         int i = 0;   //find index of the vertex missing in current subface
                         for(auto f_it = entire(face), sf_it = entire(subface);
                               (*f_it)==(*sf_it) && !sf_it.at_end(); ++f_it, ++sf_it)
                            ++i;

                         bd(r,reindex_map[sf]) = i%2 ? Coeff(1) : -Coeff(1);
                      }
                      ++r;
                   }
                   ///////////////////////////
                   /*

                    int r=0; //row index;
                    for (auto f=entire(d_set); !f.at_end(); ++f){//iterate over d-faces
                        new_reindex_map[*f] = r;
                        Coeff sgn = Coeff(1);
                        C[*f-1] = Cell(degs[*f-1],d,r);//put indices into cell array
                        for (auto subf=HD.in_adjacent_nodes(*f).begin();  !subf.at_end(); ++subf){//iterate over their boundary
                            bd[r][reindex_map[*subf]]=sgn;
                            sgn = -sgn;
                        }
                        r++;
                    }
                    */
                    bd_matrix[d] = bd;
                    reindex_map = new_reindex_map;
                }

                sort();
            }


            //keeps track of ind matrix for easy access of boundaries
            void update_indices(){
                ind.resize(bd_matrix.size());
                for(auto i = ensure(ind,(pm::cons<pm::end_sensitive, pm::indexed>*)0).begin(); !i.at_end(); ++i)
                    (*i).resize(bd_matrix[i.index()].rows());
                for (auto c=ensure(C, (pm::cons<pm::end_sensitive, pm::indexed>*)0).begin(); !c.at_end(); ++c) {
                    ind[(*c).dim][(*c).idx] = c.index();
                }
            }

            public:
            int n_cells() const{
                return C.size();
            }

            int n_frames() const{
                return C[n_cells()-1].deg; //TODO this only works with sorted array...
            }

            int dim() const{
                return bd_matrix.size()-1;
            }

            typedef SparseVector<Coeff> Chain;
            Chain bd(int i) const{
                Cell cell = C[i];
                int d = cell.dim;
                Chain c(C.size());
                if(d==0) return c; //points have empty boundary
                Chain b = bd_matrix[d].row(cell.idx);
                for (auto e = entire(b); !e.at_end(); ++e) {
                    c[ind[d-1][e.index()]] = *e;
                }
                return c;
            }

            // sort cells by degree first and dimension second, as required by persistent homology algo.
            private:
            struct cellComparator {
                bool operator()(const Cell& c1, const Cell& c2) {
                    if (c1.deg < c2.deg) return true;
                    if (c1.deg == c2.deg){
                        if(c1.dim < c2.dim) return true;
                        if(c1.dim == c2.dim) return c1.idx < c2.idx; // idx gets sorted lex to allow equality checking
                    }
                    return false;
                }
            };

            void sort(){
                std::sort(C.begin(), C.end(), cellComparator());
                update_indices();//TODO do this while sorting?
            }

            public:
            const Cell operator[](int i) const{
                return C[i];
            }

            const MatrixType boundary_matrix(int d){
                return bd_matrix[d];
            }

			const Array<Cell> cells() const{
			    return C;
			}

            //returns d-bd matrix of t-th frame TODO accept non-sorted filtrations?
            pm::MatrixMinor<MatrixType&, const Set<int>&, const Set<int>& > boundary_matrix(int d, int t){
                if(t>n_frames()) throw std::runtime_error("Filtration: input exceeds number of frames");
                if(d>dim()) throw std::runtime_error("Filtration: input exceeds filtration dimension");
                MatrixType B = bd_matrix[d];
                Set<int> frame; //indices of d-simplices present in this frame
                Set<int> frame_bd; //indices of d-1-simplices present

                for(auto i = ensure(ind[d],(pm::cons<pm::end_sensitive, pm::indexed>*)0).begin(); !i.at_end(); ++i){
                    if(C[*i].deg <= t) frame += i.index();
                }
                if(d>0){
                    for(auto i = ensure(ind[d-1],(pm::cons<pm::end_sensitive, pm::indexed>*)0).begin(); !i.at_end(); ++i){
                        if(C[*i].deg <= t) frame_bd += i.index();
                    }
                }else frame_bd = sequence(0,B.cols());

                return B.minor(frame,frame_bd);
            }

            pm::ensure_features<Array<Cell>, pm::cons<pm::end_sensitive, pm::indexed> >::const_iterator get_iter() const{
                return ensure(C, (pm::cons<pm::end_sensitive, pm::indexed>*)0).begin();
            }

            //for testing.
            friend std::ostream & operator<<(std::ostream & os, const Filtration & c){
                for(int i=0; i<c.n_cells(); ++i) os << c[i] << ",";
                return os;
            }

            template<typename MatrixType2>
            bool operator==(const Filtration<MatrixType2> & other) const{
                return bd_matrix == other.bd_matrix && C == other.C;
            }

            template <typename> friend struct pm::spec_object_traits;
        };


}}

namespace pm{

    template <>
        struct spec_object_traits< Serialized< polymake::topaz::Cell > > :
        spec_object_traits<is_composite> {

            typedef polymake::topaz::Cell masquerade_for;

            typedef cons<int,cons<int,int> > elements;

            template <typename Me, typename Visitor>
                static void visit_elements(Me& me, Visitor& v)
                {
                    v << me.deg << me.dim << me.idx;
                }
        };
    template <typename MatrixType>
        struct spec_object_traits< Serialized< polymake::topaz::Filtration<MatrixType> > > :
        spec_object_traits<is_composite> {

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

            typedef cons<Array<polymake::topaz::Cell>, Array<MatrixType> > elements;

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

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

}
#endif