File: TriangFlips.cc

package info (click to toggle)
topcom 0.17.8%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 78,572 kB
  • sloc: cpp: 16,640; sh: 975; makefile: 345; ansic: 40
file content (225 lines) | stat: -rw-r--r-- 6,552 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
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
////////////////////////////////////////////////////////////////////////////////
// 
// TriangFlips.cc
//
//    produced: 27/05/98 jr
// last change: 27/05/98 jr
// 
////////////////////////////////////////////////////////////////////////////////
#include <iostream>

#include <set>

#include "Flip.hh"
#include "TriangFlips.hh"

// internal algorithms:

void TriangFlips::_remove_destroyed_flips(const TriangNode& tn, 
					  const Flip& flip,
					  const SymmetryGroup& symmetries) {
  static MarkedFlips old_flips;
  old_flips = _flips;
  for (MarkedFlips::const_iterator iter = old_flips.begin(); iter != old_flips.end(); ++iter) {
#ifndef STL_FLIPS
    const FlipRep fliprep(iter->key());
#else
    const FlipRep fliprep((*iter).first);
#endif
    const Flip old_flip = Flip(tn, fliprep);
    if (!(old_flip.first * flip.first).is_empty()) {
      _flips.erase(fliprep);
    }
  }
}

void TriangFlips::_add_new_flips(const Chirotope&         chiro,
				 const TriangNode&        tn,
				 const SimplicialComplex& restriction,
				 const SymmetryGroup&     symmetries,
				 const SymmetryGroup&     tn_symmetries,
				 const bool               forbid_vertex_removal,
				 const bool               forbid_card_change) {

#ifndef STL_CONTAINERS
  static HashSet<dependent_set_type> dependent_sets;
#else
  static std::set<dependent_set_type>     dependent_sets;
#endif
  static dependent_set_type          dependent_set;
#ifndef STL_CONTAINERS
  static SimplicialComplex           done_set;
#else
  static std::set<Simplex>                done_set;
#endif

  const Simplex tn_support(tn.support());
  const Simplex groundset(Permutation(_no, _no));
  const Simplex missing_vertices(groundset - tn_support);
  // any new flip in tn must contain one of the flipped-in simplices:
  size_type countdown(restriction.card());
  for (SimplicialComplex::const_iterator iter1 = restriction.begin();
       iter1 != restriction.end();
       ++iter1) {
    --countdown;
    const Simplex& simp1(*iter1);
#ifndef STL_CONTAINERS
    if (done_set.contains(simp1, _rank)) {
#else
    if (done_set.find(simp1) != done_set.end()) {
#endif
      // processed already:
      continue;
    }
#ifndef STL_CONTAINERS
    done_set.insert(simp1, _rank);
#else
    done_set.insert(simp1);
#endif
    for (SymmetryGroup::const_iterator sym_iter = tn_symmetries.begin();
	 sym_iter != tn_symmetries.end();
	 ++sym_iter) {
      const Symmetry& g(*sym_iter);
#ifndef STL_CONTAINERS
      done_set.insert(g(simp1), _rank);
#else
      done_set.insert(g(simp1));
#endif
    }
    if (CommandlineOptions::verbose() && (_no > 50)) {
      std::cerr << "... still " << countdown << " simplices to check for flips ..." << std::endl;
    }
    // search for missing interior points:
    for (Simplex::const_iterator missing_iter = missing_vertices.begin();
	 missing_iter != missing_vertices.end();
	 ++missing_iter) {
      dependent_set = simp1 + *missing_iter;
#ifndef STL_CONTAINERS
      if (dependent_sets.member(dependent_set)) {
#else
      if (dependent_sets.find(dependent_set) != dependent_sets.end()) {
#endif
	// processed already:
	continue;
      }
      // try to build a flip from dependent_set:
      const FlipRep fliprep(chiro, dependent_set, tn);
      if (fliprep) {
	// succeeded:
	if (forbid_vertex_removal && fliprep.kills_vertex()) {
	  continue;
	}
	if (forbid_card_change && !fliprep.is_balanced()) {
	  continue;
	}
// 	else if (CommandlineOptions::reduce_points() && !fliprep.kills_vertex()) {
// 	  continue;
// 	}
// 	else if (CommandlineOptions::dont_add_points() && fliprep.adds_vertex()) {
// 	  continue;
// 	}
	// insert flip:
	_flips[fliprep] = false;
	dependent_sets.insert(dependent_set);
	for (SymmetryGroup::const_iterator sym_iter = tn_symmetries.begin();
	     sym_iter != tn_symmetries.end();
	     ++sym_iter) {
	  // insert all equivalent flips:
	  const Symmetry& g(*sym_iter);
	  _flips[g(fliprep)] = false;
	  dependent_sets.insert(g(dependent_set));
	}
      }
      else {
	// save processed dependent set:
	dependent_sets.insert(dependent_set);
	for (SymmetryGroup::const_iterator sym_iter = tn_symmetries.begin();
	     sym_iter != tn_symmetries.end();
	     ++sym_iter) {
	  // save equivalent dependent sets:
	  const Symmetry& g(*sym_iter);
	  dependent_sets.insert(g(dependent_set));
	}
      }      
    }
    int count(0);
    // search for adjacent simplices:
    for (SimplicialComplex::const_iterator iter2 = tn.begin();
	 iter2 != tn.end();
	 ++iter2) {
      const Simplex& simp2(*iter2);
      dependent_set = (simp1 + simp2);
      if (dependent_set.card() != _rank + 1) {
	continue;
      }
      // simp2 is adjacent to simp1:
#ifndef STL_CONTAINERS
      if (dependent_sets.member(dependent_set)) {
#else
      if (dependent_sets.find(dependent_set) != dependent_sets.end()) {
#endif
	// processed already:
	continue;
      }
      // try to build a flip from dependent_set:
      const FlipRep fliprep(chiro, dependent_set, tn);
      if (fliprep) {
	// succeeded:
	if (forbid_vertex_removal && fliprep.kills_vertex()) {
	  continue;
	}
// 	else if (CommandlineOptions::reduce_points() && !fliprep.kills_vertex()) {
// 	  continue;
// 	}
	else if (CommandlineOptions::dont_add_points() && fliprep.adds_vertex()) {
	  continue;
	}
	// insert flip:
	_flips[fliprep] = false;
	dependent_sets.insert(dependent_set);
	for (SymmetryGroup::const_iterator sym_iter = tn_symmetries.begin();
	     sym_iter != tn_symmetries.end();
	     ++sym_iter) {
	  // insert all equivalent flips:
	  const Symmetry& g(*sym_iter);
	  _flips[g(fliprep)] = false;
	  dependent_sets.insert(g(dependent_set));
	}
      }
      else {
	// save processed dependent set:
	dependent_sets.insert(dependent_set);
	for (SymmetryGroup::const_iterator sym_iter = tn_symmetries.begin();
	     sym_iter != tn_symmetries.end();
	     ++sym_iter) {
	  // save equivalent dependent sets:
	  const Symmetry& g(*sym_iter);
	  dependent_sets.insert(g(dependent_set));
	}
      }
      if (++count > _rank) {
	// we have all neighbors already:
	break;
      }
    }
  }
  dependent_sets.clear();
  done_set.clear();
  if (!forbid_vertex_removal
      && CommandlineOptions::neighborcount() 
#ifndef STL_FLIPS
      && (_flips.load() < _no - _rank)) {
#else
      && (_flips.size() < _no - _rank)) {
#endif
    std::cerr << "triangulation" << std::endl
	 << tn << std::endl
#ifndef STL_FLIPS
 	 << "has only " << _flips.load() << " flips." << std::endl;
#else
	 << "has only " << _flips.size() << " flips." << std::endl;
#endif
  }
}

// eof TriangFlips.cc