File: HasseDiagramTools.h

package info (click to toggle)
polymake 3.0r2-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 19,752 kB
  • ctags: 30,928
  • sloc: cpp: 151,785; perl: 32,510; ansic: 3,597; java: 2,654; python: 278; makefile: 181; xml: 103; sh: 79
file content (146 lines) | stat: -rw-r--r-- 5,172 bytes parent folder | download
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
/* Copyright (c) 1997-2015
   Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany)
   http://www.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.
--------------------------------------------------------------------------------
*/

#ifndef POLYMAKE_GRAPH_HASSE_DIAGRAM_TOOLS_H
#define POLYMAKE_GRAPH_HASSE_DIAGRAM_TOOLS_H

#include "polymake/Set.h"
#include "polymake/graph/HasseDiagram.h"
#include "polymake/graph/BFSiterator.h"


namespace polymake { namespace graph {

int find_vertex_node(const HasseDiagram& HD, int v);

template <typename SetTop>
int find_face_node(const HasseDiagram& HD, const GenericSet<SetTop,int>& f, int dim=-1)
{
   for (Entire<HasseDiagram::nodes_of_dim_set>::const_iterator it=entire(HD.nodes_of_dim(dim)); !it.at_end(); ++it)
      if (HD.face(*it).front()==f)
         return *it;
   throw no_match("face node not found");
}

class HasseDiagram_facet_iterator
   : public BFSiterator< Graph<Directed> > {
   typedef BFSiterator< Graph<Directed> > super;
protected:
   const HasseDiagram *HD;
   int top_node;

   void valid_position()
   {
      int n;
      while (n=*(*this), HD->out_adjacent_nodes(n).front() != top_node)
         super::operator++();
   }
public:
   typedef HasseDiagram_facet_iterator iterator;
   typedef HasseDiagram_facet_iterator const_iterator;

   HasseDiagram_facet_iterator() : HD(0) {}

   HasseDiagram_facet_iterator(const HasseDiagram& HD_arg)
      : super(HD_arg.graph(), HD_arg.bottom_node()), HD(&HD_arg), top_node(HD_arg.top_node())
   {
      if (!at_end() && *(*this)!=top_node) valid_position();
   }

   HasseDiagram_facet_iterator(const HasseDiagram& HD_arg, int start_node)
      : super(HD_arg.graph(), start_node), HD(&HD_arg), top_node(HD_arg.top_node())
   {
      if (!at_end() && *(*this)!=top_node) valid_position();
   }

   iterator& operator++()
   {
      queue.pop_front();
      if (!at_end()) valid_position();
      return *this;
   }
   const iterator operator++(int) { iterator copy(*this); operator++(); return copy; }

   const Set<int>& face() const { return HD->face(*(*this)); }
   const Graph<Directed>& graph() const { return HD->graph(); }
   const Set<int>& face(int n) const { return HD->face(n); }
};

typedef bool2type<true> Down;
typedef bool2type<false> Up;

template<typename Direction>
Set<int> order_ideal(const Set<int>& generators, const graph::HasseDiagram& LF)
{
   Set<int> queue(generators), order_ideal; // make the queue a Set because any given element will be inserted lots of times
   while(queue.size()) {
      const int s(queue.front());
      queue -= s;
      order_ideal += s;
      if (Direction::value)
         queue += LF.in_adjacent_nodes(s);
      else 
         queue += LF.out_adjacent_nodes(s);
   }
   return order_ideal;
}

template<typename HDType>
bool is_convex_subset(const Set<int>& Cset, const HDType& LF, bool verbose) {
   // prepare down-sets and up-sets
   std::vector<Set<int> > down_set_of(LF.nodes()), up_set_of(LF.nodes());
   for (Entire<Set<int> >::const_iterator cit = entire(Cset); !cit.at_end(); ++cit) {
      down_set_of[*cit] = order_ideal<Down>(scalar2set(*cit), LF);
      up_set_of  [*cit] = order_ideal<Up>(scalar2set(*cit), LF);
   }

   // check convexity
   for (int d1=1; d1 <= LF.dim()-2; ++d1) {
      for (typename Entire<typename HDType::nodes_of_dim_set>::const_iterator d1it = entire(LF.nodes_of_dim(d1)); !d1it.at_end(); ++d1it) {
         if (!Cset.contains(*d1it)) continue;
         for (int d2=d1+2; d2 <= LF.dim(); ++d2) {
            for (typename Entire<typename HDType::nodes_of_dim_set>::const_iterator d2it = entire(LF.nodes_of_dim(d2)); !d2it.at_end(); ++d2it) {
               if (!Cset.contains(*d2it)) continue;
               const Set<int> interval = up_set_of[*d1it] * down_set_of[*d2it];
               if (incl(interval, Cset) > 0) {
                  if (verbose) cout << "The given set is not convex because "
                                    << "it contains " << *d1it << "=" << LF.face(*d1it) 
                                    << " and " << *d2it << "=" << LF.face(*d2it)
                                    << ", but not the faces indexed by " << interval - Cset << " which are contained in the interval between them."
                                    << endl;
                  return false;
               }
            }
         }
      }
   }
   return true;
}

} } // end namespaces

namespace pm {
template <>
struct check_iterator_feature< polymake::graph::HasseDiagram_facet_iterator, end_sensitive > : True {};
}

#endif // POLYMAKE_GRAPH_HASSE_DIAGRAM_TOOLS_H

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