Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/geometry/triangulation/triangulations.cc
4097 views
1
#include <algorithm>
2
#include "triangulations.h"
3
4
5
//------------ traverse the edges of the secondary polytope ------------
6
triangulations::triangulations(const flips& all_flips)
7
: hash_max(10000),
8
hash_list(hash_max,hash_max),
9
bistellar_flips(all_flips),
10
position(0),
11
star(-1),
12
fine(false),
13
need_resize(false)
14
{}
15
16
17
// find the correct position for t in the hash
18
void triangulations::find_hash_position(const compact_simplices& t,
19
hash_value& pos, bool& is_new) const
20
{
21
hash_value freespace;
22
const hash_value initial_guess = t.hash_function() % hash_max;
23
24
for (hash_value i=0; i<hash_max; ++i) {
25
pos = (initial_guess+i) % hash_max;
26
if (hash_list[pos]==hash_max) {
27
// found empty place in hash
28
is_new=true;
29
if (i>5)
30
need_resize = true;
31
return;
32
}
33
else if ((*this)[hash_list[pos]]==t) {
34
// found ourselves in hash
35
is_new = false;
36
return;
37
}
38
// hash collision: continue
39
}
40
assert(false); // the need_resize was not honored, bug?
41
}
42
43
44
void triangulations::add_triang_if_new(const compact_simplices & new_triang)
45
{
46
hash_value pos;
47
bool is_new;
48
find_hash_position(new_triang, pos, is_new);
49
if (!is_new) return;
50
51
while (need_resize) {
52
hash_max = 2*hash_max+1;
53
hash_list = std::vector<size_t>(hash_max, hash_max);
54
for (size_t i=0; i<size(); i++) {
55
find_hash_position( (*this)[i], pos, is_new);
56
assert(is_new);
57
hash_list[pos] = i;
58
}
59
need_resize = false;
60
find_hash_position(new_triang, pos, is_new);
61
}
62
63
push_back(new_triang);
64
hash_list[pos] = size()-1;
65
}
66
67
68
void triangulations::add_neighbours(const simplices & s)
69
{
70
for (flips::const_iterator
71
f=bistellar_flips.begin(); f!=bistellar_flips.end(); ++f) {
72
goodcircuit goody(s,*f);
73
if (goody.is_good()) {
74
goody.do_flip(s,*f);
75
compact_simplices new_triang=goody.get_neighbor();
76
add_triang_if_new(new_triang);
77
}
78
}
79
}
80
81
82
bool triangulations::have_more_triangulations()
83
{
84
while (position != this->size()) {
85
// eat all non-star triangulations
86
simplices triangulation((*this)[position]);
87
88
if ((star>=0) && !(triangulation.starshaped(star))) {
89
next_triangulation();
90
continue;
91
}
92
// eat non-fine triangulations
93
if (fine && !(triangulation.fine())) {
94
next_triangulation();
95
continue;
96
}
97
return true;
98
}
99
return false;
100
}
101
102
103
const compact_simplices& triangulations::next_triangulation()
104
{
105
add_neighbours((*this)[position]);
106
return (*this)[position++];
107
}
108
109
110
111
112
//------------ to be called from Python -------------------------
113
triangulations_ptr init_triangulations
114
(int n, int d, int star, bool fine, PyObject* py_seed, PyObject* py_flips)
115
{
116
vertices().set_dimensions(n,d);
117
118
compact_simplices seed;
119
for (int i=0; i<PySequence_Size(py_seed); i++) {
120
PyObject* simplex = PySequence_GetItem(py_seed,i);
121
seed.push_back(PyInt_AS_LONG(simplex));
122
Py_DECREF(simplex);
123
}
124
125
flips all_flips;
126
for (int i=0; i<PySequence_Size(py_flips); i++) {
127
PyObject* py_flip = PySequence_GetItem(py_flips,i);
128
PyObject* py_flip_pos = PySequence_GetItem(py_flip,0);
129
PyObject* py_flip_neg = PySequence_GetItem(py_flip,1);
130
131
std::vector<vertices> pos;
132
for (int j=0; j<PySequence_Size(py_flip_pos); j++) {
133
PyObject* py_simplex = PySequence_GetItem(py_flip_pos,j);
134
vertices simplex;
135
for (int k=0; k<PySequence_Size(py_simplex); k++) {
136
PyObject* py_vertex = PySequence_GetItem(py_simplex,k);
137
simplex.insert(simplex.begin(), PyInt_AS_LONG(py_vertex));
138
Py_DECREF(py_vertex);
139
}
140
pos.push_back(simplex);
141
Py_DECREF(py_simplex);
142
}
143
144
std::vector<vertices> neg;
145
for (int j=0; j<PySequence_Size(py_flip_neg); j++) {
146
PyObject* py_simplex = PySequence_GetItem(py_flip_neg,j);
147
vertices simplex;
148
for (int k=0; k<PySequence_Size(py_simplex); k++) {
149
PyObject* py_vertex = PySequence_GetItem(py_simplex,k);
150
simplex.insert(simplex.begin(), PyInt_AS_LONG(py_vertex));
151
Py_DECREF(py_vertex);
152
}
153
neg.push_back(simplex);
154
Py_DECREF(py_simplex);
155
}
156
157
all_flips.push_back(flip(pos,neg));
158
all_flips.push_back(flip(neg,pos));
159
Py_DECREF(py_flip_pos);
160
Py_DECREF(py_flip_neg);
161
Py_DECREF(py_flip);
162
}
163
164
// print data so we can see that it worked
165
/*
166
std::cout << "\n" << "Seed triangulation: " << seed << "\n";
167
{
168
std::cout << "Vertices of seed triangulation: ";
169
simplices s(seed);
170
std::cout << s << "\n";
171
}
172
std::cout << "All flips:\n";
173
for (flips::const_iterator i=all_flips.begin(); i!=all_flips.end(); ++i)
174
std::cout << *i << std::endl;
175
*/
176
177
triangulations_ptr t = new triangulations(all_flips);
178
179
if (star>=0)
180
t->require_star_triangulation(star);
181
182
if (fine)
183
t->require_fine_triangulation(fine);
184
185
t->add_triang_if_new(seed);
186
187
return t;
188
}
189
190
191
PyObject* next_triangulation(triangulations_ptr t)
192
{
193
if (!t->have_more_triangulations())
194
return PyTuple_New(0);
195
196
const compact_simplices& triang = t->next_triangulation();
197
PyObject* py_triang = PyTuple_New(triang.size());
198
for (int i=0; i<triang.size(); i++)
199
PyTuple_SET_ITEM(py_triang, i, PyInt_FromLong(triang[i]));
200
201
return py_triang;
202
}
203
204
205
void delete_triangulations(triangulations_ptr t)
206
{
207
delete(t);
208
}
209
210
211