2
/**************************************************************************
4
* Regina - A Normal Surface Theory Calculator *
5
* Computational Engine *
7
* Copyright (c) 1999-2013, Ben Burton *
8
* For further details contact Ben Burton (bab@debian.org). *
10
* This program is free software; you can redistribute it and/or *
11
* modify it under the terms of the GNU General Public License as *
12
* published by the Free Software Foundation; either version 2 of the *
13
* License, or (at your option) any later version. *
15
* As an exception, when this program is distributed through (i) the *
16
* App Store by Apple Inc.; (ii) the Mac App Store by Apple Inc.; or *
17
* (iii) Google Play by Google Inc., then that store may impose any *
18
* digital rights management, device limits and/or redistribution *
19
* restrictions that are required by its terms of service. *
21
* This program is distributed in the hope that it will be useful, but *
22
* WITHOUT ANY WARRANTY; without even the implied warranty of *
23
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
24
* General Public License for more details. *
26
* You should have received a copy of the GNU General Public *
27
* License along with this program; if not, write to the Free *
28
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, *
29
* MA 02110-1301, USA. *
31
**************************************************************************/
35
/* To be included from nmaxadmissible.h. */
37
#ifndef __NMAXADMISSIBLE_IMPL_H
39
#define __NMAXADMISSIBLE_IMPL_H
42
#include "enumerate/nenumconstraint.h"
43
#include "enumerate/nmaxadmissible.h"
49
template <class BitmaskType, class RayIterator>
50
std::vector<BitmaskType>* NMaxAdmissible::enumerate(
51
RayIterator beginExtremalRays, RayIterator endExtremalRays,
52
const NEnumConstraintList* constraints) {
53
if (beginExtremalRays == endExtremalRays) {
54
// Input is empty, so output is empty.
55
return new std::vector<BitmaskType>();
58
size_t dim = (*beginExtremalRays)->size();
62
// Rewrite the constraints as bitmasks.
63
std::vector<BitmaskType> constMasks;
65
NEnumConstraintList::const_iterator cit;
66
std::set<unsigned long>::const_iterator sit;
67
for (cit = constraints->begin(); cit != constraints->end(); ++cit) {
69
for (sit = cit->begin(); sit != cit->end(); ++sit)
71
constMasks.push_back(b);
75
// Create a set of bitmasks representing the admissible 1-faces of
76
// the cone, i.e., the set of admissible extremal rays.
77
std::vector<BitmaskType> rays;
78
for (RayIterator rit = beginExtremalRays; rit != endExtremalRays; ++rit) {
79
for (i = 0; i < dim; ++i)
80
b.set(i, (**rit)[i] != 0);
84
// Create a working set of admissible faces.
85
// We initialise this to the set of all admissible 1-faces, as above.
86
std::list<BitmaskType> faces(rays.begin(), rays.end());
88
// Create the final set of faces to return.
89
std::vector<BitmaskType>* maxFaces = new std::vector<BitmaskType>();
91
// Keep expanding the faces using additional extremal rays until we can
93
// The ith iteration of the following loop enumerates _all_ admissible
94
// faces of dimension i+1, and identifies all _maximal_ admissible
95
// faces of dimension i.
96
std::list<BitmaskType> nextDim;
97
typename std::vector<BitmaskType>::const_iterator r, c;
98
typename std::list<BitmaskType>::const_iterator f;
99
typename std::list<BitmaskType>::iterator n, next;
101
while (! faces.empty()) {
102
for (f = faces.begin(); f != faces.end(); ++f) {
103
// Expand this face by combining with other extremal rays.
105
for (r = rays.begin(); r != rays.end(); ++r) {
106
BitmaskType comb(*f);
109
// Ignore rays already in this face.
113
// Ignore rays that will break admissibility.
115
for (c = constMasks.begin(); c != constMasks.end(); ++c) {
118
if (! b.atMostOneBit()) {
126
// comb expands *f to a higher-dimensional superface.
129
// Strip out duplicates, and also strip out superfaces of
130
// too high a dimension (since we only want to step up one
131
// dimension at a time).
134
while (n != nextDim.end()) {
138
// comb has too high a dimension, or is a duplicate.
143
// *n has too high a dimension.
149
nextDim.push_back(comb);
152
maxFaces->push_back(*f);
154
std::swap(nextDim, faces);
162
} // namespace regina