Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/geometry/triangulation/data.cc
4045 views
1
#include <iostream>
2
#include <fstream>
3
#include <set>
4
#include <functional>
5
#include <vector>
6
#include <algorithm>
7
#include "functions.h"
8
#include "data.h"
9
10
11
12
13
// ------- class vertices ----------------------------
14
15
int vertices::n=0;
16
17
int vertices::d=0;
18
19
vertices_lookup vertices::lookup=vertices_lookup();
20
21
22
void vertices::set_dimensions(int N, int D)
23
{
24
n=N; d=D;
25
lookup.generate_tables(n,d);
26
}
27
28
29
vertices::vertices()
30
{
31
}
32
33
34
vertices::vertices(const simplex& S)
35
{
36
simplex_to_vertices(S);
37
}
38
39
40
const simplex vertices::vertices_to_simplex() const
41
{
42
simplex s=1;
43
vertex k=1, l;
44
const_iterator l_iterator=begin();
45
for (vertex i=1; i<=d; ++i) {
46
l = (*l_iterator)+1;
47
for (vertex j=k; j<=l-1; ++j)
48
s=s+lookup.get_binomial(n-j,d-i);
49
k=l+1;
50
++l_iterator;
51
}
52
return(s);
53
}
54
55
56
const vertices & vertices::simplex_to_vertices(const simplex & S)
57
{
58
(*this) = lookup.simplex_to_vertices(S);
59
return(*this);
60
}
61
62
63
std::ostream & operator << (std::ostream & out, const vertices & v)
64
{
65
out << *( v.begin() );
66
vertices::const_iterator i=v.begin(); i++;
67
for (; i!=v.end(); ++i)
68
out << "_" << *i;
69
return(out);
70
}
71
72
73
bool vertices_order::operator()(const vertices & a, const vertices & b) const
74
{
75
size_t n1=a.size(), n2=b.size();
76
if (n1<n2) return(true);
77
if (n1>n2) return(false);
78
// a,b have same size
79
for (vertices::iterator i=a.begin(), j=b.begin();
80
i!=a.end() && j!=b.end(); ++i, ++j) {
81
if (*i < *j) return(true);
82
if (*i > *j) return(false);
83
}
84
// a == b
85
return(false);
86
}
87
88
89
bool operator==(const vertices & a, const vertices & b)
90
{
91
return( std::set<vertex,std::less<vertex> >(a) ==
92
std::set<vertex,std::less<vertex> >(b) );
93
}
94
95
96
// ------- class vertices_lookup --------------------
97
98
const vertices & vertices_lookup::simplex_to_vertices(const simplex & S) const
99
{
100
return( SimplexToVertices[S-1] );
101
}
102
103
104
// this one is messy, but it only reverses vertices_to_simplex()
105
vertices vertices_lookup::manual_vertices_to_simplex(const simplex & S) const
106
{
107
vertices result;
108
simplex s=S;
109
simplex b;
110
vertex i,j,l=0,k;
111
for (k=1; k<d; k++) {
112
l++; i=l; j=1;
113
b=binomial(n-l,d-k);
114
while (s>b && b>0) {
115
j++; l++;
116
s=s-b;
117
b=binomial(n-l,d-k);
118
}
119
result.insert(result.begin(),l-1);
120
}
121
result.insert(result.begin(),s+l-1);
122
return(result);
123
}
124
125
// tweaked for special (e.g. negative) values
126
int vertices_lookup::get_binomial(int i, int j) const
127
{
128
if (i>=0 && i<=n && j>=0 && j<=d && j<=i)
129
return(fast_binomial[i][j]);
130
else
131
return(1);
132
}
133
134
135
void vertices_lookup::generate_tables(int N, int D)
136
{
137
n=N; d=D;
138
fast_binomial.erase(fast_binomial.begin(),fast_binomial.end());
139
for(int i=0; i<=n; ++i) {
140
std::vector<int> row;
141
for(int j=0; j<=i && j<=d; j++)
142
row.push_back( binomial(i,j) );
143
fast_binomial.push_back( row );
144
}
145
SimplexToVertices.erase(SimplexToVertices.begin(),SimplexToVertices.end());
146
for(int s=1; s<=binomial(n,d); ++s)
147
SimplexToVertices.push_back(manual_vertices_to_simplex(s));
148
}
149
150
151
152
153
// ------- class compact_simplices -------------------
154
155
compact_simplices::compact_simplices()
156
{
157
reserve(50);
158
}
159
160
compact_simplices::~compact_simplices()
161
{
162
}
163
164
std::ostream & operator << (std::ostream & out, const compact_simplices & t)
165
{
166
out << "[" << *( t.begin() );
167
for (compact_simplices::const_iterator i=t.begin()+1; i!=t.end(); ++i)
168
out << "," << *i;
169
out << "]";
170
return(out);
171
}
172
173
const bool operator==(const compact_simplices & a, const compact_simplices & b)
174
{
175
// friendship is not inherited
176
return( std::vector<simplex>(a) == std::vector<simplex>(b) );
177
}
178
179
hash_value compact_simplices::hash_function() const
180
{
181
hash_value result=0;
182
int n=101;
183
for (const_iterator i=begin(); i!=end(); ++i, n+=37)
184
result += n* (*i) + n*n;
185
return(result);
186
}
187
188
189
190
191
192
// ------- class simplices ---------------------------
193
194
simplices::simplices(const compact_simplices & s)
195
:compact_simplices(s)
196
{
197
decompress(); // de-compress vertex information
198
}
199
200
simplices::simplices(const std::set<vertices,vertices_order> & s)
201
{
202
v.erase(v.begin(), v.end());
203
copy(s.begin(), s.end(), back_inserter(v) );
204
compress();
205
}
206
207
208
simplices::~simplices()
209
{
210
}
211
212
void simplices::compress()
213
{
214
erase(begin(),end());
215
for (std::vector<vertices>::const_iterator i=v.begin(); i!=v.end(); i++)
216
push_back( (*i).vertices_to_simplex() );
217
std::sort(begin(),end());
218
}
219
220
221
void simplices::decompress()
222
{
223
v.erase(v.begin(),v.end());
224
for (const_iterator i=begin(); i!=end(); i++)
225
v.push_back( vertices().simplex_to_vertices(*i) );
226
}
227
228
229
bool simplices::starshaped(const vertex origin) const
230
{
231
bool result = true;
232
for (std::vector<vertices>::const_iterator
233
vi=v.begin(); vi!=v.end(); vi++) {
234
result=result && (find(vi->begin(),vi->end(),origin)!=vi->end());
235
}
236
return(result);
237
}
238
239
240
bool simplices::fine() const
241
{
242
vertices support;
243
for (std::vector<vertices>::const_iterator
244
vi=v.begin(); vi!=v.end(); vi++) {
245
support.insert(vi->begin(), vi->end());
246
}
247
return support.full_set();
248
}
249
250
251
std::ostream & operator << (std::ostream & out, const simplices & s)
252
{
253
out << "[" << s.v.front();
254
for (std::vector<vertices>::const_iterator
255
si=s.v.begin()+1; si!=s.v.end(); si++)
256
out << ", " << *si;
257
out << "]";
258
return(out);
259
}
260
261
// ------- class flip --------------------------------
262
263
flip::flip()
264
{
265
deltaplus.reserve(10);
266
deltaminus.reserve(10);
267
}
268
269
flip::flip(const std::vector<vertices>& pos, const std::vector<vertices>& neg)
270
: deltaplus(pos), deltaminus(neg)
271
{}
272
273
flip::flip(const flip & copyfrom)
274
{
275
deltaplus.reserve(10);
276
deltaminus.reserve(10);
277
(*this)=copyfrom;
278
}
279
280
flip::~flip()
281
{
282
}
283
284
flip & flip::operator =(const flip & copyfrom)
285
{
286
deltaplus = copyfrom.get_deltaplus();
287
deltaminus = copyfrom.get_deltaminus();
288
return(*this);
289
}
290
291
std::ostream & operator << (std::ostream & out, const flip & f)
292
{
293
out << "< ";
294
for (std::vector<vertices>::const_iterator i=f.get_deltaplus().begin();
295
i!=f.get_deltaplus().end(); ++i) {
296
std::cout << *i << " ";
297
}
298
out << "| ";
299
for (std::vector<vertices>::const_iterator i=f.get_deltaminus().begin();
300
i!=f.get_deltaminus().end(); ++i) {
301
std::cout << *i << " ";
302
}
303
out << ">";
304
return(out);
305
}
306
307
void flip::mirror()
308
{
309
swap(deltaplus,deltaminus);
310
}
311
312
313
314
315
// ------- class flips -------------------------------
316
317
flips::flips()
318
{
319
}
320
321
flips::~flips()
322
{
323
}
324
325
326
// ------- class goodcircuit -------------------------
327
328
329
goodcircuit::goodcircuit(const simplices & s, const flip & f)
330
:supporter(f)
331
{
332
const std::vector<vertices> & deltaplus = f.get_deltaplus();
333
const std::vector<vertices> & v = s.get_vertices();
334
supported.reserve(deltaplus.size());
335
good=true;
336
337
338
// find simplices that include members of deltaplus
339
std::vector<vertices> empty_result;
340
for (size_t n=0; n<deltaplus.size(); n++) {
341
supported.push_back(empty_result); supported[n].reserve(10);
342
bool found_match=false;
343
for (std::vector<vertices>::const_iterator i=v.begin(); i!=v.end(); ++i) {
344
if (includes( (*i).begin(), (*i).end(),
345
deltaplus[n].begin(), deltaplus[n].end() )) {
346
found_match=true;
347
supported[n].push_back(*i);
348
}
349
}
350
good=good && found_match;
351
if (!good) return;
352
}
353
354
// check that all links are equal
355
for (size_t n=0; n<deltaplus.size(); n++) {
356
std::set<vertices,vertices_order> l;
357
for (std::vector<vertices>::const_iterator i=supported[n].begin();
358
i!=supported[n].end(); ++i) {
359
vertices one_simplex;
360
std::insert_iterator<vertices>
361
ins(one_simplex,one_simplex.begin());
362
set_difference( (*i).begin(), (*i).end(),
363
deltaplus[n].begin(), deltaplus[n].end(),
364
ins );
365
l.insert(l.begin(),one_simplex);
366
}
367
link.push_back(l);
368
if (n>0 && link[0]!=link[n]) {
369
good=false;
370
return;
371
}
372
}
373
}
374
375
376
void goodcircuit::do_flip(const simplices & s, const flip & f)
377
{
378
bistellarneighbor.erase(bistellarneighbor.begin(), bistellarneighbor.end());
379
380
const std::set<vertices,vertices_order> & use_link = link[0];
381
const std::vector<vertices> & v = s.get_vertices();
382
const std::vector<vertices> & deltaplus = f.get_deltaplus();
383
const std::vector<vertices> & deltaminus = f.get_deltaminus();
384
385
// start with all simplices
386
std::set<vertices,vertices_order> tri;
387
copy(v.begin(), v.end(), inserter(tri,tri.begin()) );
388
389
// remove all suported simplices
390
std::set<vertices,vertices_order> to_remove;
391
392
for (std::set<vertices,vertices_order>::const_iterator i=use_link.begin();
393
i!=use_link.end(); ++i)
394
for (std::vector<vertices>::const_iterator j=deltaplus.begin();
395
j!=deltaplus.end(); ++j) {
396
vertices one_simplex;
397
set_union( (*j).begin(), (*j).end(),
398
(*i).begin(), (*i).end(),
399
inserter(one_simplex,one_simplex.begin()) );
400
to_remove.insert(to_remove.begin(),one_simplex);
401
}
402
set_difference( tri.begin(), tri.end(),
403
to_remove.begin(), to_remove.end(),
404
inserter(bistellarneighbor,bistellarneighbor.begin()),
405
vertices_order() );
406
407
// now add the flip of the supported simplices
408
for (std::set<vertices,vertices_order>::const_iterator i=use_link.begin();
409
i!=use_link.end(); ++i)
410
for (std::vector<vertices>::const_iterator j=deltaminus.begin();
411
j!=deltaminus.end(); j++) {
412
vertices one_simplex;
413
set_union( (*j).begin(), (*j).end(),
414
(*i).begin(), (*i).end(),
415
inserter(one_simplex,one_simplex.begin()) );
416
bistellarneighbor.insert( bistellarneighbor.begin(), one_simplex );
417
}
418
}
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433